/* ============================================================
   File:        payments.css
   Project:     StudioFlow (Grace Aerobics & Fitness Center)
   Developer:   Janvi Vakhariya — V Techno Labs
   Created:     2026-09-07
   Purpose:     Design system for Payments — three comparable period rows, filters, and an A-Z list.
   Copyright:   © 2026 V Techno Labs. All rights reserved.
                Proprietary software developed by V Techno Labs.
   ============================================================

   Prefix: sf-pay-, and nothing else. Never sf-member- / sf-memact- / sf-mdet- /
   sf-dash- / sf-idash- / sf-plan- / sf-batch- / sf-user- / sf-dev-. The only
   non-prefixed selector is the .sf-app shell override at the foot.

   THE SHAPE OF THE PAGE. Three rows that answer "how are we doing", then the
   filters, then the list. The three rows carry the same structure as each other
   so the eye can run straight down a column and compare -- which is the whole
   reason they are rows rather than three cards side by side: at 360px, three
   cards means three narrow columns and numbers that have to shrink to fit, and
   the numbers are the point.

   MONEY THAT ARRIVED VS MONEY THAT DID NOT. Collected, UPI and Cash are one
   block. Discount and Remaining sit below a rule, in a quieter tone, labelled
   "not collected" -- because they are different KINDS of money: one was never
   charged, the other has not come in yet. Adding either to the takings would
   overstate what the studio earned, so the layout never lets them look like
   part of the same sum.

   Four things this file does differently from the rest of the app:

   1. The A-Z strip is a nine-column GRID, not a scrolling row. The Members list
      shipped as one row that scrolled sideways with the scrollbar hidden, and
      every letter past I was unreachable at 360px -- the bug this file exists
      not to repeat. Nine columns puts all 27 keys on three full rows with
      nothing to discover.

   2. Figures in the summary are LINKS. Each one filters the list below to
      exactly the rows it counted, so a number and the rows behind it can be
      checked against each other in one tap.

   3. Tabular numerals everywhere money is printed, so figures in the three rows
      line up vertically and can be compared without reading them.

   4. The page paints no background: site.css already paints one on .sf-frame
      for every signed-in screen.
   ============================================================ */

.sf-pay {
  /* Muted deepened from #6d6b58, which measured 4.05:1 against the darkest
     part of the shared ball-pit ground -- under the 4.5:1 minimum for any
     muted line that sits on the ground rather than inside a card. #615F4E
     measures 4.85:1 there and 6.45:1 on white. Deepening the ink was the fix,
     not a panel behind the text. */
  --sf-pay-ink: #2b2a1f; --sf-pay-muted: #615F4E;
  --sf-pay-pink: #c2185b; --sf-pay-pink-deep: #98123f;
  --sf-pay-card: #ffffff; --sf-pay-edge: rgba(43,42,31,.10);
  --sf-pay-line: rgba(43,42,31,.12);
  --sf-pay-good: #1d7a3f; --sf-pay-good-tint: #e3f3e8;
  --sf-pay-warn: #9a5b00; --sf-pay-warn-tint: #fdf0d7;
  --sf-pay-bad: #b3261e; --sf-pay-bad-tint: #fdecea;
  --sf-pay-upi: #0f766e; --sf-pay-upi-tint: #dff1ef;
  --sf-pay-cash: #6d28d9; --sf-pay-cash-tint: #efe8fa;

  --sf-pay-aer: #0f766e; --sf-pay-aer-tint: #dff1ef;
  --sf-pay-yog: #c96a00; --sf-pay-yog-tint: #fdeedd;
  --sf-pay-dan: #6d28d9; --sf-pay-dan-tint: #efe8fa;

  --sf-pay-wing: linear-gradient(90deg,#43a047,#d4b91e,#f57c00,#e53957,#c2185b,#7e57c2,#5c6f91);
  --sf-pay-radius: 18px;

  /* The shell's real fixed bars. Zeroed inside .sf-app, which already pads the
     body past both -- Payments is a main tabbed page, so the bottom bar is
     really there. */
  --sf-pay-top-bar: var(--appbar-h, 56px); --sf-pay-bottom-bar: var(--tabbar-h, 64px);

  box-sizing: border-box; max-width: 640px; margin: 0 auto;
  display: flex; flex-direction: column; gap: 14px;
  padding: calc(var(--sf-pay-top-bar) + 14px) 16px calc(var(--sf-pay-bottom-bar) + 26px + env(safe-area-inset-bottom, 0px));
  color: var(--sf-pay-ink);
  font-family: "Archivo", system-ui, sans-serif; font-size: 15px; line-height: 1.5;
  -webkit-tap-highlight-color: transparent;
}

.sf-app .sf-pay {
  --sf-pay-top-bar: 0px;
  --sf-pay-bottom-bar: 0px;
  padding-left: 0; padding-right: 0;
}

.sf-pay *, .sf-pay *::before, .sf-pay *::after { box-sizing: border-box; }
/* A real selector, not :where(): site.css's link colour has weight, and a
   zero-specificity rule loses to it -- every figure would go link-blue. */
.sf-pay a { color: inherit; text-decoration: none; }
.sf-pay :focus-visible { outline: 2px solid var(--sf-pay-pink); outline-offset: 2px; }

.sf-pay-card {
  background: var(--sf-pay-card);
  border: 1.5px solid var(--sf-pay-edge);
  border-radius: var(--sf-pay-radius);
  box-shadow: 0 14px 30px -18px rgba(194,24,91,.4);
}

/* ---------- header ---------- */
.sf-pay-head { display: flex; align-items: center; gap: 12px; }
.sf-pay-intro { min-width: 0; }
.sf-pay-title { margin: 0; font-size: 22px; font-weight: 800; letter-spacing: -.01em; }
.sf-pay-sub { margin: 2px 0 0; font-size: 13.5px; color: var(--sf-pay-muted); text-wrap: pretty; }

/* ============================================================
   THE THREE PERIOD ROWS
   ============================================================ */
.sf-pay-periods { display: flex; flex-direction: column; gap: 10px; }

.sf-pay-period { padding: 12px 14px 10px; position: relative; overflow: hidden; }
.sf-pay-period::before { content: ""; position: absolute; inset: 0 0 auto 0; height: 4px; background: var(--sf-pay-wing); }

.sf-pay-period-head { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; margin: 4px 0 8px; }
.sf-pay-period-name { margin: 0; font-size: 12px; font-weight: 800; letter-spacing: .09em; text-transform: uppercase; color: var(--sf-pay-muted); }
.sf-pay-period-range { font-size: 11.5px; font-weight: 700; color: var(--sf-pay-muted); font-variant-numeric: tabular-nums; white-space: nowrap; }

/* the headline: collected, and how many people it came from */
.sf-pay-collected {
  display: flex; align-items: baseline; justify-content: space-between; gap: 10px;
  min-height: 44px; padding: 6px 10px; border-radius: 12px;
  background: var(--sf-pay-good-tint);
}
.sf-pay-collected-label { font-size: 11.5px; font-weight: 800; letter-spacing: .06em; text-transform: uppercase; color: var(--sf-pay-good); }
.sf-pay-collected-figure { text-align: right; }
.sf-pay-collected-amt { display: block; font-size: 24px; font-weight: 800; letter-spacing: -.02em; color: var(--sf-pay-good); font-variant-numeric: tabular-nums; line-height: 1.15; }
.sf-pay-collected-who { display: block; font-size: 12px; font-weight: 700; color: var(--sf-pay-good); opacity: .85; }

/* the two methods, side by side and adding up to the headline */
.sf-pay-methods { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; margin-top: 8px; }
.sf-pay-method {
  display: flex; flex-direction: column; gap: 1px;
  min-height: 44px; padding: 7px 10px; border-radius: 12px;
  border: 1.5px solid transparent;
}
.sf-pay-method--upi { background: var(--sf-pay-upi-tint); border-color: rgba(15,118,110,.2); }
.sf-pay-method--cash { background: var(--sf-pay-cash-tint); border-color: rgba(109,40,217,.2); }
.sf-pay-method-label { font-size: 10.5px; font-weight: 800; letter-spacing: .07em; text-transform: uppercase; }
.sf-pay-method--upi .sf-pay-method-label { color: var(--sf-pay-upi); }
.sf-pay-method--cash .sf-pay-method-label { color: var(--sf-pay-cash); }
.sf-pay-method-amt { font-size: 16px; font-weight: 800; font-variant-numeric: tabular-nums; }
.sf-pay-method-who { font-size: 11.5px; font-weight: 700; color: var(--sf-pay-muted); }

/* THE RULE. Everything below it is money that did not arrive. */
.sf-pay-notcollected {
  margin-top: 10px; padding-top: 9px;
  border-top: 1.5px dashed var(--sf-pay-line);
}
.sf-pay-notcollected-label {
  display: block; margin-bottom: 6px;
  font-size: 10px; font-weight: 800; letter-spacing: .09em; text-transform: uppercase;
  color: var(--sf-pay-muted);
}
.sf-pay-secondary { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
.sf-pay-sec {
  display: flex; flex-direction: column; gap: 1px;
  padding: 6px 10px; border-radius: 10px; background: rgba(43,42,31,.04);
}
.sf-pay-sec-label { font-size: 10.5px; font-weight: 800; letter-spacing: .06em; text-transform: uppercase; color: var(--sf-pay-muted); }
.sf-pay-sec-amt { font-size: 15px; font-weight: 800; font-variant-numeric: tabular-nums; color: var(--sf-pay-ink); }
.sf-pay-sec-who { font-size: 11.5px; font-weight: 700; color: var(--sf-pay-muted); }
.sf-pay-sec--due .sf-pay-sec-amt { color: var(--sf-pay-bad); }

/* BOTH SECONDARY FIGURES ARE LINKS, AND NEITHER IS PROMOTED FOR IT.

   Tapping Discount or Remaining opens the people behind the number. That is a
   link, so it gets a link's affordances -- a hover, a focus ring, a real tap
   target -- and nothing else. It keeps the same quiet grey pill, the same type
   sizes and the same position under the "not collected" rule that it had as
   plain text.

   This is deliberate and worth stating: the moment these look like the UPI and
   Cash tiles, the rule above them stops being read, and money that never
   arrived starts reading as takings. Being tappable is not a promotion. */
a.sf-pay-sec { text-decoration: none; color: inherit; min-height: 44px; justify-content: center; }
a.sf-pay-sec:hover { background: rgba(43,42,31,.08); }
a.sf-pay-sec:focus-visible { outline: 2px solid var(--sf-pay-pink); outline-offset: 2px; }
a.sf-pay-sec:active { background: rgba(43,42,31,.12); }

/* the split not adding up is a fault, and says so rather than hiding */
.sf-pay-mismatch {
  margin: 8px 0 0; padding: 7px 10px; border-radius: 10px;
  background: var(--sf-pay-bad-tint); color: var(--sf-pay-bad);
  font-size: 12px; font-weight: 700;
}

/* ---------- filters ---------- */
.sf-pay-filters { padding: 12px 14px; display: flex; flex-direction: column; gap: 10px; }
.sf-pay-note { margin: 0; font-size: 12.5px; color: var(--sf-pay-muted); text-wrap: pretty; }
.sf-pay-note strong { color: var(--sf-pay-ink); }

.sf-pay-dates { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
.sf-pay-field { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.sf-pay-label { font-size: 12px; font-weight: 800; letter-spacing: .02em; }
.sf-pay-input {
  width: 100%; min-height: 46px; padding: 0 10px;
  border: 1.5px solid rgba(43,42,31,.2); border-radius: 12px;
  background: #fff; color: var(--sf-pay-ink);
  font-family: inherit; font-size: 15px; font-weight: 600;
  font-variant-numeric: tabular-nums;
}
.sf-pay-input:focus { border-color: var(--sf-pay-pink); outline: none; box-shadow: 0 0 0 3px rgba(194,24,91,.15); }
.sf-pay-go {
  min-height: 46px; padding: 0 16px; border: 0; border-radius: 12px; cursor: pointer;
  background: linear-gradient(155deg, #e0447a, var(--sf-pay-pink-deep));
  color: #fff; font-family: inherit; font-size: 14px; font-weight: 800;
}
.sf-pay-go:active { transform: translateY(1px); filter: brightness(.95); }

/* the quick period shortcuts, which FILL the dates rather than replacing them */
.sf-pay-presets { display: flex; flex-wrap: wrap; gap: 6px; }
.sf-pay-preset {
  display: inline-flex; align-items: center; min-height: 38px; padding: 0 12px;
  border-radius: 999px; border: 1.5px solid var(--sf-pay-edge); background: #fff;
  font-size: 12.5px; font-weight: 800; white-space: nowrap;
}
.sf-pay-preset.is-on { border-color: transparent; color: #fff; background: linear-gradient(155deg, #e0447a, var(--sf-pay-pink-deep)); }

/* activity buttons — the same control the Members and Batches lists carry */
.sf-pay-acts { display: flex; flex-wrap: wrap; gap: 6px; }
.sf-pay-act {
  display: inline-flex; align-items: center; gap: 6px;
  min-height: 40px; padding: 0 12px; border-radius: 999px;
  border: 1.5px solid var(--sf-pay-edge); background: #fff;
  font-size: 13px; font-weight: 800; white-space: nowrap;
}
.sf-pay-act small { font-weight: 700; color: var(--sf-pay-muted); font-variant-numeric: tabular-nums; }
.sf-pay-act img { flex: none; }
.sf-pay-act.is-on { border-color: transparent; color: #fff; }
.sf-pay-act.is-on small { color: rgba(255,255,255,.85); }
.sf-pay-act--all.is-on { background: linear-gradient(155deg, #e0447a, var(--sf-pay-pink-deep)); }
.sf-pay-act--aer.is-on { background: var(--sf-pay-aer); }
.sf-pay-act--yog.is-on { background: var(--sf-pay-yog); }
.sf-pay-act--dan.is-on { background: var(--sf-pay-dan); }

.sf-pay-search { display: flex; gap: 8px; }
.sf-pay-search .sf-pay-input { flex: 1; min-width: 0; }

/* a filter currently narrowing the screen, with its own way off */
.sf-pay-chiprow { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; }
.sf-pay-chip {
  display: inline-flex; align-items: center; gap: 6px;
  min-height: 32px; padding: 0 10px; border-radius: 999px;
  background: var(--sf-pay-warn-tint); color: var(--sf-pay-warn);
  font-size: 12px; font-weight: 800;
}
.sf-pay-chip-clear { text-decoration: underline; text-underline-offset: 2px; }

/* ============================================================
   THE A-Z STRIP — a grid, never a scroller. See note 1.
   ============================================================ */
.sf-pay-az { display: grid; grid-template-columns: repeat(9, minmax(0, 1fr)); gap: 6px; }
.sf-pay-azkey {
  display: grid; place-items: center;
  min-width: 0; height: 44px; padding: 0 2px; border-radius: 11px;
  border: 1.5px solid var(--sf-pay-edge); background: #fff;
  font-size: 13.5px; font-weight: 800; color: var(--sf-pay-ink);
}
.sf-pay-azkey.is-on { border-color: transparent; color: #fff; background: linear-gradient(155deg, #e0447a, var(--sf-pay-pink-deep)); }
/* Nothing behind this letter under the filters that are on. A different KIND of
   thing rather than a dimmer copy of the same one: no border, no card, just a
   grey character -- and a title on every one saying which filter emptied it. */
.sf-pay-azkey--empty {
  border-color: transparent; background: transparent;
  color: var(--sf-pay-muted); opacity: .55; font-weight: 700; cursor: default;
}

/* ---------- the list ---------- */
.sf-pay-sechead { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; margin: 2px 2px -4px; }
.sf-pay-sechead h2 { margin: 0; font-size: 13px; font-weight: 800; letter-spacing: .07em; text-transform: uppercase; color: var(--sf-pay-muted); }
.sf-pay-sechead-link { font-size: 12.5px; font-weight: 800; color: var(--sf-pay-pink); }

.sf-pay-group { padding: 0 14px; overflow: hidden; }
.sf-pay-groupsum {
  display: flex; align-items: center; gap: 10px;
  min-height: 52px; margin: 0 -14px; padding: 0 16px;
}
.sf-pay-groupsum-letter {
  flex: none; display: grid; place-items: center;
  width: 34px; height: 34px; border-radius: 11px;
  background: linear-gradient(155deg, #e0447a, var(--sf-pay-pink-deep));
  color: #fff; font-size: 15px; font-weight: 800;
}
.sf-pay-groupsum-note { flex: 1; min-width: 0; font-size: 13px; font-weight: 700; color: var(--sf-pay-muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-variant-numeric: tabular-nums; }
.sf-pay-chev { flex: none; color: var(--sf-pay-muted); transition: transform .15s; }
.sf-pay-group.is-open .sf-pay-chev { transform: rotate(180deg); }
.sf-pay-group.is-open .sf-pay-groupsum { border-bottom: 1px solid var(--sf-pay-line); }

/* one payment: name left and truncating, figures right and never squeezed */
.sf-pay-rows { list-style: none; margin: 0; padding: 0; }
.sf-pay-row {
  display: grid; grid-template-columns: minmax(0,1fr) auto;
  align-items: baseline; column-gap: 10px;
  padding: 11px 0; border-top: 1px solid var(--sf-pay-line);
}
.sf-pay-rows > li:first-child .sf-pay-row { border-top: 0; }
.sf-pay-row-name { min-width: 0; font-size: 14.5px; font-weight: 700; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sf-pay-row-right { display: flex; align-items: baseline; gap: 8px; white-space: nowrap; }
.sf-pay-row-amt { font-size: 15px; font-weight: 800; font-variant-numeric: tabular-nums; }
.sf-pay-row-date { font-size: 12px; font-weight: 700; color: var(--sf-pay-muted); font-variant-numeric: tabular-nums; }
.sf-pay-method-chip {
  display: inline-flex; align-items: center; min-height: 20px; padding: 0 7px;
  border-radius: 999px; font-size: 10.5px; font-weight: 800; letter-spacing: .04em; text-transform: uppercase;
  background: rgba(43,42,31,.07); color: var(--sf-pay-muted);
}
.sf-pay-method-chip--upi { background: var(--sf-pay-upi-tint); color: var(--sf-pay-upi); }
.sf-pay-method-chip--cash { background: var(--sf-pay-cash-tint); color: var(--sf-pay-cash); }

/* A write-off is not part of what arrived, so it is marked apart from the
   figure and in a different colour -- never beside it as if it were more money. */
.sf-pay-waived { margin: 1px 0 0; font-size: 11.5px; font-weight: 700; color: var(--sf-pay-warn); }
.sf-pay-by { margin: 1px 0 0; font-size: 11px; color: var(--sf-pay-muted); opacity: .85; }

/* ---------- the two "not collected" lists ----------

   Opened by tapping Discount or Remaining on a period row. They reuse the
   payment row wholesale -- name left and truncating, figure right and never
   squeezed -- so a list here is read exactly the way the list on Payments is,
   and only the parts that differ are defined below. */

/* What is on screen, restated from the figure that opened it. Printed so the
   list can be CHECKED against the number it came from rather than trusted. */
.sf-pay-drill { padding: 12px 14px; display: flex; flex-direction: column; gap: 6px; }
.sf-pay-drill-period {
  margin: 0; font-size: 11px; font-weight: 800; letter-spacing: .07em;
  text-transform: uppercase; color: var(--sf-pay-muted);
}
.sf-pay-drill-figure { margin: 0; display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; }
.sf-pay-drill-amt { font-size: 24px; font-weight: 800; font-variant-numeric: tabular-nums; color: var(--sf-pay-ink); }
.sf-pay-drill-who { font-size: 12.5px; font-weight: 700; color: var(--sf-pay-muted); }
.sf-pay-drill-note { margin: 0; font-size: 12px; color: var(--sf-pay-muted); text-wrap: pretty; }
.sf-pay-drill-note strong { color: var(--sf-pay-ink); }
.sf-pay-drill-chips { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 2px; }

/* An inset note sits with the cards rather than against the page edge. */
.sf-pay-note--inset { padding: 0 4px; }

/* The two figures these lists explain. Neither is takings, so neither is
   printed in the ink Collected uses: a concession is amber, a debt is red. */
.sf-pay-row-amt--off { color: var(--sf-pay-warn); }
.sf-pay-row-amt--due { color: var(--sf-pay-bad); }

/* The plan under a row. Small, and the icon is the app's own finished tile
   placed at its natural size -- never masked, never recoloured. */
.sf-pay-sub-line {
  display: flex; align-items: center; gap: 6px;
  margin: 1px 0 0; font-size: 11.5px; font-weight: 700; color: var(--sf-pay-muted);
}
.sf-pay-sub-line img { flex: none; display: block; border-radius: 4px; }
.sf-pay-sub-line span { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* Why a concession was given, in the words that were recorded. */
.sf-pay-reason {
  margin: 3px 0 0; font-size: 12px; font-style: italic;
  color: var(--sf-pay-ink); opacity: .8; text-wrap: pretty;
}

/* The sum behind a red figure, printed so it can be checked rather than
   trusted: fee, less what arrived, less what was written off. */
.sf-pay-breakdown {
  display: flex; flex-wrap: wrap; gap: 4px 12px;
  margin: 3px 0 0; font-size: 11.5px; color: var(--sf-pay-muted);
}
.sf-pay-breakdown strong { font-weight: 800; font-variant-numeric: tabular-nums; color: var(--sf-pay-ink); }
.sf-pay-breakdown-waived strong { color: var(--sf-pay-warn); }

.sf-pay-empty {
  background: rgba(255,255,255,.6);
  border: 2px dashed rgba(43,42,31,.22); border-radius: var(--sf-pay-radius);
  padding: 24px 18px; text-align: center;
  display: flex; flex-direction: column; align-items: center; gap: 6px;
}
.sf-pay-empty-title { margin: 0; font-size: 15px; font-weight: 800; }
.sf-pay-empty-sub { margin: 0; max-width: 34ch; font-size: 13px; color: var(--sf-pay-muted); text-wrap: pretty; }

/* ---------- footer ---------- */
.sf-pay-foot { text-align: center; padding: 4px 2px 0; }
.sf-pay-wingbar { height: 4px; border: 0; width: 132px; margin: 0 auto 12px; border-radius: 999px; background: var(--sf-pay-wing); }

@media (prefers-reduced-motion: reduce) {
  .sf-pay-chev { transition: none; }
}
