/* ==========================================================================
   MHMRWS Portal — Shared Design System
   Max Heights Majestic Resident Welfare Society

   Type system:
     --font-display  Fraunces      → ceremonial numerals, hero, section titles
     --font-body      IBM Plex Sans → all interface text, forms, tables
     --font-mono       IBM Plex Mono → Member IDs, Receipt Nos, Txn IDs

   Signature motif: the "seal" — a circular emblem ring used around the
   society mark and around every verified/verification moment, echoing the
   receipt's own verification QR seal.
   ========================================================================== */

@import url('https://fonts.googleapis.com/css2?family=Fraunces:opsz,wght@9..144,500;9..144,600;9..144,700&family=IBM+Plex+Sans:wght@400;500;600;700&family=IBM+Plex+Mono:wght@500;600&display=swap');

:root{
  /* --- Color tokens -------------------------------------------------- */
  --navy-950:#0A1B33;
  --navy-900:#0F2547;
  --navy-800:#163564;
  --navy-700:#1F4585;
  --navy-600:#2B5AA6;

  --saffron-300:#FFC978;
  --saffron-500:#FF9933;
  --saffron-600:#F27B0E;

  --gold-300:#E4C765;
  --gold-500:#C9A227;
  --gold-700:#8F7115;

  /* Sampled from the society's own brochure — this is the magenta the
     "Majestic" script is set in, and the accent colour used throughout
     the developer's material. Used sparingly, as a third accent. */
  --magenta-500:#C01860;
  --magenta-600:#A31350;
  --magenta-100:#FBE9F1;

  /* Warm ivory surfaces instead of cold white/grey — the single biggest lift
     toward a "luxury civic" feel. Cards sit on ivory; raised cards are a
     barely-warmer near-white so they still read as lifted. */
  --paper:#FAF8F4;          /* page background — warm ivory */
  --paper-raised:#FFFDF9;   /* card surface — warmer than pure white */
  --white:#FFFFFF;          /* kept for PDFs / places that need true white */
  --ivory:#FAF8F4;
  --gold-glow:rgba(201,162,39,.18);   /* soft gold used in shadows/borders */

  --ink-900:#10192B;
  --ink-700:#2B3448;
  --ink-600:#465066;
  --ink-400:#7C879C;
  --ink-200:#C4CBD8;

  --line:#EAE6DC;           /* warm hairline to match ivory (was cool grey) */
  --line-strong:#D9D3C6;

  --success:#1B7A4D;
  --success-bg:#E6F4EC;
  --success-line:#B7DFC7;

  --danger:#B3261E;
  --danger-bg:#FBEAE8;
  --danger-line:#F0C1BC;

  --warning:#B5760A;
  --warning-bg:#FDF3E2;
  --warning-line:#F1D89A;

  --info:#1F4585;
  --info-bg:#E9EFFA;
  --info-line:#C3D2F0;

  /* --- Type ------------------------------------------------------------ */
  --font-display:'Fraunces', 'Georgia', serif;
  --font-body:'IBM Plex Sans', -apple-system, sans-serif;
  --font-mono:'IBM Plex Mono', 'Courier New', monospace;

  /* --- Shape / elevation ------------------------------------------------ */
  --radius-lg:20px;
  --radius-md:12px;
  --radius-sm:8px;
  --radius-pill:999px;
  --shadow-card:0 1px 2px rgba(58,44,20,.05), 0 12px 30px -14px rgba(58,44,20,.18);
  --shadow-pop:0 6px 14px rgba(58,44,20,.09), 0 24px 54px -18px rgba(58,44,20,.26);

  --gradient-saffron:linear-gradient(120deg, var(--saffron-300) 0%, var(--saffron-500) 45%, var(--saffron-600) 100%);
  --gradient-navy:radial-gradient(120% 140% at 15% 0%, var(--navy-700) 0%, var(--navy-900) 45%, var(--navy-950) 100%);
  --gradient-magenta:linear-gradient(120deg, var(--magenta-500) 0%, var(--magenta-600) 100%);
}

/* --- Scroll reveal -----------------------------------------------------------
   Elements marked .reveal fade and lift into place as they scroll into view.
   The .is-visible class is added by an IntersectionObserver in index.html.
   The reduced-motion block further down neutralises all of this for anyone
   who has asked their device for less animation. */
.reveal{ opacity:0; transform:translateY(18px); transition:opacity .6s cubic-bezier(.2,.7,.3,1), transform .6s cubic-bezier(.2,.7,.3,1); }
.reveal.is-visible{ opacity:1; transform:none; }
.reveal-d1{ transition-delay:.07s; }
.reveal-d2{ transition-delay:.14s; }
.reveal-d3{ transition-delay:.21s; }

*,*::before,*::after{ box-sizing:border-box; }
html{ -webkit-text-size-adjust:100%; scroll-behavior:smooth; overflow-x:hidden; }
body{
  margin:0;
  font-family:var(--font-body);
  color:var(--ink-900);
  background:var(--paper);
  line-height:1.55;
  -webkit-font-smoothing:antialiased;
  overflow-x:hidden;
  max-width:100vw;
}
h1,h2,h3,h4{ font-family:var(--font-display); font-weight:600; line-height:1.15; margin:0; color:var(--navy-950); }
p{ margin:0; }
figure{ margin:0; }   /* browsers default figure to 40px side margins */
a{ color:inherit; text-decoration:none; }
img{ max-width:100%; display:block; }
button{ font-family:inherit; }
ul{ margin:0; padding:0; list-style:none; }

@media (prefers-reduced-motion: reduce){
  *{ animation-duration:.001ms !important; animation-iteration-count:1 !important; transition-duration:.001ms !important; scroll-behavior:auto !important; }
  /* Neutralising the transition alone would leave .reveal elements stuck at
     opacity:0 if the observer never fires — so show them outright. */
  .reveal{ opacity:1 !important; transform:none !important; }
}

:focus-visible{ outline:3px solid var(--saffron-500); outline-offset:2px; border-radius:4px; }

/* --- Layout helpers ---------------------------------------------------- */
.wrap{ width:100%; max-width:1180px; margin-inline:auto; padding-inline:20px; }
.grid{ display:grid; gap:20px; }
.stack{ display:flex; flex-direction:column; }
.row{ display:flex; align-items:center; }
.spread{ display:flex; align-items:center; justify-content:space-between; }
.sr-only{ position:absolute; width:1px; height:1px; padding:0; margin:-1px; overflow:hidden; clip:rect(0,0,0,0); white-space:nowrap; border:0; }

/* --- Eyebrow / micro label ---------------------------------------------- */
.eyebrow{
  font-family:var(--font-mono); font-size:11.5px; font-weight:500; letter-spacing:.14em;
  text-transform:uppercase; color:var(--gold-700);
}
.eyebrow.on-dark{ color:var(--saffron-300); }

/* --- Seal motif : the signature element --------------------------------
   A concentric ring device used around the crest mark and around verified
   states. Built from layered borders + a dashed inner ring so it reads as
   an engraved official seal rather than a decorative circle. */
.seal{
  position:relative; display:inline-grid; place-items:center; border-radius:50%;
  background:var(--white); box-shadow:var(--shadow-card);
}
.seal::before{
  content:''; position:absolute; inset:6px; border-radius:50%;
  border:1.5px dashed var(--gold-500); opacity:.55;
}
.seal::after{
  content:''; position:absolute; inset:0; border-radius:50%;
  border:1px solid var(--gold-300);
}
.seal img{ width:78%; height:78%; object-fit:contain; border-radius:50%; }
.seal.seal-navy{ background:var(--gradient-navy); }
.seal.seal-navy::after{ border-color:rgba(228,199,101,.5); }
.seal.seal-sm{ width:44px; height:44px; }
.seal.seal-md{ width:64px; height:64px; }
.seal.seal-lg{ width:128px; height:128px; }
.seal.seal-xl{ width:192px; height:192px; }
.seal.seal-xl::before{ inset:14px; }

/* --- Buttons ------------------------------------------------------------ */
.btn{
  display:inline-flex; align-items:center; justify-content:center; gap:8px;
  font-family:var(--font-body); font-weight:600; font-size:14.5px;
  padding:12px 22px; border-radius:var(--radius-pill); border:1px solid transparent;
  cursor:pointer; transition:transform .15s ease, box-shadow .15s ease, background .15s ease, border-color .15s ease;
  white-space:nowrap;
}
.btn:active{ transform:translateY(1px); }
.btn-primary{ background:var(--gradient-saffron); color:var(--navy-950); box-shadow:0 8px 20px -8px rgba(242,123,14,.55); }
.btn-primary:hover{ box-shadow:0 10px 24px -8px rgba(242,123,14,.7); }
.btn-navy{ background:var(--navy-900); color:var(--white); }
.btn-navy:hover{ background:var(--navy-800); }
.btn-outline{ background:transparent; border-color:var(--line-strong); color:var(--navy-900); }
.btn-outline:hover{ border-color:var(--gold-500); background:var(--paper); box-shadow:0 0 0 4px var(--gold-glow); }
.btn-outline.on-dark{ border-color:rgba(255,255,255,.35); color:var(--white); }
.btn-outline.on-dark:hover{ background:rgba(255,255,255,.08); }

/* Premium gold-bordered button — a matte-gold outline that glows softly and
   reveals a → on hover. Used for elegant secondary CTAs (e.g. Resident Login). */
.btn-gold{
  background:transparent; color:var(--navy-950);
  border:1.5px solid var(--gold-500);
}
.btn-gold::after{
  content:"→"; margin-left:2px; opacity:0; width:0; overflow:hidden;
  transition:opacity .18s ease, width .18s ease, margin .18s ease;
}
@media (hover:hover){
  .btn-gold:hover{ box-shadow:0 0 0 4px var(--gold-glow), 0 10px 22px -10px rgba(201,162,39,.5); background:rgba(201,162,39,.05); }
  .btn-gold:hover::after{ opacity:1; width:1em; margin-left:6px; }
}
.btn-gold.on-dark{ color:var(--white); border-color:var(--gold-300); }
.btn-ghost{ background:transparent; color:var(--navy-800); padding:10px 14px; }
.btn-ghost:hover{ background:var(--paper); }
.btn-danger{ background:var(--danger-bg); color:var(--danger); border-color:var(--danger-line); }
.btn-danger:hover{ background:var(--danger); color:var(--white); }
.btn-sm{ padding:8px 14px; font-size:13px; }
.btn-block{ width:100%; }
.btn[disabled]{ opacity:.55; cursor:not-allowed; }
.btn .spinner{ width:14px; height:14px; }

/* --- Card / Surface ------------------------------------------------------ */
.card{
  position:relative;
  background:var(--paper-raised);
  border:1px solid var(--line);
  border-radius:24px;
  box-shadow:var(--shadow-card);
  transition:transform .2s cubic-bezier(.22,.61,.36,1), box-shadow .2s ease;
}
/* A hair-thin matte-gold accent along the very top edge — the "premium" tell,
   restrained (not a heavy border). */
.card::before{
  content:""; position:absolute; left:24px; right:24px; top:0; height:2px;
  background:linear-gradient(90deg, transparent, var(--gold-500), transparent);
  opacity:.55; border-radius:2px;
}
/* Lift on hover — desktop only (no hover on touch, so mobile is unaffected). */
@media (hover:hover){
  .card:hover{ transform:translateY(-3px); box-shadow:var(--shadow-pop); }
}
.card-pad{ padding:26px; }

/* --- Badges / status pills ------------------------------------------------ */
.badge{
  display:inline-flex; align-items:center; gap:6px; font-size:12.5px; font-weight:600;
  padding:5px 12px; border-radius:var(--radius-pill); border:1px solid transparent; white-space:nowrap;
}
.badge-dot{ width:6px; height:6px; border-radius:50%; background:currentColor; }
.badge-success{ background:var(--success-bg); color:var(--success); border-color:var(--success-line); }
.badge-warning{ background:var(--warning-bg); color:var(--warning); border-color:var(--warning-line); }
.badge-danger{ background:var(--danger-bg); color:var(--danger); border-color:var(--danger-line); }
.badge-info{ background:var(--info-bg); color:var(--info); border-color:var(--info-line); }
.badge-gold{ background:#FBF3DC; color:var(--gold-700); border-color:var(--gold-300); }
.badge-neutral{ background:var(--paper); color:var(--ink-600); border-color:var(--line); }

/* --- Forms ---------------------------------------------------------------- */
.field{ display:flex; flex-direction:column; gap:6px; margin-bottom:16px; }
.field label{ font-size:13px; font-weight:600; color:var(--navy-900); }
.field .hint{ font-size:12px; color:var(--ink-400); }
.field .error{ font-size:12px; color:var(--danger); font-weight:500; }
input, select, textarea{
  font-family:var(--font-body); font-size:14.5px; color:var(--ink-900);
  background:var(--white); border:1.5px solid var(--line); border-radius:var(--radius-sm);
  padding:11px 13px; width:100%; transition:border-color .15s ease, box-shadow .15s ease;
}
input:focus, select:focus, textarea:focus{
  outline:none; border-color:var(--gold-500); box-shadow:0 0 0 4px rgba(201,162,39,.14);
}
input[type="file"]{ padding:9px; font-size:13px; }

/* --- Password show/hide toggle ------------------------------------------------ */
.pw-wrap{ position:relative; display:block; }
.pw-wrap input{ padding-right:44px; }          /* room for the eye button */
.pw-toggle{
  position:absolute; top:0; right:0; height:100%; width:42px;
  display:flex; align-items:center; justify-content:center;
  background:none; border:none; padding:0; cursor:pointer;
  color:var(--ink-400); border-radius:0 var(--radius-sm) var(--radius-sm) 0;
}
.pw-toggle:hover{ color:var(--navy-700); }
.pw-toggle:focus-visible{ outline:2px solid var(--navy-600); outline-offset:-2px; }
.pw-toggle svg{ width:20px; height:20px; display:block; }
.pw-toggle .pw-eye-off{ display:none; }
.pw-toggle.is-on .pw-eye{ display:none; }
.pw-toggle.is-on .pw-eye-off{ display:block; }
.checkbox-row{ display:flex; align-items:flex-start; gap:10px; font-size:13.5px; color:var(--ink-700); }
.checkbox-row input{ width:auto; margin-top:3px; accent-color:var(--navy-800); }
fieldset{ border:1px solid var(--line); border-radius:var(--radius-md); padding:18px; margin:0 0 18px; }
legend{ font-family:var(--font-mono); font-size:11.5px; letter-spacing:.1em; text-transform:uppercase; color:var(--ink-400); padding:0 8px; }

/* --- Tables ----------------------------------------------------------------- */
.table-wrap{ overflow-x:auto; border:1px solid var(--line); border-radius:var(--radius-md); background:var(--white); }
table{ width:100%; border-collapse:collapse; font-size:13.5px; min-width:640px; }
thead th{
  text-align:left; font-family:var(--font-mono); font-size:11px; letter-spacing:.08em; text-transform:uppercase;
  color:var(--ink-400); padding:12px 14px; border-bottom:1px solid var(--line); background:var(--paper); white-space:nowrap;
}
/* Proportional digits make a column of rupee figures unreadable: 1 is narrow,
   4 and 7 are wide, so 1,400 and 2,400 do not line up and a defaulters list
   reads as mush. Tabular figures give every digit the same advance width, so
   the decimal points stack the way they would on a printed ledger. IBM Plex
   Sans ships the feature; this is the whole fix. */
tbody td{ padding:12px 14px; border-bottom:1px solid var(--line); color:var(--ink-700); vertical-align:middle;
          font-variant-numeric:tabular-nums; }
tbody tr:last-child td{ border-bottom:none; }
tbody tr:hover{ background:#FAFBFD; }
.mono{ font-family:var(--font-mono); font-size:12.5px; letter-spacing:.01em; font-variant-numeric:tabular-nums; }
/* Any figure meant to be compared against another figure above or below it. */
.tnum, .stat-strip .stat b, .badge, .print-receipt .pr-amount .num, .print-receipt .pr-grid{
  font-variant-numeric:tabular-nums;
}

/* --- Responsive tables ------------------------------------------------------
   Add class "responsive" to a .table-wrap and give every <td> a data-label.
   Below 760px each row collapses into a self-contained card with the column
   name shown beside each value. This exists because the payment-verification
   workflow has to be usable one-handed on a phone — a 640px-wide table forces
   sideways scrolling just to reach the action button, which is unusable when
   someone is standing at the RWA office waiting for their receipt. */
@media (max-width: 760px){
  .table-wrap.responsive{ border:none; background:transparent; overflow-x:visible; }
  .table-wrap.responsive table{ min-width:0; }
  .table-wrap.responsive thead{ display:none; }
  .table-wrap.responsive table,
  .table-wrap.responsive tbody,
  .table-wrap.responsive tr,
  .table-wrap.responsive td{ display:block; width:100%; }
  .table-wrap.responsive tr{
    border:1px solid var(--line); border-radius:var(--radius-md); background:var(--white);
    margin-bottom:10px; overflow:hidden; box-shadow:var(--shadow-card);
  }
  .table-wrap.responsive tr:hover{ background:var(--white); }
  .table-wrap.responsive td{
    display:flex; justify-content:space-between; align-items:center; gap:14px;
    padding:10px 14px; border-bottom:1px solid var(--line); text-align:right;
  }
  .table-wrap.responsive td:last-child{ border-bottom:none; }
  .table-wrap.responsive td::before{
    content:attr(data-label);
    font-family:var(--font-mono); font-size:10px; letter-spacing:.07em; text-transform:uppercase;
    color:var(--ink-400); flex-shrink:0; text-align:left;
  }
  /* A row's action cell becomes a full-width, thumb-sized button. */
  .table-wrap.responsive td[data-label="Actions"],
  .table-wrap.responsive td[data-label="Remind"]{ display:block; padding:12px 14px; }
  .table-wrap.responsive td[data-label="Actions"]::before,
  .table-wrap.responsive td[data-label="Remind"]::before{ display:none; }
  /* 14px padding keeps this at/above the 44px minimum touch target. */
  .table-wrap.responsive td[data-label="Actions"] .btn,
  .table-wrap.responsive td[data-label="Remind"] .btn{ width:100%; padding:14px; font-size:14px; min-height:44px; }
  /* An empty-state row spans the whole card. */
  .table-wrap.responsive td[colspan]{ display:block; text-align:center; padding:26px 14px; }
  .table-wrap.responsive td[colspan]::before{ display:none; }
}

/* --- Modal ------------------------------------------------------------------ */
.modal-backdrop{
  position:fixed; inset:0; background:rgba(10,20,40,.55); backdrop-filter:blur(2px);
  display:none; align-items:center; justify-content:center; padding:20px; z-index:80;
}
.modal-backdrop.open{ display:flex; animation:modal-veil .18s ease both; }
.modal{ background:var(--white); border-radius:var(--radius-lg); max-width:560px; width:100%; max-height:88vh; overflow-y:auto; box-shadow:var(--shadow-pop); }

/* The backdrop is toggled by adding/removing .open, which flips `display` —
   and display is not animatable, so the modal used to appear in a single
   frame. Animating on the .open class instead costs no JavaScript change and
   gives the payment-verification dialog, the most-used control in the admin
   panel, somewhere to come from.

   Entry only. There is no exit animation because .open is removed
   synchronously and the element is gone before a transition could run; doing
   that properly needs the <dialog> element (see the note below). An instant
   dismissal reads as responsive anyway — it is the arrival that needs to be
   explained to the eye, not the departure. */
.modal-backdrop.open .modal{ animation:modal-rise .24s cubic-bezier(.2,.7,.3,1) both; }
@keyframes modal-veil{ from{ opacity:0; } }
@keyframes modal-rise{ from{ opacity:0; transform:translateY(14px) scale(.985); } }

/* On a phone a sheet rising from the bottom edge matches where the thumb
   already is, and matches what every native app on the device does. */
@media (max-width: 640px){
  .modal-backdrop{ align-items:flex-end; padding:0; }
  .modal{ max-width:none; border-radius:var(--radius-lg) var(--radius-lg) 0 0; max-height:92vh;
          padding-bottom:env(safe-area-inset-bottom); }
  .modal-backdrop.open .modal{ animation:modal-sheet .26s cubic-bezier(.2,.7,.3,1) both; }
  @keyframes modal-sheet{ from{ transform:translateY(100%); } }
}

/* NOTE for later: replacing .modal-backdrop with a real <dialog> and
   showModal() would give focus trapping, Esc-to-close, an inert background and
   animatable exits, all for free. It is a markup change across six dialogs in
   admin.html, so it is not done here — but it is the right end state. */
.modal-head{ display:flex; align-items:center; justify-content:space-between; padding:20px 24px; border-bottom:1px solid var(--line); }
.modal-body{ padding:24px; }

/* --- Toast ------------------------------------------------------------------ */
/* Pages that have a fixed bottom bar raise this so toasts clear it. */
:root{ --toast-bottom-gap:16px; }

#toast-region{ position:fixed; top:18px; right:18px; z-index:100; display:flex; flex-direction:column; gap:10px; max-width:340px; }
.toast{
  background:var(--navy-950); color:var(--white); padding:13px 16px; border-radius:var(--radius-md);
  font-size:13.5px; box-shadow:var(--shadow-pop); display:flex; align-items:flex-start; gap:10px;
  animation:toast-in .25s ease;
}
.toast.success{ background:var(--success); }
.toast.error{ background:var(--danger); }
.toast.leaving{ animation:toast-out .3s ease forwards; }
@keyframes toast-in{ from{ opacity:0; transform:translateY(-8px);} to{ opacity:1; transform:translateY(0);} }
@keyframes toast-out{ to{ opacity:0; transform:translateY(-6px); } }

/* Top-right is the wrong corner on a phone. It sits under the sticky header,
   and it is the furthest point on the screen from the thumb — so a toast that
   says "verify your email first" appears exactly where nobody is looking.
   Anchored to the bottom instead, clear of the tab bar, full width. */
@media (max-width: 900px){
  #toast-region{
    top:auto; bottom:calc(var(--toast-bottom-gap) + env(safe-area-inset-bottom));
    left:14px; right:14px; max-width:none;
  }
  .toast{ font-size:14px; padding:14px 16px; animation:toast-in-up .25s ease; }
  .toast.leaving{ animation:toast-out-down .3s ease forwards; }
  @keyframes toast-in-up{ from{ opacity:0; transform:translateY(10px);} to{ opacity:1; transform:translateY(0);} }
  @keyframes toast-out-down{ to{ opacity:0; transform:translateY(8px); } }
}

/* --- Loader ------------------------------------------------------------------ */
.spinner{ width:20px; height:20px; border-radius:50%; border:2.5px solid rgba(255,255,255,.35); border-top-color:currentColor; animation:spin .7s linear infinite; }
@keyframes spin{ to{ transform:rotate(360deg); } }
.skeleton{ background:linear-gradient(90deg, var(--line) 25%, #EDF0F6 37%, var(--line) 63%); background-size:400% 100%; animation:sk 1.4s ease infinite; border-radius:6px; }
@keyframes sk{ 0%{background-position:100% 50%;} 100%{background-position:0 50%;} }

/* Reusable skeleton rows for lists and tables. Instead of a bare "Loading…"
   that then jumps to content, every list shows a few grey rows shaped like the
   real thing, so the arrival is a fade rather than a jolt. Build them with the
   skeletonRows()/skeletonList() helpers in app-common.js. */
.sk-row{ display:flex; align-items:center; gap:14px; padding:14px 4px; }
.sk-line{ height:12px; border-radius:6px; }
.sk-line.sk{ background:linear-gradient(90deg, var(--line) 25%, #EDF0F6 37%, var(--line) 63%);
  background-size:400% 100%; animation:sk 1.4s ease infinite; }
.sk-w-40{ width:40%; } .sk-w-60{ width:60%; } .sk-w-25{ width:25%; } .sk-w-80{ width:80%; }
.sk-stack{ display:flex; flex-direction:column; gap:8px; flex:1; }
.sk-pill{ width:74px; height:26px; border-radius:var(--radius-pill); flex-shrink:0; }
@media (prefers-reduced-motion: reduce){ .skeleton, .sk-line.sk{ animation:none; } }

/* --- Empty state -------------------------------------------------------------- */
.empty{ text-align:center; padding:48px 20px; color:var(--ink-400); }
.empty .seal{ margin:0 auto 16px; }
.empty h4{ color:var(--ink-600); font-size:15px; margin-bottom:6px; }
.empty p{ font-size:13.5px; max-width:340px; margin:0 auto; }
/* Compact variant for inside a table cell or a short panel. */
.empty.empty-sm{ padding:30px 16px; }

/* --- Inline field errors ------------------------------------------------------ */
/* A validation problem belongs under the field that caused it, not in a toast
   at the corner of the screen the user then has to hunt back from. */
.field.has-error input, .field.has-error select, .field.has-error textarea{
  border-color:var(--danger); background:#FEF4F3;
}
.field-error{ display:none; color:var(--danger); font-size:12px; margin-top:5px; font-weight:500; }
.field.has-error .field-error{ display:block; }

/* --- Callout (inline info box) ------------------------------------------------- */
.callout{ border-radius:var(--radius-md); padding:12px 14px; margin:4px 0 16px; line-height:1.5; }
.callout-info{ background:rgba(37,99,235,.07); border:1px solid rgba(37,99,235,.2); color:var(--ink-700); }
.callout-info b{ color:var(--navy-950); }

/* --- Payment detail box (bank details in the payment modal) ------------------- */
.pay-detail-box{ text-align:left; margin-top:4px; border:1px solid var(--line); border-radius:var(--radius-md); overflow:hidden; }
.pay-detail-box .pdl{ display:flex; justify-content:space-between; gap:14px; padding:7px 12px; font-size:12.8px; border-bottom:1px solid var(--line); }
.pay-detail-box .pdl:last-child{ border-bottom:none; }
.pay-detail-box .pdl span:first-child{ color:var(--ink-400); font-family:var(--font-mono); font-size:10.5px; letter-spacing:.04em; text-transform:uppercase; white-space:nowrap; padding-top:2px; }
.pay-detail-box .pdl span:last-child{ text-align:right; font-weight:600; color:var(--navy-950); font-variant-numeric:tabular-nums; }

/* --- Payment type toggle (membership vs maintenance) -------------------------- */
.paytype-toggle{ display:flex; gap:8px; margin-bottom:16px; }
.paytype{ flex:1; padding:12px; border:1.5px solid var(--line); border-radius:var(--radius-md);
  background:var(--white); cursor:pointer; text-align:left; transition:border-color .15s ease, background .15s ease; }
.paytype.selected{ border-color:var(--saffron-500); background:var(--paper); }
.paytype .pt-top{ font-size:11px; color:var(--ink-400); font-family:var(--font-mono); letter-spacing:.04em; text-transform:uppercase; }
.paytype .pt-amt{ font-size:15px; font-weight:700; color:var(--navy-950); font-variant-numeric:tabular-nums; margin-top:2px; }

/* --- Maintenance invoice (payment modal) -------------------------------------- */
/* Turns "type an amount" into "here is exactly what you owe, tap to pay it".
   The committee's per-tower rate already produces expected/paid/outstanding
   (duesFor); this just shows that breakdown as a bill and pre-locks the amount
   to the outstanding figure, so a resident pays the right sum without doing
   arithmetic — the whole point of the feature. */
.invoice-card{ border:1px solid var(--line); border-radius:var(--radius-md); overflow:hidden; margin-bottom:16px; }
.invoice-head{ background:var(--navy-950); color:#fff; padding:12px 14px; display:flex; align-items:center; justify-content:space-between; }
.invoice-head .lbl{ font-family:var(--font-mono); font-size:10.5px; letter-spacing:.1em; text-transform:uppercase; color:var(--gold-500); }
.invoice-head .fy{ font-size:12px; color:rgba(255,255,255,.75); }
.invoice-rows{ padding:6px 14px; }
.invoice-rows .r{ display:flex; justify-content:space-between; padding:8px 0; font-size:13.5px; border-bottom:1px solid var(--line); font-variant-numeric:tabular-nums; }
.invoice-rows .r:last-child{ border-bottom:none; }
.invoice-rows .r.total{ font-weight:700; color:var(--navy-950); font-size:15px; }
.invoice-rows .r .muted{ color:var(--ink-400); }
.invoice-rows .r .paid{ color:var(--success); }
.invoice-rows .r .owe{ color:var(--danger); font-weight:700; }
.invoice-clear{ padding:16px 14px; text-align:center; }
.invoice-clear .tick{ color:var(--success); font-size:15px; font-weight:600; }
/* Amount presets */
.amount-presets{ display:flex; gap:8px; margin-bottom:10px; flex-wrap:wrap; }
.amount-preset{ flex:1; min-width:120px; padding:11px 12px; border:1.5px solid var(--line); border-radius:var(--radius-md);
  background:var(--white); cursor:pointer; text-align:left; transition:border-color .15s ease, background .15s ease; }
.amount-preset.selected{ border-color:var(--saffron-500); background:var(--paper); }
.amount-preset .pa-top{ font-size:11px; color:var(--ink-400); font-family:var(--font-mono); letter-spacing:.04em; text-transform:uppercase; }
.amount-preset .pa-amt{ font-size:16px; font-weight:700; color:var(--navy-950); font-variant-numeric:tabular-nums; margin-top:2px; }
.amount-preset.locked-note{ cursor:default; }

/* --- Maintenance invoice (payment modal) end ---------------------------------- */

/* --- Offline banner ----------------------------------------------------------- */
.offline-banner{
  position:fixed; left:0; right:0; top:0; z-index:130;
  background:var(--ink-700); color:#fff; padding:9px 16px;
  display:flex; align-items:center; justify-content:center; gap:9px;
  font-size:13px; font-weight:500; box-shadow:0 3px 12px rgba(0,0,0,.15);
  animation:offline-drop .25s ease;
}
.offline-banner svg{ color:var(--gold-500); flex-shrink:0; }
@keyframes offline-drop{ from{ transform:translateY(-100%); } }
@media (prefers-reduced-motion: reduce){ .offline-banner{ animation:none; } }

/* --- Pager --------------------------------------------------------------------- */
.pager{ display:flex; align-items:center; justify-content:space-between; gap:14px;
  flex-wrap:wrap; margin-top:16px; }
.pager:empty{ margin-top:0; }
.pager-info{ font-family:var(--font-mono); font-size:12px; color:var(--ink-400); font-variant-numeric:tabular-nums; }
.pager-btns{ display:flex; align-items:center; gap:4px; margin-left:auto; }
.pager-btn{
  min-width:34px; height:34px; padding:0 8px; border-radius:var(--radius-md);
  border:1px solid var(--line); background:var(--white); color:var(--ink-700);
  font-size:13.5px; font-weight:600; cursor:pointer; font-variant-numeric:tabular-nums;
  transition:background .15s ease, border-color .15s ease;
}
.pager-btn:hover:not(:disabled):not(.is-current){ border-color:var(--gold-500); background:var(--paper); }
.pager-btn.is-current{ background:var(--navy-950); color:#fff; border-color:transparent; cursor:default; }
.pager-btn:disabled{ opacity:.4; cursor:not-allowed; }
.pager-gap{ color:var(--ink-400); padding:0 2px; }
@media (max-width:560px){ .pager{ justify-content:center; } .pager-btns{ margin-left:0; } }

/* --- Registration steps ------------------------------------------------------- */
/* The form has three natural sections; on a phone all fifteen fields in one
   scroll is a wall. Showing one section at a time with a progress indicator
   makes it feel short. Pure progressive enhancement: .steps-on is added by JS,
   so if the script fails every fieldset simply shows and the form still works. */
.step-indicator{ display:flex; align-items:center; gap:0; margin:0 0 22px; }
.step-dot{ display:flex; flex-direction:column; align-items:center; gap:6px; flex:0 0 auto; }
.step-dot .num{
  width:30px; height:30px; border-radius:50%; display:grid; place-items:center;
  font-family:var(--font-mono); font-size:13px; font-weight:600;
  background:var(--paper); color:var(--ink-400); border:1.5px solid var(--line); transition:all .25s ease;
}
.step-dot .lbl{ font-size:10.5px; font-weight:600; letter-spacing:.03em; text-transform:uppercase; color:var(--ink-400); transition:color .25s ease; }
.step-dot.active .num{ background:var(--gradient-saffron); color:#fff; border-color:transparent; }
.step-dot.active .lbl{ color:var(--navy-950); }
.step-dot.done .num{ background:var(--navy-950); color:#fff; border-color:transparent; }
.step-line{ flex:1; height:2px; background:var(--line); margin:0 8px; align-self:flex-start; margin-top:14px; border-radius:2px; transition:background .25s ease; }
.step-line.done{ background:var(--navy-950); }
.steps-on fieldset{ display:none; }
.steps-on fieldset.step-current{ display:block; animation:step-in .25s ease; }
@keyframes step-in{ from{ opacity:0; transform:translateY(6px); } }
.step-nav{ display:flex; gap:10px; margin-top:8px; }
.step-nav .btn{ flex:1; }
/* The declaration + submit belong to the last step only. */
.steps-on .final-only{ display:none; }
.steps-on.at-last .final-only{ display:block; }
@media (prefers-reduced-motion: reduce){ .steps-on fieldset.step-current{ animation:none; } }

/* --- Session expiry banner ---------------------------------------------------- */
.session-banner{
  position:fixed; left:0; right:0; bottom:0; z-index:120;
  background:var(--navy-950); color:#fff; padding:14px 18px;
  display:flex; align-items:center; gap:14px; flex-wrap:wrap; justify-content:center;
  box-shadow:0 -6px 24px rgba(0,0,0,.18); font-size:13.5px;
  transform:translateY(100%); animation:session-rise .3s ease forwards;
}
@keyframes session-rise{ to{ transform:translateY(0); } }
.session-banner button{ padding:8px 16px; border-radius:var(--radius-md); font-weight:600; font-size:13px; cursor:pointer; border:none; }
.session-banner .stay{ background:var(--gold-500); color:var(--navy-950); }
.session-banner .out{ background:transparent; color:rgba(255,255,255,.7); border:1px solid rgba(255,255,255,.3); }

/* --- Utility text colors -------------------------------------------------------- */
.t-muted{ color:var(--ink-400); }
.t-sub{ color:var(--ink-600); }
.t-success{ color:var(--success); }
.t-danger{ color:var(--danger); }
.t-gold{ color:var(--gold-700); }

/* --- Scrollbar (webkit) --------------------------------------------------------- */
::-webkit-scrollbar{ width:10px; height:10px; }
::-webkit-scrollbar-thumb{ background:var(--line-strong); border-radius:99px; }
::-webkit-scrollbar-track{ background:transparent; }

/* --- Print (used by receipt view) ------------------------------------------------ */
#printReceiptArea{ display:none; }
.print-receipt{
  font-family:var(--font-body); color:#000; max-width:720px; margin:0 auto; padding:24px;
}
.print-receipt .pr-head{ display:flex; align-items:center; gap:16px; border-bottom:2px solid #0A1B33; padding-bottom:16px; margin-bottom:20px; }
.print-receipt .pr-head img{ width:56px; height:56px; }
.print-receipt .pr-head h1{ font-size:18px; margin:0; }
.print-receipt .pr-head p{ font-size:11px; color:#444; margin:2px 0 0; }
.print-receipt .pr-title{ margin-left:auto; text-align:right; font-size:11px; }
.print-receipt .pr-grid{ display:grid; grid-template-columns:1fr 1fr; gap:14px 24px; margin-bottom:20px; font-size:13px; }
.print-receipt .pr-grid b{ display:block; font-size:9.5px; text-transform:uppercase; letter-spacing:.05em; color:#666; font-weight:600; margin-bottom:2px; }
.print-receipt .pr-amount{ border:1px solid #ccc; border-radius:8px; padding:14px 16px; display:flex; justify-content:space-between; align-items:center; margin-bottom:20px; }
.print-receipt .pr-amount .num{ font-size:22px; font-weight:700; }
.print-receipt .pr-qr{ text-align:center; }
.print-receipt .pr-qr img{ width:90px; height:90px; }
.print-receipt .pr-foot{ font-size:10px; color:#666; border-top:1px solid #ccc; padding-top:12px; margin-top:10px; }

@media print{
  .no-print{ display:none !important; }
  body{ background:var(--white); }
  body.printing-receipt > *:not(#printReceiptArea){ display:none !important; }
  body.printing-receipt #printReceiptArea{ display:block !important; }
  @page{ margin:14mm; }
}

/* ============================================================================
   PREMIUM TOUCH — loading screen, page transitions, success + confetti
   All animations respect prefers-reduced-motion (see the media query at end).
   ============================================================================ */

/* --- Elegant loading screen (society logo) -------------------------------- */
#appLoader{
  position:fixed; inset:0; z-index:9999; display:flex; flex-direction:column;
  align-items:center; justify-content:center; gap:22px;
  background:var(--gradient-navy, radial-gradient(120% 140% at 15% 0%, #1F4585 0%, #0F2547 45%, #0A1B33 100%));
  transition:opacity .6s ease, visibility .6s ease;
}
#appLoader.hide{ opacity:0; visibility:hidden; pointer-events:none; }
#appLoader .al-seal{
  width:96px; height:96px; border-radius:50%; background:#fff; padding:8px;
  box-shadow:0 10px 40px rgba(0,0,0,.35); object-fit:contain;
  animation:alPulse 2s ease-in-out infinite;
}
#appLoader .al-name{
  color:#fff; font-family:var(--font-display, Georgia, serif); font-size:19px;
  letter-spacing:.02em; text-align:center; opacity:.96;
}
#appLoader .al-sub{
  color:var(--gold-300,#E4C765); font-family:var(--font-mono, monospace);
  font-size:10.5px; letter-spacing:.28em; text-transform:uppercase; margin-top:-14px;
}
#appLoader .al-bar{
  width:120px; height:3px; border-radius:3px; overflow:hidden;
  background:rgba(255,255,255,.15); position:relative;
}
#appLoader .al-bar::after{
  content:""; position:absolute; inset:0; width:40%; border-radius:3px;
  background:linear-gradient(90deg, transparent, var(--gold-300,#E4C765), transparent);
  animation:alSlide 1.15s ease-in-out infinite;
}
@keyframes alPulse{ 0%,100%{ transform:scale(1); box-shadow:0 10px 40px rgba(0,0,0,.35);} 50%{ transform:scale(1.06); box-shadow:0 14px 50px rgba(201,162,39,.35);} }
@keyframes alSlide{ 0%{ transform:translateX(-120%);} 100%{ transform:translateX(370%);} }

/* --- Smooth page / view transitions --------------------------------------- */
.fade-in{ animation:fadeInUp .5s cubic-bezier(.22,.61,.36,1) both; }
.fade-in-soft{ animation:fadeIn .45s ease both; }
@keyframes fadeInUp{ from{ opacity:0; transform:translateY(14px);} to{ opacity:1; transform:translateY(0);} }
@keyframes fadeIn{ from{ opacity:0;} to{ opacity:1;} }
/* Stagger helper: children appear one after another */
.stagger > *{ animation:fadeInUp .5s cubic-bezier(.22,.61,.36,1) both; }
.stagger > *:nth-child(1){ animation-delay:.04s; }
.stagger > *:nth-child(2){ animation-delay:.10s; }
.stagger > *:nth-child(3){ animation-delay:.16s; }
.stagger > *:nth-child(4){ animation-delay:.22s; }
.stagger > *:nth-child(5){ animation-delay:.28s; }
.stagger > *:nth-child(6){ animation-delay:.34s; }

/* --- Success animation (animated checkmark) ------------------------------- */
.success-pop{
  display:flex; flex-direction:column; align-items:center; gap:14px;
  text-align:center; padding:8px 0 4px;
}
.success-ring{
  width:76px; height:76px; border-radius:50%;
  display:flex; align-items:center; justify-content:center;
  background:rgba(19,122,75,.10); border:2px solid #137a4b;
  animation:successRing .5s cubic-bezier(.22,1.2,.36,1) both;
}
.success-ring svg{ width:40px; height:40px; }
.success-ring .tick{
  stroke:#137a4b; stroke-width:3.5; fill:none;
  stroke-linecap:round; stroke-linejoin:round;
  stroke-dasharray:32; stroke-dashoffset:32;
  animation:tickDraw .45s .18s cubic-bezier(.65,0,.45,1) forwards;
}
.success-pop .success-title{ font-family:var(--font-display,Georgia,serif); font-size:19px; color:var(--navy-950,#0A1B33); }
.success-pop .success-msg{ font-size:13.5px; color:var(--ink-400,#6b7688); max-width:280px; line-height:1.5; }
@keyframes successRing{ 0%{ transform:scale(.4); opacity:0;} 60%{ transform:scale(1.08);} 100%{ transform:scale(1); opacity:1;} }
@keyframes tickDraw{ to{ stroke-dashoffset:0; } }

/* --- Confetti ------------------------------------------------------------- */
#confettiCanvas{ position:fixed; inset:0; z-index:9998; pointer-events:none; }

@media (prefers-reduced-motion: reduce){
  #appLoader .al-seal, #appLoader .al-bar::after,
  .fade-in, .fade-in-soft, .stagger > *, .success-ring, .success-ring .tick{
    animation:none !important;
  }
  .success-ring .tick{ stroke-dashoffset:0; }
}

/* ============================================================================
   PREMIUM CIVIC — dividers, hero glass, logo treatment
   Mobile-fast: no texture images, glass limited to the hero only.
   ============================================================================ */

/* --- Thin gold section divider (restrained ❖, not a heavy rule) ----------- */
.gold-divider{
  display:flex; align-items:center; justify-content:center; gap:16px;
  margin:8px auto; max-width:340px; color:var(--gold-500);
}
.gold-divider::before, .gold-divider::after{
  content:""; height:1px; flex:1;
  background:linear-gradient(90deg, transparent, var(--gold-500));
}
.gold-divider::after{ background:linear-gradient(90deg, var(--gold-500), transparent); }
.gold-divider .gd-mark{ font-size:12px; opacity:.9; }

/* --- Logo ring + glow ------------------------------------------------------
   Wrap a seal <img> in .logo-ring to give it a matte-gold ring, soft glow and
   shadow, so it reads as an emblem rather than a pasted image. */
.logo-ring{
  position:relative; display:inline-flex; align-items:center; justify-content:center;
  border-radius:50%; padding:5px;
  background:radial-gradient(circle at 50% 30%, rgba(255,255,255,.9), var(--paper-raised));
  box-shadow:0 0 0 2px var(--gold-500), 0 0 0 6px var(--gold-glow), 0 12px 30px -10px rgba(58,44,20,.35);
}
.logo-ring.on-dark{
  background:radial-gradient(circle at 50% 30%, rgba(255,255,255,.14), rgba(255,255,255,.04));
  box-shadow:0 0 0 2px var(--gold-300), 0 0 24px var(--gold-glow), 0 12px 30px -8px rgba(0,0,0,.5);
}
.logo-ring img{ border-radius:50%; display:block; width:100%; height:100%; object-fit:contain; }

/* --- Hero frosted-glass card (glass used ONLY here, for performance) ------- */
.glass{
  background:rgba(255,255,255,.08);
  border:1px solid rgba(255,255,255,.14);
  border-radius:24px;
  -webkit-backdrop-filter:blur(14px); backdrop-filter:blur(14px);
  box-shadow:0 8px 32px -12px rgba(0,0,0,.4), inset 0 1px 0 rgba(255,255,255,.12);
}
/* Graceful fallback where backdrop-filter isn't supported: a solid tint so
   text stays legible (never a see-through unreadable panel). */
@supports not ((backdrop-filter:blur(1px)) or (-webkit-backdrop-filter:blur(1px))){
  .glass{ background:rgba(15,37,71,.72); }
}

/* ============================================================================
   LOGGED-IN VIEW — focus mode
   Once a resident logs in, hide the sections aimed at a PROSPECTIVE resident
   (the pitch: hero, about, benefits, community feel, the login/register
   tabs) so the dashboard isn't buried under a full landing page. Sections a
   resident keeps needing AFTER joining — Notices, financial transparency,
   Bylaws/AGM documents, Committee contacts, office contact details — stay
   visible; hiding those was the actual bug here: a logged-in resident is
   exactly who most needs to see a maintenance-shutoff notice or find the
   office phone number, and this used to hide the entire rest of the page
   the moment they signed in, notices included.
   Toggled by adding/removing the 'logged-in' class on <body> in the auth
   handler. Purely presentational — sections stay in the DOM, just hidden,
   so logout restores everything instantly.
   ============================================================================ */
body.logged-in #top,
body.logged-in #about,
body.logged-in #benefits,
body.logged-in #community,
body.logged-in #portal{
  display:none !important;
}
/* Trim the header to just the brand + logout on the dashboard, and hide the
   marketing nav links (About / Community / Accounts …) which don't apply here. */
body.logged-in .main-nav{ display:none; }
body.logged-in .site-header{ position:sticky; top:0; z-index:40; }
/* Give the dashboard a little breathing room now that it stands alone. */
body.logged-in #dashboard{ min-height:calc(100vh - 66px); padding-top:26px; }
/* The mobile bottom tab-bar stays useful (Home / Pay / Account), so keep it. */

/* ============================================================================
   CARD GRADIENT HEADER + FAB + bigger touch targets
   ============================================================================ */

/* Optional navy→gold gradient header strip for a card. Add <div class="card-head-gradient">…</div>
   as the first child of a .card. Keeps the rest of the card clean. */
.card-head-gradient{
  margin:-1px -1px 0;                 /* sit flush over the card's rounded top */
  padding:16px 22px;
  border-radius:24px 24px 0 0;
  background:linear-gradient(120deg, var(--navy-900) 0%, var(--navy-800) 55%, #163a70 100%);
  color:#fff; display:flex; align-items:center; gap:12px;
  position:relative; overflow:hidden;
}
/* A soft gold sheen across the header — the "premium" cue. */
.card-head-gradient::after{
  content:""; position:absolute; inset:0;
  background:linear-gradient(90deg, transparent 40%, rgba(201,162,39,.18) 75%, transparent);
  pointer-events:none;
}
.card-head-gradient h3, .card-head-gradient .ch-title{
  font-family:var(--font-display, Georgia, serif); font-size:16.5px; margin:0; color:#fff;
}
.card-head-gradient .ch-sub{ font-size:12px; color:rgba(255,255,255,.72); margin-top:1px; }
.card-head-gradient svg{ width:22px; height:22px; color:var(--gold-300); flex-shrink:0; }
/* When a card leads with a gradient header, drop the thin gold top-accent line
   (the header already carries the accent) and let the header meet the corners. */
.card:has(> .card-head-gradient)::before{ display:none; }

/* --- Floating Action Button (mobile) -------------------------------------
   A round navy+gold button pinned bottom-right, above the tab bar. Used for the
   primary "add" action on a screen (e.g. admin → Add Member). Desktop keeps the
   normal inline buttons, so the FAB only shows on narrow screens. */
.fab{
  display:none; position:fixed; right:18px; bottom:88px; z-index:75;
  width:56px; height:56px; border-radius:50%; border:none; cursor:pointer;
  background:var(--gradient-saffron, linear-gradient(135deg,#F29D38,#E4890F));
  color:var(--navy-950); box-shadow:0 8px 24px -6px rgba(242,123,14,.6);
  align-items:center; justify-content:center;
  transition:transform .15s ease, box-shadow .15s ease;
}
.fab svg{ width:26px; height:26px; }
.fab:active{ transform:scale(.94); }
.fab .fab-label{
  position:absolute; right:64px; white-space:nowrap; background:var(--navy-900); color:#fff;
  font-size:12.5px; padding:6px 11px; border-radius:8px; opacity:0; transform:translateX(6px);
  transition:opacity .15s ease, transform .15s ease; pointer-events:none;
}
@media (max-width:820px){
  .app-shell.active ~ .fab, .fab.fab-always{ display:flex; }
}

/* --- Larger touch targets on small screens -------------------------------
   Bump interactive elements to the ~44px comfortable-tap minimum on phones. */
@media (max-width:640px){
  .btn{ min-height:44px; padding-top:12px; padding-bottom:12px; }
  .btn-sm{ min-height:40px; }
  .icon-btn{ min-width:42px; min-height:42px; }
  input, select, textarea{ min-height:46px; font-size:16px; }  /* 16px stops iOS zoom-on-focus */
  .pw-toggle{ width:46px; }
  .paytype, .pay-option{ min-height:52px; }
  .tabbar-mobile a{ padding:9px 2px; }   /* a little taller for easier tapping */
}

/* ============================================================================
   FAMILY MEMBERS EDITOR — dynamic rows for DOB/anniversary wishing
   ============================================================================ */
.fm-editor{ display:flex; flex-direction:column; gap:8px; margin-bottom:6px; }
.fm-row-wrap{ display:flex; flex-direction:column; gap:4px; }
.fm-minor-badge{ font-size:11.5px; color:#8A5A00; background:#FFF3D6; border:1px solid #F0D089; border-radius:5px; padding:2px 8px; align-self:flex-start; }
.fm-row{ display:grid; grid-template-columns:1fr 130px 150px 34px; gap:8px; align-items:center; }
.fm-row input, .fm-row select{ margin:0; }
.vehicle-editor{ display:flex; flex-direction:column; gap:8px; margin-bottom:6px; }
.vehicle-row{ display:grid; grid-template-columns:1fr 1fr 34px; gap:8px; align-items:center; }
.vehicle-row input{ margin:0; }
@media (max-width:520px){
  .vehicle-row{ grid-template-columns:1fr 1fr; grid-template-areas:"veh park" "rem rem"; }
  .vehicle-row .veh-number{ grid-area:veh; }
  .vehicle-row .veh-parking{ grid-area:park; }
  .vehicle-row .fm-remove{ grid-area:rem; width:100%; }
}
.fm-remove{
  width:34px; height:38px; border-radius:var(--radius-sm,8px); border:1.5px solid var(--line);
  background:var(--white); color:var(--ink-400,#7C879C); cursor:pointer; font-size:15px; line-height:1;
  display:flex; align-items:center; justify-content:center; flex-shrink:0;
}
.fm-remove:hover{ border-color:var(--danger,#c0392b); color:var(--danger,#c0392b); }
.fm-add-btn{ align-self:flex-start; margin-top:2px; }
@media (max-width:600px){
  .fm-row{ grid-template-columns:1fr 1fr; grid-template-areas:"name name" "rel dob" "rem rem"; }
  .fm-row .fm-name{ grid-area:name; }
  .fm-row .fm-relation{ grid-area:rel; }
  .fm-row .fm-dob{ grid-area:dob; }
  .fm-row .fm-remove{ grid-area:rem; width:100%; }
}

/* --- Today's celebrations widget (admin overview) -------------------------- */
.celeb-card{ margin-bottom:20px; }
.celeb-list{ display:flex; flex-direction:column; gap:0; }
.celeb-item{
  display:flex; align-items:center; gap:12px; padding:12px 0; border-bottom:1px solid var(--line);
}
.celeb-item:last-child{ border-bottom:none; }
.celeb-icon{
  width:38px; height:38px; border-radius:50%; flex-shrink:0; display:flex; align-items:center; justify-content:center;
  font-size:18px; background:var(--gold-glow, rgba(201,162,39,.15));
}
.celeb-info{ flex:1; min-width:0; }
.celeb-name{ font-weight:600; font-size:13.5px; }
.celeb-sub{ font-size:12px; color:var(--ink-400,#7C879C); }

/* Required-field asterisk marker — shared so it renders consistently
   wherever a form uses <i class="req">*</i> next to a label (index.html had
   its own copy of this; admin.html's forms need it too). */
.field label .req{ color:var(--magenta-500,#C01860); font-style:normal; font-weight:700; margin-left:2px; }


/* Inline text-link-styled button — used for "read full policy" style links
   inside body text where a full <button> would look too heavy. */
.link-btn{
  background:none; border:none; padding:0; margin-left:4px;
  color:var(--navy-700,#1E3A5F); font-weight:600; font-size:inherit;
  text-decoration:underline; cursor:pointer; display:inline;
}
.link-btn:hover{ color:var(--gold-600,#A8841E); }

/* ============================================================================
   UNIVERSAL SEARCH (admin sidebar) — searches Members, Payments, Events and
   Expenses at once. Results render in NORMAL DOCUMENT FLOW right below the
   input (not position:absolute) deliberately: the sidebar itself scrolls
   (overflow-y:auto), and an absolutely-positioned dropdown would get
   silently clipped whenever the sidebar isn't scrolled to exactly the right
   spot — a bug that looks fine in a quick check and breaks in real use. The
   nav shifting down while results show is a normal, well-understood trade.
   ============================================================================ */
.usearch-wrap{ padding:0 8px 10px; }
.usearch-wrap input{
  width:100%; box-sizing:border-box; padding:9px 12px; border-radius:10px;
  border:1px solid rgba(255,255,255,.14); background:rgba(255,255,255,.06); color:var(--white);
  font-size:13px; font-family:inherit;
}
.usearch-wrap input::placeholder{ color:rgba(255,255,255,.45); }
.usearch-wrap input:focus{ outline:2px solid var(--gold-500,#C9A227); outline-offset:1px; background:rgba(255,255,255,.1); }
.usearch-results{ display:none; margin-top:8px; max-height:340px; overflow-y:auto; border-radius:10px; background:rgba(255,255,255,.04); }
.usearch-results.open{ display:block; }
.usearch-group-label{ padding:8px 10px 4px; font-size:10.5px; font-weight:700; letter-spacing:.04em; text-transform:uppercase; color:rgba(255,255,255,.4); }
.usearch-item{
  display:block; width:100%; text-align:left; background:none; border:none; cursor:pointer;
  padding:8px 10px; color:rgba(255,255,255,.85); font-size:12.5px; font-family:inherit;
  border-radius:6px;
}
.usearch-item:hover, .usearch-item:focus{ background:rgba(255,255,255,.08); }
.usearch-item b{ color:var(--white); font-weight:600; }
.usearch-item .usearch-sub{ display:block; color:rgba(255,255,255,.5); font-size:11px; margin-top:1px; }
.usearch-empty{ padding:12px 10px; font-size:12px; color:rgba(255,255,255,.45); text-align:center; }

/* Poll options editor — a simpler sibling of .fm-row (which is built for
   name+relation+dob and would leave two unused grid areas here): just a
   text field and a remove button per option. */
.poll-opt-row{ display:grid; grid-template-columns:1fr 34px; gap:8px; align-items:center; margin-bottom:8px; }
.poll-opt-row input{ margin:0; }

/* Treasurer Dashboard — a compact grid of labelled metric tiles. Deliberately
   smaller/denser than .stat-cards since this card packs 7 figures into one
   place rather than one figure per card. */
.td-grid{ display:grid; grid-template-columns:repeat(4,1fr); gap:12px; }
.td-tile{ background:var(--paper,#FAF8F3); border-radius:10px; padding:12px 14px; }
.td-tile .td-label{ font-size:11px; color:var(--ink-500,#6B7385); text-transform:uppercase; letter-spacing:.03em; margin-bottom:4px; }
.td-tile .td-value{ font-size:17px; font-weight:700; color:var(--ink-900,#101B2B); }
.td-tile .td-note{ font-size:11px; color:var(--ink-500,#6B7385); margin-top:2px; }
@media (max-width:900px){ .td-grid{ grid-template-columns:repeat(2,1fr); } }

/* Command Center — a row of clickable "needs attention" pills. Navy
   background matches this app's primary-navigation colour (per the design
   note: navy = trust/navigation, saffron = the actionable accent on top of
   it), deliberately NOT using magenta here — this is a workspace tool, not
   a festive highlight. */
.cc-strip{ display:flex; gap:10px; overflow-x:auto; padding-bottom:2px; margin-bottom:20px; scrollbar-width:thin; }
.cc-strip:empty{ display:none; margin-bottom:0; }
.cc-pill{
  flex:0 0 auto; display:flex; flex-direction:column; gap:2px; min-width:132px;
  background:var(--navy-950); color:var(--white); border-radius:12px; padding:12px 16px;
  cursor:pointer; border:none; text-align:left; font-family:inherit;
  transition:transform .12s ease, box-shadow .12s ease;
}
.cc-pill:hover, .cc-pill:focus-visible{ transform:translateY(-1px); box-shadow:0 6px 18px rgba(10,27,51,.22); outline:2px solid var(--saffron-500); outline-offset:1px; }
.cc-pill .cc-num{ font-family:var(--font-display, Georgia, serif); font-size:22px; font-weight:700; color:var(--saffron-300); line-height:1; }
.cc-pill .cc-lbl{ font-size:11.5px; color:rgba(255,255,255,.78); white-space:nowrap; }

/* Society Health Score — overall number on the left, individual metric
   chips wrap on the right. Each chip's color is set inline per-metric
   (green/yellow/red by that metric's own score), so the CSS here only
   handles layout and typography, not the health-based coloring itself. */
.health-score-head{ display:flex; align-items:baseline; gap:10px; margin-bottom:14px; flex-wrap:wrap; }
.health-score-num{ font-family:var(--font-display, Georgia, serif); font-size:34px; font-weight:700; line-height:1; }
.health-score-sub{ font-size:12.5px; color:var(--ink-600); }
.health-metric-grid{ display:grid; grid-template-columns:repeat(auto-fit, minmax(150px, 1fr)); gap:10px; }
.health-metric{
  padding:10px 12px; border-radius:10px; background:var(--paper,#FAF8F3);
  border:1px solid var(--line,#E2E6EF);
}
.health-metric .hm-pct{ font-size:19px; font-weight:700; font-family:var(--font-mono); }
.health-metric .hm-lbl{ font-size:11.5px; color:var(--ink-600); margin-top:2px; }
.health-metric .hm-detail{ font-size:10.5px; color:var(--ink-400,#8891A3); margin-top:1px; }

/* Pet registration cards — each pet gets its own bordered card (unlike the
   compact single-row family-member editor, a pet carries too many fields —
   species, breed, vet contact, four certificate checkboxes — to fit one
   row sensibly). */
.pet-card{ border:1px solid var(--line,#E2E6EF); border-radius:12px; padding:16px; margin-bottom:14px; background:var(--paper,#FAF8F3); }
.pet-card-header{ display:flex; align-items:center; justify-content:space-between; margin-bottom:12px; }
.pet-card-header b{ font-size:14px; color:var(--navy-950,#0A1B33); }
.pet-section-label{ font-size:12px; font-weight:700; text-transform:uppercase; letter-spacing:.03em; color:var(--ink-500,#6B7385); margin:14px 0 8px; padding-top:10px; border-top:1px dashed var(--line,#E2E6EF); }
.pet-cert-checks{ display:flex; flex-direction:column; gap:6px; margin-bottom:4px; }
.pet-toggle-row{ display:flex; gap:20px; margin-bottom:4px; }

/* Complaint satisfaction rating — plain-text stars, not default button boxes. */
.cplt-rate-row{ font-size:12.5px; color:var(--ink-500,#6B7385); }
.cplt-star{ background:none; border:none; cursor:pointer; font-size:16px; padding:0 1px; color:var(--gold-500,#C9A227); line-height:1; vertical-align:middle; }
.cplt-star:hover{ transform:scale(1.15); }
