/* =========================================================================
   Micro Jobs Africa — components
   Buttons, chips, avatars, cards and form controls.
   ====================================================================== */

/* --------------------------------------------------------------- button */

.btn {
  --btn-py: 14px;
  --btn-px: 26px;

  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  padding: var(--btn-py) var(--btn-px);
  border: 1px solid transparent;
  border-radius: var(--r-sm);
  font-size: .95rem;
  font-weight: 700;
  line-height: 1.2;
  letter-spacing: -0.01em;
  white-space: nowrap;
  cursor: pointer;
  transition: transform .22s cubic-bezier(.22,.61,.36,1),
              box-shadow .22s ease,
              background-color .22s ease,
              border-color .22s ease,
              color .22s ease;
}

.btn:active { transform: translateY(1px) scale(.99); }

.btn__icon {
  display: inline-flex;
  width: 16px;
  height: 16px;
  transition: transform .25s cubic-bezier(.22,.61,.36,1);
}
.btn__icon svg { width: 100%; height: 100%; }

.btn:hover .btn__icon { transform: translateX(3px); }

.btn--sm { --btn-py: 10px; --btn-px: 20px; font-size: .875rem; }
.btn--md { --btn-py: 15px; --btn-px: 28px; }

.btn--block { width: 100%; }

/* Primary — the solid brand green */
.btn--primary {
  background: var(--grad-btn);
  color: #fff;
  box-shadow: 0 10px 22px -10px rgba(0, 122, 42, .65);
}
.btn--primary:hover {
  box-shadow: 0 16px 30px -12px rgba(0, 122, 42, .75);
  transform: translateY(-2px);
}

/* Ghost — white with a hairline border */
.btn--ghost {
  background: var(--c-surface);
  color: var(--c-heading);
  border-color: var(--c-line);
}
.btn--ghost:hover {
  border-color: var(--c-green-bright);
  color: var(--c-green);
  transform: translateY(-2px);
  box-shadow: 0 12px 24px -16px rgba(11, 59, 38, .5);
}

/* Light — for placement on the forest sections */
.btn--light {
  background: #fff;
  color: var(--c-forest);
}
.btn--light:hover { transform: translateY(-2px); }

/* Gold accent */
.btn--gold {
  background: linear-gradient(180deg, var(--c-gold) 0%, var(--c-gold-deep) 100%);
  color: #3B2A05;
  box-shadow: 0 10px 22px -10px rgba(245, 166, 35, .7);
}
.btn--gold:hover { transform: translateY(-2px); }

/* ----------------------------------------------------------------- chip */

.chip {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 7px 15px 7px 12px;
  border-radius: var(--r-pill);
  font-size: .72rem;
  font-weight: 700;
  letter-spacing: .09em;
  text-transform: uppercase;
}

.chip--light {
  background: var(--c-chip);
  color: var(--c-chip-ink);
}

.chip--dark {
  background: rgba(255, 255, 255, .12);
  color: #EAF6EC;
  border: 1px solid rgba(255, 255, 255, .16);
}

.chip__mark {
  display: inline-flex;
  width: 12px;
  height: 12px;
}
.chip__mark svg { width: 100%; height: 100%; }

.chip__mark--star { color: var(--c-gold-deep); }

.chip--dark .chip__mark--star { color: var(--c-gold); }

/* Sentence-case chip variant (the hero badge) */
.chip--badge {
  padding: 9px 17px 9px 13px;
  font-size: .8rem;
  letter-spacing: -0.005em;
  text-transform: none;
  background: var(--c-line-soft);
  color: var(--c-heading);
  box-shadow: 0 2px 10px -6px rgba(11, 59, 38, .4);
}
.chip--badge .chip__mark { width: 14px; height: 14px; color: var(--c-gold-deep); }

/* -------------------------------------------------------------- avatars */

.avatars {
  display: flex;
  align-items: center;
}

.avatars__item {
  display: grid;
  place-items: center;
  width: 40px;
  height: 40px;
  margin-right: -12px;
  border-radius: 50%;
  border: 2.5px solid #fff;
  font-size: .78rem;
  font-weight: 800;
  color: #fff;
  letter-spacing: -0.02em;
  box-shadow: 0 3px 10px -4px rgba(11, 59, 38, .5);
}

.avatars__item:last-child { margin-right: 0; }

.avatars__item--a { background: linear-gradient(150deg, #17A24A, #00762A); }
.avatars__item--b { background: linear-gradient(150deg, #F5B93E, #E08A12); }
.avatars__item--c { background: linear-gradient(150deg, #2FB65C, #0A5C2E); }
.avatars__item--d { background: linear-gradient(150deg, #57C97E, #17A24A); }

.avatars--light .avatars__item { border-color: rgba(255, 255, 255, .9); }

/* ----------------------------------------------------------------- card */

.card {
  background: var(--c-surface);
  border: 1px solid var(--c-line);
  border-radius: var(--r-lg);
  transition: transform .3s cubic-bezier(.22,.61,.36,1), box-shadow .3s ease;
}

.card:hover {
  transform: translateY(-4px);
  box-shadow: 0 22px 44px -28px rgba(11, 59, 38, .45);
}

/* ----------------------------------------------------------------- form */

.field {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 7px 7px 7px 8px;
  background: #fff;
  border: 1px solid var(--c-line);
  border-radius: var(--r-pill);
  transition: border-color .2s ease, box-shadow .2s ease;
}

.field:focus-within {
  border-color: var(--c-green-bright);
  box-shadow: 0 0 0 4px rgba(31, 163, 71, .13);
}

.field__input {
  flex: 1 1 auto;
  min-width: 0;
  padding: 10px 12px;
  border: 0;
  background: transparent;
  font-size: .95rem;
  color: var(--c-heading);
}
.field__input::placeholder { color: var(--c-muted-soft); }
.field__input:focus { outline: none; }

.field .btn { flex: 0 0 auto; border-radius: var(--r-pill); }

/* ---------------------------------------------------- inline field note
   The small explanatory line under a form control. Shared by the settings
   sheets and the rewards claim form, so it lives here rather than in one
   page's stylesheet. */
.sheet__note {
  display: grid;
  grid-template-columns: 16px 1fr;
  align-items: start;
  gap: 9px;
  font-size: .76rem;
  line-height: 1.5;
  color: var(--c-muted-soft);
}
.sheet__note svg { width: 16px; height: 16px; margin-top: 1px; color: var(--c-green); }
.sheet__note--warn { color: #9A6206; }
.sheet__note--warn svg { color: var(--c-gold-deep); }

/* -------------------------------------------------------------- sheets
   A bottom sheet that rises over a blurred page and stops around half
   height. Used by settings and by the task board.
   -------------------------------------------------------------------- */

.sheet-scrim {
  position: fixed;
  inset: 0;
  z-index: 150;
  background: rgba(6, 32, 18, .42);
  /* The blur is what puts the page behind out of focus. */
  -webkit-backdrop-filter: blur(7px);
          backdrop-filter: blur(7px);
  opacity: 0;
  transition: opacity .28s ease;
}
.sheet-scrim.is-open { opacity: 1; }

.sheet {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 160;
  display: flex;
  flex-direction: column;
  /* Half the screen by default; taller only if the form needs it. */
  min-height: 50svh;
  max-height: 88svh;
  background: var(--c-surface);
  border-radius: 26px 26px 0 0;
  box-shadow: 0 -22px 60px -30px rgba(6, 32, 18, .6);
  transform: translateY(100%);
  transition: transform .34s cubic-bezier(.22, 1, .36, 1);
}
.sheet.is-open { transform: none; }

/* Reduced motion still needs the sheet to appear, just not to travel. */
@media (prefers-reduced-motion: reduce) {
  .sheet { transition: none; }
  .sheet-scrim { transition: none; }
}

.sheet__head {
  position: relative;
  flex: 0 0 auto;
  padding: 18px 52px 14px 20px;
  border-bottom: 1px solid var(--c-line-soft);
}

/* The drag handle every mobile sheet has. */
.sheet__grip {
  position: absolute;
  top: 8px;
  left: 50%;
  transform: translateX(-50%);
  width: 38px;
  height: 4px;
  border-radius: 999px;
  background: var(--c-line);
}

.sheet__title {
  font-size: 1.04rem;
  font-weight: 800;
  color: var(--c-heading);
}

.sheet__close {
  position: absolute;
  top: 14px;
  right: 14px;
  display: grid;
  place-items: center;
  width: 32px;
  height: 32px;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: var(--c-line-soft);
  color: var(--c-muted);
  transition: background-color .18s ease, color .18s ease;
}
.sheet__close svg { width: 16px; height: 16px; }
.sheet__close:hover { background: var(--c-line); color: var(--c-heading); }

/* The body scrolls, the header stays put. */
.sheet__body {
  flex: 1 1 auto;
  display: grid;
  /* One column that cannot grow past the sheet. Without the minmax this is an
     implicit `auto` column sized to its widest child, so a single over-wide row
     — a long account name, or the bank <select> sizing itself to its longest
     option — dragged every other row out past the padding with it. */
  grid-template-columns: minmax(0, 1fr);
  gap: 14px;
  align-content: start;
  padding: 18px 20px calc(24px + env(safe-area-inset-bottom, 0px));
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
}

/* Grid children default to min-width:auto, which refuses to shrink below their
   own content however narrow the column gets. This is what lets them. */
.sheet__body > * { min-width: 0; }

/* A <select> sizes itself to its longest option — the bank list is full of
   names like "Guaranty Trust Bank Limited" — so it is clamped to its field
   rather than being allowed to set the width of the sheet. */
.sheet__body .afield,
.sheet__body label { min-width: 0; }

.sheet__body select,
.sheet__body input,
.sheet__body textarea { max-width: 100%; }


.btn.sheet__submit { --btn-py: 15px; margin-top: 4px; border-radius: var(--r-sm); }

/* While a sheet is open the page behind must not scroll under it. */
body.is-sheet-open { overflow: hidden; }

/* ------------------------------------------------------ carousel dots */
/* Shared by the homepage carousels and the dashboard balance cards, so it
   lives here rather than in home.css. */
.dotnav { display: flex; align-items: center; gap: 7px; }

.dotnav button {
  width: 8px; height: 8px;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: rgba(0, 132, 42, .25);
  transition: width .28s ease, background-color .28s ease;
}

.dotnav button.is-active {
  width: 22px;
  border-radius: 999px;
  background: var(--c-green);
}

/* --------------------------------------------------- circular icon disc */

.disc {
  display: grid;
  place-items: center;
  flex: 0 0 auto;
  width: 34px;
  height: 34px;
  border-radius: 50%;
  background: var(--c-chip);
  color: var(--c-green);
}
.disc svg { width: 17px; height: 17px; }

.disc--gold { background: var(--c-gold-deep); color: #fff; }
.disc--solid { background: var(--c-green); color: #fff; }

/* =========================================================================
   Toasts — the single success / error surface, shared by every page.
   Fixed to the top-right, sliding in from off-screen. Saturated fills, not
   tinted pastels, so a failure is unmistakable at a glance.
   ====================================================================== */

.toasts {
  position: fixed;
  top: 16px;
  right: 16px;
  z-index: 200;
  display: flex;
  flex-direction: column;
  gap: 10px;
  width: min(360px, calc(100vw - 32px));
  pointer-events: none;
}

.toast {
  position: relative;
  display: grid;
  grid-template-columns: 22px 1fr 18px;
  align-items: center;
  gap: 11px;
  padding: 14px 14px 15px;
  border-radius: 12px;
  color: #fff;
  pointer-events: auto;
  overflow: hidden;
  box-shadow: 0 18px 40px -18px rgba(6, 32, 18, .55),
              0 2px 6px -2px rgba(6, 32, 18, .3);

  /* Runs on render, so a toast still animates with JavaScript disabled. */
  animation: toast-in .42s cubic-bezier(.22, 1, .36, 1) both;
}

@keyframes toast-in {
  from { transform: translateX(115%); opacity: 0; }
  to   { transform: none;             opacity: 1; }
}

.toast.is-out {
  animation: toast-out .3s cubic-bezier(.55, 0, .68, .2) both;
}

@keyframes toast-out {
  from { transform: none;             opacity: 1; max-height: 120px; }
  to   { transform: translateX(115%); opacity: 0; max-height: 0; }
}

.toast--success { background: linear-gradient(135deg, #00C853 0%, #009B3F 100%); --toast-ink: #00873A; }
.toast--error   { background: linear-gradient(135deg, #FF3B30 0%, #D91F11 100%); --toast-ink: #C9190D; }
.toast--info    { background: linear-gradient(135deg, #1FA347 0%, #00842A 100%); --toast-ink: #00742A; }

/* White disc, glyph in the toast's own colour. */
.toast__icon {
  display: grid;
  place-items: center;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  background: #fff;
}
.toast__icon svg {
  width: 14px;
  height: 14px;
  color: var(--toast-ink, #00742A);
}

.toast__text {
  font-size: .88rem;
  font-weight: 600;
  line-height: 1.45;
}

.toast__close {
  display: grid;
  place-items: center;
  width: 18px;
  height: 18px;
  padding: 0;
  border: 0;
  background: none;
  color: rgba(255, 255, 255, .75);
  transition: color .18s ease;
}
.toast__close svg { width: 14px; height: 14px; }
.toast__close:hover { color: #fff; }

/* Drains left to right for the life of the toast. */
.toast__timer {
  position: absolute;
  left: 0;
  bottom: 0;
  height: 3px;
  width: 100%;
  background: rgba(255, 255, 255, .45);
  transform-origin: left;
  animation: toast-timer 5s linear forwards;
}

@keyframes toast-timer {
  from { transform: scaleX(1); }
  to   { transform: scaleX(0); }
}

/* Hovering or focusing holds the toast open. */
.toast:hover .toast__timer,
.toast:focus-within .toast__timer { animation-play-state: paused; }

@media (prefers-reduced-motion: reduce) {
  .toast { animation: none; }
  .toast.is-out { animation: none; opacity: 0; }
  .toast__timer { animation-duration: 5s; }
}

@media (max-width: 599px) {
  .toasts { top: 10px; right: 10px; left: 10px; width: auto; }
}

/* -------------------------------------------------------- header actions
   The notifications + settings pair that sits at the right end of every
   header. The buttons keep their own page's *-hero__btn styling; this only
   groups them and hangs the unread dot.
   -------------------------------------------------------------------- */

.hero-acts {
  display: flex;
  align-items: center;
  gap: 2px;
  justify-self: end;
}

/* The dot is positioned against the button, so the button is the origin. */
.hero-acts__btn { position: relative; }

.hero-acts__dot {
  position: absolute;
  top: 6px;
  right: 6px;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--c-green-bright);
  /* On a dark hero the ring reads as a cut-out; on a white bar it separates
     the dot from the glyph. Same colour works for both because the ring is
     the surrounding surface either way. */
  box-shadow: 0 0 0 2px rgba(255, 255, 255, .9);
}

/* ------------------------------------------------------ profile picture */
/* avatar() is always an <img> now: the member's photo, or the default
   picture (img/profile.jpg) when they have not added one. Fill the circle
   and crop, whatever shape the uploaded photo is. */
img.avatar,
img.dash__avatar,
img.dash__greet-avatar,
img.phero__avatar,
img.pphoto__img,
img.inv-tree__avatar { object-fit: cover; }

/* =========================================================================
   Cookie notice (includes/cookie-notice.php)

   A card that rises from the bottom, not a bar across the top: a bar pushes
   the page down and the first thing a visitor sees becomes an argument about
   cookies. It sits over the corner on a wide screen and spans the bottom on a
   phone. Refusing costs exactly one tap, the same as accepting.
   ====================================================================== */

.ckn {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 120;
  display: flex;
  justify-content: flex-start;
  padding: 16px;
  padding-bottom: calc(16px + env(safe-area-inset-bottom, 0px));
  pointer-events: none;
}
.ckn[hidden] { display: none; }

@media (min-width: 720px) {
  .ckn { padding: 24px; }
}

.ckn__panel {
  pointer-events: auto;
  width: min(100%, 460px);
  padding: 20px;
  border: 1px solid rgba(255, 255, 255, .6);
  border-radius: 20px;
  background: rgba(255, 255, 255, .92);
  backdrop-filter: saturate(180%) blur(18px);
  -webkit-backdrop-filter: saturate(180%) blur(18px);
  box-shadow:
    0 28px 60px rgba(11, 59, 38, .22),
    0 4px 12px rgba(11, 59, 38, .08);
  transform: translateY(18px);
  opacity: 0;
  transition: transform .42s cubic-bezier(.2, .8, .25, 1), opacity .42s ease;
}

.ckn.is-in .ckn__panel { transform: none; opacity: 1; }
.ckn.is-out .ckn__panel { transform: translateY(18px); opacity: 0; }

.ckn__top { display: flex; gap: 14px; align-items: flex-start; }

.ckn__mark {
  flex: 0 0 auto;
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  border-radius: 14px;
  background: linear-gradient(150deg, #FFF6E2 0%, #FBE7BD 100%);
  box-shadow: inset 0 0 0 1px rgba(233, 169, 58, .35);
}
.ckn__mark svg { width: 26px; height: 26px; }

.ckn__words { min-width: 0; }

.ckn__title {
  margin: 0 0 5px;
  font-size: 1.02rem;
  font-weight: 800;
  color: var(--c-heading);
}

.ckn__text {
  margin: 0;
  font-size: .87rem;
  line-height: 1.6;
  color: var(--c-muted);
}
.ckn__text a { color: var(--c-green); font-weight: 700; }

/* ------------------------------------------------------- the toggles */

.ckn__choices {
  display: grid;
  gap: 2px;
  margin-top: 16px;
  padding-top: 14px;
  border-top: 1px solid var(--c-line);
}
.ckn__choices[hidden] { display: none; }

.ckn__row {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 2px;
  cursor: pointer;
}
.ckn__row--locked { cursor: default; }

.ckn__row-words { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.ckn__row-words strong { font-size: .88rem; font-weight: 700; color: var(--c-heading); }
.ckn__row-words small { font-size: .78rem; line-height: 1.45; color: var(--c-muted); }

.ckn__switch {
  flex: 0 0 auto;
  position: relative;
  width: 42px;
  height: 24px;
  border-radius: 999px;
  background: var(--c-line);
  transition: background .2s ease;
}
.ckn__switch i {
  position: absolute;
  top: 3px;
  left: 3px;
  width: 18px;
  height: 18px;
  border-radius: 50%;
  background: #fff;
  box-shadow: 0 1px 3px rgba(11, 59, 38, .3);
  transition: transform .2s cubic-bezier(.2, .8, .3, 1);
}
.ckn__switch.is-on { background: var(--c-green); }
.ckn__switch.is-on i { transform: translateX(18px); }
.ckn__switch.is-locked { background: var(--c-chip-ink); opacity: .55; }

/* The real checkbox is off-screen but still focusable; show that. */
.ckn__row input:focus-visible + .ckn__switch,
.ckn__row input:focus-visible ~ .ckn__switch {
  outline: 3px solid var(--c-green-bright);
  outline-offset: 2px;
}

/* -------------------------------------------------------- the buttons */

.ckn__acts {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 16px;
}

.ckn__btn {
  flex: 1 1 auto;
  min-height: 42px;
  padding: 10px 14px;
  border: 1px solid transparent;
  border-radius: 999px;
  font-family: inherit;
  font-size: .87rem;
  font-weight: 700;
  cursor: pointer;
  transition: background .18s ease, border-color .18s ease, color .18s ease;
}
.ckn__btn[hidden] { display: none; }

.ckn__btn--go { background: var(--c-green); color: #fff; }
.ckn__btn--go:hover { background: var(--c-green-deep); }

.ckn__btn--quiet { background: var(--c-surface-soft); color: var(--c-heading); border-color: var(--c-line); }
.ckn__btn--quiet:hover { background: var(--c-chip); }

.ckn__btn--ghost { flex: 0 0 auto; background: transparent; color: var(--c-muted); }
.ckn__btn--ghost:hover { color: var(--c-heading); background: var(--c-surface-soft); }

@media (prefers-reduced-motion: reduce) {
  .ckn__panel { transition: opacity .2s ease; transform: none; }
  .ckn.is-out .ckn__panel { transform: none; }
  .ckn__switch i { transition: none; }
}

/* Dark-ish surfaces behind it on some pages: keep the card readable. */
@media (prefers-color-scheme: dark) {
  .ckn__panel { background: rgba(255, 255, 255, .95); }
}

/* =========================================================================
   "All activities are limited!" — the scarcity line under a page's hero text
   (owner, 2026-10-05). Wording is theirs; it is not to be reworded.

   One rule for all four pages that carry it (surveys, tasks, train AI,
   WhatsApp Status), whose heroes do not agree on colour: some set white text
   on green, others dark text on white. So this carries its own solid
   background and ink rather than inheriting, and reads the same on either.
   It lives here because components.css is the sheet every page loads.
   ====================================================================== */

.hero-limited {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  margin: 7px 0 0;
  padding: 3px 8px;
  border-radius: 999px;
  /*
   * The palette's own chip green, not a colour of its own (owner, 2026-10-05:
   * the amber it started as fought every hero it sat on). These are the two
   * tokens the chips elsewhere on the site already use, so this reads as part
   * of the design rather than a sticker on top of it — on the white survey
   * hero and on the deep green ones alike.
   */
  background: var(--c-chip, #E8F3EA);
  color: var(--c-chip-ink, #1B8A3C);
  /*
   * Small enough to disturb nothing, on one line always. nowrap forbids the
   * wrap; the clamp is what makes that affordable, shrinking the text with
   * the screen so nowrap can never push the pill wider than the hero.
   */
  white-space: nowrap;
  font-size: clamp(.46rem, 2.1vw, .55rem);
  font-weight: 600;
  line-height: 1.45;
  letter-spacing: -.01em;
}
