*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }

:root {
  --brand:    #2E7D32;
  --brand-dk: #1B5E20;
  --success:  #16a34a;
  --warn:     #d97706;
  --danger:   #dc2626;
  --bg:       #F5F5F5;
  --surface:  #ffffff;
  --border:   #e2e8f0;
  --text:     #1e293b;
  --muted:    #64748b;
  --radius:   10px;
}

body { font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif; background: var(--bg); color: var(--text); min-height: 100vh; }

a { color: var(--brand); text-decoration: none; }

/* ── Layout ── */
.page-center { min-height: 100vh; display: flex; align-items: center; justify-content: center; padding: 24px; }
.card        { background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius); padding: 32px; width: 100%; max-width: 440px; box-shadow: 0 1px 3px rgba(0,0,0,.06); }
.card-wide   { max-width: 820px; }
.card-full   { max-width: 100%; }

header.top-bar {
  background: var(--surface);
  border-bottom: 1px solid var(--border);
  padding: 0 24px;
  height: 60px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  position: sticky; top: 0; z-index: 10;
}
.top-bar .logo {
  font-size: 15px; font-weight: 700; color: var(--brand);
  display: flex; align-items: center; gap: 8px;
  min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.top-bar .phase-badge { font-size: 12px; background: #e8f5e9; color: var(--brand); padding: 3px 10px; border-radius: 20px; font-weight: 600; }

/* ── Notification bell ── */
.notif-wrap { position: relative; margin-left: auto; margin-right: 10px; }
/* .notif-badge is a child of #notif-bell-btn, not of .notif-wrap - without this, its
   position:absolute skips the (unpositioned) button and anchors to .notif-wrap instead,
   which is fine only by coincidence when the two boxes happen to match. */
#notif-bell-btn { position: relative; }
.notif-badge { position: absolute; top: -4px; right: -4px; min-width: 16px; height: 16px; padding: 0 3px; border-radius: 10px; background: var(--danger); color: #fff; font-size: 10px; font-weight: 700; display: flex; align-items: center; justify-content: center; }
/* width:320px alone overflows off-screen at narrow viewports (320px wide, minus the
   header's own 24px side padding, leaves less room than the panel's fixed width) -
   max-width caps it to whatever the viewport actually has, with a small margin either
   side, so it can never clip. */
.notif-panel { position: absolute; top: calc(100% + 8px); right: 0; width: 320px; max-width: calc(100vw - 32px); max-height: 400px; background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius); box-shadow: 0 8px 24px rgba(0,0,0,.12); overflow: hidden; z-index: 20; display: flex; flex-direction: column; }
.notif-panel-header { display: flex; align-items: center; justify-content: space-between; padding: 12px 16px; border-bottom: 1px solid var(--border); font-size: 13px; font-weight: 700; }
.btn-link { background: none; border: none; color: var(--brand); font-size: 12px; font-weight: 600; cursor: pointer; padding: 0; }
.notif-list { overflow-y: auto; }
.notif-item { padding: 12px 16px; border-bottom: 1px solid var(--border); cursor: pointer; }
.notif-item:last-child { border-bottom: none; }
.notif-item:hover { background: #f5f5f5; }
.notif-item.notif-unread { background: #e8f5e9; }
.notif-title { font-size: 13px; font-weight: 700; }
.notif-body { font-size: 12px; color: var(--muted); margin-top: 2px; }
.notif-time { font-size: 11px; color: var(--muted); margin-top: 4px; }

.main-content { max-width: 900px; margin: 0 auto; padding: 32px 24px; }

/* ── Bottom nav (rep app) ── */
.bottom-nav { position: sticky; bottom: 0; background: var(--surface); border-top: 1px solid var(--border); display: flex; z-index: 10; }
.bottom-nav a { flex: 1; text-align: center; padding: 10px 4px 8px; font-size: 11px; color: var(--muted); display: flex; flex-direction: column; align-items: center; gap: 2px; }
.bottom-nav a.active { color: var(--brand); font-weight: 700; }

/* ── Typography ── */
h1 { font-size: 22px; font-weight: 700; }
h2 { font-size: 17px; font-weight: 600; margin-bottom: 4px; }
.subtitle { font-size: 13px; color: var(--muted); margin-top: 4px; }
.label { font-size: 12px; font-weight: 600; color: var(--muted); text-transform: uppercase; letter-spacing: .04em; margin-bottom: 6px; display: block; }

/* ── Inputs ── */
.input, select.input, textarea.input {
  width: 100%; padding: 10px 12px; font-size: 14px;
  border: 1px solid var(--border); border-radius: 8px;
  background: #fff; color: var(--text);
  transition: border-color .15s, box-shadow .15s;
  font-family: inherit;
}
.input:focus { outline: none; border-color: var(--brand); box-shadow: 0 0 0 3px rgba(46,125,50,.12); }
.form-group { margin-bottom: 16px; }
.form-row   { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
.field-error { font-size: 12px; color: var(--danger); margin-top: 4px; }

/* ── Buttons ── */
.btn { display: inline-flex; align-items: center; gap: 6px; padding: 10px 20px; font-size: 14px; font-weight: 600; border-radius: 8px; border: none; cursor: pointer; transition: opacity .15s, transform .1s; }
.btn:active { transform: scale(.98); }
.btn:disabled { opacity: .5; cursor: not-allowed; }
.btn-primary   { background: var(--brand);   color: #fff; }
.btn-primary:hover   { background: var(--brand-dk); }
.btn-success   { background: var(--success); color: #fff; }
.btn-danger    { background: var(--danger);  color: #fff; }
.btn-outline   { background: #fff; color: var(--text); border: 1px solid var(--border); }
.btn-outline:hover { border-color: var(--brand); color: var(--brand); }
.btn-sm        { padding: 6px 14px; font-size: 13px; }
.btn-icon      { padding: 7px; border-radius: 6px; justify-content: center; }
.btn-block     { width: 100%; justify-content: center; }

/* ── Status badges ── */
.badge { display: inline-flex; align-items: center; gap: 4px; padding: 3px 10px; border-radius: 20px; font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: .04em; }
.badge-awaiting_applicant { background: #fef9c3; color: #a16207; }
.badge-submitted          { background: #dbeafe; color: #1d4ed8; }
.badge-approved           { background: #dcfce7; color: #15803d; }
.badge-executed           { background: #dcfce7; color: #15803d; }
.badge-rejected           { background: #fee2e2; color: #b91c1c; }
.badge-disputed           { background: #fee2e2; color: #b91c1c; }
.badge-cancelled          { background: #f1f5f9; color: #64748b; }

/* ── Stat cards ── */
.stats-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); gap: 16px; margin-bottom: 28px; }
.stat-card  { background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius); padding: 20px; }
.stat-value { font-size: 32px; font-weight: 800; line-height: 1; }
.stat-label { font-size: 12px; color: var(--muted); margin-top: 4px; }
.stat-card.vacant   { border-color: #fed7aa; }
.stat-card.occupied { border-color: #bfdbfe; }
.stat-card.paid     { border-color: #bbf7d0; }
.stat-card.unpaid   { border-color: #fecaca; }

/* ── Table / List ── */
.table-wrap  { overflow-x: auto; }
table        { width: 100%; border-collapse: collapse; font-size: 13px; }
th           { text-align: left; padding: 10px 12px; font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: .05em; color: var(--muted); border-bottom: 2px solid var(--border); background: #f5f5f5; }
td           { padding: 11px 12px; border-bottom: 1px solid var(--border); vertical-align: middle; }
tr:last-child td { border-bottom: none; }
tr:hover td  { background: #f5f5f5; }

/* ── Household list item ── */
.hh-item { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 14px 0; border-bottom: 1px solid var(--border); cursor: pointer; }
.hh-item:last-child { border-bottom: none; }
.hh-number { font-weight: 700; font-size: 15px; }
.hh-meta   { flex: 1; }
.hh-meta .street { font-size: 13px; color: var(--muted); }
.hh-right  { text-align: right; font-size: 13px; color: var(--muted); }

/* ── Occupant repeater ── */
.occupant-row { display: grid; grid-template-columns: 1fr 1fr 28px; gap: 8px; align-items: center; margin-bottom: 8px; }
.btn-remove   { color: var(--danger); background: none; border: none; cursor: pointer; font-size: 18px; padding: 0 4px; }

/* ── Alert ── */
.alert { padding: 12px 16px; border-radius: 8px; font-size: 13px; margin-bottom: 16px; }
.alert-info    { background: #eff6ff; border: 1px solid #bfdbfe; color: #1d4ed8; }
.alert-success { background: #f0fdf4; border: 1px solid #bbf7d0; color: #166534; }
.alert-warn    { background: #fffbeb; border: 1px solid #fde68a; color: #92400e; }
.alert-danger  { background: #fff1f2; border: 1px solid #fecdd3; color: #9f1239; }

/* ── Spinner ── */
.spinner { width: 20px; height: 20px; border: 2px solid var(--border); border-top-color: var(--brand); border-radius: 50%; animation: spin .6s linear infinite; display: inline-block; vertical-align: middle; }
@keyframes spin { to { transform: rotate(360deg); } }

/* ── Toast ── */
#toast-container { position: fixed; bottom: 24px; right: 24px; display: flex; flex-direction: column; gap: 8px; z-index: 9999; }
.toast { padding: 12px 18px; border-radius: 8px; font-size: 13px; font-weight: 500; color: #fff; box-shadow: 0 4px 12px rgba(0,0,0,.15); animation: toast-in .2s ease; }
.toast-success { background: var(--success); }
.toast-error   { background: var(--danger); }
.toast-info    { background: var(--brand); }
@keyframes toast-in { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: translateY(0); } }

/* ── Section header ──
   width:100% on .section-hdr alone wasn't enough - same underlying issue as header.top-bar/
   .bottom-nav (a display:flex element with an explicit width doesn't reliably expand in this
   rendering context). Same fix: plain block outer, flex row moved to an inner wrapper. */
.section-hdr { width: 100%; margin-bottom: 16px; }
.section-hdr-row { display: flex; align-items: center; justify-content: space-between; width: 100%; }

/* ── Photo preview ── */
.photo-preview { width: 96px; height: 96px; border-radius: 8px; object-fit: cover; border: 1px solid var(--border); }

/* ── Empty state ── */
.empty-state { text-align: center; padding: 60px 20px; color: var(--muted); }
.empty-state p { font-size: 14px; margin-top: 8px; }

.hidden { display: none !important; }
.mt-4 { margin-top: 16px; }
.mt-2 { margin-top: 8px; }
.mb-4 { margin-bottom: 16px; }
.gap-2 { gap: 8px; }
.flex { display: flex; align-items: center; }
.flex-wrap { flex-wrap: wrap; }
.justify-between { justify-content: space-between; }
.text-sm { font-size: 13px; }
.text-muted { color: var(--muted); }
.w-full { width: 100%; }

/* ── Responsive ── */
@media (max-width: 600px) {
  .form-row { grid-template-columns: 1fr; }
  .main-content { padding: 16px; }
  .input, select.input, textarea.input { font-size: 16px; }
  .occupant-row { grid-template-columns: 1fr 1fr 28px; }
}

/* ─────────────────────────────────────────────────────────────────────────
   Native App Shell
   header.top-bar and .bottom-nav are position:fixed, pinned to the viewport
   edges unconditionally - not sticky (which only locks a last-child element
   like .bottom-nav into place once you've scrolled all the way to the end
   of the content, leaving it hidden while scrolling through anything
   longer than one screen) and not the old fixed-height flex-column +
   overflow:hidden shell (which relied on 100dvh/--app-height exactly
   matching the true visible viewport - across three separate fix attempts
   it never reliably did, on Android Chrome and iOS Safari alike, and any
   mismatch meant .bottom-nav rendered below the visible area with no way
   to scroll to it). position:fixed needs no viewport-height measurement at
   all; body/html scroll normally, and .main-content reserves padding at
   top/bottom so real content never renders underneath the fixed bars.
   ───────────────────────────────────────────────────────────────────────── */
:root {
  --safe-top: env(safe-area-inset-top, 0px);
  --safe-bottom: env(safe-area-inset-bottom, 0px);
  --header-height: 60px;
  --nav-height: 58px;
}

* { -webkit-tap-highlight-color: transparent; }

/* Suppresses double-tap-to-zoom (and the ~300ms tap delay) on interactive elements, without
   touching deliberate pinch-zoom - the narrower middle ground between blocking zoom outright
   (an accessibility regression, since this app has no other text-scaling mechanism) and
   leaving double-tap free to misfire during quick repeated taps on buttons/cards. */
button, a, input, select, textarea, .hh-item, .list-item-card {
  touch-action: manipulation;
}

/* Chrome (nav, buttons, cards, headings) shouldn't highlight/select like page text on a
   tap-and-hold; form inputs still need normal text selection for editing. */
header.top-bar, .bottom-nav, .btn, .stat-card, .hh-item, .list-item-card,
.action-tile, .sheet-handle, h1, h2, .section-hdr, .tab-item {
  -webkit-user-select: none;
  user-select: none;
}
input, textarea, select { -webkit-user-select: text; user-select: text; }

/* Centering header.top-bar itself via max-width+margin:auto (as a flex item of body) didn't
   reliably clamp its rendered width in practice - it kept spanning full viewport width on
   desktop despite the rule being present and deployed. Switched to the same technique
   .main-content already uses successfully: the outer element stays a plain full-width,
   fixed-position box, and a normal inner wrapper carries the max-width + margin:auto
   centering, exactly the way .main-content itself centers. */
header.top-bar {
  position: fixed;
  top: 0;
  z-index: 10;
  height: auto;
  width: 100%;
  padding: 0;
  display: block;
}
.top-bar-inner {
  width: 100%;
  max-width: 900px;
  margin: 0 auto;
  min-height: var(--header-height);
  padding: 0 24px;
  padding-top: max(0px, var(--safe-top));
  display: flex;
  align-items: center;
  justify-content: space-between;
}

.main-content, .page-center {
  width: 100%;
  box-sizing: border-box;
}
/* Centering .main-content via max-width+margin:auto (like the original rule at the top of
   this file does) was unreliable in practice, the same issue that affected
   header.top-bar/.bottom-nav/.section-hdr. Cancel that out and center via calculated padding
   instead, which doesn't depend on auto-margin resolution at all: padding grows past the
   24px floor only once the viewport is wider than 900px+48px, pinching the content to a
   900px column exactly like max-width:900px would, but through arithmetic that can't be
   silently ignored. Top/bottom padding additionally clears the fixed header/nav bars, with a
   little slack built in since (unlike the old exact-height shell) a slightly-too-generous
   value here just leaves a small gap - it can never hide the nav itself. */
.main-content {
  max-width: none;
  margin: 0;
  padding: 32px max(24px, calc((100% - 900px) / 2));
  padding-top: calc(var(--header-height) + var(--safe-top) + 24px);
  padding-bottom: calc(var(--nav-height) + var(--safe-bottom) + 24px);
}
/* #stepper's own margin-top already clears the fixed header (see .stepper-bar above) -
   when it's visible and sits right before .main-content in normal flow, the header
   has already been cleared once; repeating the same clearance here just adds a large,
   unnecessary gap between the stepper and the form below it. Matches the #stepper +
   .main-content selector's own specificity in the narrow-screen override below, so
   each width picks up its own smaller value instead of this one unconditionally
   winning via the ID selector's higher specificity. */
#stepper:not(.hidden) + .main-content {
  padding-top: 24px;
}
@media (max-width: 600px) {
  /* Restates the original narrow-screen padding - it lived in the earlier @media block
     (line ~189), but this later, unconditional .main-content rule would otherwise always
     win over it regardless of viewport width, since source order breaks the specificity
     tie without regard for which media query currently matches. */
  .main-content {
    padding: 16px;
    padding-top: calc(var(--header-height) + var(--safe-top) + 16px);
    padding-bottom: calc(var(--nav-height) + var(--safe-bottom) + 16px);
  }
  #stepper:not(.hidden) + .main-content {
    padding-top: 16px;
  }
}
/* ── Bottom tab bar - icon + label, capped at 4-5 primary destinations.
   Move-in/Move-out/New unit moved to the FAB's Quick Actions sheet. ── */
.bottom-nav {
  position: fixed;
  bottom: 0;
  width: 100%;
  display: block;
}
.bottom-nav-inner {
  width: 100%;
  max-width: 900px;
  margin: 0 auto;
  display: flex;
  padding: 6px 0 max(6px, var(--safe-bottom));
  min-height: var(--nav-height);
}
.bottom-nav a {
  min-height: 48px;
  justify-content: center;
  font-size: 10.5px;
  gap: 3px;
  transition: transform .1s ease;
}
.bottom-nav a i { font-size: 19px; }
.bottom-nav a:active { transform: scale(0.94); }

/* Forms reached via the FAB sheet (and apply.html, the standalone applicant form) drop the
   tab bar - their submit button sits in a fixed footer instead, pinned the same way
   .bottom-nav is and for the same reason (see the Native App Shell note above). */
.app-footer-actions {
  position: fixed;
  bottom: 0;
  left: 0;
  right: 0;
  z-index: 10;
  background: var(--surface);
  border-top: 1px solid var(--border);
  padding: 12px 16px max(12px, var(--safe-bottom));
  width: 100%;
  max-width: 900px;
  margin: 0 auto;
  box-sizing: border-box;
}

/* ── Touch targets (44-48px minimum) & tap feedback ── */
.btn      { min-height: 44px; }
.btn-sm   { min-height: 44px; }
.btn-icon { min-height: 44px; min-width: 44px; }
.hh-item, .list-item-card { min-height: 56px; }
.hh-item:active, .list-item-card:active, .action-tile:active { transform: scale(0.98); background: #f5f5f5; }
.input[readonly] { background: #f1f5f9; color: var(--muted); cursor: not-allowed; }

/* ── List item card - replaces <table> rows for mobile (dashboard defaulters/collections) ── */
.list-item-card {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px 4px;
  border-bottom: 1px solid var(--border);
  transition: transform .1s ease, background .1s ease;
}
.list-item-card:last-child { border-bottom: none; }
.list-icon {
  width: 40px; height: 40px; border-radius: 10px; flex-shrink: 0;
  display: flex; align-items: center; justify-content: center; font-size: 16px;
}
.list-icon.danger { background: #fee2e2; color: var(--danger); }
.list-icon.brand  { background: #e8f5e9; color: var(--brand); }
.list-main  { flex: 1; min-width: 0; }
.list-title { font-weight: 600; font-size: 14.5px; }
.list-sub   { font-size: 12.5px; color: var(--muted); margin-top: 2px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.list-meta  { text-align: right; flex-shrink: 0; }
.list-value { font-weight: 700; font-size: 14.5px; }
.list-tag   { display: inline-block; font-size: 10.5px; font-weight: 700; padding: 2px 7px; border-radius: 6px; margin-top: 3px; background: #fef3c7; color: #b45309; }

/* ── Floating Action Button ── */
.fab-btn {
  position: fixed;
  /* On viewports wider than the app's centered 900px column, track the column's right edge
     instead of the browser's - otherwise the FAB floats disconnected from the content next
     to it. max() falls back to the plain 18px inset on any narrower/mobile viewport, where
     50vw - 450px is negative. */
  right: max(18px, calc(50vw - 450px + 18px));
  bottom: calc(var(--nav-height) + 12px + var(--safe-bottom));
  width: 56px; height: 56px;
  border-radius: 28px;
  background: var(--brand);
  color: #fff;
  display: flex; align-items: center; justify-content: center;
  font-size: 22px;
  border: none;
  box-shadow: 0 6px 16px rgba(46,125,50,.35);
  z-index: 30;
  cursor: pointer;
  transition: transform .1s ease;
}
.fab-btn:active { transform: scale(0.92); }

/* ── iOS-style bottom sheet (Quick Actions, shared across pages) ── */
.sheet-backdrop {
  position: fixed; inset: 0;
  background: rgba(15,23,42,.45);
  z-index: 1000;
  opacity: 0; pointer-events: none;
  transition: opacity .25s ease;
}
.sheet-backdrop.active { opacity: 1; pointer-events: auto; }

.bottom-sheet {
  position: fixed; left: 0; right: 0; bottom: 0;
  width: 100%;
  max-width: 900px;
  margin: 0 auto;
  background: var(--surface);
  border-radius: 22px 22px 0 0;
  padding-bottom: max(20px, var(--safe-bottom));
  z-index: 1001;
  transform: translateY(100%);
  transition: transform .3s cubic-bezier(.16,1,.3,1);
  box-shadow: 0 -8px 30px rgba(0,0,0,.18);
  max-height: 80vh;
  display: flex; flex-direction: column;
}
.bottom-sheet.active    { transform: translateY(0); }
.bottom-sheet.dragging  { transition: none; }

.sheet-handle-bar { display: flex; justify-content: center; padding: 10px 0 2px; flex-shrink: 0; }
.sheet-handle { width: 36px; height: 5px; background: var(--border); border-radius: 3px; }

.sheet-header {
  display: flex; align-items: center; justify-content: space-between;
  padding: 8px 20px 14px; border-bottom: 1px solid var(--border); flex-shrink: 0;
}
.sheet-title { font-weight: 700; font-size: 16px; }
.sheet-close-btn {
  background: #f1f5f9; border: none; width: 32px; height: 32px; border-radius: 50%;
  color: var(--muted); display: flex; align-items: center; justify-content: center; cursor: pointer;
}
.sheet-body { padding: 16px 20px; overflow-y: auto; }

.action-tile {
  display: flex; align-items: center; gap: 14px;
  padding: 14px 16px; min-height: 60px;
  background: #f5f5f5; border-radius: 14px;
  text-decoration: none; color: inherit;
  margin-bottom: 10px;
  transition: background .15s ease, transform .1s ease;
}
.action-tile:last-child { margin-bottom: 0; }
.action-icon {
  width: 44px; height: 44px; border-radius: 12px; flex-shrink: 0;
  display: flex; align-items: center; justify-content: center; font-size: 18px;
}
.action-icon.icon-brand   { background: #e8f5e9; color: var(--brand); }
.action-icon.icon-warn    { background: #ffedd5; color: #ea580c; }
.action-icon.icon-success { background: #d1fae5; color: #059669; }
.action-title { font-weight: 600; font-size: 14.5px; }
.action-sub   { font-size: 12px; color: var(--muted); margin-top: 2px; }
.action-arrow { color: #94a3b8; font-size: 13px; margin-left: auto; flex-shrink: 0; }

/* ── Applicant wizard (apply.html) - section cards, stepper, identity card ── */
.section-card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 16px;
  padding: 18px;
  margin-bottom: 14px;
}
.section-card h2 { font-size: 15px; margin-bottom: 4px; }
.section-card .desc { font-size: 12.5px; color: var(--muted); margin-bottom: 14px; }

.stepper-bar {
  display: flex; gap: 8px; padding: 10px 16px;
  background: var(--surface); border-bottom: 1px solid var(--border);
  flex-shrink: 0;
  width: 100%;
  max-width: 900px;
  /* header.top-bar is position:fixed (out of flow), so #stepper - which sits right after
     it in apply.html, before .main-content's own top padding ever applies - would
     otherwise render at y=0, hidden underneath the header. */
  margin: calc(var(--header-height) + var(--safe-top)) auto 0;
}
.step-pill { flex: 1; height: 4px; background: var(--border); border-radius: 2px; transition: background .25s ease; }
.step-pill.active    { background: var(--brand); }
.step-pill.completed { background: var(--success); }

.form-step { display: none; }
.form-step.active { display: block; animation: stepFadeIn .2s ease; }
@keyframes stepFadeIn { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }

.identity-card {
  background: #e8f5e9; border: 1px solid #c8e6c9; border-radius: 14px;
  padding: 14px; display: flex; align-items: center; gap: 12px; margin-top: 14px;
}
.identity-avatar { width: 52px; height: 52px; border-radius: 50%; object-fit: cover; background: #e8f5e9; border: 2px solid #fff; flex-shrink: 0; }
.identity-info { flex: 1; min-width: 0; }
.identity-name { font-weight: 700; font-size: 14.5px; color: var(--brand-dk); }
.identity-meta { font-size: 12px; color: var(--brand); margin-top: 2px; }

.dynamic-list { display: flex; flex-direction: column; gap: 8px; margin-bottom: 10px; }
.dynamic-row { display: flex; align-items: center; gap: 8px; background: #f5f5f5; border: 1px solid var(--border); border-radius: 12px; padding: 8px 10px; }
.dynamic-row .input, .dynamic-row .flex .input { height: 40px; font-size: 13.5px; background: #fff; min-width: 0; }
.btn-add {
  width: 100%; min-height: 44px; background: #e8f5e9; color: var(--brand);
  border: 1px dashed #c8e6c9; border-radius: 12px; font-weight: 600; font-size: 13.5px;
  display: flex; align-items: center; justify-content: center; gap: 8px; cursor: pointer;
}
.btn-remove {
  min-width: 32px; min-height: 32px; border-radius: 8px; flex-shrink: 0;
  background: #fee2e2; color: var(--danger); border: none;
  display: flex; align-items: center; justify-content: center; font-size: 15px; cursor: pointer;
}

.attest-card { background: #f5f5f5; border: 1px solid var(--border); border-radius: 12px; padding: 14px; display: flex; gap: 12px; align-items: flex-start; }
.attest-card input[type="checkbox"] { width: 22px; height: 22px; accent-color: var(--brand); margin-top: 2px; flex-shrink: 0; }
.attest-card span { font-size: 12.5px; color: var(--muted); line-height: 1.45; }

/* ── Live input validation (NIN / phone / email) ── */
.input-wrapper { position: relative; }
.input-wrapper .input { padding-right: 34px; }
.input-icon { position: absolute; right: 12px; top: 50%; transform: translateY(-50%); font-size: 14px; pointer-events: none; }
.input.is-valid   { border-color: var(--success) !important; background: #f0fdf4 !important; }
.input.is-invalid { border-color: var(--danger)  !important; background: #fef2f2 !important; }
.input-icon.valid-icon   { color: var(--success); }
.input-icon.invalid-icon { color: var(--danger); }
.field-error-text { font-size: 11.5px; color: var(--danger); margin-top: 4px; display: none; }
.field-error-text.show { display: block; }
