/* ============================================================================
   39-admin-finance.css — the Finance workspace (Students · Money · Setup).
   Loaded LAST of the admin sheets so its sub-tab and row styling wins over the
   generic .adm-row rules in 11-admin-reading.css.

   The panes are only display-toggled, never re-created, so entrance animations
   live in the @keyframes (with `both`) rather than on a bare selector — an
   element parked at opacity:0 reads as a hole in the layout.
   ============================================================================ */

/* ---------- sub-tabs ---------- */
.fin-tabs{
  display:inline-flex; gap:6px; flex-wrap:wrap;
  margin:0 0 18px; padding:5px;
  background:rgba(255,255,255,.03);
  border:1px solid var(--adm-border);
  border-radius:14px;
}
.fin-tab{
  display:inline-flex; align-items:center; gap:8px;
  padding:9px 16px; border-radius:10px;
  font-size:15.5px; font-weight:700; letter-spacing:.1px;
  color:var(--adm-muted); text-decoration:none;
  border:1px solid transparent;
  transition:background .18s, color .18s, border-color .18s;
}
.fin-tab:hover{ color:var(--adm-text); background:rgba(255,255,255,.05); }
.fin-tab.is-active{
  color:var(--adm-text);
  background:var(--adm-card-hi);
  border-color:var(--adm-border-hi);
  box-shadow:0 1px 0 rgba(255,255,255,.05) inset;
}
.fin-tab-ic{ font-size:16px; line-height:1; }
.fin-tab-badge{
  min-width:19px; padding:1px 6px; border-radius:999px;
  background:var(--adm-accent); color:#1b1005;
  font-size:13px; font-weight:800; text-align:center;
}
.fin-tab-badge.is-warn{ background:var(--adm-warning); }
.fin-tab-badge[hidden]{ display:none; }

/* ---------- panes ---------- */
.fin-pane{ display:none; }
.fin-pane.is-active{ display:block; animation:finPaneIn .22s ease both; }
@keyframes finPaneIn{ from{ opacity:0; transform:translateY(4px); } to{ opacity:1; transform:none; } }

.fin-hint{
  margin:2px 0 14px; font-size:14.5px; color:var(--adm-muted);
}
.fin-hint kbd{
  display:inline-block; min-width:17px; padding:1px 5px; margin:0 1px;
  border:1px solid var(--adm-border); border-bottom-width:2px; border-radius:5px;
  background:rgba(255,255,255,.05); font:inherit; font-size:13px; font-weight:700;
  color:var(--adm-text); text-align:center;
}

/* ---------- students: search bar ----------
   A full-width bar rather than the generic .adm-search box. Finding a person is
   the first move on this page for almost every visit, so it gets the weight. */
.fin-st-bar{ display:flex; gap:10px; margin:0 0 12px; }
.fin-st-search{
  flex:1; display:flex; align-items:center; gap:10px;
  height:46px; padding:0 16px; border-radius:13px;
  background:rgba(0,0,0,.22); border:1px solid var(--adm-border);
  transition:border-color .18s, background .18s, box-shadow .18s;
}
.fin-st-search:focus-within{
  border-color:var(--adm-border-hi); background:rgba(0,0,0,.3);
  box-shadow:0 0 0 3px rgba(255,138,91,.1);
}
.fin-st-search-ico{ font-size:16px; opacity:.6; flex:none; }
.fin-st-search input{
  flex:1; min-width:0; height:100%; border:none; outline:none; background:none;
  font-family:inherit; font-size:16px; font-weight:600; color:var(--adm-text);
}
.fin-st-search input::placeholder{ color:var(--adm-muted); font-weight:500; }

/* Pill counts sit inside the pill so the number and its label can never be
   read against the wrong pill (they were separate elements before). */
#finStudentSegs .adm-pill b{
  margin-left:6px; padding:1px 6px; border-radius:99px;
  background:rgba(255,255,255,.08); font-size:13px; font-weight:800;
}
#finStudentSegs .adm-pill.active b{ background:rgba(20,8,13,.22); }

/* ---------- students: rows ---------- */
.fin-st-row{
  display:grid; grid-template-columns:46px minmax(0,1fr) auto auto;
  gap:14px; align-items:center;
  padding:12px 14px; margin-bottom:8px;
  background:var(--adm-card); border:1px solid var(--adm-border);
  border-radius:13px;
  animation:finStRowIn .3s cubic-bezier(.22,1,.36,1) both;
  animation-delay:calc(var(--i, 0) * 22ms);
  transition:border-color .18s, background .18s, transform .18s;
}
.fin-st-row:hover{ border-color:var(--adm-border-hi); background:var(--adm-card-hi); }
/* Entrance state lives in the keyframes, not on the selector: a row parked at
   opacity:0 by a rule reads as a hole if the animation never runs. */
@keyframes finStRowIn{
  from{ opacity:0; transform:translateY(8px); }
  to  { opacity:1; transform:none; }
}
/* The left edge carries the state, so a long list is scannable without reading:
   amber = running out, grey = gone, gold = lifetime. */
.fin-st-row[data-state="expiring"]{ box-shadow:inset 3px 0 0 var(--adm-warning); }
.fin-st-row[data-state="lapsed"]  { box-shadow:inset 3px 0 0 rgba(139,147,164,.55); }
.fin-st-row[data-state="lifetime"]{ box-shadow:inset 3px 0 0 var(--adm-accent-2); }

.fin-st-av{
  width:44px; height:44px; border-radius:12px; flex:none;
  display:grid; place-items:center;
  font-size:16px; font-weight:800; color:#fff;
  background:linear-gradient(135deg, var(--adm-accent), var(--adm-accent-2));
  box-shadow:0 6px 16px -8px rgba(255,120,73,.7);
}
.fin-st-who{ min-width:0; }
.fin-st-name{
  display:flex; align-items:center; gap:7px;
  font-size:16.5px; font-weight:750; color:var(--adm-text);
  white-space:nowrap; overflow:hidden; text-overflow:ellipsis;
}
.fin-st-tag{
  padding:1px 6px; border-radius:5px; flex:none;
  font-size:11.5px; font-weight:800; letter-spacing:.5px;
  color:var(--adm-accent-2); background:rgba(251,191,36,.14);
  border:1px solid rgba(251,191,36,.3);
}
.fin-st-sub{
  display:flex; align-items:center; flex-wrap:wrap; gap:0 2px; margin-top:3px;
  font-size:14px; color:var(--adm-muted);
}
.fin-st-sep{
  width:3px; height:3px; margin:0 8px; border-radius:50%;
  background:currentColor; opacity:.45; flex:none;
}
.fin-st-dates{ display:inline-flex; align-items:center; opacity:.85; }
.fin-st-id{
  display:inline-flex; align-items:center; gap:4px; padding:0; cursor:pointer;
  border:none; background:none; color:inherit;
  font-family:ui-monospace, SFMono-Regular, Menlo, monospace; font-size:13.5px;
  transition:color .15s;
}
.fin-st-id:hover{ color:var(--adm-text); }
.fin-st-copy{ opacity:.5; font-size:12px; }
.fin-st-id.is-copied{ color:var(--adm-success); }
.fin-st-id.is-copied .fin-st-copy::after{ content:" copied"; font-size:12px; }

/* ---------- students: access state ---------- */
.fin-st-acc{
  display:inline-flex; align-items:center; gap:5px; white-space:nowrap;
  padding:5px 11px; border-radius:99px;
  font-size:14px; font-weight:700;
  color:var(--adm-success); background:rgba(52,211,153,.12);
  border:1px solid rgba(52,211,153,.28);
}
/* A monospace countdown so the digits don't shuffle the pill's width every
   second — the row jittered once per tick with proportional figures. */
.fin-st-acc b{ font-family:ui-monospace, SFMono-Regular, Menlo, monospace; font-weight:800; }
.fin-st-acc.is-soon{
  color:var(--adm-warning); background:rgba(251,191,36,.12); border-color:rgba(251,191,36,.32);
}
.fin-st-acc.is-life{
  color:var(--adm-accent-2); background:rgba(251,191,36,.14); border-color:rgba(251,191,36,.34);
}
.fin-st-acc.is-lapsed{
  color:var(--adm-muted); background:rgba(139,147,164,.12); border-color:rgba(139,147,164,.28);
}
.fin-st-acc.is-free{
  color:var(--adm-muted); background:rgba(255,255,255,.04); border-color:var(--adm-border);
}

/* ---------- students: row actions ---------- */
.fin-st-acts{ display:flex; align-items:center; gap:6px; flex:none; }
.fin-st-btn{
  height:36px; padding:0 12px; border-radius:9px; cursor:pointer;
  font-family:inherit; font-size:14.5px; font-weight:700; white-space:nowrap;
  color:var(--adm-muted); background:rgba(255,255,255,.05);
  border:1px solid var(--adm-border);
  transition:color .15s, background .15s, border-color .15s, transform .15s;
}
.fin-st-btn:hover{ color:var(--adm-text); border-color:var(--adm-border-hi); transform:translateY(-1px); }
.fin-st-btn.is-primary{
  color:var(--adm-text); background:rgba(255,138,91,.14); border-color:var(--adm-border-hi);
}
.fin-st-btn.is-primary:hover{
  color:#fff; border-color:transparent;
  background:linear-gradient(100deg, var(--adm-accent), var(--adm-accent-2));
}

/* ---------- record-a-payment drawer ---------- */
.fin-cash{
  margin:0 0 20px; padding:18px;
  background:var(--adm-card); border:1px solid var(--adm-border-hi);
  border-radius:14px;
  animation:finPaneIn .2s ease both;
}
.fin-cash[hidden]{ display:none; }
.fin-cash-head{ margin-bottom:14px; }
.fin-cash-head b{ display:block; font-size:17px; color:var(--adm-text); }
.fin-cash-head span{ display:block; margin-top:3px; font-size:15px; color:var(--adm-muted); }
.fin-cash-head em{ font-style:normal; color:var(--adm-accent-2); font-weight:700; }
.fin-cash-actions{ display:flex; gap:10px; justify-content:flex-end; margin-top:14px; }
.fin-check{
  display:inline-flex; align-items:center; gap:8px; margin-top:4px;
  font-size:15px; color:var(--adm-muted); cursor:pointer;
}
.fin-check input{ accent-color:var(--adm-accent); width:15px; height:15px; }

/* ---------- responsive ---------- */
@media (max-width: 860px){
  /* Stack: name block on top, state + actions below it. Keeping the 4-column
     grid here squeezed the name to a couple of characters before the actions
     would give up any width. */
  .fin-st-row{ grid-template-columns:46px minmax(0,1fr); row-gap:10px; }
  .fin-st-state{ grid-column:2; }
  .fin-st-acts{ grid-column:2; justify-content:flex-start; flex-wrap:wrap; }
  .fin-st-btn{ flex:1; min-width:96px; text-align:center; }
  .fin-st-btn.is-primary{ flex:2; }
}
@media (max-width: 760px){
  .fin-tabs{ display:flex; flex-wrap:nowrap; overflow-x:auto; -webkit-overflow-scrolling:touch; }
  .fin-tab{ flex:none; padding:9px 13px; }
  .fin-st-search{ height:48px; padding:0 13px; }
  .fin-st-search input{ font-size:18px; }  /* < 16px makes iOS zoom on focus */
  .fin-st-dates{ display:none; }           /* the countdown pill already says it */
}

/* ---------- light theme ---------- */
:root[data-theme="light"] .fin-tabs{ background:rgba(30,40,80,.03); }
:root[data-theme="light"] .fin-tab:hover{ background:rgba(30,40,80,.05); }
:root[data-theme="light"] .fin-st-search{ background:rgba(30,40,80,.04); }
:root[data-theme="light"] .fin-st-search:focus-within{ background:rgba(30,40,80,.06); }
:root[data-theme="light"] .fin-hint kbd,
:root[data-theme="light"] .fin-st-btn{ background:rgba(30,40,80,.05); }

/* ---- accent inks are tuned for the dark panel; re-darken them here ----
   Measured on the light card (rgba(255,255,255,.85) over #f1f4fb), text vs the
   pill's own flattened background:
     --adm-success #34d399  →  1.75:1   the plain "44d left" pill — unreadable
     --adm-warning #fbbf24  →  1.67:1   the "expiring" pill that must shout
     --adm-muted   #64748b  →  4.28:1   row buttons, just under AA
   Only where the accent is the TEXT. Backgrounds, borders and gradients stay
   as they are, and dark theme is untouched. */
:root[data-theme="light"] .fin-st-acc{
  color:#047857; background:rgba(4,120,87,.10); border-color:rgba(4,120,87,.28);
}
/* amber-800, not amber-700: #b45309 measures 4.32:1 here, and these pills are
   12px bold — normal text by WCAG's sizing, so 4.5 is the bar, not 3. */
:root[data-theme="light"] .fin-st-acc.is-soon{
  color:#92400e; background:rgba(180,83,9,.10); border-color:rgba(180,83,9,.32);
}
/* These two must restate background AND border, not just colour. The base
   `.fin-st-acc` override above repaints the pill GREEN for light theme (it is
   the "premium, healthy" state), and a colour-only override left Lapsed and
   Free wearing a green pill with grey text — the one state that means "this
   person is gone" looked like the one that means "all good". */
:root[data-theme="light"] .fin-st-acc.is-lapsed,
:root[data-theme="light"] .fin-st-acc.is-free{
  color:#475569; background:rgba(71,85,105,.10); border-color:rgba(71,85,105,.24);
}
:root[data-theme="light"] .fin-st-btn{ color:#475569; }
:root[data-theme="light"] .fin-st-acc.is-life,
:root[data-theme="light"] .fin-st-tag{
  color:#92400e; background:rgba(180,83,9,.10); border-color:rgba(180,83,9,.28);
}
:root[data-theme="light"] .fin-st-row[data-state="expiring"]{ box-shadow:inset 3px 0 0 #d97706; }
:root[data-theme="light"] .fin-st-row[data-state="lifetime"]{ box-shadow:inset 3px 0 0 #d97706; }

/* The grant comment on a student row. One line, ellipsised — a comped account's
   reason belongs next to the account, but it must never push the row taller and
   break the scan-down rhythm of the roster. */
.fin-st-note{
  margin-top:5px; max-width:52ch;
  font-size:13.5px; line-height:1.4; color:var(--adm-accent-2);
  white-space:nowrap; overflow:hidden; text-overflow:ellipsis;
  opacity:.92;
}
@media (max-width: 720px){ .fin-st-note{ max-width:100%; } }

/* ============================================================================
   PAYMENT LEDGER (Money tab) — every payment, searchable, with the two-step undo.

   Sits directly under the headline tiles and above the charts: charts answer
   "how are we doing", this answers "what happened, and undo it", which is the
   question the tab gets opened with when something is wrong.

   Grid, not a table: at 4 columns a table needs horizontal scroll on a phone,
   whereas these tracks collapse to two rows (see the query at the bottom) and
   keep the amount and the actions reachable without sideways scrolling.
   ============================================================================ */
.adm-pay-tools{
  display:flex; flex-wrap:wrap; gap:10px; align-items:center;
  margin:0 0 12px;
}
.adm-pay-search{
  position:relative; display:flex; align-items:center; gap:8px;
  flex:1 1 260px; min-width:0;
  padding:0 12px; border-radius:11px;
  background:var(--adm-card); border:1px solid var(--adm-border);
  color:var(--adm-muted);
}
.adm-pay-search:focus-within{ border-color:var(--adm-accent); }
.adm-pay-search input{
  flex:1 1 auto; min-width:0; min-height:42px;
  background:none; border:0; outline:none;
  color:var(--adm-text); font-size:14px; font-family:inherit;
}
.adm-pay-filters{ display:flex; flex-wrap:wrap; gap:6px; }

.adm-pay-list{ display:flex; flex-direction:column; gap:8px; }
.adm-pay-row{
  display:grid;
  grid-template-columns:minmax(0,1fr) auto auto auto auto;
  gap:12px; align-items:center;
  padding:11px 14px;
  background:var(--adm-card); border:1px solid var(--adm-border);
  border-radius:12px;
  transition:border-color .18s, background .18s, opacity .18s;
}
.adm-pay-row:hover{ border-color:var(--adm-border-hi); background:var(--adm-card-hi); }
/* An in-flight row must look inert without collapsing — the list would jump
   under the pointer if the row resized while a request was running. */
.adm-pay-row.is-busy{ opacity:.5; pointer-events:none; }

.adm-pay-who{ min-width:0; display:flex; flex-wrap:wrap; align-items:baseline; gap:4px 8px; }
.adm-pay-who b{ color:var(--adm-text); font-size:14.5px; font-weight:700; }
.adm-pay-who span{ color:var(--adm-muted); font-size:12.5px; }
.adm-pay-who i{ color:var(--adm-muted); font-size:12px; font-style:normal; opacity:.7; }
/* The note is the only free text here and the only thing that explains an odd
   row, so it gets the full width rather than being truncated into the name. */
.adm-pay-who em{
  flex:1 0 100%; color:var(--adm-muted); font-size:12.5px; font-style:normal;
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap;
}
.adm-pay-meta{ display:flex; flex-wrap:wrap; gap:4px 10px; align-items:center; color:var(--adm-muted); font-size:12.5px; }
.adm-pay-method{ text-transform:capitalize; }
.adm-pay-at{ font-variant-numeric:tabular-nums; }

.adm-pay-amt{ font-size:15px; font-weight:800; color:var(--adm-text); white-space:nowrap; font-variant-numeric:tabular-nums; }
.adm-pay-amt small{ font-size:11px; font-weight:700; color:var(--adm-muted); }
/* A reversed amount is struck through rather than hidden: the row still has to
   say how much was originally taken, or the history cannot be reconciled. */
.adm-pay-amt.is-struck{ text-decoration:line-through; opacity:.55; }

.adm-pay-tag{
  padding:4px 10px; border-radius:99px; white-space:nowrap;
  font-size:11.5px; font-weight:800; text-transform:uppercase; letter-spacing:.03em;
  border:1px solid transparent;
}
.adm-pay-tag.is-ok  { color:var(--adm-success); border-color:color-mix(in srgb, var(--adm-success) 40%, transparent); }
.adm-pay-tag.is-warn{ color:var(--adm-warning); border-color:color-mix(in srgb, var(--adm-warning) 40%, transparent); }
.adm-pay-tag.is-info{ color:var(--adm-accent);  border-color:color-mix(in srgb, var(--adm-accent)  40%, transparent); }
.adm-pay-tag.is-dim { color:var(--adm-muted);   border-color:var(--adm-border); }

.adm-pay-actions{ display:flex; gap:6px; }
.adm-pay-btn{
  display:inline-flex; align-items:center; gap:6px;
  min-height:38px; padding:0 12px; border-radius:10px;
  background:var(--adm-card); border:1px solid var(--adm-border);
  color:var(--adm-muted); font-size:13px; font-weight:700; font-family:inherit;
  cursor:pointer; transition:color .16s, border-color .16s, background .16s;
}
.adm-pay-btn:hover{ color:var(--adm-text); border-color:var(--adm-border-hi); }
.adm-pay-btn.is-undo:hover{ color:var(--adm-warning); border-color:var(--adm-warning); }
/* Destructive, and second in the pair — it only ever appears on a row that is
   already worth nothing, so it stays quiet until deliberately hovered. */
.adm-pay-btn.is-del{ padding:0 10px; }
.adm-pay-btn.is-del:hover{ color:var(--adm-danger, #f87186); border-color:var(--adm-danger, #f87186); }
.adm-pay-btn[disabled]{ opacity:.45; cursor:default; }

.adm-pay-empty{
  padding:22px 14px; text-align:center;
  color:var(--adm-muted); font-size:13.5px;
  background:var(--adm-card); border:1px dashed var(--adm-border); border-radius:12px;
}

/* Phones: the five tracks become two rows — who/amount on top, everything else
   underneath — so nothing needs horizontal scrolling and the buttons stay at a
   full tap size. */
@media (max-width:760px){
  .adm-pay-row{ grid-template-columns:minmax(0,1fr) auto; row-gap:9px; }
  .adm-pay-meta{ grid-column:1; }
  .adm-pay-tag{ grid-column:2; justify-self:end; }
  .adm-pay-actions{ grid-column:1 / -1; }
  .adm-pay-btn{ flex:1 1 auto; justify-content:center; min-height:44px; }
  .adm-pay-btn.is-del{ flex:0 0 52px; }
}
