/* ----------------------------------------------------------------------------------------
 * Author        : Prospera
 * File          : My Points (client loyalty) css
 * ----------------------------------------------------------------------------------------
 *
 * Points are shown the way css/bookings.css shows sessions: as a course of care
 * rather than a scoreboard. There are no tiers, no streaks and no badges here on
 * purpose -- a mental health client is not a frequent flyer, and celebrating
 * somebody for needing more therapy is the one thing this page must never do.
 * The programme is framed as a thank-you for continuity, and every figure on the
 * page is a fact the ledger can defend.
 *
 * The signature is the release rail: points open PENDING when a session is paid
 * for and unlock to READY when that session is completed (LoyaltyLedger::earn ->
 * unlockLot). That transition is the one thing about this ledger a client cannot
 * guess, so it is drawn rather than explained in a tooltip.
 *
 * Colour discipline is inherited from bookings.css: no new brand colours, and
 * gold (--gold-color) is spent in exactly one place -- a reward the client has
 * enough points for right now. Earned is teal; everything spent or lost recedes
 * into muted ink, so the page never sounds an alarm over a normal event.
 *
 * Class prefix `lp-` (loyalty points). The page wrapper is `.bk-page lp-scope`,
 * which is what resolves --bk-ink / --bk-thread / --bk-hair and friends; a
 * wrapper under any other class name leaves the shared .bk-state / .bk-btn /
 * .bk-spinner pieces colourless.
 * -------------------------------------------------------------------------- */

.lp-scope {
  --lp-on-dark: rgba(255, 255, 255, 0.72);
  --lp-on-dark-quiet: rgba(255, 255, 255, 0.2);
}

/* --- The hero: one number, and the rail that explains the other one -------- */

.lp-hero {
  position: relative;
  background: var(--bk-ink);
  border-radius: 24px;
  padding: 34px 40px 38px;
  overflow: hidden;
  color: var(--white-color);
}

/* The same single teal light .bk-next carries -- this page's only ornament. */
.lp-hero::after {
  content: '';
  position: absolute;
  inset-block-start: -140px;
  inset-inline-end: -90px;
  width: 360px;
  height: 360px;
  border-radius: 50%;
  background: radial-gradient(
    circle,
    rgba(47, 168, 160, 0.32) 0%,
    rgba(47, 168, 160, 0) 70%
  );
  pointer-events: none;
}

.lp-hero > * {
  position: relative;
  z-index: 1;
}

.lp-hero-eyebrow {
  display: block;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--sand-color);
  margin-bottom: 26px;
}

/* Loading and error hold the card near its settled height so the page does not
   jump when the figure arrives. */
.lp-hero-loading,
.lp-hero-error {
  display: flex;
  align-items: center;
  min-height: 96px;
}

/* One request feeds the balance, the rail and the history, so one failure gets
   one error -- stated here, on the card, rather than repeated down the page. */
.lp-hero-error {
  flex-direction: column;
  align-items: flex-start;
  gap: 18px;
}

.lp-hero-error p {
  margin: 0;
  max-width: 420px;
  font-size: 15px;
  line-height: 1.7em;
  color: var(--lp-on-dark);
}

.lp-hero-loading .bk-spinner {
  margin: 0;
  border-color: var(--lp-on-dark-quiet);
  border-top-color: var(--accent-color);
}

/* --- The ready figure ------------------------------------------------------ */

.lp-ready-figure {
  display: block;
  font-family: var(--accent-font);
  font-size: clamp(56px, 11vw, 92px);
  line-height: 0.92;
  color: var(--white-color);
}

.lp-ready-label {
  display: block;
  margin-top: 14px;
  font-size: 15px;
  line-height: 1.6em;
  color: var(--lp-on-dark);
}

/* --- The release rail: pending -> ready ------------------------------------ */

/* Beads and captions are ONE grid, not two stacked ones: separate grid
   containers size their tracks independently, so a caption would drift out from
   under its own bead the moment the two rows held different content. Row 1 is
   bead / track / bead; row 2 is the two captions in the outer columns. */
.lp-rail {
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  column-gap: 14px;
  row-gap: 16px;
  margin-top: 34px;
  padding-top: 30px;
  border-top: 1px solid var(--lp-on-dark-quiet);
}

.lp-rail-bead {
  grid-row: 1;
  width: 13px;
  height: 13px;
  border-radius: 50%;
}

/* Hollow: these points exist, but they are not yours to spend yet. */
.lp-rail-bead--pending {
  grid-column: 1;
  justify-self: start;
  border: 2px solid var(--sand-color);
}

.lp-rail-bead--ready {
  grid-column: 3;
  justify-self: end;
  background: var(--accent-color);
  box-shadow: 0 0 0 5px rgba(47, 168, 160, 0.22);
}

.lp-rail-track {
  grid-row: 1;
  grid-column: 2;
  position: relative;
  height: 2px;
  border-radius: 2px;
  background: var(--lp-on-dark-quiet);
  overflow: hidden;
}

/* One travelling highlight, the page's only animation: it shows points moving
   from pending into ready, which is the transition this rail exists to explain.
   Silenced for anyone who asks for less motion (see the end of this file). */
.lp-rail-track::after {
  content: '';
  position: absolute;
  inset-block: 0;
  inset-inline-start: 0;
  width: 42%;
  background: linear-gradient(
    to right,
    rgba(47, 168, 160, 0) 0%,
    var(--accent-color) 50%,
    rgba(47, 168, 160, 0) 100%
  );
  animation: lp-travel 3.6s ease-in-out infinite;
}

@keyframes lp-travel {
  0% {
    transform: translateX(-100%);
  }
  100% {
    transform: translateX(280%);
  }
}

/* In Arabic the rail reads right to left, so the highlight has to travel the
   other way or it depicts the transition backwards. */
body.rtl .lp-rail-track::after {
  animation-name: lp-travel-rtl;
}

@keyframes lp-travel-rtl {
  0% {
    transform: translateX(100%);
  }
  100% {
    transform: translateX(-280%);
  }
}

/* The middle column of row 2 carries nothing; each caption sits in the outer
   column its own bead sits in, and is aligned to the same edge. */
.lp-rail-stop {
  grid-row: 2;
  grid-column: 1;
  max-width: 210px;
}

.lp-rail-stop--end {
  grid-column: 3;
  justify-self: end;
  text-align: end;
}

.lp-rail-figure {
  display: block;
  font-family: var(--accent-font);
  font-size: 26px;
  line-height: 1;
  color: var(--white-color);
}

.lp-rail-name {
  display: block;
  margin-top: 8px;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--sand-color);
}

.lp-rail-note {
  display: block;
  margin-top: 7px;
  font-size: 12px;
  line-height: 1.6em;
  color: var(--lp-on-dark);
}

/* --- Footnote: the fact that does not belong on the card ------------------- */

/* The gap below the summary lives on the wrapper, not on the footnote, so it
   survives the footnote being hidden (a client with no lifetime total yet). */
.lp-summary {
  margin-bottom: 44px;
}

.lp-footnote {
  margin: 18px 4px 0;
  font-size: 13px;
  line-height: 1.7em;
  color: var(--bk-muted);
}

.lp-footnote span + span::before {
  content: '\00b7';
  margin: 0 10px;
}

/* An expiry inside 30 days stops being a footnote and becomes a prompt. */
.lp-footnote .lp-soon {
  color: var(--gold-color);
  font-weight: 600;
}

/* --- Section headings ------------------------------------------------------ */

.lp-section {
  margin-bottom: 48px;
}

.lp-section-title {
  font-family: var(--accent-font);
  font-size: 26px;
  line-height: 1.3em;
  color: var(--bk-ink);
  margin: 0 0 8px;
}

.lp-section-note {
  font-size: 13px;
  line-height: 1.7em;
  color: var(--bk-muted);
  margin: 0 0 24px;
  max-width: 540px;
}

/* --- Rewards --------------------------------------------------------------- */

.lp-rewards {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
  gap: 16px;
}

.lp-reward {
  display: flex;
  flex-direction: column;
  background: var(--bk-surface);
  border: 1px solid var(--bk-hair);
  border-radius: 16px;
  padding: 22px 24px;
}

/* A reward the client can have today is the only gold on this page. */
.lp-reward--ready {
  border-color: rgba(212, 162, 76, 0.55);
}

.lp-reward-value {
  font-family: var(--accent-font);
  font-size: 30px;
  line-height: 1;
  color: var(--bk-ink);
}

.lp-reward-name {
  margin-top: 10px;
  font-size: 15px;
  font-weight: 600;
  color: var(--bk-ink);
}

.lp-reward-terms {
  margin-top: 7px;
  font-size: 12px;
  line-height: 1.6em;
  color: var(--bk-muted);
}

/* margin-top:auto pins the footer to the bottom of the tallest card in the
   row, so the costs line up across a row of uneven names. */
.lp-reward-foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
  margin-top: auto;
  padding-top: 16px;
  border-top: 1px solid var(--bk-hair);
}

.lp-reward-foot-spacer {
  margin-top: 20px;
}

.lp-reward-cost {
  font-size: 13px;
  font-weight: 600;
  color: var(--bk-ink);
}

.lp-reward-state {
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--bk-muted);
  white-space: nowrap;
}

.lp-reward--ready .lp-reward-state {
  color: var(--gold-color);
}

/* --- History on the thread ------------------------------------------------- */

/* Sits where .bk-node-card sits, but is not a button: nothing on this page
   opens a detail drawer, so these rows take no hover or cursor treatment. */
.lp-entry {
  display: flex;
  align-items: center;
  gap: 20px;
  background: var(--bk-surface);
  border: 1px solid var(--bk-hair);
  border-radius: 16px;
  padding: 20px 24px;
}

.lp-entry-main {
  flex: 1;
  min-width: 0;
}

.lp-entry-title {
  display: block;
  font-size: 15px;
  font-weight: 600;
  color: var(--bk-ink);
}

.lp-entry-meta {
  display: block;
  margin-top: 6px;
  font-size: 13px;
  line-height: 1.6em;
  color: var(--bk-muted);
}

.lp-entry-meta span + span::before {
  content: '\00b7';
  margin: 0 8px;
}

.lp-entry-figure {
  flex: 0 0 auto;
  font-family: var(--accent-font);
  font-size: 24px;
  line-height: 1;
  direction: ltr;
  color: var(--bk-muted);
}

.lp-entry-figure.is-earned {
  color: var(--bk-thread);
}

/* Points that left the balance recede rather than alarm: spending them was the
   point of having them, and letting them expire is not worth colouring red. */
.lp-entry-figure.is-spent {
  color: var(--bk-ink);
}

/* A zero-point entry ("your points unlocked") is a state change, not a
   movement, so it carries a mark instead of a misleading "+0". */
.lp-entry--marker .lp-entry-figure {
  font-size: 15px;
  color: var(--bk-thread);
}

.lp-entry--lost {
  background: transparent;
  border-style: dashed;
}

.lp-entry--lost .lp-entry-title {
  color: var(--bk-muted);
  font-weight: 500;
}

/* --- How points work: shown to a client who has none yet ------------------- */

.lp-steps {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
  gap: 14px;
  margin-top: 30px;
  text-align: start;
}

.lp-step {
  background: var(--bk-surface);
  border: 1px solid var(--bk-hair);
  border-radius: 16px;
  padding: 20px 22px;
}

/* Numbered because these really are a sequence: you cannot unlock points you
   have not earned, or spend points that have not unlocked. */
.lp-step-index {
  display: block;
  font-family: var(--accent-font);
  font-size: 20px;
  color: var(--bk-thread);
  margin-bottom: 10px;
}

.lp-step-text {
  display: block;
  font-size: 13px;
  line-height: 1.7em;
  color: var(--bk-muted);
}

/* --- Responsive ------------------------------------------------------------ */

@media only screen and (max-width: 767px) {
  .lp-hero {
    padding: 26px 22px 30px;
  }

  /* The captions stack full width and the bead row stays: at this width the two
     captions collide long before the track is short enough to be worth dropping,
     and the track is the part that carries the meaning. */
  .lp-rail-stop,
  .lp-rail-stop--end {
    grid-column: 1 / -1;
    justify-self: stretch;
    max-width: none;
    text-align: start;
  }

  .lp-rail-stop {
    grid-row: 2;
  }

  .lp-rail-stop--end {
    grid-row: 3;
  }

  .lp-entry {
    padding: 18px;
    gap: 14px;
  }

  .lp-section-title {
    font-size: 22px;
  }
}

@media (prefers-reduced-motion: reduce) {
  .lp-rail-track::after {
    animation: none;
    /* Parked at the ready end rather than removed: the highlight carries
       meaning (points arriving), not decoration. */
    inset-inline-start: auto;
    inset-inline-end: 0;
    width: 26%;
  }
}
