/* =========================================================
   ABADAYA CoopTrack — main stylesheet
   ========================================================= */

:root{
  --green-700:#1e5f46;
  --green-600:#2e7d4f;
  --green-500:#4a9163;
  --green-100:#e5f3ea;
  --blue-600:#2f6fb3;
  --blue-500:#3f82c9;
  --blue-100:#e7f0fa;
  --navy-900:#111827;
  --ink-900:#16211c;
  --ink-700:#3f4a45;
  --ink-500:#6b756f;
  --bg-page:#f4f6f7;
  --card-bg:rgba(255,255,255,.90);
  --border-soft:#e6e9e8;
  --yellow-100:#fdf3d6;
  --yellow-700:#8a6d1a;
  --red-100:#fbe4e4;
  --red-600:#d64545;
  /* Text weight of red for body copy sitting on a --red-100 tint: --red-600 only reaches ~3.7:1
     there, which is fine for a short badge but too light for sentences, so awareness notes and
     panel headings use this darker step (~6.1:1) instead. */
  --red-700:#9b2f2f;
  --purple-100:#efe6fb;
  --purple-700:#7048b0;
  --gold-600:#b8860b;
  --gold-500:#c99a2e;
  --gold-100:#faf1dc;
  --shadow-card:0 1px 3px rgba(16,24,20,.06), 0 1px 2px rgba(16,24,20,.04);
  --shadow-pop:0 10px 30px rgba(16,24,20,.12);
  --radius-lg:16px;
  --radius-md:12px;
  --radius-sm:8px;
}

*{box-sizing:border-box;}

body{
  font-family:"Inter","Segoe UI",system-ui,-apple-system,sans-serif;
  color:var(--ink-900);
  -webkit-font-smoothing:antialiased;
  background:
    linear-gradient(rgba(244,246,247,.62), rgba(244,246,247,.62)),
    url("../img/backgrounds/page-bg.jpeg") center/cover fixed no-repeat;
  background-color:var(--bg-page);
}
@media (max-width:991px){
  body{ background-attachment:scroll; }
}

h1,h2,h3,h4,h5,h6{font-family:"Poppins","Inter",sans-serif; font-weight:700; color:var(--ink-900);}

a{ text-decoration:none; }

.text-muted-soft{ color:var(--ink-500); }

/* =========================================================
   Buttons
   ========================================================= */
.btn-coop-green{
  background:var(--green-600); border:1px solid var(--green-600); color:#fff;
  border-radius:999px; font-weight:600; padding:.65rem 1.4rem;
  transition:background .15s ease, transform .1s ease;
}
.btn-coop-green:hover{ background:var(--green-700); color:#fff; }
.btn-coop-blue{
  background:var(--blue-600); border:1px solid var(--blue-600); color:#fff;
  border-radius:999px; font-weight:600; padding:.65rem 1.4rem;
}
.btn-coop-blue:hover{ background:#245a92; color:#fff; }
.btn-coop-outline{
  background:transparent; border:1px solid rgba(255,255,255,.7); color:#fff;
  border-radius:999px; font-weight:600; padding:.65rem 1.4rem;
}
.btn-coop-outline:hover{ background:rgba(255,255,255,.15); color:#fff; }
.btn-coop-ghost{
  background:#fff; border:1px solid var(--border-soft); color:var(--ink-700);
  border-radius:999px; font-weight:600; padding:.5rem 1.1rem;
}
.btn-coop-ghost:hover{ background:#f4f6f7; }
/* Solid red call-to-action for a step that is still outstanding — the admin's eye should land on
   it before anything else on the panel. Pairs with .btn-coop-done below, which is what the same
   button turns into once the step is satisfied. */
.btn-coop-alert{
  background:var(--red-600); border:1px solid var(--red-600); color:#fff;
  border-radius:999px; font-weight:700; padding:.5rem 1.1rem;
  transition:background .15s ease, box-shadow .15s ease;
}
.btn-coop-alert:hover{ background:#b93a3a; border-color:#b93a3a; color:#fff; box-shadow:0 4px 14px rgba(214,69,69,.38); }
.btn-coop-alert:focus-visible{ outline:3px solid rgba(214,69,69,.45); outline-offset:2px; }
.btn-coop-done{
  background:var(--green-100); border:1px solid transparent; color:var(--green-700);
  border-radius:999px; font-weight:600; padding:.5rem 1.1rem;
}
.btn-coop-done:disabled{ opacity:1; color:var(--green-700); }
.btn-pill-sm{ border-radius:999px; padding:.3rem .9rem; font-size:.82rem; font-weight:600; }

/* animated icon-only approve/reject buttons */
.btn-icon-anim{
  width:32px; height:32px; border-radius:50%; border:none; padding:0; margin-left:.35rem;
  display:inline-flex; align-items:center; justify-content:center; vertical-align:middle;
  font-size:1rem; cursor:pointer; animation:btn-icon-pulse 2.2s ease-in-out infinite;
  transition:transform .15s ease, background .15s ease, color .15s ease, box-shadow .15s ease;
}
.btn-icon-anim:hover{ transform:scale(1.15); animation-play-state:paused; }
.btn-icon-anim:active{ transform:scale(.9); }
.btn-icon-approve{ background:var(--green-100); color:var(--green-700); }
.btn-icon-approve:hover{ background:var(--green-600); color:#fff; box-shadow:0 4px 14px rgba(46,125,79,.4); }
.btn-icon-reject{ background:var(--red-100); color:var(--red-600); }
.btn-icon-reject:hover{ background:var(--red-600); color:#fff; box-shadow:0 4px 14px rgba(214,69,69,.4); }
@keyframes btn-icon-pulse{
  0%, 100%{ transform:scale(1); }
  50%{ transform:scale(1.08); }
}

/* =========================================================
   Public site navbar
   ========================================================= */
.coop-navbar{
  background:linear-gradient(120deg,var(--green-700),var(--green-600));
  border-bottom:1px solid rgba(0,0,0,.08);
  padding:.85rem 0; position:fixed; top:0; left:0; right:0; z-index:56;
  box-shadow:0 2px 10px rgba(16,24,20,.12);
}
.coop-logo-round{
  border-radius:50%; object-fit:cover; flex-shrink:0; background:#fff;
  border:1px solid rgba(255,255,255,.5);
}
.coop-brand-text b{ display:block; line-height:1.1; font-size:1.05rem; color:#fff; letter-spacing:.02em;}
.coop-brand-text span{
  display:block; line-height:1.25; font-size:.63rem; color:rgba(255,255,255,.85); font-weight:600;
  text-transform:uppercase; letter-spacing:.04em; margin-top:.1rem;
}
.coop-nav-link{
  color:rgba(255,255,255,.9); font-weight:500; margin:0 .75rem; font-size:.95rem;
  transition:color .15s ease;
}
.coop-nav-link:hover{ color:#fff; text-decoration:underline; text-underline-offset:4px; }
.coop-nav-link.active{ color:#fff; text-decoration:underline; text-underline-offset:4px; }
.public-nav-mobile a.active{ color:#fff; background:rgba(255,255,255,.08); }

/* About mega-menu (desktop hover dropdown) */
.nav-dropdown{ position:relative; display:inline-flex; align-items:center; }
.dropdown-trigger{ cursor:pointer; display:inline-flex; align-items:center; gap:.3rem; user-select:none; }
.dropdown-trigger i{ font-size:.7rem; transition:transform .15s ease; }
.dropdown-panel{
  display:none; position:absolute; top:100%; left:50%; transform:translateX(-50%);
  margin-top:.6rem; min-width:260px; background:#fff; border-radius:var(--radius-md);
  box-shadow:var(--shadow-pop); padding:.5rem; z-index:55;
}
.nav-dropdown:hover .dropdown-panel, .nav-dropdown:focus-within .dropdown-panel{ display:block; }
.nav-dropdown:hover .dropdown-trigger i, .nav-dropdown:focus-within .dropdown-trigger i{ transform:rotate(180deg); }
.dropdown-panel-link{
  display:block; padding:.6rem .8rem; border-radius:var(--radius-sm); color:var(--ink-700);
  font-weight:500; font-size:.9rem;
}
.dropdown-panel-link:hover{ background:var(--green-100); color:var(--green-700); }
.dropdown-panel-link.active{ background:var(--green-100); color:var(--green-700); font-weight:700; }

.mobile-nav-group-label{
  padding:.85rem 1.3rem .3rem; color:rgba(255,255,255,.6); font-size:.72rem; font-weight:700;
  text-transform:uppercase; letter-spacing:.05em;
}
.mobile-sub-link{ padding-left:2rem !important; font-weight:500 !important; }
.coop-seal-badge{ width:44px; height:44px; object-fit:contain; filter:drop-shadow(0 1px 2px rgba(0,0,0,.25)); }
.coop-navbar-logo{ width:44px; height:44px; }

.navbar-burger{
  width:38px; height:38px; border-radius:8px; background:rgba(255,255,255,.16); border:1px solid rgba(255,255,255,.3);
  color:#fff; display:flex; align-items:center; justify-content:center; font-size:1.15rem; flex-shrink:0;
}
.navbar-burger:hover{ background:rgba(255,255,255,.28); }
.public-nav-mobile{
  display:none; flex-direction:column; background:var(--green-700); border-top:1px solid rgba(255,255,255,.15);
  /* .coop-navbar (this menu's parent) is position:fixed, so on a short screen this dropdown
     can't just grow past the viewport bottom — nothing would ever scroll it into view. Cap it
     to whatever room is left below the navbar's top row (set by renderPublicNav() in main.js)
     and let it scroll internally instead, so every link stays reachable regardless of height. */
  max-height:calc(100vh - var(--navbar-row-height, 70px)); overflow-y:auto;
}
.public-nav-mobile.open{ display:flex; }
.public-nav-mobile a{
  color:rgba(255,255,255,.92); font-weight:600; padding:.85rem 1.3rem; border-bottom:1px solid rgba(255,255,255,.1);
}
.public-nav-mobile a:hover{ background:rgba(255,255,255,.08); color:#fff; }

@media (max-width:575px){
  .coop-navbar-logo{ width:36px; height:36px; }
  .coop-brand-text b{ font-size:.92rem; }
  .coop-seal-badge{ width:34px; height:34px; }
}

/* =========================================================
   Hero
   ========================================================= */
.hero-section{
  position:relative; min-height:520px; display:flex; align-items:center;
  background:
    linear-gradient(120deg, rgba(20,60,45,.5), rgba(30,70,110,.5)),
    url("../img/backgrounds/hero-bg.jpeg") center/cover no-repeat;
  color:#fff; text-align:center; padding:2.5rem 0;
}
.hero-section h1{ color:#fff; font-size:3rem; font-weight:800; text-shadow:0 2px 12px rgba(0,0,0,.45); }
.hero-section p{ color:#fff; font-size:1.05rem; max-width:640px; margin:0 auto; text-shadow:0 1px 8px rgba(0,0,0,.4); }
@media (max-width:575px){
  .hero-section{ min-height:auto; }
  .hero-section h1{ font-size:2rem; }
  .hero-section p{ font-size:.92rem; }
}

/* =========================================================
   Section tags / headings
   ========================================================= */
.section-tag{
  display:inline-block; padding:.35rem .9rem; border-radius:999px;
  font-size:.72rem; font-weight:700; letter-spacing:.05em;
}
.section-tag.blue{ background:var(--blue-100); color:var(--blue-600); }
.section-tag.green{ background:var(--green-100); color:var(--green-700); }
.section-heading{ font-size:2.1rem; font-weight:800; margin-top:.5rem; }
@media (max-width:575px){
  section.public-section{ padding:3rem 0; }
  .section-heading{ font-size:1.5rem; }
}

section.public-section{ padding:5rem 0; }

/* Links sitting inside a paragraph of body copy (the homepage intro, the "read next" lines at the
   foot of the About pages). The global `a{text-decoration:none}` strips the underline that is the
   only thing marking a link as a link mid-sentence, so these opt it back in and take the brand
   green rather than Bootstrap's default blue. */
.prose-links a{ color:var(--green-700); text-decoration:underline; text-underline-offset:2px; }
.prose-links a:hover{ color:var(--green-600); }
[data-bs-theme="dark"] .prose-links a{ color:#5cc78d; }
[data-bs-theme="dark"] .prose-links a:hover{ color:#8bdcae; }
section.public-section.alt{ background:rgba(255,255,255,.72); }

/* History card: semi-transparent background, text kept at full opacity/contrast */
.history-card{
  background:rgba(255,255,255,.55); border:1px solid rgba(255,255,255,.6); border-radius:var(--radius-lg);
  padding:1.6rem 1.8rem; backdrop-filter:blur(2px);
}
.history-card p{ color:var(--ink-900); opacity:1; }

/* Timeline (History) */
.timeline-dot{
  width:40px; height:40px; border-radius:50%; flex-shrink:0;
  background:linear-gradient(135deg,var(--green-600),var(--blue-600));
  color:#fff; display:flex; align-items:center; justify-content:center;
}
.timeline-card{
  background:#f4f6f7; border-radius:var(--radius-md); padding:.9rem 1.1rem; flex:1;
}
.timeline-card .yr{ color:var(--green-700); font-weight:700; font-size:.9rem;}

/* Board card (services.php/contact.php were redesigned to their own bento-style layouts with
   page-local <style> blocks, so only the board.php/history.php card variant is still live here) */
.board-card{
  background:var(--card-bg); border:1px solid var(--border-soft); border-radius:var(--radius-lg);
  padding:1.6rem 1.3rem; height:100%;
  transition:transform .18s ease, box-shadow .18s ease;
}
.board-card:hover{
  transform:translateY(-5px); box-shadow:var(--shadow-pop);
}
.board-photo{
  width:120px; height:120px; border-radius:50%; object-fit:cover; object-position:top center;
  margin:0 auto .9rem; display:block; border:3px solid var(--card-bg); box-shadow:0 4px 14px rgba(22,33,28,.16);
}
.board-card.lead .board-photo{ width:140px; height:140px; }


/* =========================================================
   Leadership groups (board.php)
   Each unit from the cooperative's organisational chart — management staff, the
   secretary and treasurer, the three assembly-level committees, then the standing
   committees — is one labelled group of portraits. The group itself is transparent:
   only its green title bar and the portraits sit on the page, and it is exactly as
   wide as the number of people in it, so a five-member board reads wider than a
   three-member committee. Groups flow centred and wrap, so the same markup works
   from a phone up to a wide desktop.
   ========================================================= */
.org-chart{ max-width:1640px; margin:0 auto; }

/* One band of groups. Groups are content-sized, so the row simply centres and wraps them. */
.org-row{
  display:flex; flex-wrap:wrap; justify-content:center; align-items:flex-start;
  /* Column gap kept tight: three three-member groups plus two gaps have to clear a
     1400px window once its scrollbar is taken off, or they drop to two per line. */
  gap:2rem 1.4rem; margin-bottom:2.4rem;
}
.org-row:last-child{ margin-bottom:0; }

/* `max-content` is what makes the width follow the headcount: it lays every portrait out
   on one line and takes that as the group's width. `max-width:100%` lets it fall back to
   wrapping its portraits once the screen is narrower than that ideal width. */
.org-group{
  width:max-content; max-width:100%;
  display:flex; flex-direction:column; background:transparent; border:0; box-shadow:none;
}
.org-group-head{
  background:linear-gradient(120deg,var(--green-700),var(--green-600)); color:#fff;
  font-family:"Poppins","Inter",sans-serif; font-weight:700; font-size:.8rem;
  letter-spacing:.05em; text-transform:uppercase; padding:.6rem 1rem; text-align:center;
  border-radius:999px; box-shadow:var(--shadow-card);
}
.org-group-body{
  display:flex; flex-wrap:wrap; justify-content:center; align-items:flex-start;
  align-content:flex-start; gap:1rem .6rem; padding:1.1rem 0 0;
}

/* One person. Fixed width and a column layout, so the photo, the name and the role chip
   line up across every group however long a name runs. */
.org-node{ width:120px; display:flex; flex-direction:column; text-align:center; }
.org-photo{
  width:82px; height:82px; border-radius:50%; object-fit:cover; object-position:top center;
  display:block; margin:0 auto .5rem; border:3px solid #fff; background:var(--green-100);
  box-shadow:0 3px 10px rgba(22,33,28,.18);
}
/* Stand-in for a chart slot with no photograph supplied: initials, or an icon for the
   Compliance Committee boxes, which the chart itself leaves unnamed. */
.org-photo-blank{
  display:flex; align-items:center; justify-content:center;
  font-family:"Poppins","Inter",sans-serif; font-weight:700; font-size:1.45rem;
  color:var(--green-700); border-style:dashed; border-color:var(--border-soft);
}
/* Two lines' worth of fixed room for the name, so the role chips below it stay on one
   line across a row whether a name wraps or not. */
.org-name{ flex:0 0 auto; min-height:2.1rem; font-weight:700; font-size:.8rem; line-height:1.3; color:var(--ink-900); }
.org-name.vacant{ font-weight:600; color:var(--ink-500); }
.org-role{
  margin-top:.3rem; align-self:center; font-size:.6rem; font-weight:700; letter-spacing:.05em;
  text-transform:uppercase; color:var(--green-700); background:var(--green-100);
  padding:.16rem .5rem; border-radius:999px; white-space:nowrap;
}
.org-role.chair{ color:#fff; background:var(--green-600); }

/* Desktop gets the larger portraits; the group widths follow from the node width. */
@media (min-width:992px){
  .org-node{ width:136px; }
  .org-photo{ width:102px; height:102px; }
  .org-name{ font-size:.86rem; min-height:2.25rem; }
  .org-role{ font-size:.64rem; }
  .org-group-head{ font-size:.86rem; padding:.65rem 1.3rem; }
}
/* Phone: narrow enough that a three-member committee still lands on one row, the way it
   sits in one box on the printed chart. */
@media (max-width:575px){
  .org-group-head{ font-size:.72rem; padding:.55rem .8rem; }
  .org-group-body{ gap:.8rem .35rem; padding-top:.9rem; }
  .org-row{ gap:1.2rem; margin-bottom:1.8rem; }
  .org-node{ width:96px; }
  .org-photo{ width:64px; height:64px; }
  .org-name{ font-size:.73rem; }
  /* At this width a long label like "Cashier / Encoder" is wider than its portrait and
     would run into the chip beside it, so chips wrap here instead of staying on one line. */
  .org-role{ font-size:.55rem; padding:.14rem .42rem; white-space:normal; max-width:100%; }
}
.contact-icon{
  width:52px; height:52px; border-radius:12px; display:flex; align-items:center;
  justify-content:center; font-size:1.3rem; margin-bottom:.9rem;
}
.contact-icon.green{ background:var(--green-100); color:var(--green-700); }
.contact-icon.blue{ background:var(--blue-100); color:var(--blue-600); }

/* Footer */
.coop-footer{ background:var(--navy-900); color:#cfd8d4; padding:2.2rem 0; }
.coop-footer b{ color:#fff; }
.coop-footer-links{ display:flex; flex-wrap:wrap; gap:.4rem 1.2rem; }
.coop-footer-links a{ color:#cfd8d4; font-size:.85rem; font-weight:500; }
.coop-footer-links a:hover{ color:#fff; text-decoration:underline; text-underline-offset:3px; }
.coop-footer-legal{ border-top:1px solid rgba(255,255,255,.12); gap:.4rem 1rem; }
.coop-footer-legal a{ font-size:.76rem; color:#9fb0aa; }
.coop-footer-legal a:hover{ color:#fff; }

/* Legal / compliance pages (Privacy Policy, Terms of Service, Cookie Policy, Refund Policy) */
.legal-hero{
  position:relative; overflow:hidden; padding:3rem 0 4rem; text-align:center; color:#fff;
  background:radial-gradient(circle at 20% 20%, var(--green-500), var(--green-700) 70%);
}
.legal-hero h1{ font-weight:800; font-size:2.1rem; margin:.4rem 0 .6rem; color:#fff; }
.legal-hero p{ color:rgba(255,255,255,.92); max-width:560px; margin:0 auto; }
.legal-hero-wave{ position:absolute; left:0; right:0; bottom:-1px; width:100%; height:44px; display:block; }
.legal-content{ max-width:820px; margin:2rem auto 3rem; padding:0 1rem; }
.legal-content h2{ font-size:1.1rem; font-weight:700; color:var(--green-700); margin-top:2.1rem; margin-bottom:.7rem; }
.legal-content h2:first-of-type{ margin-top:0; }
.legal-content p, .legal-content li{ color:var(--ink-700); line-height:1.7; }
.legal-content ul{ padding-left:1.3rem; }
.legal-content a{ color:var(--green-700); font-weight:600; }
.legal-updated{ color:var(--ink-500); font-size:.85rem; margin-bottom:1.5rem; }
.legal-toc{ background:var(--green-100); border-radius:var(--radius-md); padding:1rem 1.2rem; margin-bottom:1.5rem; }
.legal-toc a{ display:block; font-size:.88rem; padding:.15rem 0; }
.legal-flag{ background:var(--yellow-100); border:1px solid #f1e0a1; border-radius:var(--radius-md); padding:.9rem 1.1rem; font-size:.85rem; color:var(--yellow-700); margin-bottom:1.5rem; }

/* Footer pinned to the bottom of the viewport at all times, on every page — the public site
   and the member/admin app shell alike. renderFooter() measures the footer and publishes its
   height as --footer-offset (plus a matching body padding-bottom), which the rules below use
   to keep the app shell from running underneath it. */
.coop-footer-fixed{
  position:fixed; left:0; right:0; bottom:0; z-index:55;
  box-shadow:0 -2px 10px rgba(16,24,20,.15);
}
/* The shell's own `min-height:100vh` would reserve a full viewport *on top of* the body's
   footer padding, forcing every short app page to scroll by exactly the footer's height. Taking
   the footer back out of that minimum keeps short pages unscrolled, and keeps the stretched
   green #sidebar-mount column finishing level with the footer's top edge rather than sliding
   behind it. */
.has-fixed-footer .app-shell{ min-height:calc(100vh - var(--footer-offset, 0px)); }
/* Inside the app shell the pinned footer is permanently eating viewport height that the data
   tables and forms need, so it collapses to a single compact bar: the legal row and the
   copyright/version chips move out of the way and only the brand mark and section links stay. */
.has-fixed-footer .app-shell ~ #footer-mount .coop-footer-fixed{ padding:.55rem 0; }
.has-fixed-footer .app-shell ~ #footer-mount .coop-footer-fixed .coop-footer-legal,
.has-fixed-footer .app-shell ~ #footer-mount .coop-footer-fixed .badge,
.has-fixed-footer .app-shell ~ #footer-mount .coop-footer-fixed small{ display:none !important; }
.has-fixed-footer .app-shell ~ #footer-mount .coop-footer-fixed .coop-logo-round{ width:26px !important; height:26px !important; }
/* .app-topbar has no Bootstrap .container — it deliberately spans the full width next to the
   sidebar (title on the left, actions/icons on the right, out to the true edge minus its own
   1.4rem padding). The footer's content was still wrapped in a normal capped .container though,
   so on any screen wider than that cap (~1320px) its content stopped hundreds of pixels short of
   where the topbar's did — the two bars' right (and left) edges only lined up by accident on
   narrower screens. Matching the topbar's own padding here keeps them level at every width. */
.app-shell ~ #footer-mount .coop-footer .container{ max-width:none; padding-left:1.4rem; padding-right:1.4rem; }
@media (max-width:575px){
  .coop-footer-fixed{ padding:.7rem 0; }
  .coop-footer-fixed .container{ gap:.3rem !important; }
  /* A fixed footer permanently eats into the viewport, so on phones it shows only what's
     essential (brand mark + the links themselves) — the subtitle, copyright line, and version
     badge are all still one tap away via the About/Contact pages, not worth the vertical space
     here. */
  .coop-footer-fixed .coop-logo-round{ width:26px !important; height:26px !important; }
  .coop-footer-fixed small, .coop-footer-fixed .small, .coop-footer-fixed .badge{ display:none; }
  .coop-footer-fixed .coop-footer-links{ gap:.2rem .7rem; }
  .coop-footer-fixed .coop-footer-links a{ font-size:.72rem; }
  .coop-footer-fixed .coop-footer-legal{ margin-top:.3rem !important; padding-top:.3rem !important; gap:.2rem .6rem; }
  .coop-footer-fixed .coop-footer-legal a{ font-size:.66rem; }
}

/* Back-to-top floating button, stacks directly above the help fab */
.back-to-top-fab{
  position:fixed; right:1.4rem; bottom:calc(var(--footer-offset, 1.4rem) + 56px);
  width:44px; height:44px; border-radius:50%;
  background:var(--green-700); color:#fff; display:flex; align-items:center; justify-content:center;
  box-shadow:var(--shadow-pop); z-index:60; border:none; cursor:pointer;
  opacity:0; visibility:hidden; transform:translateY(8px);
  transition:opacity .2s ease, transform .2s ease, visibility .2s, bottom .2s ease;
}
.back-to-top-fab.show{ opacity:1; visibility:visible; transform:translateY(0); }
.back-to-top-fab:hover{ background:var(--green-600); }

/* =========================================================
   Auth pages (login / register)
   ========================================================= */
.auth-bg{
  min-height:100vh; display:flex; align-items:center; justify-content:center; padding:2.5rem 1rem;
  background:
    linear-gradient(120deg, rgba(20,70,55,.82), rgba(30,95,140,.82)),
    url("https://images.unsplash.com/photo-1500937386664-56d1dfef3854?q=80&w=1740&auto=format&fit=crop") center/cover fixed;
}
.auth-card{
  width:100%; background:#fff; border-radius:var(--radius-lg); overflow:hidden;
  box-shadow:var(--shadow-pop);
}
.auth-card.narrow{ max-width:460px; }
.auth-header{
  background:linear-gradient(120deg,var(--blue-600),var(--green-600));
  color:#fff; text-align:center; padding:2rem 1.5rem 1.6rem;
}
.auth-body{ padding:1.8rem; }
.auth-note{
  background:var(--blue-100); border:1px solid #cfe0f5; border-radius:var(--radius-md);
  padding:.8rem 1rem; font-size:.85rem; color:#274a6c; margin-bottom:1.2rem;
}
/* Awareness note. Red, not amber: every "you must act / this has a consequence" sign in the app
   reads as one colour, so an admin never has to work out which tint means what. Purely
   informational tips keep the plain blue .auth-note above. */
.auth-note.warn{ background:var(--red-100); border-color:#f3c9c9; color:var(--red-700); }
.auth-note.warn strong{ color:var(--red-700); }

.form-label{ font-weight:600; color:var(--ink-900); font-size:.9rem; }
.form-label .req{ color:var(--red-600); }
.form-control, .form-select{
  border-radius:10px; border:1px solid #d9dedb; padding:.6rem .85rem; font-size:.92rem;
}
.form-control:focus, .form-select:focus{
  border-color:var(--green-500); box-shadow:0 0 0 .18rem rgba(74,145,99,.18);
}
.field-hint{ font-size:.76rem; color:var(--ink-500); margin-top:.25rem; }
.field-error{ font-size:.78rem; color:var(--red-600); margin-top:.25rem; display:none; }
.is-invalid ~ .field-error, .field-error.show{ display:block; }

.pw-toggle-wrap{ position:relative; }
/* Reserve room for the absolutely-positioned eye-icon button below so a long password's own
   characters never render underneath it — .form-control's own padding-right (from the generic
   rule above) only leaves ~13.6px, but the button itself sits 12px from the edge and is ~16px
   wide, so without this the two visibly overlapped once the typed value got long enough. */
.pw-toggle-wrap .form-control{ padding-right:2.5rem; }
.pw-toggle-btn{
  position:absolute; right:12px; top:50%; transform:translateY(-50%);
  background:none; border:none; color:var(--ink-500); cursor:pointer; padding:0;
  /* Center the icon glyph itself in the button's box (rather than relying on the icon
     font's own line-height/baseline), so the eye icon doesn't sit visually off-center
     even though the button box itself is already vertically centered in the wrapper. */
  display:flex; align-items:center; justify-content:center; line-height:1; height:1.2rem;
}
/* Also suppress the browser's own native password-reveal/clear icons (Edge/IE render these at
   the same right-edge spot), so only our custom eye-icon button ever shows there. */
input[type="password"]::-ms-reveal, input[type="password"]::-ms-clear{ display:none; }

.pw-checklist{ font-size:.78rem; margin-top:.4rem; display:flex; flex-wrap:wrap; gap:.5rem 1rem; }
.pw-checklist span{ color:var(--ink-500); }
.pw-checklist span.ok{ color:var(--green-700); font-weight:600; }

/* Password strength meter (real-time, register/settings/forgot-password) */
.pw-strength-bar{ display:flex; gap:.3rem; margin-top:.4rem; }
.pw-strength-bar span{ flex:1; height:5px; border-radius:999px; background:#dfe4e1; transition:background .15s ease; }
.pw-strength-label{ font-size:.74rem; font-weight:700; margin-top:.25rem; }

/* =========================================================
   App shell (member / admin portal)
   ========================================================= */
.app-shell{ display:flex; min-height:100vh; }
/* #sidebar-mount is the flex child (not .app-sidebar itself). It stretches to match
   .app-main's full content height via the flex row's default align-items:stretch, so the
   green column runs the full length of the page; the sidebar panel inside it is sticky and
   stays pinned to the viewport while that column scrolls past behind it. */
#sidebar-mount{
  flex-shrink:0; width:260px; align-self:stretch;
  background:linear-gradient(180deg,var(--green-700),var(--green-600));
}
@media (max-width:991px){ #sidebar-mount{ width:0; background:none; } }
.app-sidebar{
  width:260px; flex-shrink:0; background:linear-gradient(180deg,var(--green-700),var(--green-600));
  border-right:1px solid rgba(0,0,0,.08);
  display:flex; flex-direction:column; padding:.75rem .9rem;
  /* Pinned, so the nav never scrolls away: the panel sticks to the top of the viewport
     inside the full-height #sidebar-mount column. Its height stops at the pinned footer's
     top edge, and its own overflow scrolls the link list on a viewport too short to show
     every entry. Sticky rather than fixed, so it keeps its place in the flex row and needs
     no left offset. Mobile still slides it in as an overlay — see the ≤991px block. */
  position:sticky; top:0;
  height:calc(100vh - var(--footer-offset, 0px));
  min-height:0;
  overflow-y:auto;
  /* A default scrollbar reads as a bright grey gash down the green column, so the nav
     keeps a thin translucent one of its own. */
  scrollbar-width:thin; scrollbar-color:rgba(255,255,255,.3) transparent;
}
.app-sidebar::-webkit-scrollbar{ width:6px; }
.app-sidebar::-webkit-scrollbar-track{ background:transparent; }
.app-sidebar::-webkit-scrollbar-thumb{ background:rgba(255,255,255,.26); border-radius:999px; }
.app-sidebar:hover::-webkit-scrollbar-thumb{ background:rgba(255,255,255,.4); }
.sidebar-brand{ display:flex; align-items:center; gap:.6rem; padding:.2rem .3rem .6rem; }
.sidebar-brand .coop-brand-text b{ color:#fff; }
.sidebar-brand .coop-brand-text span{ color:rgba(255,255,255,.85); }
.identity-card{
  display:flex; align-items:center; gap:.6rem; padding:.55rem .6rem; border-radius:var(--radius-md);
  background:rgba(255,255,255,.14); margin-bottom:.5rem;
}
.identity-avatar{
  width:38px; height:38px; border-radius:10px; flex-shrink:0;
  background:rgba(255,255,255,.9); color:var(--green-700);
  display:flex; align-items:center; justify-content:center; font-weight:700;
}
.identity-card .name{ font-weight:700; font-size:.92rem; line-height:1.2; color:#fff; }
.identity-card .role{ font-size:.76rem; color:rgba(255,255,255,.85); }
.identity-card .tags{ font-size:.72rem; color:rgba(255,255,255,.7); }

/* `flex:0 0 auto` (not `flex:1`) so the nav takes only the height its links need and Sign Out
   follows directly beneath them. With flex:1 the nav absorbed all the leftover column height and
   pushed Sign Out to the very bottom of the sidebar — on the Credit Investigation and Collector
   sides, whose nav is a single link, that stranded Sign Out hundreds of pixels below it with
   nothing in between. This was previously scoped to `.role-admin`; every role now gets it. */
.sidebar-nav{ flex:0 0 auto; display:flex; flex-direction:column; gap:.05rem; }
.sidebar-link{
  display:flex; align-items:center; gap:.65rem; padding:.4rem .7rem; border-radius:var(--radius-sm);
  color:rgba(255,255,255,.85); font-size:.87rem; font-weight:500; position:relative;
}
.sidebar-link i{ font-size:1rem; width:18px; text-align:center; color:rgba(255,255,255,.7);}
.sidebar-link:hover{ background:rgba(255,255,255,.14); color:#fff; }
.sidebar-link.active{ background:#fff; color:var(--green-700); font-weight:700; border-left:4px solid var(--green-700); padding-left:calc(.7rem - 4px); }
.sidebar-link.active i{ color:var(--green-700); }
.sidebar-badge{
  margin-left:auto; background:var(--red-600); color:#fff; font-size:.68rem; font-weight:700;
  border-radius:999px; padding:.05rem .42rem;
}
.sidebar-signout{
  color:#ffd4d4; font-weight:600; font-size:.87rem; display:flex; align-items:center; gap:.5rem;
  padding:.5rem .7rem; margin-top:2.5rem; border-top:1px solid rgba(255,255,255,.18); padding-top:.6rem;
  flex-shrink:0;
}
.sidebar-signout:hover{ color:#fff; }

/* Width breakpoints (above/below) cap the sidebar's own position/height per screen; this one
   caps it by viewport HEIGHT instead, so a short window (small laptop, landscape tablet/phone)
   shrinks the identity card and link spacing to surface more nav items before the internal
   scrollbar (overflow-y:auto on .app-sidebar) has to kick in. Declared after the base
   .sidebar-link/.identity-avatar/etc. rules above (same specificity, so source order decides)
   so it actually wins when the media condition matches, instead of being overridden by them. */
@media (max-height:700px){
  .app-sidebar{ padding:.5rem .8rem; }
  .sidebar-brand{ padding:.1rem .3rem .4rem; }
  .identity-card{ padding:.4rem .5rem; margin-bottom:.3rem; }
  .identity-avatar{ width:32px; height:32px; }
  .sidebar-link{ padding:.32rem .7rem; font-size:.84rem; }
  .sidebar-signout{ margin-top:.2rem; padding:.4rem .7rem; padding-top:.5rem; }
}

.app-main{ flex:1; padding:1.8rem 2.1rem; min-width:0;
  background:
    linear-gradient(rgba(244,246,247,.6), rgba(244,246,247,.6)),
    url("../img/backgrounds/page-bg.jpeg") center/cover fixed no-repeat;
}
@media (max-width:991px){ .app-main{ background-attachment:scroll; } }
/* The topbar is pinned to the top of the content column and stays there while the page
   scrolls under it. #topbar-mount (not .app-topbar) carries the sticky, because a sticky
   element only travels within its own parent's box — the mount is the child of the full-height
   .app-main, while .app-topbar's parent would be the mount itself, which is exactly the bar's
   own height and so would pin nothing. Sticky rather than fixed keeps the bar at the content
   column's width automatically at every breakpoint, with no measured offset or spacer. The
   negative top/side margins let it span that column edge-to-edge despite .app-main's padding,
   and the bottom margin restores the usual gap beneath it. */
#topbar-mount{ position:sticky; top:0; z-index:45; margin:-1.8rem -2.1rem 1.8rem; }
@media (max-width:991px){ #topbar-mount{ margin:-1.2rem -1.2rem 1.2rem; } }
.app-topbar{
  display:flex; align-items:center; gap:.8rem; padding:.85rem 1.4rem;
  background:linear-gradient(120deg,var(--green-700),var(--green-600));
  border-bottom:1px solid rgba(0,0,0,.08); position:static;
}
.app-topbar strong{ color:#fff; font-size:1.02rem; }
.app-topbar .btn-coop-ghost{ background:rgba(255,255,255,.16); border-color:rgba(255,255,255,.35); color:#fff; }
.app-topbar .btn-coop-ghost:hover{ background:rgba(255,255,255,.28); }
.app-topbar-seals{ margin-left:auto; display:flex; align-items:center; gap:.5rem; }
.topbar-brand-text{ color:#fff; font-weight:700; font-size:.95rem; letter-spacing:.02em; }
.topbar-role-badge{
  background:rgba(255,255,255,.18); color:#fff; font-size:.7rem; font-weight:700;
  letter-spacing:.03em; text-transform:uppercase; padding:.22rem .6rem; border-radius:999px;
  border:1px solid rgba(255,255,255,.3);
}
.coop-seal-badge-sm{ width:32px; height:32px; object-fit:contain; filter:drop-shadow(0 1px 2px rgba(0,0,0,.25)); }

/* Persistent topbar bell (unread notifications / pending approvals) */
.topbar-bell{ position:relative; color:#fff; font-size:1.15rem; display:flex; align-items:center; }
.topbar-bell-badge{
  position:absolute; top:-6px; right:-8px; background:var(--red-600); color:#fff; font-size:.62rem; font-weight:700;
  border-radius:999px; padding:.05rem .38rem; border:1.5px solid var(--green-700); line-height:1.3;
}

@media (max-width:991px){
  .app-sidebar{
    position:fixed; left:-280px; top:0; z-index:1050; transition:left .2s ease; box-shadow:var(--shadow-pop);
    /* The footer is pinned on every page now, so the drawer stops short of it rather than
       covering it — its own overflow-y:auto scrolls the nav list inside whatever height is left. */
    height:calc(100vh - var(--footer-offset, 0px)); max-height:calc(100vh - var(--footer-offset, 0px));
    /* max-height is belt-and-braces alongside the base rule's height: min-height beats
       max-height in CSS, so min-height stays pinned at 0 here. */
    min-height:0;
    overflow-y:auto;
  }
  .app-sidebar.open{ left:0; }
  .app-main{ padding:1.2rem; }
  /* Stops at the pinned footer's top edge, so the always-visible footer isn't dimmed behind the
     drawer's scrim (the backdrop sits far above the footer's own z-index). */
  .sidebar-backdrop{ display:none; position:fixed; top:0; left:0; right:0; bottom:var(--footer-offset, 0px); background:rgba(0,0,0,.35); z-index:1040; }
  .sidebar-backdrop.show{ display:block; }
}

@media (max-width:575px){
  /* At narrow widths the topbar's logo + brand text + role badge + bell + two seal
     badges no longer fit on one row and the last seal was overflowing off-screen
     (clipped, since the page has no horizontal scroll) — drop the decorative seals
     here the same way .coop-footer-fixed already drops its own badges on mobile. */
  .app-topbar{ padding:.75rem .9rem; gap:.5rem; }
  .app-topbar-seals{ gap:.35rem; }
  .app-topbar-seals img.coop-seal-badge-sm{ display:none; }
}

/* =========================================================
   App page hero (shared banner used at the top of every
   member/admin page in place of a plain <h2> title)
   ========================================================= */
.app-hero{
  position:relative; overflow:hidden; border-radius:var(--radius-lg);
  padding:1.7rem 1.8rem 2.5rem; margin-bottom:1.7rem; color:#fff;
  background:linear-gradient(120deg,var(--green-700),var(--green-600));
  box-shadow:var(--shadow-pop);
}
.app-hero h2{ color:#fff; font-size:1.55rem; margin:0 0 .3rem; }
.app-hero p{ color:rgba(255,255,255,.88); margin:0; font-size:.92rem; max-width:560px; }
.app-hero-wave{ position:absolute; left:0; right:0; bottom:-1px; width:100%; height:34px; display:block; }
.app-hero-row{ display:flex; justify-content:space-between; align-items:flex-start; gap:1rem; position:relative; z-index:1; }
.app-hero-action{ flex-shrink:0; }
.app-hero .btn-coop-green{ background:#fff; border-color:#fff; color:var(--green-700); }
.app-hero .btn-coop-green:hover{ background:var(--green-100); border-color:var(--green-100); }
@media (max-width:575px){
  .app-hero{ padding:1.4rem 1.4rem 2.1rem; }
  .app-hero h2{ font-size:1.3rem; }
  .app-hero-row{ flex-direction:column; }
}

/* ---------- loan document templates band (tall, layered wave divider) ---------- */
.doc-band-card{ padding:0; overflow:hidden; }
.doc-band{
  position:relative; overflow:hidden; padding:1.2rem 1.4rem 5.8rem;
  background:linear-gradient(120deg,var(--green-700),var(--green-600)); color:#fff;
}
.doc-band-label{ color:#fff; font-weight:700; font-size:.82rem; letter-spacing:.03em; display:flex; align-items:center; gap:.4rem; position:relative; z-index:1; }
.doc-band-wave{ position:absolute; left:0; right:0; bottom:-1px; width:100%; height:150px; display:block; }
.doc-band-body{ padding:1.3rem 1.4rem 1.4rem; margin-top:-1.8rem; position:relative; }
@media (max-width:575px){
  .doc-band{ padding:1rem 1.1rem 4.4rem; }
  .doc-band-wave{ height:115px; }
}

/* ---------- downloadable-file card (shared everywhere a file can be downloaded:
   loan document templates, report exports, data backups, etc.) ---------- */
.doc-card-grid{ display:grid; grid-template-columns:repeat(auto-fit, minmax(230px, 1fr)); gap:1rem; }
.doc-card{
  display:flex; flex-direction:column; background:#fff; border:1px solid var(--border-soft);
  border-radius:var(--radius-md); padding:1.1rem 1.1rem 1.2rem; box-shadow:var(--shadow-card);
}
.doc-card-icon{
  width:42px; height:42px; border-radius:12px; display:flex; align-items:center; justify-content:center;
  font-size:1.15rem; margin-bottom:.8rem; flex-shrink:0;
  background:var(--green-100); color:var(--green-700);
}
.doc-card-icon.blue{ background:var(--blue-100); color:var(--blue-600); }
.doc-card-icon.purple{ background:var(--purple-100); color:var(--purple-700); }
.doc-card-icon.gold{ background:var(--gold-100); color:var(--gold-600); }
.doc-card-title{ font-weight:700; font-size:.96rem; color:var(--ink-900); margin-bottom:.25rem; }
.doc-card-desc{ color:var(--ink-500); font-size:.82rem; line-height:1.4; margin-bottom:.8rem; flex:1; }
.doc-card-tags{ display:flex; flex-wrap:wrap; align-items:center; gap:.35rem; margin-bottom:.9rem; }
.doc-card-tags .badge-coop{ padding:.24rem .55rem; font-size:.68rem; }
.doc-card .btn{ margin-top:auto; }

/* =========================================================
   Cards / stat tiles / tables shared across portal pages
   ========================================================= */
.card-coop{
  background:var(--card-bg); border:1px solid var(--border-soft); border-radius:var(--radius-lg);
  box-shadow:var(--shadow-card); padding:1.3rem 1.4rem;
}
/* Reusable card section header (icon + title + caption) for clearer separation between
   stacked sections on a page, e.g. Savings' Growth Chart / Transaction History cards. */
.section-eyebrow{
  display:flex; align-items:center; gap:.4rem; text-transform:uppercase; letter-spacing:.05em;
  font-size:.76rem; font-weight:700; color:var(--green-700); margin-bottom:.7rem;
}
.card-section-header{ display:flex; align-items:center; gap:.7rem; margin-bottom:1rem; }
.card-section-icon{
  width:38px; height:38px; border-radius:10px; flex-shrink:0; display:flex; align-items:center; justify-content:center;
  background:var(--green-100); color:var(--green-700); font-size:1.05rem;
}
.card-section-icon.alt{ background:var(--blue-100); color:var(--blue-600); }
/* Subtle corner watermark icon reflecting the cooperative's fisherfolk/farmer identity —
   decorative only, kept low-opacity so it never competes with real card content. */
.card-watermark-icon{
  position:absolute; right:-.6rem; bottom:-1rem; font-size:5.5rem; color:var(--green-600);
  opacity:.07; pointer-events:none; line-height:1;
}

.stat-tile{
  background:var(--card-bg); border:1px solid var(--border-soft); border-radius:var(--radius-lg);
  padding:1rem 1.15rem; display:flex; align-items:center; gap:.8rem; box-shadow:var(--shadow-card);
}
.stat-tile .stat-icon{
  width:42px; height:42px; border-radius:10px; display:flex; align-items:center; justify-content:center;
  font-size:1.1rem; flex-shrink:0;
}
.stat-icon.green{ background:var(--green-100); color:var(--green-700); }
.stat-icon.blue{ background:var(--blue-100); color:var(--blue-600); }
.stat-icon.yellow{ background:var(--yellow-100); color:var(--yellow-700); }
.stat-icon.purple{ background:var(--purple-100); color:var(--purple-700); }
.stat-tile .stat-label{ font-size:.78rem; color:var(--ink-500); }
.stat-tile .stat-value{ font-size:1.15rem; font-weight:700; color:var(--ink-900); }

.cta-banner{
  background:linear-gradient(120deg,var(--green-700),var(--blue-600)); color:#fff;
  border-radius:var(--radius-lg); padding:1.1rem 1.4rem; display:flex; align-items:center;
  gap:1rem; text-decoration:none;
}
.cta-banner .cta-icon{
  width:44px; height:44px; border-radius:10px; background:rgba(255,255,255,.18);
  display:flex; align-items:center; justify-content:center; font-size:1.2rem;
}
.cta-banner:hover{ opacity:.94; color:#fff; }

/* Status dot (before a member's name in a roster list) */
.status-dot{ display:inline-block; width:8px; height:8px; border-radius:50%; margin-right:.4rem; vertical-align:middle; }
.status-dot-green{ background:var(--green-600); }
.status-dot-yellow{ background:var(--yellow-700); }

/* Badges */
.badge-coop{ border-radius:999px; padding:.32rem .7rem; font-size:.74rem; font-weight:700; }
.badge-active{ background:var(--blue-100); color:var(--blue-600); }
.badge-approved, .badge-posted{ background:var(--green-100); color:var(--green-700); }
.badge-pending{ background:var(--yellow-100); color:var(--yellow-700); }
.badge-rejected{ background:var(--red-100); color:var(--red-600); }
.badge-planned{ background:var(--purple-100); color:var(--purple-700); }
.badge-completed, .badge-cashedout{ background:#eef0ef; color:var(--ink-700); }
.badge-farmer{ background:var(--green-100); color:var(--green-700); }
.badge-fisherfolk{ background:var(--blue-100); color:var(--blue-600); }
.badge-suspended{ background:var(--red-100); color:var(--red-600); }
.badge-inactive{ background:#eef0ef; color:var(--ink-500); }

/* Tables */
.table-coop{ width:100%; }
.table-coop thead th{
  font-size:.72rem; letter-spacing:.04em; text-transform:uppercase; color:var(--ink-500);
  font-weight:700; border-bottom:1px solid var(--border-soft); padding:.6rem .5rem;
  position:sticky;  background:#fff; z-index:15;
}
.table-coop tbody td{ padding:.75rem .5rem; border-bottom:1px solid var(--border-soft); font-size:.9rem; vertical-align:middle;}
.table-coop tbody tr:last-child td{ border-bottom:none; }
.table-coop tfoot td{ font-weight:700; padding:.75rem .5rem; border-top:2px solid var(--border-soft);}

/* Upload / signature boxes */
.upload-box{
  border:1.5px dashed #cfd6d2; border-radius:var(--radius-md); padding:1rem; text-align:left;
  color:var(--ink-500); font-size:.9rem; cursor:pointer; display:flex; align-items:center; gap:.6rem;
  background:#fff;
}
.upload-box:hover{ border-color:var(--green-500); }
.upload-box.filled{ border-color:var(--green-500); background:var(--green-100); color:var(--green-700); }
.signature-box{
  border:1.5px dashed #cfd6d2; border-radius:var(--radius-md); background:#fff; height:170px;
  display:flex; align-items:center; justify-content:center; position:relative; cursor:crosshair;
}
.signature-box canvas{ width:100%; height:100%; border-radius:var(--radius-md); }
.signature-placeholder{ position:absolute; text-align:center; color:var(--ink-500); font-size:.85rem; pointer-events:none;}

/* Step wizard */
.step-dots{ display:flex; justify-content:center; gap:.4rem; margin:.9rem 0 1.6rem; }
.step-dots span{ width:38px; height:6px; border-radius:999px; background:#dfe4e1; }
.step-dots span.done, .step-dots span.active{ background:var(--green-600); }

/* Labeled step tracker (registration wizard) */
.reg-stepper{ display:flex; align-items:flex-start; justify-content:center; margin:.9rem 0 1.6rem; }
.reg-step{ display:flex; flex-direction:column; align-items:center; gap:.3rem; flex:0 0 auto; width:64px; }
.reg-step-circle{
  width:28px; height:28px; border-radius:50%; background:#dfe4e1; color:var(--ink-500);
  display:flex; align-items:center; justify-content:center; font-size:.78rem; font-weight:700;
  transition:background .15s ease, color .15s ease; flex-shrink:0;
}
.reg-step.done .reg-step-circle{ background:var(--green-600); color:#fff; }
.reg-step.active .reg-step-circle{ background:var(--green-700); color:#fff; box-shadow:0 0 0 4px var(--green-100); }
.reg-step-label{ font-size:.68rem; font-weight:600; color:var(--ink-500); text-align:center; }
.reg-step.done .reg-step-label, .reg-step.active .reg-step-label{ color:var(--ink-900); }
.reg-step-line{ flex:1 1 auto; height:2px; background:#dfe4e1; margin-top:14px; min-width:8px; }
.reg-step-line.done{ background:var(--green-600); }
@media (max-width:575px){ .reg-step{ width:44px; } .reg-step-label{ font-size:.58rem; } }

/* Product / project cards */
.product-card{ background:var(--card-bg); border:1px solid var(--border-soft); border-radius:var(--radius-lg); overflow:hidden; box-shadow:var(--shadow-card); transition:transform .18s ease, box-shadow .18s ease; height:100%; display:flex; flex-direction:column;}
.product-card:hover{ transform:translateY(-5px); box-shadow:var(--shadow-pop); }
/* One fixed tile for every photo: 4:3, centred and contained on white, so a tall
   feed sack and a wide rope coil read at the same size and neither gets cropped.
   The catalogue thumbnails are pre-fitted to this ratio (see database/seed_products.sql);
   contain is what keeps an admin-uploaded photo of any other shape tidy too. */
.product-banner{
  aspect-ratio:4/3; flex:0 0 auto; position:relative; color:#fff;
  background-color:#fff; background-size:contain; background-position:center; background-repeat:no-repeat;
  border-bottom:1px solid var(--border-soft);
  display:flex; align-items:flex-end; padding:.7rem .8rem; font-size:.85rem; font-weight:600;
}
/* The pack-size / sack-price badge carries its own chip rather than sitting on a
   full-tile scrim, which would wash grey over the clean white of a product photo. */
.product-banner span{
  position:relative; z-index:1; background:rgba(16,24,20,.74); color:#fff;
  padding:.22rem .6rem; border-radius:999px; font-size:.78rem; line-height:1.35;
  box-shadow:0 1px 6px rgba(16,24,20,.22);
}
/* Cards in a row are stretched to a common height; the body grows to absorb the
   difference so the action buttons stay on one line across the grid. */
.product-body{ padding:1rem 1.1rem; flex:1 1 auto; display:flex; flex-direction:column; }
.product-body .product-actions{ margin-top:auto; }
.progress-coop{ height:8px; border-radius:999px; background:#e9ecea; overflow:hidden; }
.progress-coop > div{ height:100%; background:var(--green-600); border-radius:999px; }

/* Occupation filter pills (member management) */
.filter-pill{
  border:1px solid var(--border-soft); border-radius:999px; padding:.4rem 1rem; font-size:.85rem;
  font-weight:600; color:var(--ink-700); background:#fff;
}
.filter-pill.active{ background:var(--green-600); border-color:var(--green-600); color:#fff; }

/* Notification items */
.notif-item{
  border-radius:var(--radius-md); padding:.9rem 1.1rem; display:flex; align-items:flex-start; gap:.8rem;
  border:1px solid var(--border-soft); background:#fff; margin-bottom:.8rem;
}
.notif-item.unread{ background:var(--green-100); border-color:#cfe7d8; cursor:pointer; transition:background .15s ease, box-shadow .15s ease; }
.notif-item.unread:hover, .notif-item.unread:focus-visible{ background:#d7efe0; box-shadow:0 2px 10px rgba(16,24,20,.08); outline:none; }
.notif-item.unread:focus-visible{ outline:2px solid var(--green-600); outline-offset:2px; }
.notif-icon{
  width:34px; height:34px; border-radius:50%; display:flex; align-items:center; justify-content:center;
  background:#eef1f0; color:var(--ink-500); flex-shrink:0;
}
.notif-item.unread .notif-icon{ background:var(--green-600); color:#fff; }
.notif-dot{ width:9px; height:9px; border-radius:50%; background:var(--green-600); margin-left:auto; margin-top:.3rem; flex-shrink:0;}

/* Font size options (settings) */
.fontsize-options{ display:grid; grid-template-columns:repeat(3,1fr); gap:.7rem; }
.fontsize-btn{
  border:1.5px solid #d9dedb; border-radius:var(--radius-md); padding:.7rem; text-align:center;
  background:#fff; font-weight:600; color:var(--ink-700); cursor:pointer;
}
.fontsize-btn.selected{ border-color:var(--green-600); background:var(--green-100); color:var(--green-700); }

/* Appearance options (settings — Interface: Light / Dark / System) */
.appearance-options{ display:grid; grid-template-columns:repeat(3,1fr); gap:.7rem; }
.appearance-btn{
  border:1.5px solid #d9dedb; border-radius:var(--radius-md); padding:.7rem; text-align:center;
  background:#fff; font-weight:600; color:var(--ink-700); cursor:pointer;
}
.appearance-btn i{ display:block; font-size:1.3rem; margin-bottom:.3rem; }
.appearance-btn.selected{ border-color:var(--green-600); background:var(--green-100); color:var(--green-700); }

/* Help fab */
.help-fab{
  position:fixed; right:1.4rem; bottom:var(--footer-offset, 1.4rem); width:44px; height:44px; border-radius:50%;
  background:var(--navy-900); color:#fff; display:flex; align-items:center; justify-content:center;
  box-shadow:var(--shadow-pop); z-index:60; transition:bottom .2s ease;
}

/* Chart container */
.chart-wrap{ position:relative; height:230px; }

/* MOA agreement box */
.section-label{
  font-weight:700; font-size:.82rem; text-transform:uppercase; letter-spacing:.04em; color:var(--green-700);
  margin:1.4rem 0 .8rem; padding-bottom:.4rem; border-bottom:1px solid var(--border-soft);
}
.section-label:first-of-type{ margin-top:.4rem; }
.child-row .form-control{ max-width:400px; }

.moa-box{
  border:1px solid var(--border-soft); border-radius:var(--radius-md); background:#f9fafa;
  padding:.9rem 1rem; max-height:150px; overflow-y:auto; font-size:.78rem; color:var(--ink-700); line-height:1.55;
}
.moa-check-wrap{
  display:flex; align-items:flex-start; gap:.6rem; margin-top:.6rem; padding:.7rem .8rem;
  background:var(--yellow-100); border-radius:var(--radius-md); border:1px solid #f1e0a1;
}

/* Email verification */
.verify-row{ display:flex; gap:.5rem; }
.verify-badge{
  display:inline-flex; align-items:center; gap:.3rem; font-size:.76rem; font-weight:700; padding:.15rem .55rem;
  border-radius:999px; background:var(--green-100); color:var(--green-700);
}

/* Seminar progress */
.seminar-progress-wrap{ display:flex; align-items:center; gap:.5rem; }
.seminar-dots{ display:flex; gap:.25rem; }
.seminar-dots span{ width:14px; height:14px; border-radius:50%; background:#e2e6e4; }
.seminar-dots span.done{ background:var(--green-600); }
/* A seminar still owed. Drawn as a red ring rather than a filled red dot so a roster of pending
   members doesn't read as a wall of errors, while the outstanding count stays unmistakable. */
.seminar-dots span.todo{ background:var(--red-100); box-shadow:inset 0 0 0 2px var(--red-600); }
.seminar-count-unmet{ color:var(--red-700); font-weight:700; }

/* ---------------------------------------------------------
   Pre-approval checklist (admin → Members → View, pending member)
   ---------------------------------------------------------
   Seminar attendance and the membership fee are the two things that gate Approve, so the panel
   sits at the very top of the detail modal — above the profile fields the admin would otherwise
   have to scroll past to reach it. Red while anything is outstanding, green once both are met,
   so the panel itself answers "can I approve this person yet?" at a glance. */
.approval-alert{
  border:1.5px solid var(--red-600); background:var(--red-100);
  border-radius:var(--radius-lg); padding:.95rem 1rem; margin-bottom:1.1rem;
}
.approval-alert.ready{ border-color:var(--green-600); background:var(--green-100); }
.approval-alert-head{
  display:flex; align-items:center; gap:.5rem; flex-wrap:wrap;
  font-weight:800; font-size:.8rem; letter-spacing:.045em; text-transform:uppercase;
  color:var(--red-700); margin-bottom:.8rem;
}
.approval-alert.ready .approval-alert-head{ color:var(--green-700); }
.approval-alert-count{
  margin-left:auto; background:var(--red-600); color:#fff; border-radius:999px;
  padding:.18rem .6rem; font-size:.7rem; font-weight:700; letter-spacing:.02em; text-transform:none;
}
.approval-alert.ready .approval-alert-count{ background:var(--green-600); }
.approval-task{
  background:var(--card-bg); border:1px solid #f0cfcf; border-left:4px solid var(--red-600);
  border-radius:var(--radius-md); padding:.8rem .9rem; height:100%;
  display:flex; flex-direction:column;
}
.approval-task.done{ border-color:#c4e2d1; border-left-color:var(--green-600); }
.approval-task-title{
  display:flex; align-items:center; gap:.4rem; font-weight:700; font-size:.8rem;
  letter-spacing:.04em; text-transform:uppercase; color:var(--red-700); margin-bottom:.35rem;
}
.approval-task.done .approval-task-title{ color:var(--green-700); }
.approval-task-desc{ font-size:.78rem; color:var(--ink-500); margin-bottom:.6rem; line-height:1.5; }
.approval-task-status{ display:flex; align-items:center; gap:.6rem; flex-wrap:wrap; margin-bottom:.7rem; font-size:.85rem; font-weight:600; }
.approval-task .btn{ margin-top:auto; align-self:flex-start; }
/* Requirement-not-met chip. Distinct from the neutral amber .badge-pending, which marks ordinary
   in-progress states ("New", "Draft", "Awaiting release") that need no one's attention. */
.badge-unmet{ background:var(--red-100); color:var(--red-700); }
/* The blocked-Approve explanation under the modal footer buttons. */
.approval-block-hint{ font-size:.78rem; color:var(--red-700); font-weight:600; width:100%; text-align:right; margin-bottom:.4rem; }

/* Collateral note */
.tier-note{ font-size:.78rem; border-radius:var(--radius-sm); padding:.5rem .7rem; margin-top:.4rem; }
.tier-note.ok{ background:var(--green-100); color:var(--green-700); }
.tier-note.warn{ background:var(--yellow-100); color:var(--yellow-700); }

/* Loan detail modal key-value */
.kv-row{ display:flex; justify-content:space-between; padding:.5rem 0; border-bottom:1px solid var(--border-soft); font-size:.88rem; }
.kv-row:last-child{ border-bottom:none; }
.kv-row .k{ color:var(--ink-500); }
.kv-row .v{ font-weight:600; color:var(--ink-900); text-align:right; }

/* Small helpers */
.avatar-round{
  width:44px; height:44px; border-radius:10px; display:flex; align-items:center; justify-content:center;
  color:#fff; font-weight:700; background:linear-gradient(135deg,var(--green-700),var(--blue-600));
}
.text-strong{ color:var(--ink-900); font-weight:700; }

/* ---------- toast feedback ---------- */
.coop-toast{
  display:flex; align-items:center; gap:.6rem; background:#fff; border-radius:var(--radius-md);
  box-shadow:0 8px 24px rgba(22,33,28,.14); padding:.75rem 1rem; font-size:.88rem; font-weight:600;
  color:var(--ink-900); border-left:4px solid var(--green-600);
  opacity:0; transform:translateX(16px); transition:opacity .25s ease, transform .25s ease;
}
.coop-toast.show{ opacity:1; transform:translateX(0); }
.coop-toast i{ font-size:1.1rem; }
.coop-toast-success{ border-left-color:var(--green-600); }
.coop-toast-success i{ color:var(--green-600); }
.coop-toast-error{ border-left-color:var(--red-600); }
.coop-toast-error i{ color:var(--red-600); }
.coop-toast-warning{ border-left-color:var(--yellow-700); }
.coop-toast-warning i{ color:var(--yellow-700); }

/* ---------- pagination ---------- */
.pagination-wrap{ display:flex; align-items:center; justify-content:center; gap:.35rem; flex-wrap:wrap; padding-top:1rem; }
.page-btn{
  min-width:34px; height:34px; padding:0 .5rem; border-radius:8px; border:1px solid var(--border-soft);
  background:#fff; color:var(--ink-700); font-weight:600; font-size:.85rem;
}
.page-btn:hover:not(:disabled){ border-color:var(--green-500); color:var(--green-700); }
.page-btn.active{ background:var(--green-600); border-color:var(--green-600); color:#fff; }
.page-btn:disabled{ opacity:.4; }

/* ---------- stock/category filters, doc viewer ---------- */
.doc-preview-frame{
  width:100%; max-height:420px; border-radius:var(--radius-md); border:1px solid var(--border-soft);
  background:#f6f8f7; display:flex; align-items:center; justify-content:center; min-height:220px; overflow:hidden;
}
.doc-preview-frame img{ max-width:100%; max-height:420px; object-fit:contain; }
.map-embed-frame{ width:100%; height:360px; border-radius:var(--radius-md); overflow:hidden; border:1px solid var(--border-soft); }

/* ---------- pending actions ---------- */
.pending-action-row:last-child{ border-bottom:none !important; }
.pending-action-row:hover{ background:#f6f8f7; }

/* ---------- step wizard chrome (register, loan-apply) ---------- */
/* sticky footer: keeps the footer pinned to the bottom of the screen when wizard content is short */
body:has(.wizard-topbar){ min-height:100vh; display:flex; flex-direction:column; }
body:has(.wizard-topbar) .wizard-wrap{ flex:1 0 auto; }
.wizard-topbar{ background:linear-gradient(120deg,var(--green-700),var(--green-600)); border-bottom:1px solid rgba(0,0,0,.08); padding:1rem 1.5rem; text-align:center; position:sticky; top:0; z-index:30; color:#fff;}
.wizard-topbar a{ color:#fff; }
.wizard-topbar .small{ color:rgba(255,255,255,.85); }
.wizard-topbar-seals{ position:absolute; right:1rem; top:50%; transform:translateY(-50%); display:flex; gap:.4rem; }
.wizard-wrap{ max-width:650px; margin:0 auto; padding:1.5rem 1rem 2rem; }
#step1, #step2, #step3, #step4, #step5, #step6, #step7{ position:relative; }
#step1 > h2, #step2 > h2, #step3 > h2, #step4 > h2, #step5 > h2, #step6 > h2, #step7 > h2{ padding-right:4.5rem; }
.wizard-back-btn{ position:absolute; top:.2rem; right:0; white-space:nowrap; }
.wizard-footer{
 border-top:1px solid var(--border-soft);
  padding:.9rem 0; display:flex; justify-content:center; align-items:center;
  min-height:56px; box-sizing:border-box;
}
.wizard-continue-wrap{ padding:1rem 0 0; }

/* ---------- community gallery ---------- */
.gallery-wrap{ position:relative; display:flex; align-items:center; gap:.9rem; max-width:1320px; margin:0 auto; }
.gallery-track{
  display:flex; gap:1rem; overflow-x:auto; scroll-snap-type:x mandatory; scroll-behavior:smooth;
  -webkit-overflow-scrolling:touch; flex:1; min-width:0; padding:.25rem; scrollbar-width:none;
}
.gallery-track::-webkit-scrollbar{ display:none; }
.gallery-card{
  position:relative; flex:0 0 100%; scroll-snap-align:start; border:1px solid var(--border-soft); padding:0;
  background:var(--card-bg); border-radius:var(--radius-lg); overflow:hidden; cursor:pointer; text-align:left;
  box-shadow:var(--shadow-pop);
}
@media (min-width:640px){
  .gallery-card{ flex-basis:calc((100% - 1rem) / 2); }
}
@media (min-width:1024px){
  .gallery-card{ flex-basis:calc((100% - 2rem) / 3); }
}
.gallery-card img{ width:100%; aspect-ratio:4/3; object-fit:cover; display:block; -webkit-user-drag:none; user-select:none; }
.gallery-card::after{
  content:""; position:absolute; inset:0; background:linear-gradient(0deg, rgba(0,0,0,.62) 0%, rgba(0,0,0,0) 45%);
  pointer-events:none;
}
.gallery-card-caption{
  position:absolute; left:0; right:0; bottom:0; z-index:2; padding:.9rem 1rem .8rem;
  display:flex; flex-direction:column; gap:.1rem;
}
.gallery-card-caption .cap-title{ color:#fff; font-family:"Poppins","Inter",sans-serif; font-weight:700; font-size:1.1rem; text-shadow:0 1px 6px rgba(0,0,0,.4); }
.gallery-card-caption .cap-year{ color:var(--green-100); font-weight:600; font-size:.76rem; letter-spacing:.05em; }
.gallery-nav-btn{
  flex:0 0 auto; width:44px; height:44px; border-radius:50%; border:1px solid var(--border-soft);
  background:#fff; color:var(--ink-900); display:flex; align-items:center; justify-content:center;
  box-shadow:var(--shadow-pop); cursor:pointer; font-size:1.1rem; transition:background .15s ease, color .15s ease;
}
.gallery-nav-btn:hover{ background:var(--green-600); color:#fff; }
@media (max-width:639px){
  .gallery-nav-btn{ display:none; }
}
.gallery-counter-pill{
  display:inline-block; padding:.3rem .85rem; border-radius:999px; background:var(--card-bg);
  border:1px solid var(--border-soft); color:var(--ink-500); font-size:.78rem; font-weight:600; letter-spacing:.02em;
}

/* ---------- community gallery lightbox ---------- */
.gallery-lightbox{
  position:fixed; inset:0; z-index:1000; background:rgba(10,16,13,.92);
  display:flex; align-items:center; justify-content:center; padding:2.5rem 1rem;
}
.gallery-lightbox[hidden]{ display:none; }
.gallery-lightbox-stage{ max-width:900px; width:100%; display:flex; flex-direction:column; align-items:center; gap:.9rem; }
.gallery-lightbox-stage img{
  max-width:100%; max-height:70vh; width:auto; object-fit:contain; border-radius:var(--radius-md);
  box-shadow:0 20px 60px rgba(0,0,0,.5); -webkit-user-drag:none; user-select:none;
}
.gallery-lightbox-caption{ text-align:center; display:flex; flex-direction:column; gap:.15rem; }
.gallery-lightbox-caption .cap-title{ color:#fff; font-family:"Poppins","Inter",sans-serif; font-weight:700; font-size:1.15rem; }
.gallery-lightbox-caption .cap-year{ color:var(--green-100); font-weight:600; font-size:.8rem; letter-spacing:.05em; }
.gallery-lightbox-close{
  position:absolute; top:1.2rem; right:1.2rem; width:44px; height:44px; border-radius:50%; border:none;
  background:rgba(255,255,255,.12); color:#fff; display:flex; align-items:center; justify-content:center;
  font-size:1.15rem; cursor:pointer; transition:background .15s ease; z-index:2;
}
.gallery-lightbox-close:hover{ background:rgba(255,255,255,.25); }
.gallery-lightbox-arrow{
  position:absolute; top:50%; transform:translateY(-50%); width:48px; height:48px; border-radius:50%; border:none;
  background:rgba(255,255,255,.12); color:#fff; display:flex; align-items:center; justify-content:center;
  font-size:1.3rem; cursor:pointer; transition:background .15s ease; z-index:2;
}
.gallery-lightbox-arrow:hover{ background:rgba(255,255,255,.25); }
.gallery-lightbox-prev{ left:1rem; }
.gallery-lightbox-next{ right:1rem; }
@media (max-width:639px){
  .gallery-lightbox{ padding:4.5rem .5rem 2rem; }
  .gallery-lightbox-prev{ left:.4rem; }
  .gallery-lightbox-next{ right:.4rem; }
  .gallery-lightbox-close{ top:.8rem; right:.8rem; }
}

/* ---------- image lightbox (zoom / rotate) for reviewing uploaded IDs/docs ---------- */
.lightbox-toolbar{ display:flex; gap:.5rem; justify-content:center; margin-bottom:.9rem; }
.lightbox-frame{
  width:100%; min-height:260px; max-height:60vh; overflow:auto; border-radius:var(--radius-md);
  border:1px solid var(--border-soft); background:#f6f8f7; display:flex; align-items:center; justify-content:center;
}
.lightbox-frame img{ max-width:100%; transition:transform .15s ease; }

/* ---------- out-of-stock product cards (Project Stakes) ---------- */
.product-card.out-of-stock .product-banner{ filter:grayscale(1) brightness(.75); }
.product-card.out-of-stock .product-body .text-success{ color:var(--ink-500) !important; }
.product-card.out-of-stock{ opacity:.85; }

/* ---------- submit bar (long single-page forms on mobile) ---------- */
@media (max-width:767px){
  .floating-submit-bar{
    padding:.8rem 1rem 0; border-top:1px solid var(--border-soft);
  }
  .floating-submit-bar .btn{ width:100%; }
}

/* =========================================================
   Dark mode (Settings → Interface → Appearance: Light / Dark / System)
   Activated by [data-bs-theme="dark"] on <html> — set by applyTheme() in main.js, persisted in
   localStorage, "system" resolved live from prefers-color-scheme. Bootstrap's own components
   (.form-control/.form-select colors, .modal-content, .dropdown-menu, .btn-close, etc.) already
   re-theme automatically from data-bs-theme; most of this app's OWN classes already read color
   from the :root custom properties above too, so redefining those here does most of the work in
   one place. What's left are the handful of surfaces still hardcoded to a literal light color.
   Known gap: services.php/contact.php/history.php/board.php carry their own page-local <style>
   blocks (a separate, newer layout pattern) not covered here — a follow-up if dark mode should
   extend to those too. */
[data-bs-theme="dark"]{
  --bg-page:#12181a;
  --card-bg:rgba(27,36,34,.92);
  --border-soft:#2c3634;
  --ink-900:#eef1ee;
  --ink-700:#c3ccc7;
  --ink-500:#93a099;
  --green-100:#173226;
  --blue-100:#152b3d;
  --yellow-100:#3a3316;
  --red-100:#3a1f1f;
  --purple-100:#241a35;
  --gold-100:#332a13;
  --surface-sunken:#171f1d;
}
[data-bs-theme="dark"] body{
  background:
    linear-gradient(rgba(10,14,13,.78), rgba(10,14,13,.78)),
    url("../img/backgrounds/page-bg.jpeg") center/cover fixed no-repeat;
  background-color:var(--bg-page);
}
[data-bs-theme="dark"] .app-main{
  background:
    linear-gradient(rgba(10,14,13,.75), rgba(10,14,13,.75)),
    url("../img/backgrounds/page-bg.jpeg") center/cover fixed no-repeat;
}
/* Primary surfaces — cards, panels, pills, toasts — that were hardcoded to a literal white
   instead of reading var(--card-bg) like .card-coop/.stat-tile/etc already do. */
[data-bs-theme="dark"] .dropdown-panel,
[data-bs-theme="dark"] .auth-card,
[data-bs-theme="dark"] .doc-card,
[data-bs-theme="dark"] .upload-box,
[data-bs-theme="dark"] .signature-box,
[data-bs-theme="dark"] .filter-pill,
[data-bs-theme="dark"] .notif-item,
[data-bs-theme="dark"] .fontsize-btn,
[data-bs-theme="dark"] .appearance-btn,
[data-bs-theme="dark"] .table-coop thead th,
[data-bs-theme="dark"] .page-btn,
[data-bs-theme="dark"] .coop-toast,
[data-bs-theme="dark"] .gallery-nav-btn,
[data-bs-theme="dark"] .timeline-card,
[data-bs-theme="dark"] .btn-coop-ghost{
  background:var(--card-bg); color:var(--ink-900);
}
[data-bs-theme="dark"] .btn-coop-ghost:hover,
[data-bs-theme="dark"] .pending-action-row:hover{ background:var(--surface-sunken); }
/* Recessed/secondary panels — sit a shade darker than the primary surfaces above. */
[data-bs-theme="dark"] .moa-box,
[data-bs-theme="dark"] .doc-preview-frame,
[data-bs-theme="dark"] .lightbox-frame,
[data-bs-theme="dark"] .notif-icon{ background:var(--surface-sunken); }
[data-bs-theme="dark"] .badge-completed, [data-bs-theme="dark"] .badge-cashedout,
[data-bs-theme="dark"] .badge-inactive{ background:var(--surface-sunken); }
[data-bs-theme="dark"] .notif-item.unread:hover, [data-bs-theme="dark"] .notif-item.unread:focus-visible{ background:#1c3327; }
/* "Unfilled" decorative tracks (progress bars, step dots/lines) — a mid-dark gray so they still
   read as empty against the dark page background. */
[data-bs-theme="dark"] .pw-strength-bar span,
[data-bs-theme="dark"] .step-dots span,
[data-bs-theme="dark"] .reg-step-circle,
[data-bs-theme="dark"] .reg-step-line,
[data-bs-theme="dark"] .seminar-dots span,
[data-bs-theme="dark"] .progress-coop{ background:var(--border-soft); }
/* Hardcoded border colors that would otherwise stay light-mode gray against a dark surface. */
[data-bs-theme="dark"] .form-control, [data-bs-theme="dark"] .form-select,
[data-bs-theme="dark"] .fontsize-btn, [data-bs-theme="dark"] .appearance-btn,
[data-bs-theme="dark"] .upload-box, [data-bs-theme="dark"] .signature-box{
  border-color:var(--border-soft);
}
[data-bs-theme="dark"] .card-watermark-icon{ opacity:.14; }
/* Accent "chip" pairs (light tint background + matching dark, saturated text — badges, stat/doc
   icon tiles, selected pills) keep their tint backgrounds unchanged in dark mode (a light badge
   reads fine as a spot of color against a dark card), but the paired TEXT color must switch to a
   brighter version of the same hue — the original -700/-600 text was tuned for contrast against
   a light tint, and reads almost invisibly dark against that same tint once .card-bg's own base
   turns dark. */
[data-bs-theme="dark"] .btn-icon-approve, [data-bs-theme="dark"] .dropdown-panel-link:hover,
[data-bs-theme="dark"] .dropdown-panel-link.active, [data-bs-theme="dark"] .section-tag.green,
[data-bs-theme="dark"] .contact-icon.green, [data-bs-theme="dark"] .doc-card-icon,
[data-bs-theme="dark"] .card-section-icon, [data-bs-theme="dark"] .stat-icon.green,
[data-bs-theme="dark"] .badge-approved, [data-bs-theme="dark"] .badge-posted,
[data-bs-theme="dark"] .badge-farmer, [data-bs-theme="dark"] .upload-box.filled,
[data-bs-theme="dark"] .fontsize-btn.selected, [data-bs-theme="dark"] .appearance-btn.selected,
[data-bs-theme="dark"] .verify-badge, [data-bs-theme="dark"] .tier-note.ok,
[data-bs-theme="dark"] .org-role:not(.chair), [data-bs-theme="dark"] .org-photo-blank{
  color:#5cc78d;
}
[data-bs-theme="dark"] .section-tag.blue, [data-bs-theme="dark"] .contact-icon.blue,
[data-bs-theme="dark"] .doc-card-icon.blue, [data-bs-theme="dark"] .card-section-icon.alt,
[data-bs-theme="dark"] .stat-icon.blue, [data-bs-theme="dark"] .badge-active,
[data-bs-theme="dark"] .badge-fisherfolk{
  color:#6fb3ef;
}
[data-bs-theme="dark"] .legal-flag,
[data-bs-theme="dark"] .stat-icon.yellow, [data-bs-theme="dark"] .badge-pending,
[data-bs-theme="dark"] .tier-note.warn{
  color:#e0c15c;
}
[data-bs-theme="dark"] .btn-icon-reject, [data-bs-theme="dark"] .badge-rejected,
[data-bs-theme="dark"] .badge-suspended, [data-bs-theme="dark"] .badge-unmet,
[data-bs-theme="dark"] .auth-note.warn, [data-bs-theme="dark"] .auth-note.warn strong,
[data-bs-theme="dark"] .approval-alert-head, [data-bs-theme="dark"] .approval-task-title,
[data-bs-theme="dark"] .approval-block-hint, [data-bs-theme="dark"] .seminar-count-unmet{
  color:#e88888;
}
/* The checklist's own green "satisfied" state, matching the dark-mode green used for every other
   approved/complete accent above. */
[data-bs-theme="dark"] .approval-alert.ready .approval-alert-head,
[data-bs-theme="dark"] .approval-task.done .approval-task-title,
[data-bs-theme="dark"] .btn-coop-done, [data-bs-theme="dark"] .btn-coop-done:disabled{
  color:#5cc78d;
}
/* Tint borders hardcoded to a light red/green would glow against the dark card surface. */
[data-bs-theme="dark"] .auth-note.warn{ border-color:#5c2d2d; }
[data-bs-theme="dark"] .approval-task{ border-color:#5c2d2d; border-left-color:var(--red-600); }
[data-bs-theme="dark"] .approval-task.done{ border-color:#27503a; border-left-color:var(--green-600); }
[data-bs-theme="dark"] .doc-card-icon.purple, [data-bs-theme="dark"] .stat-icon.purple,
[data-bs-theme="dark"] .badge-planned{
  color:#b79ce6;
}
[data-bs-theme="dark"] .doc-card-icon.gold{ color:#d9b45c; }

/* =========================================================
   Admin side (body.role-admin is set by renderSidebar("admin", ...))
   ========================================================= */

/* Solid (not see-through) cards, tiles, and panels — including the dashboard's Quick Actions —
   so the page's background artwork no longer shows through them or appears to run across
   their contents. */
body.role-admin{ --card-bg:#ffffff; }
[data-bs-theme="dark"] body.role-admin{ --card-bg:#1b2422; }
.role-admin .quick-actions-card{ background:var(--card-bg); }

/* The admin sidebar used to carry its own position override here; it now behaves exactly like
   every other role's — pinned on desktop, drawer on mobile — straight off the base
   `.app-sidebar` rules. The Sign Out placement that also lived here (nav not stretching, Sign
   Out two spaces below the last link) is on the base `.sidebar-nav` / `.sidebar-signout` rules
   instead, so the member, Credit Investigation and Collector sidebars match the admin one. */

/* Admin bell panel — opening it marks everything listed as viewed, which resets the badge. */
.app-topbar-seals{ position:relative; }
.topbar-bell-panel{
  display:none; position:absolute; top:calc(100% + .7rem); right:0; width:330px; max-width:calc(100vw - 2rem);
  background:var(--card-bg, #fff); border:1px solid var(--border-soft); border-radius:var(--radius-md);
  box-shadow:var(--shadow-pop); z-index:1060; overflow:hidden;
}
.topbar-bell-panel.show{ display:block; }
.topbar-bell-panel-head{ padding:.7rem 1rem; font-weight:700; font-size:.9rem; color:var(--ink-900); border-bottom:1px solid var(--border-soft); }
.topbar-bell-item{
  display:flex; align-items:center; gap:.6rem; padding:.65rem 1rem; font-size:.85rem;
  color:var(--ink-900); text-decoration:none; border-bottom:1px solid var(--border-soft);
}
.topbar-bell-item:last-child{ border-bottom:none; }
.topbar-bell-item:hover{ background:var(--surface-sunken, #f6f8f7); color:var(--ink-900); }
.topbar-bell-item i{ color:var(--green-700); }
.topbar-bell-new-dot{ margin-left:auto; width:8px; height:8px; border-radius:50%; background:var(--red-600); flex-shrink:0; }
.topbar-bell-empty{ padding:1rem; font-size:.85rem; color:var(--ink-500); }

/* Clickable tiles that open a form (Admin Settings sections, Admin Savings / Withdraws). */
.form-tile{
  display:flex; align-items:center; gap:.9rem; width:100%; height:100%; text-align:left;
  background:var(--card-bg, #fff); border:1px solid var(--border-soft); border-radius:var(--radius-lg);
  box-shadow:var(--shadow-card); padding:1.1rem 1.2rem; cursor:pointer; color:var(--ink-900);
  transition:transform .15s ease, box-shadow .15s ease;
}
.form-tile:hover{ transform:translateY(-2px); box-shadow:var(--shadow-pop); }
.form-tile .form-tile-icon{
  width:44px; height:44px; flex-shrink:0; border-radius:12px; display:flex; align-items:center; justify-content:center;
  background:var(--green-100); color:var(--green-700); font-size:1.2rem;
}
.form-tile .form-tile-body{ min-width:0; }
.form-tile .form-tile-title{ display:block; font-weight:700; color:var(--ink-900); font-size:.95rem; }
.form-tile .form-tile-desc{ display:block; font-size:.8rem; color:var(--ink-500); }
.form-tile .form-tile-meta{ display:block; font-size:.78rem; color:var(--green-700); font-weight:600; margin-top:.15rem; }
.form-tile .bi-chevron-right{ margin-left:auto; color:var(--ink-500); flex-shrink:0; }
.form-tile .tile-count{ margin-left:auto; flex-shrink:0; }

/* Keep long text (e.g. a sign-in's browser/device string) inside its row instead of pushing a
   badge out past the card's edge. */
.row-fit{ display:flex; justify-content:space-between; align-items:center; flex-wrap:wrap; gap:.5rem; }
.row-fit > .row-fit-main{ min-width:0; flex:1 1 220px; }

/* =========================================================
   Compact cards on small screens
   ---------------------------------------------------------
   Every card surface in this app was built at desktop proportions (≈1.3rem of padding, 42-44px
   icons, 16px corner radii) and then simply carried, unchanged, down to phone widths. On a
   375px screen that meant roughly a quarter of each row was padding before any content started,
   so cards looked oversized and a page that fits in one screenful on a laptop needed several
   swipes on a phone.

   This block tightens that across the board at ≤575px: padding and gaps come down, decorative
   icons shrink, and corner radii step down with them so a smaller card doesn't look rounder.
   Only spacing and sizing are touched — no color, no layout structure, so dark mode and the
   desktop appearance are both unaffected. It sits at the end of the stylesheet deliberately:
   every base rule it tightens is defined earlier, so source order lets these win without
   needing !important.
   ========================================================= */
@media (max-width:575px){

  /* The page gutter itself: 1.2rem each side on a 375px screen spent 13% of the width on
     margin before a card even began. */
  .app-main{ padding:1rem .85rem; }
  #topbar-mount{ margin:-1rem -.85rem 1rem; }

  /* ---------- the main card surface (.card-coop) and its section headers ---------- */
  .card-coop{ padding:.95rem 1rem; border-radius:var(--radius-md); }
  .card-section-header{ gap:.55rem; margin-bottom:.7rem; }
  .card-section-icon{ width:32px; height:32px; border-radius:9px; font-size:.95rem; }
  .section-eyebrow{ font-size:.7rem; margin-bottom:.5rem; }
  /* The decorative corner watermark is sized for a desktop card; at this width it sprawls
     across the text it sits behind, so it scales down with the card. */
  .card-watermark-icon{ font-size:3.6rem; right:-.4rem; bottom:-.7rem; }

  /* ---------- stat tiles ---------- */
  .stat-tile{ padding:.7rem .8rem; gap:.6rem; border-radius:var(--radius-md); }
  .stat-tile .stat-icon{ width:34px; height:34px; border-radius:9px; font-size:.95rem; }
  .stat-tile .stat-label{ font-size:.72rem; }
  .stat-tile .stat-value{ font-size:1rem; }

  /* ---------- downloadable-file cards ---------- */
  /* auto-fit with a 230px minimum already collapses to one column here, but the 1rem gap and
     desktop padding stay unless they're told otherwise. */
  .doc-card-grid{ gap:.7rem; }
  .doc-card{ padding:.9rem .9rem 1rem; border-radius:var(--radius-md); }
  .doc-card-icon{ width:34px; height:34px; border-radius:9px; font-size:.95rem; margin-bottom:.55rem; }
  .doc-card-title{ font-size:.9rem; }
  .doc-card-desc{ font-size:.78rem; margin-bottom:.6rem; }
  .doc-card-tags{ gap:.3rem; margin-bottom:.65rem; }

  /* ---------- clickable form tiles (admin Settings, Savings, Withdrawals) ---------- */
  .form-tile{ padding:.8rem .85rem; gap:.65rem; border-radius:var(--radius-md); }
  .form-tile .form-tile-icon{ width:36px; height:36px; border-radius:10px; font-size:1rem; }
  .form-tile .form-tile-title{ font-size:.88rem; }
  .form-tile .form-tile-desc{ font-size:.75rem; }
  .form-tile .form-tile-meta{ font-size:.73rem; }
  /* A tile's hover lift is a pointer affordance — on a touch screen it only ever fires as a
     lingering stuck state after a tap, so it's dropped along with the card's shadow jump. */
  .form-tile:hover, .board-card:hover, .product-card:hover{ transform:none; box-shadow:var(--shadow-card); }

  /* ---------- public-site cards ---------- */
  .board-card{ padding:1.05rem .9rem; border-radius:var(--radius-md); }
  .board-photo{ width:88px; height:88px; margin-bottom:.6rem; }
  .board-card.lead .board-photo{ width:104px; height:104px; }
  .history-card{ padding:1.05rem 1rem; border-radius:var(--radius-md); }
  .timeline-card{ padding:.7rem .85rem; }
  .timeline-dot{ width:32px; height:32px; }
  .contact-icon{ width:42px; height:42px; border-radius:10px; font-size:1.05rem; }
  .auth-header{ padding:1.4rem 1.1rem 1.15rem; }

  /* ---------- Quick Actions tiles (admin and member dashboards) ---------- */
  /* These are pill buttons (border-radius:999px) stacked to ~94px tall by their icon-over-label
     layout. At full pill radius that tall a box renders as an oval blob rather than a tile, and
     the curved sides squeeze two-word labels like "Add Member" onto two lines. A flat card
     radius and tighter padding make them read as buttons again and fit each label on one line. */
  .quick-actions-row .btn{ border-radius:var(--radius-md); padding:.7rem .5rem; font-size:.84rem; }
  .quick-actions-row .btn i{ font-size:1.15rem !important; margin-bottom:.15rem !important; }

  /* A `g-5` row sets a 3rem gutter, which Bootstrap applies as a -1.5rem margin on each side of
     the row. That is wider than the .container's own .75rem padding, so the row hung 12px past
     the viewport on both sides and the whole page scrolled sideways on a phone. Halving the
     gutter here makes the negative margin and the container padding cancel exactly, and 1.5rem
     is ample separation at this width anyway. */
  .row.g-5{ --bs-gutter-x:1.5rem; --bs-gutter-y:1.5rem; }

  /* ---------- Bootstrap cards and modals used alongside the app's own ---------- */
  .card-body{ padding:.95rem 1rem; }
  .modal-body{ padding:.95rem 1rem; }
  .modal-header, .modal-footer{ padding:.7rem 1rem; }
  .modal-title{ font-size:1rem; }
}

/* =========================================================
   Table row cap (see initTableRowCaps() in main.js)
   ---------------------------------------------------------
   Tables show the first few rows and offer the rest behind a "View all" button. The rows past
   the cap are hidden rather than removed, so each page's own row listeners stay attached and the
   table can be expanded again without re-rendering anything.
   `display:none` is forced here because a <tr>'s own `display:table-row` would otherwise win
   over the browser's default styling for the hidden state.
   ========================================================= */
.table-cap-hidden{ display:none !important; }
.table-cap-anchor{ display:none; }
.table-cap-more{ display:flex; justify-content:center; margin-top:.6rem; }
.table-cap-more .btn{ border-radius:999px; }
/* The expanded view is the whole point of the button, so give the table room to breathe and let
   a wide one scroll sideways inside the modal rather than squashing its columns. */
#tableCapModal .modal-body{ padding-top:.9rem; }
#tableCapModal .table-responsive{ margin-bottom:0; }
@media (max-width:575px){
  .table-cap-more{ margin-top:.45rem; }
  .table-cap-more .btn{ width:100%; }
}

/* Payment-type chooser (admin Shared Capital -> Add Payment). Two selectable tiles rather
   than a dropdown, because which pool the money lands in is the most consequential choice
   in that modal — Capital Build-Up and Shared Capital have separate totals, separate
   ledgers and separate minimums, so the pick needs to be visible, not buried in a select. */
.pay-type-tile{
  display:flex; flex-direction:column; align-items:flex-start; gap:.1rem;
  background:#fff; border:1.5px solid var(--border-soft); border-radius:14px;
  padding:.7rem .85rem; text-align:left; cursor:pointer; height:100%;
  transition:border-color .15s, background .15s, box-shadow .15s;
}
.pay-type-tile i{ font-size:1.15rem; color:var(--ink-500); margin-bottom:.15rem; }
.pay-type-tile .pay-type-title{ font-weight:700; font-size:.86rem; color:var(--ink-900); line-height:1.2; }
.pay-type-tile .pay-type-sub{ font-size:.73rem; color:var(--ink-500); }
.pay-type-tile:hover{ border-color:var(--green-700); }
.pay-type-tile.active{
  border-color:var(--green-700); background:var(--green-100);
  box-shadow:0 0 0 3px rgba(30,95,70,.12);
}
.pay-type-tile.active i,
.pay-type-tile.active .pay-type-title,
.pay-type-tile.active .pay-type-sub{ color:var(--green-700); }

[data-bs-theme="dark"] .pay-type-tile{ background:var(--surface-sunken); border-color:var(--border-soft); }
[data-bs-theme="dark"] .pay-type-tile.active{ background:var(--green-100); }
