/* ============================================================================
   Button motion, shared by every app page.

   Loaded last on each page so these transitions win over the pages' own.
   The rules are few and deliberate:
     * every button answers a press: it gives slightly under the pointer;
     * with a mouse, a button rises a pixel to say it can be pressed, and
       the primary actions glow and catch a sheen of light;
     * close buttons turn a quarter; round icon buttons swell a little;
     * dialogs arrive (fade plus a small rise and scale) instead of popping in.
   Hover motion is gated to fine pointers, since a touch tap fires a false
   hover. Reduced motion keeps the colour changes and the dialog fade and
   drops every movement.
   ========================================================================= */
:root {
  --m-ease: cubic-bezier(.23, 1, .32, 1);       /* strong ease-out, as the pages use */
  --m-press: 160ms;
}

/* ── one named transition for every button ─────────────────────────────── */
.more, .va, .drishti-btn, .yoga-footer a, .what-btn, .pill-btn, .back, .dr-toggle button,
.cta, .dl, .btn, .sb-download,
.modal-x, .dlg-x, .modal-close, .dr-close, .info-btn, .help, .act, .avatar-btn, .info-dot, .tab {
  transition: transform var(--m-press) var(--m-ease), background-color .15s ease, border-color .15s ease,
    color .15s ease, box-shadow .2s ease, filter .15s ease, opacity .15s ease;
}

/* ── press: the button gives under the pointer ─────────────────────────── */
:is(.more, .va, .drishti-btn, .yoga-footer a, .what-btn, .pill-btn, .back, .dr-toggle button, .tab):active {
  transform: scale(.96);
}
:is(.cta, .dl, .btn):not(:disabled):not([aria-busy="true"]):active { transform: scale(.975); }
:is(.modal-x, .dlg-x, .modal-close, .dr-close, .info-btn, .help, .avatar-btn, .info-dot):active {
  transform: scale(.9);
}
/* this one is centred with a translate, so the press keeps it */
.act:active { transform: translateY(-50%) scale(.9); }

/* ── hover, mouse only ─────────────────────────────────────────────────── */
@media (hover: hover) and (pointer: fine) {
  /* small pills and text buttons: rise a pixel */
  :is(.more, .va, .drishti-btn, .what-btn, .pill-btn, .back):hover { transform: translateY(-1px); }
  :is(.more, .va, .drishti-btn, .what-btn, .pill-btn, .back):hover:active { transform: translateY(-1px) scale(.96); }
  .more:hover, .va:hover, .drishti-btn:hover { box-shadow: 0 4px 14px rgba(236, 72, 153, .22); }

  /* primary actions: rise, glow */
  :is(.cta, .dl, .btn):not(:disabled):not([aria-busy="true"]):hover {
    transform: translateY(-2px);
    box-shadow: 0 10px 28px rgba(236, 72, 153, .38), 0 2px 8px rgba(168, 85, 247, .3);
  }
  :is(.cta, .dl, .btn):not(:disabled):not([aria-busy="true"]):hover:active { transform: translateY(-1px) scale(.975); }
  .sb-download:not([aria-busy="true"]):hover { box-shadow: 0 8px 22px rgba(168, 85, 247, .3); }

  /* close buttons turn a quarter, which leaves the cross looking the same */
  :is(.modal-x, .dlg-x, .modal-close, .dr-close):hover { transform: rotate(90deg); }
  :is(.modal-x, .dlg-x, .modal-close, .dr-close):hover:active { transform: rotate(90deg) scale(.9); }

  /* round icon buttons swell a little */
  :is(.help, .info-btn, .info-dot):hover { transform: scale(1.1); }
  .avatar-btn:hover { transform: scale(1.06); box-shadow: 0 0 0 3px rgba(236, 72, 153, .22), 0 6px 18px rgba(168, 85, 247, .35); }
  .act:hover { transform: translateY(-50%) scale(1.08); }
  /* the press still gives while hovered: it wins over the swell */
  :is(.help, .info-btn, .info-dot, .avatar-btn):hover:active { transform: scale(.92); }
  .act:hover:active { transform: translateY(-50%) scale(.92); }
}

/* ── the primary actions' sheen ─────────────────────────────────────────
   A band of light crosses the button once when the pointer arrives. It
   travels only on the way in; leaving snaps it back while it is clipped
   out of sight, so it never runs backwards. */
.cta, .dl, .btn, .sb-download { position: relative; overflow: hidden; isolation: isolate; }
:is(.cta, .dl, .btn, .sb-download)::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  background: linear-gradient(105deg, transparent 30%, rgba(255, 255, 255, .24) 48%, rgba(255, 255, 255, .06) 56%, transparent 70%);
  transform: translateX(-110%);
}
@media (hover: hover) and (pointer: fine) and (prefers-reduced-motion: no-preference) {
  :is(.cta, .dl, .btn, .sb-download):not(:disabled):not([aria-busy="true"]):hover::after {
    transform: translateX(110%);
    transition: transform 700ms var(--m-ease);
  }
}

/* ── dialogs arrive ────────────────────────────────────────────────────── */
/* Dasha, Manglik, Medical: .modal[hidden] toggles, so @starting-style gives the entry */
.modal:has(> .modal-box) { transition: opacity .2s ease; }
.modal:has(> .modal-box) > .modal-box { transition: opacity .2s ease, transform 260ms var(--m-ease); }
@starting-style {
  .modal:has(> .modal-box) { opacity: 0; }
  .modal:has(> .modal-box) > .modal-box { opacity: 0; transform: translateY(12px) scale(.97); }
}

/* Kundali's all-yogas list: the overlay already fades on .open; the box rises with it */
.modal-overlay .modal-box { transform: translateY(12px) scale(.97); transition: transform 260ms var(--m-ease); }
.modal-overlay.open .modal-box { transform: none; }

/* Kundali's Meaning panel */
#drishti.open .dr-scrim { transition: opacity .2s ease; }
#drishti.open .dr-panel { transition: opacity .2s ease, transform 280ms var(--m-ease); }
@starting-style {
  #drishti.open .dr-scrim { opacity: 0; }
  #drishti.open .dr-panel { opacity: 0; transform: translateY(14px) scale(.985); }
}

/* Marriage Match: native <dialog> */
dialog.dlg[open] { transition: opacity .2s ease, transform 260ms var(--m-ease); }
dialog.dlg[open]::backdrop { transition: opacity .2s ease; }
@starting-style {
  dialog.dlg[open] { opacity: 0; transform: translateY(12px) scale(.97); }
  dialog.dlg[open]::backdrop { opacity: 0; }
}

/* ── Overview and the seven score pages ────────────────────────────────
   Their rows and tiles already give on press and nudge a caret on hover
   (style.css). This adds what they were missing: a row that lights its own
   bar, tiles whose icon answers, the unlock action treated as the primary
   action it is, and a score's pop-up that arrives instead of blinking in. */

/* score rows: the bar brightens, the rank badge warms, the name comes forward */
:is(#overviewSection, #categorySection) .dash-row-bar i { transition: filter .2s ease, box-shadow .2s ease; }
:is(#overviewSection, #categorySection) :is(.dash-row-icon, .dash-row-name) { transition: color .15s ease, background-color .15s ease, transform var(--m-press) var(--m-ease); }
@media (hover: hover) and (pointer: fine) {
  :is(#overviewSection, #categorySection) .dash-row:hover .dash-row-bar i {
    filter: brightness(1.18) saturate(1.1);
    box-shadow: 0 0 10px rgba(236, 72, 153, .45);
  }
  :is(#overviewSection, #categorySection) .dash-row:hover .dash-row-name { color: #fff; }
  #categorySection .dash-row:hover .cat-rank { background: rgba(236, 72, 153, .22); color: #fff; transform: scale(1.08); }

  /* the Overview's category tiles: the icon swells as the tile lifts */
  #overviewSection button.kpi .kpi-icon { transition: transform 200ms var(--m-ease); }
  #overviewSection button.kpi:hover .kpi-icon { transform: scale(1.1); }
  #overviewSection .ovp:hover { transform: translateY(-1px); }
  #overviewSection .ovp:hover:active { transform: translateY(-1px) scale(.98); }

  /* the free tier's buttons */
  :is(.dash-back, .lock-free):hover { transform: translateY(-1px); }
  :is(.dash-back, .lock-free):hover:active { transform: translateY(-1px) scale(.97); }
  .plan:hover { transform: translateY(-2px); box-shadow: 0 8px 22px rgba(168, 85, 247, .22); }
  .plan:hover:active { transform: translateY(-1px) scale(.985); }
  .lock-cta:hover { transform: translateY(-2px); box-shadow: 0 10px 28px rgba(236, 72, 153, .38), 0 2px 8px rgba(168, 85, 247, .3); }
  .lock-cta:hover:active { transform: translateY(-1px) scale(.975); }
}
.dash-back, .lock-free, .plan, .lock-cta {
  transition: transform var(--m-press) var(--m-ease), background-color .18s ease, border-color .18s ease,
    box-shadow .2s ease, filter .15s ease;
}
.lock-cta:active { transform: scale(.975); }
/* the unlock action gets the same sheen as the other primary actions */
.lock-cta { position: relative; overflow: hidden; isolation: isolate; }
.lock-cta::after {
  content: ""; position: absolute; inset: 0; z-index: 1; pointer-events: none;
  background: linear-gradient(105deg, transparent 30%, rgba(255, 255, 255, .24) 48%, rgba(255, 255, 255, .06) 56%, transparent 70%);
  transform: translateX(-110%);
}
@media (hover: hover) and (pointer: fine) and (prefers-reduced-motion: no-preference) {
  .lock-cta:hover::after { transform: translateX(110%); transition: transform 700ms var(--m-ease); }
}

/* The rest of a score page is read, not pressed: the score tiles, the radar,
   Top Strengths, the boosters and the influence cards. They answer the
   pointer with light only (a warmer border, a glow, a badge that swells)
   and never lift or give, so nothing pretends to be a button. */
#categorySection .kpi, .infl {
  transition: border-color .2s ease, background-color .2s ease, box-shadow .25s ease;
}
#categorySection .kpi :is(.kpi-icon, .kpi-rank), .infl-glyph, .rank-list :is(.rank, .dot, .dot-ic) {
  transition: transform 200ms var(--m-ease), box-shadow .2s ease, background-color .2s ease;
}
#categorySection .kpi .ov-meter i { transition: filter .2s ease; }
.rank-list li, .rank-list .rank-score { transition: color .15s ease; }
.radar-area { transition: filter .3s ease; }
.radar-dot { transform-box: fill-box; transform-origin: center; transition: transform 220ms var(--m-ease); }

@media (hover: hover) and (pointer: fine) {
  /* score tiles: the border warms, a soft glow, the icon or rank swells, the meter brightens */
  #categorySection .kpi:hover {
    border-color: rgba(255, 143, 176, .5);
    background-color: rgba(255, 255, 255, .06);
    box-shadow: 0 8px 26px rgba(236, 72, 153, .16), inset 0 1px 0 rgba(255, 255, 255, .05);
  }
  #categorySection .kpi:hover :is(.kpi-icon, .kpi-rank) { transform: scale(1.1); }
  #categorySection .kpi:hover .ov-meter i { filter: brightness(1.2) saturate(1.1); }

  /* the radar: the shape glows and its points swell while the pointer is over it */
  .radar-panel:hover .radar-area { filter: drop-shadow(0 0 12px rgba(236, 72, 153, .55)); }
  .radar-panel:hover .radar-dot { transform: scale(1.35); }

  /* Top Strengths and boosters: the line comes forward, its badge swells */
  .rank-list li:hover { color: #fff; }
  .rank-list li:hover .rank-score { color: #fff; }
  .rank-list li:hover :is(.rank, .dot, .dot-ic) { transform: scale(1.18); }
  .rank-list li:hover .rank { box-shadow: 0 0 10px rgba(236, 72, 153, .6); }

  /* influence cards: the border warms and the planet glyph swells */
  .infl:hover {
    border-color: rgba(160, 107, 255, .5);
    background-color: rgba(255, 255, 255, .06);
    box-shadow: 0 8px 24px rgba(160, 107, 255, .16);
  }
  .infl:hover .infl-glyph { transform: scale(1.1); box-shadow: 0 0 14px rgba(160, 107, 255, .45); }
}

/* ── every page's cards rise like the Overview's ────────────────────────
   The Overview's category tiles lift 2px under the pointer, their border
   warming and their face lightening. The same lift now runs on every page's
   cards: the stat tiles, house cells, reference, insight and lifestyle
   cards, the influence cards. Neutral cards also take the warm border and
   lighter face; cards that carry their own colour keep it and take a soft
   shadow instead, so the colour still says what it said. Panels, the big
   containers, stay put. */
#categorySection .kpi, #categorySection .infl,
.scard, .hcell,
#daDash .kpi,
.tile, .pc, .mini,
.ref,
.kpis .kpi, .ins, .lf, .wc {
  transition: transform 160ms var(--m-ease), border-color .2s ease, background-color .2s ease, box-shadow .25s ease;
}
@media (hover: hover) and (pointer: fine) {
  /* neutral cards: the Overview's lift, border and face */
  :is(#categorySection .kpi, #categorySection .infl, .scard, .hcell, #daDash .kpi:not(.lead), .ref, .wc):hover {
    transform: translateY(-2px);
    border-color: rgba(255, 143, 176, .55);
    background-color: rgba(255, 255, 255, .06);
  }
  /* coloured cards: the lift and a shadow, their own colours untouched */
  :is(#daDash .kpi.lead, .tile, .pc, .mini, .kpis .kpi, .ins, .lf):hover {
    transform: translateY(-2px);
    box-shadow: 0 10px 24px rgba(0, 0, 0, .35), 0 0 0 1px rgba(255, 143, 176, .25);
  }
}

/* ── and the panels rise too ─────────────────────────────────────────────
   The same 2px lift and warm border on every page's panels: the score
   lists, radars, charts, tables and the rest. Panels carry gradient faces,
   so they take a deeper shadow in place of a lighter face. A copy of a
   panel shown inside a dialog stays still. */
.panel:not(.in-dlg), .bal-panel,
#daDash .card,
.card.entry, .card.what, .card.tips, #mmOut .pn:not(.in-dlg) {
  transition: transform 160ms var(--m-ease), border-color .2s ease, box-shadow .25s ease;
}
@media (hover: hover) and (pointer: fine) {
  :is(.panel:not(.in-dlg), .bal-panel, #daDash .card, .card.entry, .card.what, .card.tips, #mmOut .pn:not(.in-dlg)):hover {
    transform: translateY(-2px);
    border-color: rgba(255, 143, 176, .45);
    box-shadow: 0 12px 30px rgba(0, 0, 0, .35);
  }
}

/* ── the sidebar rises with the rest ─────────────────────────────────────
   Each entry, the Download button and the collapse toggle lift 2px like the
   cards and panels; nav.css keeps their tints, and a press still gives. */
@media (hover: hover) and (pointer: fine) {
  .sidebar :is(.nav-cat-btn, .sb-download, .sb-toggle):hover { transform: translateY(-2px); }
  .sidebar .nav-cat-btn:hover { box-shadow: 0 6px 16px rgba(0, 0, 0, .35); }
  .nav-cat.current > .nav-cat-btn:hover, .sidebar .nav-link.active:hover {
    box-shadow: inset 0 0 0 1px rgba(192, 132, 252, .28), 0 6px 16px rgba(0, 0, 0, .35);
  }
  .sidebar :is(.nav-cat-btn, .sb-download):hover:active { transform: translateY(-2px) scale(.98); }
  .sidebar .sb-toggle:hover:active { transform: translateY(-2px) scale(.94); }
}
.sidebar .nav-cat-btn { transition: background-color .15s, color .15s, box-shadow .2s ease, transform 160ms var(--m-ease); }

/* a score's pop-up: the backdrop fades, the panel rises on the strong curve
   (it had a 160ms built-in ease-out, too weak to read as an arrival) */
.modal:has(> .modal-panel) .modal-backdrop { transition: opacity .2s ease; }
@starting-style { .modal:has(> .modal-panel) .modal-backdrop { opacity: 0; } }
.modal-panel { animation-duration: 260ms; animation-timing-function: var(--m-ease); }

/* ── reduced motion: colour and fades stay, movement goes ──────────────── */
@media (prefers-reduced-motion: reduce) {
  .more, .va, .drishti-btn, .yoga-footer a, .what-btn, .pill-btn, .back, .dr-toggle button,
  .cta, .dl, .btn, .sb-download,
  .modal-x, .dlg-x, .modal-close, .dr-close, .info-btn, .help, .avatar-btn, .info-dot, .tab {
    transform: none !important;
  }
  .act { transform: translateY(-50%) !important; }
  :is(.cta, .dl, .btn, .sb-download, .lock-cta)::after { display: none; }
  .dash-back, .lock-free, .plan, .lock-cta, .ovp, .cat-rank, #overviewSection button.kpi .kpi-icon,
  #categorySection .kpi :is(.kpi-icon, .kpi-rank), .infl-glyph, .rank-list :is(.rank, .dot, .dot-ic), .radar-dot { transform: none !important; }
  #categorySection .kpi, #categorySection .infl, .scard, .hcell, #daDash .kpi, .tile, .pc, .mini, .ref,
  .kpis .kpi, .ins, .lf, .wc { transform: none !important; }
  .panel, .bal-panel, #daDash .card, .card.entry, .card.what, .card.tips, #mmOut .pn { transform: none !important; }
  .sidebar :is(.nav-cat-btn, .sb-toggle) { transform: none !important; }
  .modal-panel { animation-name: m-fade; }
  @keyframes m-fade { from { opacity: 0; } }
  .modal:has(> .modal-box) > .modal-box, .modal-overlay .modal-box, #drishti.open .dr-panel, dialog.dlg[open] {
    transform: none !important;
  }
}
