/* ============================================================
   components.css — Sylheti Shadi Shared UI Components

   Home for reusable component styles: buttons, cards, forms,
   navigation, etc. Uses CSS variables from design-system.css.

   Usage:  Load AFTER design-system.css (variables must be defined
           before they can be referenced).

             <link rel="stylesheet" href="assets/css/design-system.css">
             <link rel="stylesheet" href="assets/css/components.css">

   Fill order: sections are filled as pages adopt shared components.
   Phase 3 Step 1 (this file): base reset, utilities, top nav,
   bottom nav, footer. Buttons/cards/forms/badges come in Step 2.
   ============================================================ */


/* ============================================================
   RESET & BASE
   ============================================================ */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }

html, body { max-width: 100vw; overflow-x: hidden; }

body {
  font-family: var(--font-bengali);
  background: var(--color-cream);
  color: var(--color-text);
  line-height: var(--leading-normal);
  min-height: 100vh;
  /* Offset fixed top header (72px) and bottom nav (mobile only). Bottom
     nav is anchored to bottom: 0 with internal padding-bottom that
     absorbs the iOS safe-area inset (post–real-device polish, May 2026).
     100px reservation is enough to clear the visible nav body even on
     iPhone Safari where the home indicator pushes content up ~34px —
     the safe-area is paid for inside the nav, not below it, so body
     padding-bottom does not need to double-count it. Desktop has no
     bottom nav (hidden ≥768px) so the bottom padding is wasted there
     but harmless. */
  padding-top: 72px;
  padding-bottom: 100px;
}
@media (min-width: 768px) {
  /* Desktop: no bottom-nav, so no need for the bottom padding reservation. */
  body { padding-bottom: 24px; }
}

body.en { font-family: var(--font-body); }
body.en .display-font { font-family: var(--font-heading); }

a { color: inherit; text-decoration: none; }
ul { list-style: none; }
button { font-family: inherit; color: inherit; }
img { max-width: 100%; display: block; }


/* ============================================================
   LAYOUT UTILITIES
   .container, .skip-link
   ============================================================ */
.container {
  width: 100%;
  max-width: 1200px;
  margin-inline: auto;
  padding-inline: var(--space-4);
}

/* Skip link: visually hidden off-screen until focused by keyboard/SR. */
.skip-link {
  position: absolute;
  top: -48px;
  left: var(--space-4);
  z-index: calc(var(--z-fixed-header) + 1);
  background: var(--color-green);
  color: var(--color-text-on-dark);
  padding: var(--space-2) var(--space-4);
  border-radius: var(--radius-md);
  font-weight: var(--weight-semibold);
  transition: top var(--transition-fast);
}
.skip-link:focus { top: var(--space-2); outline: none; }

/* Stack — vertical rhythm between children. Replaces long lists of
   .mb-* margins with a single parent class. */
.stack   > * + * { margin-top: var(--space-4); }
.stack-sm > * + * { margin-top: var(--space-2); }
.stack-lg > * + * { margin-top: var(--space-6); }

/* Horizontal flex row. .row-between pushes first/last children apart. */
.row          { display: flex; align-items: center; gap: var(--space-3); }
.row-between  { display: flex; align-items: center; justify-content: space-between; gap: var(--space-3); }

/* Responsive grids — collapse to 1 column on mobile. */
.grid-2 { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-4); }
.grid-3 { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--space-4); }
.grid-4 { display: grid; grid-template-columns: repeat(4, 1fr); gap: var(--space-4); }
@media (max-width: 767px) {
  .grid-2, .grid-3, .grid-4 { grid-template-columns: 1fr; }
}
@media (min-width: 768px) and (max-width: 1023px) {
  .grid-3, .grid-4 { grid-template-columns: repeat(2, 1fr); }
}

/* Visibility helpers */
.hidden { display: none !important; }
@media (max-width: 767px)                          { .hidden-mobile  { display: none !important; } }
@media (min-width: 768px) and (max-width: 1023px)  { .hidden-tablet  { display: none !important; } }
@media (min-width: 1024px)                         { .hidden-desktop { display: none !important; } }


/* ============================================================
   BUTTONS
   .btn (base), .btn-primary / .btn-secondary / .btn-ghost / .btn-danger,
   size: .btn-sm / .btn-lg, block: .btn-block
   ============================================================ */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  padding: var(--space-3) var(--space-5);
  border: 1.5px solid transparent;
  border-radius: var(--radius-pill);
  font-family: inherit;
  font-size: var(--text-sm);
  font-weight: var(--weight-semibold);
  line-height: 1;
  text-decoration: none;
  cursor: pointer;
  transition: background var(--transition-fast),
              color var(--transition-fast),
              border-color var(--transition-fast),
              box-shadow var(--transition-fast),
              transform var(--transition-fast);
  user-select: none;
  white-space: nowrap;
}
.btn:disabled,
.btn[aria-disabled="true"] { opacity: 0.5; cursor: not-allowed; pointer-events: none; }
.btn:focus-visible { outline: none; box-shadow: var(--shadow-focus); }

/* Primary — solid green, main CTA. Subtle elevation for conversion surfaces. */
.btn-primary {
  background: var(--color-green);
  color: var(--color-text-on-dark);
  box-shadow: 0 4px 14px rgba(26, 93, 58, 0.20);
}
.btn-primary:hover {
  background: var(--color-green-dark);
  transform: translateY(-1px);
  box-shadow: 0 8px 22px rgba(26, 93, 58, 0.28);
}
.btn-primary:active { transform: translateY(0); box-shadow: 0 2px 8px rgba(26, 93, 58, 0.18); }

/* Secondary — outline, pairs with primary for secondary CTA. */
.btn-secondary {
  background: transparent;
  color: var(--color-green);
  border-color: var(--color-green);
}
.btn-secondary:hover {
  background: var(--color-green);
  color: var(--color-text-on-dark);
}

/* Ghost — minimal text-only. Cancel / back / "Skip" actions. */
.btn-ghost {
  background: transparent;
  color: var(--color-green);
}
.btn-ghost:hover { background: rgba(26, 93, 58, 0.08); }

/* Danger — destructive actions (delete photo, close account). */
.btn-danger {
  background: var(--color-error);
  color: var(--color-text-on-dark);
}
.btn-danger:hover { background: #b91c1c; }

/* Size modifiers */
.btn-sm { padding: var(--space-2) var(--space-4); font-size: var(--text-xs); }
.btn-lg { padding: var(--space-4) var(--space-6); font-size: var(--text-base); }

/* Full-width (flex required so block buttons still honor justify-content). */
.btn-block { display: flex; width: 100%; }


/* ============================================================
   CARDS
   .card (base), .card-body / .card-body-sm / .card-body-lg,
   .card-header / .card-footer, .card-title / .card-sub
   ============================================================ */
.card {
  background: var(--color-white);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-md);
  overflow: hidden;  /* clip inner elements to rounded corners */
}

.card-body    { padding: var(--space-6); }
.card-body-sm { padding: var(--space-4); }
.card-body-lg { padding: var(--space-8); }

.card-header {
  padding: var(--space-5) var(--space-6);
  border-bottom: 1px solid var(--color-border);
}
.card-footer {
  padding: var(--space-5) var(--space-6);
  border-top: 1px solid var(--color-border);
  background: var(--color-bg-muted);
}

.card-title {
  font-size: var(--text-xl);
  font-weight: var(--weight-bold);
  color: var(--color-green);
  margin-bottom: var(--space-2);
}
body.en .card-title { font-family: var(--font-heading); }

.card-sub {
  font-size: var(--text-sm);
  color: var(--color-text-muted);
  margin-bottom: var(--space-5);
}

@media (max-width: 767px) {
  .card-body    { padding: var(--space-5); }
  .card-body-lg { padding: var(--space-6); }
  .card-header,
  .card-footer  { padding: var(--space-4) var(--space-5); }
}


/* ============================================================
   FORMS & INPUTS
   .field (wrapper), .field-label / .field .req, .field input/select/
   textarea (bare selectors), .field-error / .field-helper,
   .field.has-error (error state)
   ============================================================ */
.field { margin-bottom: var(--space-4); }
.field:last-child { margin-bottom: 0; }

.field-label,
.field label {
  display: block;
  font-size: var(--text-sm);
  font-weight: var(--weight-semibold);
  color: var(--color-text);
  margin-bottom: var(--space-2);
}
.field-label .req,
.field label .req {
  color: var(--color-error);
  margin-left: 2px;
}

/* Base input styling — applies to all .field form controls.
   Bare selectors so existing markup <input type="..."> just works. */
.field input[type="text"],
.field input[type="email"],
.field input[type="tel"],
.field input[type="password"],
.field input[type="number"],
.field input[type="date"],
.field input[type="search"],
.field input[type="url"],
.field select,
.field textarea {
  width: 100%;
  padding: 13px 16px;
  /* Phase 4.5 — bumped from var(--text-sm) (14px) to var(--text-base) (16px)
     to prevent iOS Safari auto-zoom on focus. Inputs below 16px trigger a
     viewport zoom that's hard to recover from on smaller phones — affected
     register, login, forgot-password, settings, complete-profile, etc. */
  font-size: var(--text-base);
  font-family: inherit;
  color: var(--color-text);
  background: var(--color-cream);
  border: 1.5px solid var(--color-border);
  border-radius: var(--radius-md);
  outline: none;
  transition: border-color var(--transition-fast),
              background var(--transition-fast),
              box-shadow var(--transition-fast);
}
.field textarea {
  resize: vertical;
  min-height: 110px;
  line-height: var(--leading-normal);
}

.field input:focus,
.field select:focus,
.field textarea:focus {
  border-color: var(--color-green);
  background: var(--color-white);
  box-shadow: var(--shadow-focus);
}

/* Custom-drawn chevron on <select>. SVG uses the design-token green. */
.field select {
  cursor: pointer;
  appearance: none;
  -webkit-appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath d='M2 4l4 4 4-4' stroke='%231a5d3a' stroke-width='1.8' fill='none' stroke-linecap='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 16px center;
  padding-right: 40px;
}

.field input:disabled,
.field select:disabled,
.field textarea:disabled {
  background: var(--color-border);
  color: var(--color-text-muted);
  cursor: not-allowed;
}

.field input::placeholder,
.field textarea::placeholder {
  color: var(--color-text-light);
}

/* Error + helper text — sit BELOW the input. */
.field-error {
  color: var(--color-error);
  font-size: var(--text-xs);
  margin-top: var(--space-2);
  display: block;
}
.field-helper {
  color: var(--color-text-muted);
  font-size: var(--text-xs);
  margin-top: var(--space-2);
  display: block;
}

/* Error state — red border on the input. */
.field.has-error input,
.field.has-error select,
.field.has-error textarea {
  border-color: var(--color-error);
}
.field.has-error input:focus,
.field.has-error select:focus,
.field.has-error textarea:focus {
  box-shadow: 0 0 0 3px rgba(220, 38, 38, 0.15);
}


/* ============================================================
   BADGES & PILLS
   .badge-verified  — the ONLY profile identity badge (admin verified).
                      Absence = default (not verified). Deliberately minimal.
   .request-status-pill  — photo-request state inside photo lock cards.
                           Different concept: context state, not identity.
   ============================================================ */

/* Verified badge — green checkmark + label. Used on profile cards and
   profile pages. Shown ONLY when admin has manually verified the profile. */
.badge-verified {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 3px 10px;
  background: rgba(16, 185, 129, 0.12);
  color: var(--color-success);
  border-radius: var(--radius-pill);
  font-size: var(--text-xs);
  font-weight: var(--weight-bold);
  line-height: 1;
  white-space: nowrap;
}
.badge-verified::before {
  content: '';
  width: 14px;
  height: 14px;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%2310b981'%3E%3Cpath d='M12 2a10 10 0 100 20 10 10 0 000-20zm-1.5 14L6 11.5l1.5-1.5L10.5 13 16 7.5 17.5 9l-7 7z'/%3E%3C/svg%3E");
  background-size: contain;
  background-repeat: no-repeat;
  flex-shrink: 0;
}

/* Photo request status pills — state indicators for photo-view requests.
   NOT profile identity badges. Page-specific context overrides
   (e.g. on .photo-blocked.has-teaser) still live in profile.php. */
.request-status-pill {
  display: inline-block;
  padding: 7px 16px;
  border-radius: var(--radius-pill);
  font-size: var(--text-xs);
  font-weight: var(--weight-bold);
  letter-spacing: 0.2px;
  line-height: 1;
  /* Default fallback (amber) — variants below override. */
  background: #fff3cd;
  color: #8a5a00;
  border: 1px solid #f0c040;
}
.request-status-pill.pill-pending {
  background: rgba(255, 255, 255, 0.95);
  color: var(--color-text);
  border: 1px solid rgba(0, 0, 0, 0.10);
}
.request-status-pill.pill-rejected {
  background: #fee4e2;
  color: #912018;
  border: 1px solid #fda29b;
}
/* Approved — new variant for Step 4 notifications ("your request was approved"). */
.request-status-pill.pill-approved {
  background: rgba(16, 185, 129, 0.12);
  color: var(--color-success);
  border: 1px solid rgba(16, 185, 129, 0.30);
}


/* ============================================================
   NAVIGATION — top menu (fixed, smart-hide on scroll)
   .site-header, .site-nav, .site-logo, .nav-menu, .nav-item,
   .lang-toggle (.nav-item--primary / --secondary variants dropped
   in post-Step-13 polish — all top-nav items now consistent weight)
   ============================================================ */
.site-header {
  position: fixed;
  top: 0; left: 0; right: 0;
  z-index: var(--z-fixed-header);
  background: rgba(255, 255, 255, 0.96);
  backdrop-filter: blur(16px);
  -webkit-backdrop-filter: blur(16px);
  border-bottom: 1px solid rgba(201, 169, 97, 0.18);
  box-shadow: var(--shadow-sm);
  transition: transform var(--transition-base);
}
/* Smart-hide: JS in header.php toggles .is-hidden when scrolling down. */
.site-header.is-hidden { transform: translateY(-100%); }

.site-nav {
  max-width: 1200px;
  margin: 0 auto;
  padding: 0 var(--space-5);
  display: flex;
  align-items: center;
  gap: var(--space-3);
  height: 72px;
  /* Layout: logo + menu cluster on the left; .lang-toggle uses
     margin-left: auto to push itself to the far right. This avoids
     the "sparse middle" problem on wide desktops. */
}

/* Brand wordmark — two-word split so each word can be colored separately. */
.site-logo {
  display: inline-flex;
  align-items: baseline;
  gap: 0.2em;
  text-decoration: none;
  font-weight: var(--weight-bold);
  font-size: var(--text-xl);
  font-family: var(--font-bengali);
  white-space: nowrap;
  transition: opacity var(--transition-fast);
}
body.en .site-logo { font-family: var(--font-heading); }
.site-logo__word-1 { color: var(--color-green); }
.site-logo__word-2 { color: var(--color-gold-dark); }
.site-logo:hover { opacity: 0.85; }

.nav-menu {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  flex-wrap: nowrap;
  /* Sits directly after the logo with a natural gap — no flex-grow
     or center-justify, so menu items cluster on the left as a group. */
}

/* Breakpoint-conditional visibility — bottom-nav is hidden on desktop
   (≥768px), so the desktop top-nav absorbs the Brides / Grooms / Search
   / Profile items via .nav-item--desktop-only. Mobile keeps the
   simpler "Browse Profiles" link via .nav-item--mobile-only since the
   bottom-nav already provides Brides/Grooms/Search/Profile tabs. */
.nav-item--desktop-only { display: none; }
.nav-item--mobile-only  { display: list-item; }
@media (min-width: 768px) {
  .nav-item--desktop-only { display: list-item; }
  .nav-item--mobile-only  { display: none; }
}

/* Top-nav items — text-only, all consistent weight (post-Step-13 polish).
   Primary/secondary pill variants removed; active state is now a green
   underline pseudo-element under the label, NOT a pill or color shift. */
.nav-item a {
  position: relative;
  display: inline-block;
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-md);
  font-size: var(--text-sm);
  font-weight: var(--weight-medium);
  color: var(--color-text-muted);
  white-space: nowrap;
  text-decoration: none;
  transition: color var(--transition-fast), background var(--transition-fast);
}
.nav-item a:hover,
.nav-item a:focus-visible { color: var(--color-green); background: rgba(26, 93, 58, 0.06); outline: none; }

/* Active state — green underline below the label (3px high, 70% width
   centered). Replaces the previous color-only shift, which was barely
   visible against the muted default text. */
.nav-item.is-active a {
  color: var(--color-green);
  font-weight: var(--weight-semibold);
}
.nav-item.is-active a::after {
  content: '';
  position: absolute;
  left: 18%;
  right: 18%;
  bottom: 4px;
  height: 3px;
  background: var(--color-green);
  border-radius: 2px;
}

/* Language toggle pill — pushed to the far right of the header. */
.lang-toggle {
  display: inline-flex;
  background: var(--color-cream-dark);
  border-radius: var(--radius-pill);
  padding: 3px;
  border: 1px solid rgba(201, 169, 97, 0.28);
  flex-shrink: 0;
  margin-left: auto;     /* absorbs all free space between the menu and itself */
}
.lang-btn {
  padding: 4px 12px;
  border-radius: var(--radius-pill);
  font-size: var(--text-xs);
  font-weight: var(--weight-semibold);
  background: transparent;
  color: var(--color-text-muted);
  border: none;
  cursor: pointer;
  transition: all var(--transition-fast);
}
.lang-btn:hover { color: var(--color-green); }
.lang-btn.active {
  background: var(--color-green);
  color: var(--color-text-on-dark);
}
/* Bengali button label: __full ("বাংলা") shown by default,
   __short ("বা") reveals at ≤374px viewports (see media query below). */
.lang-btn__short { display: none; }

/* Mobile (≤767px): tuned so the 5 header pieces (logo + 3 menu + lang)
   fit from 375px (iPhone SE) upward without overflow. Tightened further
   than originally planned because Hind Siliguri glyphs render slightly
   wider than typical Latin fonts. */
@media (max-width: 767px) {
  .site-nav { height: 56px; padding: 0 10px; gap: var(--space-2); }
  .site-logo { font-size: 15px; }
  .nav-menu { gap: 4px; }
  .nav-item a { padding: 4px 6px; font-size: var(--text-xs); }       /* 12px */
  .nav-item.is-active a::after { bottom: 2px; height: 2px; }
  .lang-toggle { padding: 2px; }
  .lang-btn { padding: 3px 7px; font-size: 10px; }
  body { padding-top: 56px; }
}

/* Ultra-small (≤374px): iPhone 5/5s/SE-gen-1 and budget Android at 320px.
   Further shrinks menu items so the 5 header pieces still fit. */
@media (max-width: 374px) {
  .site-nav { padding: 0 6px; gap: var(--space-1); }
  .site-logo { font-size: var(--text-sm); }                          /* 14px */
  .nav-menu { gap: 2px; }
  .nav-item a { padding: 3px 5px; font-size: 11px; }
  .lang-toggle { padding: 2px; }
  .lang-btn { padding: 2px 6px; font-size: 10px; }
}

/* Narrow (≤360px): iPhone 4/5/6/7/SE-gen-1 and budget Android.
   Swap full "বাংলা" for short "বা" so the toggle fits alongside "EN"
   without overflow. 361–374px still shows full "বাংলা" — the slight
   extra width at those sizes is comfortable. */
@media (max-width: 360px) {
  .lang-btn__full  { display: none; }
  .lang-btn__short { display: inline; }
}


/* ============================================================
   NAVIGATION — bottom menu (mobile-only, Tinder-style floating pill)
   .bottom-nav, .bottom-nav-menu, .bottom-nav-item, .nav-badge

   Mobile-first redesign (post-Step-13 polish). All 4 items same visual
   weight — no oversized "primary" item. Icon-on-top + label-below per
   item. Active state = circular cream-tinted highlight around the icon
   area + bolder label. Hidden on desktop (≥768px). CSS-only animations.
   ============================================================ */
.bottom-nav {
  position: fixed;
  /* Anchored flush to viewport bottom (post–real-device polish, May 2026).
     Previously floated with bottom: 12px which left a visible gap from
     iOS Safari URL bar / Android nav bar. The iOS home-indicator safe-
     area is now absorbed into this element's padding-bottom via max(),
     so the nav still clears the home indicator on iPhone but anchors
     flush on Android / desktop browsers without bottom system UI. */
  bottom: 0; left: 12px; right: 12px;
  z-index: var(--z-sticky);
  background: var(--color-white);
  border: 1px solid rgba(201, 169, 97, 0.18);
  border-radius: 28px;
  box-shadow: 0 6px 24px rgba(10, 61, 46, 0.10), 0 2px 6px rgba(10, 61, 46, 0.06);
  padding: 6px env(safe-area-inset-right, 0px) max(8px, env(safe-area-inset-bottom, 8px)) env(safe-area-inset-left, 0px);
  /* Hide on desktop — top-nav is sufficient ≥768px. */
}
@media (min-width: 768px) {
  .bottom-nav { display: none; }
}

.bottom-nav-menu {
  display: flex;
  align-items: stretch;
  justify-content: space-around;
  max-width: 540px;
  margin: 0 auto;
  padding: 0;
  list-style: none;
}

/* Whole-bar breathe (Addition 2A) — JS toggles .is-breathing on
   .bottom-nav__pill (alias on the .bottom-nav-menu <ul>) for ~280ms.
   Cubic-bezier overshoot creates the spring-back feel. */
.bottom-nav__pill {
  transform-origin: center center;
  transition: transform 0.45s cubic-bezier(0.34, 1.56, 0.64, 1), box-shadow 0.45s ease;
}
.bottom-nav__pill.is-breathing {
  transform: scale(1.08);
  box-shadow: 0 8px 28px rgba(0, 0, 0, 0.12);
}

/* Per-item is the actual highlighted slot — pill-shaped cream-tinted
   background wraps icon + label as one unit when active (Addition 1A).
   Spring-back tap micro-animation on :active (Addition 2B). */
.bottom-nav-item {
  flex: 1;
  text-align: center;
  border-radius: 22px;
  background: transparent;
  transition: transform 0.18s cubic-bezier(0.34, 1.56, 0.64, 1), background 0.30s ease;
}
.bottom-nav-item:active { transform: scale(0.94); }

/* Anchor wraps the icon + label in a vertical stack. min-height enforces
   Apple's 44px tap-target guideline. */
.bottom-nav-item a {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 4px;
  min-height: 56px;
  padding: 8px 14px;
  text-decoration: none;
  color: var(--color-text-muted);
  font-size: 11px;
  font-weight: var(--weight-medium);
  letter-spacing: 0.1px;
  transition: color var(--transition-fast);
}
.bottom-nav-item a:focus-visible { outline: none; }

/* Icon wrapper — fixed-size slot containing TWO absolutely-positioned
   <svg> children (inactive + active variants). CSS cross-fades opacity
   on .is-active to swap the visible icon (Addition 1B). */
.bottom-nav-item__icon-wrap {
  position: relative;
  width: 22px;
  height: 22px;
  display: block;
}
.bottom-nav-item__icon-wrap > svg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  transition: opacity 0.25s ease, transform var(--transition-fast);
}
.bottom-nav-item__icon-active   { opacity: 0; }
.bottom-nav-item__icon-inactive { opacity: 1; }
.bottom-nav-item.is-active .bottom-nav-item__icon-inactive { opacity: 0; }
.bottom-nav-item.is-active .bottom-nav-item__icon-active   { opacity: 1; }
.bottom-nav-item:active .bottom-nav-item__icon-wrap > svg { transform: scale(0.92); }

/* Label — color + weight transition syncs with the icon cross-fade
   (Addition 2C). */
.bottom-nav-item__label {
  font-size: 11px;
  line-height: 1.2;
  white-space: nowrap;
  font-weight: 500;
  color: var(--color-text-muted);
  transition: color 0.28s ease, font-weight 0.28s ease;
}

/* Active state — whole-item pill highlight (Addition 1A) + green
   text/icon + bolder label (Addition 2C). Background uses a low-opacity
   green tint matching the brand palette. No icon-only halo (the old
   .icon-wrap background was moved to .bottom-nav-item itself). */
.bottom-nav-item.is-active {
  background: rgba(10, 61, 46, 0.08);
}
.bottom-nav-item.is-active a { color: var(--color-green); }
.bottom-nav-item.is-active .bottom-nav-item__label {
  color: var(--color-green);
  font-weight: 600;
}

/* Hover state — desktop only (no-op on touch). Subtle tinted background +
   gentle scale-up. Active items don't get the hover treatment to avoid
   double-highlighting (Addition 2D). */
@media (hover: hover) {
  .bottom-nav-item:hover:not(.is-active) {
    background: rgba(10, 61, 46, 0.04);
    transform: scale(1.04);
  }
  .bottom-nav-item:hover a { color: var(--color-green); }
}

@media (prefers-reduced-motion: reduce) {
  .bottom-nav__pill,
  .bottom-nav-item,
  .bottom-nav-item a,
  .bottom-nav-item__icon-wrap > svg,
  .bottom-nav-item__label { transition: none; }
  .bottom-nav-item:active,
  .bottom-nav-item:hover { transform: none; }
  .bottom-nav-item:active .bottom-nav-item__icon-wrap > svg { transform: none; }
  .bottom-nav__pill.is-breathing { transform: none; box-shadow: var(--shadow-md); }
}

/* Notification badge — Instagram-style red circle pinned to the top-right
   of the icon wrap (Profile item only). Server emits the [hidden] attr
   when count = 0 so display:none kicks in via the attribute selector. */
.nav-badge {
  position: absolute;
  top: -4px;
  right: -4px;
  min-width: 18px;
  height: 18px;
  padding: 0 5px;
  border-radius: var(--radius-pill);
  background: var(--color-error);
  color: #fff;
  font-size: 10px;
  font-weight: var(--weight-bold);
  font-family: var(--font-body);
  line-height: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 2px solid var(--color-white);
  box-shadow: 0 2px 6px rgba(220, 38, 38, 0.35);
  z-index: 2;
  pointer-events: none;
  animation: nav-badge-pulse 1.4s ease-out 0s 4;
}
.nav-badge[hidden] { display: none; }

@keyframes nav-badge-pulse {
  0%, 100% { transform: scale(1);    }
  50%      { transform: scale(1.15); }
}
@media (prefers-reduced-motion: reduce) {
  .nav-badge { animation: none; }
}


/* ============================================================
   FOOTER
   .site-footer, .footer-container, .footer-column, .footer-brand,
   .footer-heading, .footer-tagline, .footer-social, .footer-copyright
   ============================================================ */
.site-footer {
  background: var(--color-green);
  color: rgba(255, 255, 255, 0.85);
  padding: var(--space-10) var(--space-4) var(--space-6);
}

.footer-container {
  max-width: 1200px;
  margin: 0 auto;
  display: grid;
  gap: var(--space-6);
  grid-template-columns: 1fr;
}
@media (min-width: 768px) {
  .footer-container {
    grid-template-columns: 2fr 1fr 1fr 1fr;
    gap: var(--space-8);
  }
}

.footer-brand .site-logo {
  font-size: var(--text-2xl);
  margin-bottom: var(--space-3);
}
.footer-brand .site-logo__word-1 { color: var(--color-white); }
.footer-brand .site-logo__word-2 { color: var(--color-gold); }
.footer-brand .site-logo:hover { opacity: 1; }

.footer-tagline {
  color: rgba(255, 255, 255, 0.7);
  font-size: var(--text-sm);
  line-height: var(--leading-relaxed);
  max-width: 320px;
}

.footer-heading {
  font-size: var(--text-sm);
  font-weight: var(--weight-semibold);
  color: var(--color-gold);
  margin-bottom: var(--space-3);
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

.footer-column ul li {
  margin-bottom: var(--space-2);
  color: rgba(255, 255, 255, 0.8);
  font-size: var(--text-sm);
}
.footer-column ul a {
  color: rgba(255, 255, 255, 0.8);
  font-size: var(--text-sm);
  transition: color var(--transition-fast);
}
.footer-column ul a:hover { color: var(--color-gold); }

.footer-social {
  max-width: 1200px;
  margin: var(--space-8) auto 0;
  display: flex;
  justify-content: center;
  gap: var(--space-3);
  padding-top: var(--space-6);
  border-top: 1px solid rgba(255, 255, 255, 0.1);
}
.footer-social-link {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 40px; height: 40px;
  border-radius: var(--radius-pill);
  background: rgba(255, 255, 255, 0.08);
  color: rgba(255, 255, 255, 0.85);
  transition: all var(--transition-fast);
}
.footer-social-link:hover {
  background: var(--color-gold);
  color: var(--color-green);
  transform: translateY(-1px);
}

.footer-copyright {
  max-width: 1200px;
  margin: var(--space-5) auto 0;
  padding-top: var(--space-4);
  border-top: 1px solid rgba(255, 255, 255, 0.08);
  text-align: center;
  font-size: var(--text-xs);
  color: rgba(255, 255, 255, 0.6);
}


/* ============================================================
   TEXT UTILITIES
   ============================================================ */
/* Alignment */
.text-center { text-align: center; }
.text-left   { text-align: left; }
.text-right  { text-align: right; }

/* Color */
.text-muted   { color: var(--color-text-muted); }
.text-light   { color: var(--color-text-light); }
.text-error   { color: var(--color-error); }
.text-success { color: var(--color-success); }
.text-green   { color: var(--color-green); }
.text-gold    { color: var(--color-gold-dark); }
.text-white   { color: var(--color-text-on-dark); }

/* Size */
.text-xs   { font-size: var(--text-xs); }
.text-sm   { font-size: var(--text-sm); }
.text-base { font-size: var(--text-base); }
.text-lg   { font-size: var(--text-lg); }
.text-xl   { font-size: var(--text-xl); }
.text-2xl  { font-size: var(--text-2xl); }
.text-3xl  { font-size: var(--text-3xl); }

/* Weight */
.text-normal   { font-weight: var(--weight-normal); }
.text-medium   { font-weight: var(--weight-medium); }
.text-semibold { font-weight: var(--weight-semibold); }
.text-bold     { font-weight: var(--weight-bold); }

/* Overflow helpers */
.text-truncate {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}


/* ============================================================
   SPACING UTILITIES
   Based on the --space-* scale (8px unit). Keep the set small so
   the file stays legible — utilities are convenience, not a
   replacement for real layout rules.
   ============================================================ */
.m-0 { margin: 0; }
.m-2 { margin: var(--space-2); }
.m-3 { margin: var(--space-3); }
.m-4 { margin: var(--space-4); }
.m-5 { margin: var(--space-5); }
.m-6 { margin: var(--space-6); }

.mt-0 { margin-top: 0; }
.mt-2 { margin-top: var(--space-2); }
.mt-3 { margin-top: var(--space-3); }
.mt-4 { margin-top: var(--space-4); }
.mt-5 { margin-top: var(--space-5); }
.mt-6 { margin-top: var(--space-6); }
.mt-8 { margin-top: var(--space-8); }

.mb-0 { margin-bottom: 0; }
.mb-2 { margin-bottom: var(--space-2); }
.mb-3 { margin-bottom: var(--space-3); }
.mb-4 { margin-bottom: var(--space-4); }
.mb-5 { margin-bottom: var(--space-5); }
.mb-6 { margin-bottom: var(--space-6); }
.mb-8 { margin-bottom: var(--space-8); }

.mx-auto { margin-left: auto; margin-right: auto; }

.p-0 { padding: 0; }
.p-2 { padding: var(--space-2); }
.p-3 { padding: var(--space-3); }
.p-4 { padding: var(--space-4); }
.p-5 { padding: var(--space-5); }
.p-6 { padding: var(--space-6); }


/* ============================================================
   SKELETON LOADERS
   .skeleton-shimmer (base) + component-specific:
   .skeleton-card-featured  — mirrors .featured-card  (index.php)
   .skeleton-card-profile   — mirrors .profile-card   (browse.php)
   .skeleton-profile-detail — mirrors profile.php #content layout

   Server-render the skeleton markup so layout space is reserved
   during AJAX fetches; JS swaps in real content on resolve.
   Cumulative Layout Shift (CLS) stays near-zero. Reduced-motion
   users see a static placeholder (no shimmer sweep).

   Convention: every shimmer rectangle takes BOTH the .skeleton-
   shimmer base class AND a shape/size class (e.g. skeleton-line
   or a component-specific modifier).
   ============================================================ */

.skeleton-shimmer {
  position: relative;
  background: var(--color-cream-dark);
  overflow: hidden;
  border-radius: var(--radius-md);
}
.skeleton-shimmer::after {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(
    90deg,
    transparent 0%,
    rgba(255, 255, 255, 0.55) 50%,
    transparent 100%
  );
  transform: translateX(-100%);
  animation: skeleton-sweep 1.5s ease-in-out infinite;
}
@keyframes skeleton-sweep {
  from { transform: translateX(-100%); }
  to   { transform: translateX(100%);  }
}
@media (prefers-reduced-motion: reduce) {
  .skeleton-shimmer::after { animation: none; opacity: 0; }
}

/* Text-line placeholder helper. Use width via inline style or via
   a component-specific modifier; height defaults to 12px. */
.skeleton-line          { height: 12px; border-radius: var(--radius-md); }
.skeleton-line.is-tall  { height: 16px; }
.skeleton-line.is-short { height: 10px; }


/* ---------- Featured-carousel card skeleton (index.php) ---------- */
.skeleton-card-featured {
  background: var(--color-white);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  overflow: hidden;
  display: flex;
  flex-direction: column;
  box-shadow: var(--shadow-sm);
}
.skeleton-card-featured__photo {
  aspect-ratio: 1 / 1;
  border-radius: 0;
}
.skeleton-card-featured__body {
  padding: clamp(10px, 1vw, 14px);
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.skeleton-card-featured__name { width: 70%; height: 14px; }
.skeleton-card-featured__prof { width: 60%; height: 11px; }
.skeleton-card-featured__loc  { width: 50%; height: 11px; }


/* ---------- Browse-grid profile card skeleton (browse.php) ----------
   Hex values inlined to match the verbatim brides.php-derived card
   styling in browse.php (see comment at browse.php:309). */
.skeleton-card-profile {
  background: #FFFFFF;
  border-radius: 20px;
  overflow: hidden;
  border: 1px solid rgba(201, 168, 76, 0.10);
  box-shadow: 0 2px 8px rgba(10, 61, 46, 0.08);
  display: flex;
  flex-direction: column;
}
.skeleton-card-profile__photo {
  aspect-ratio: 1 / 1;
  border-radius: 0;
}
.skeleton-card-profile__body {
  padding: 18px;
  display: flex;
  flex-direction: column;
  gap: 10px;
  flex: 1;
}
.skeleton-card-profile__name { width: 60%; height: 18px; }
.skeleton-card-profile__meta { width: 50%; height: 13px; }
.skeleton-card-profile__details {
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin-top: 4px;
  flex: 1;
}
.skeleton-card-profile__details > .skeleton-shimmer { height: 12px; width: 80%; }
.skeleton-card-profile__details > .skeleton-shimmer:nth-child(2) { width: 65%; }
.skeleton-card-profile__details > .skeleton-shimmer:nth-child(3) { width: 75%; }
.skeleton-card-profile__actions {
  display: flex;
  gap: 8px;
  margin-top: auto;
}
.skeleton-card-profile__actions > .skeleton-shimmer {
  flex: 1;
  height: 40px;
  border-radius: 8px;
}

/* Mobile (≤600px) — matches .profile-card mobile rules in browse.php. */
@media (max-width: 600px) {
  .skeleton-card-profile { border-radius: 10px; }
  .skeleton-card-profile__photo { aspect-ratio: 3 / 4; }
  .skeleton-card-profile__body { padding: 8px; gap: 6px; }
  .skeleton-card-profile__name { height: 13px; }
  .skeleton-card-profile__meta { height: 10px; }
  .skeleton-card-profile__details > .skeleton-shimmer { height: 10px; }
  .skeleton-card-profile__actions { flex-direction: column; gap: 4px; }
  .skeleton-card-profile__actions > .skeleton-shimmer { height: 28px; border-radius: 6px; }
}


/* ---------- Profile detail page skeleton (profile.php) ---------- */
.skeleton-profile-detail {
  max-width: 1100px;
  margin: 0 auto;
  padding: 16px 24px 40px;
  display: grid;
  grid-template-columns: 300px 1fr;
  gap: 24px;
  align-items: start;
}
.skeleton-profile-detail__sidebar {
  display: flex;
  flex-direction: column;
  gap: 16px;
}
.skeleton-profile-detail__photo {
  aspect-ratio: 1 / 1;
  border-radius: var(--radius-lg);
  background: var(--color-cream-dark);
  position: relative;
  overflow: hidden;
}
.skeleton-profile-detail__contact {
  background: var(--color-white);
  border: 1px solid rgba(201, 168, 76, 0.10);
  border-radius: var(--radius-lg);
  padding: 24px;
  box-shadow: var(--shadow-sm);
  display: flex;
  flex-direction: column;
  gap: 14px;
}
.skeleton-profile-detail__contact > .skeleton-shimmer.is-heading { width: 55%; height: 14px; }
.skeleton-profile-detail__contact > .skeleton-shimmer.is-button  { height: 48px; border-radius: 50px; }

.skeleton-profile-detail__main {
  background: var(--color-white);
  border: 1px solid rgba(201, 168, 76, 0.10);
  border-radius: var(--radius-lg);
  padding: 28px;
  box-shadow: var(--shadow-sm);
  display: flex;
  flex-direction: column;
  gap: 20px;
}
.skeleton-profile-detail__header {
  border-bottom: 1px solid var(--color-border);
  padding-bottom: 16px;
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.skeleton-profile-detail__header > .skeleton-shimmer:nth-child(1) { width: 55%; height: 28px; }
.skeleton-profile-detail__header > .skeleton-shimmer:nth-child(2) { width: 35%; height: 14px; }
.skeleton-profile-detail__section {
  display: flex;
  flex-direction: column;
  gap: 12px;
}
.skeleton-profile-detail__section > .skeleton-shimmer.is-heading { width: 30%; height: 12px; }
.skeleton-profile-detail__grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 12px 20px;
}
.skeleton-profile-detail__grid > .skeleton-shimmer { height: 28px; }
.skeleton-profile-detail__about { height: 80px; }

@media (max-width: 900px) {
  .skeleton-profile-detail { grid-template-columns: 1fr; gap: 20px; }
  .skeleton-profile-detail__photo { max-width: 280px; margin: 0 auto; width: 100%; }
  .skeleton-profile-detail__grid  { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 600px) {
  .skeleton-profile-detail { padding: 16px; }
  .skeleton-profile-detail__main { padding: 20px 16px; }
  .skeleton-profile-detail__grid { grid-template-columns: 1fr 1fr; gap: 8px 14px; }
}


/* ============================================================
   COUNTRY CODE PICKER (.cc-picker)
   Custom dropdown component replacing native <select> for phone-
   dial-code and residency-country pickers. Bangladesh-sticky-top,
   search-as-you-type, full keyboard a11y, mobile full-screen modal.

   Markup partial: includes/country-code-picker.php
   JS module:      assets/js/country-code-picker.js
   ============================================================ */

.cc-picker {
  position: relative;
  display: block;
  font-family: inherit;
}

.cc-picker__trigger {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  width: 100%;
  padding: 13px 12px;
  background: var(--color-cream);
  color: var(--color-text);
  border: 1.5px solid var(--color-border);
  border-radius: var(--radius-md);
  font-family: inherit;
  font-size: var(--text-sm);
  font-weight: var(--weight-semibold);
  cursor: pointer;
  transition: border-color var(--transition-fast),
              background var(--transition-fast),
              box-shadow var(--transition-fast);
}
.cc-picker__trigger:hover { border-color: var(--color-green); }
.cc-picker__trigger:focus-visible {
  outline: none;
  border-color: var(--color-green);
  background: var(--color-white);
  box-shadow: var(--shadow-focus);
}
.cc-picker__trigger[aria-expanded="true"] {
  border-color: var(--color-green);
  background: var(--color-white);
}

.cc-picker__flag {
  font-size: 18px;
  line-height: 1;
  flex-shrink: 0;
}
.cc-picker__code {
  flex: 1;
  text-align: left;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.cc-picker__chevron {
  color: var(--color-text-muted);
  flex-shrink: 0;
  transition: transform var(--transition-fast);
}

/* Placeholder state — only used by the residency-abroad picker
   (excludeBangladesh + no initial selection). Italicizes the
   "Select country" prompt + mutes the trigger color so users see
   it as a hint rather than a real value. */
.cc-picker__trigger--placeholder .cc-picker__code {
  font-weight: var(--weight-medium);
  font-style: italic;
  color: var(--color-text-light);
}
.cc-picker__trigger[aria-expanded="true"] .cc-picker__chevron {
  transform: rotate(180deg);
}

/* ---------- Panel (desktop floating, mobile modal) ---------- */
.cc-picker__panel {
  position: absolute;
  top: calc(100% + 4px);
  left: 0;
  min-width: 320px;
  max-width: 92vw;
  max-height: 420px;
  background: var(--color-white);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-lg);
  /* z-index: sit above the fixed top nav (--z-fixed-header = 300). Backstop
     for stacking-context edge cases (e.g., when an ancestor creates its own
     stacking context and we'd otherwise be trapped below the nav). On
     desktop the picker pill sits mid-page so the dropdown opens below it
     without overlapping the nav in practice; the z-index alone is enough. */
  z-index: calc(var(--z-fixed-header) + 1);
  display: flex;
  flex-direction: column;
  overflow: hidden;
}
/* Explicit [hidden] override — author-CSS .cc-picker__panel { display: flex }
   above wins over the UA stylesheet's *[hidden] { display: none } rule, so
   the panel was rendering visible on page load. This selector has higher
   specificity (class + attribute = 0,2,0) than the base rule (class only =
   0,1,0) and restores the correct hidden behaviour. JS continues to toggle
   via `panel.hidden = true|false`. */
.cc-picker__panel[hidden] { display: none; }

.cc-picker__panel-header {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-2);
  border-bottom: 1px solid var(--color-border);
  background: var(--color-cream);
}
.cc-picker__search {
  flex: 1;
  padding: 10px 12px;
  /* Phase 4.5 — bumped 14→16px to prevent iOS Safari auto-zoom on focus. */
  font-size: var(--text-base);
  font-family: inherit;
  color: var(--color-text);
  background: var(--color-white);
  border: 1.5px solid var(--color-border);
  border-radius: var(--radius-md);
  outline: none;
  transition: border-color var(--transition-fast), box-shadow var(--transition-fast);
}
.cc-picker__search:focus {
  border-color: var(--color-green);
  box-shadow: var(--shadow-focus);
}
.cc-picker__close {
  display: none;     /* desktop: hidden; mobile-modal: shown */
  width: 36px; height: 36px;
  padding: 0;
  background: transparent;
  border: none;
  font-size: 22px;
  line-height: 1;
  color: var(--color-text-muted);
  cursor: pointer;
  border-radius: var(--radius-md);
  flex-shrink: 0;
  transition: color var(--transition-fast), background var(--transition-fast);
}
.cc-picker__close:hover { color: var(--color-green); background: var(--color-cream-dark); }

.cc-picker__list {
  flex: 1;
  overflow-y: auto;
  padding: var(--space-1) 0;
  margin: 0;
}
.cc-picker__list:focus { outline: none; }

.cc-picker__row {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 12px;
  min-height: 44px;          /* Apple HIG tap-target */
  font-size: var(--text-sm);
  color: var(--color-text);
  cursor: pointer;
  border-radius: 0;
  transition: background var(--transition-fast), color var(--transition-fast);
}
.cc-picker__row-flag {
  flex-shrink: 0;
  width: 24px;
  font-size: 18px;
  line-height: 1;
  text-align: center;
}
.cc-picker__row-name {
  flex: 1;
  font-weight: var(--weight-medium);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.cc-picker__row-code {
  flex-shrink: 0;
  color: var(--color-text-muted);
  font-variant-numeric: tabular-nums;
}

.cc-picker__row.is-highlighted,
.cc-picker__row[aria-selected="true"] {
  background: var(--color-cream-dark);
  color: var(--color-green);
}
.cc-picker__row[aria-selected="true"] .cc-picker__row-code { color: var(--color-green); }
@media (hover: hover) {
  .cc-picker__row:hover {
    background: var(--color-cream-dark);
    color: var(--color-green);
  }
}

/* Bangladesh sticky default — pinned at top, subtle gold tint. */
.cc-picker__row--default {
  position: sticky;
  top: 0;
  z-index: 1;
  background: rgba(201, 169, 97, 0.10);
  font-weight: var(--weight-semibold);
}
.cc-picker__row--default[aria-selected="true"],
.cc-picker__row--default.is-highlighted {
  background: rgba(201, 169, 97, 0.22);
}

.cc-picker__divider {
  list-style: none;
  height: 1px;
  margin: var(--space-1) var(--space-3);
  background: var(--color-border);
  border: none;
}

.cc-picker__empty {
  padding: var(--space-6) var(--space-4);
  text-align: center;
  color: var(--color-text-muted);
  font-size: var(--text-sm);
}

/* ---------- Mobile full-screen modal (≤480px) ---------- */
@media (max-width: 480px) {
  .cc-picker__panel.is-mobile-modal {
    position: fixed;
    inset: 0;
    top: 0;
    left: 0;
    width: 100vw;
    height: 100vh;
    height: 100dvh;
    max-width: none;
    max-height: none;
    border-radius: 0;
    border: none;
    z-index: var(--z-modal);
    box-shadow: none;
  }
  .cc-picker__panel.is-mobile-modal .cc-picker__close { display: flex; align-items: center; justify-content: center; }
  .cc-picker__panel.is-mobile-modal .cc-picker__panel-header {
    padding: var(--space-3);
    padding-top: max(var(--space-3), env(safe-area-inset-top, 0px));
  }
  .cc-picker__panel.is-mobile-modal .cc-picker__list {
    padding-bottom: env(safe-area-inset-bottom, 0px);
  }
}
body.cc-picker-locked { overflow: hidden; }

@media (prefers-reduced-motion: reduce) {
  .cc-picker__trigger,
  .cc-picker__chevron,
  .cc-picker__row,
  .cc-picker__close,
  .cc-picker__search { transition: none; }
}

/* ---------------------------------------------------------------
 * Photo protection (paired with assets/js/photo-protect.js).
 * Casual deterrent — disables text selection + native drag on
 * profile photos site-wide. NOT real protection (DevTools still
 * works). Selectors cover every profile-photo render site:
 * profile detail (main + gallery + lightbox), browse cards,
 * featured cards, and my_photos.php filled slots.
 * --------------------------------------------------------------- */
img.main-photo,
.profile-photo img,
.photo-gallery img,
.card-photo img,
.featured-card__photo img,
.photo-slot--filled img,
#lbImg {
  user-select: none;
  -webkit-user-select: none;
  -webkit-user-drag: none;
  -webkit-touch-callout: none;
}

/* =============================================================
   Phase 4 Step 3 — Notifications panel (dropdown / bottom-sheet)
   Single DOM rendered server-side, hidden by default. Two responsive
   skins: anchored dropdown on desktop (≥768px), slide-up bottom sheet
   on mobile (<768px). Toggled by the JS controller via .is-open.
   ============================================================= */

/* Desktop bell trigger inside .nav-menu */
.nav-bell {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 6px 8px;
  border-radius: 8px;
  text-decoration: none;
  color: inherit;
  line-height: 1;
  cursor: pointer;
}
.nav-bell:hover { background: rgba(255,255,255,0.08); }
.nav-bell__icon { width: 20px; height: 20px; }
.nav-bell__sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0;
  margin: -1px; overflow: hidden; clip: rect(0,0,0,0); white-space: nowrap; border: 0;
}
.nav-bell.is-open { background: rgba(201,168,76,0.18); color: var(--color-gold); }

/* Notification badge — shared by top-nav bell + bottom-nav bell. */
.nav-badge {
  position: absolute;
  top: -2px;
  right: -4px;
  min-width: 16px;
  height: 16px;
  padding: 0 4px;
  background: var(--color-red, #C4566A);
  color: #fff;
  border-radius: 8px;
  font-size: 10px;
  font-weight: 700;
  line-height: 16px;
  text-align: center;
  pointer-events: none;
}

/* Backdrop — only used on mobile (<768px). */
.notif-backdrop {
  position: fixed;
  inset: 0;
  background: rgba(0,0,0,0.35);
  z-index: var(--z-modal-backdrop);
  opacity: 0;
  transition: opacity 200ms ease-out;
  display: none;
  pointer-events: none;
}
.notif-backdrop.is-open { opacity: 1; pointer-events: auto; }
@media (max-width: 767px) {
  .notif-backdrop { display: block; }
}

/* Panel — desktop: anchored dropdown top-right under the bell area. */
.notif-panel {
  position: fixed;
  top: calc(64px + 4px);
  right: 16px;
  width: min(360px, calc(100vw - 32px));
  max-height: calc(100vh - 100px);
  background: var(--color-white);
  border: 1px solid var(--color-border);
  border-radius: 14px;
  box-shadow: 0 16px 40px rgba(10, 61, 46, 0.18);
  z-index: calc(var(--z-fixed-header) + 1);
  overflow: hidden;
  opacity: 0;
  transform: translateY(-8px) scale(0.98);
  transition: opacity 180ms ease-out, transform 180ms ease-out;
  pointer-events: none;
}
.notif-panel.is-open {
  opacity: 1;
  transform: translateY(0) scale(1);
  pointer-events: auto;
}
.notif-panel__inner {
  display: flex;
  flex-direction: column;
  max-height: inherit;
}
.notif-panel__header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 14px 18px;
  border-bottom: 1px solid var(--color-border);
  background: var(--color-cream);
  flex-shrink: 0;
}
.notif-panel__title {
  margin: 0;
  font-size: 16px;
  font-weight: 600;
  color: var(--color-green);
}
.notif-panel__close {
  width: 28px;
  height: 28px;
  border: none;
  background: transparent;
  font-size: 22px;
  line-height: 1;
  color: var(--color-text-muted);
  cursor: pointer;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
}
.notif-panel__close:hover { background: var(--color-cream-dark); color: var(--color-text); }
.notif-panel__content {
  overflow-y: auto;
  padding: 12px;
  flex: 1 1 auto;
}

/* Mobile — slide-up bottom sheet above the fixed bottom-nav. */
@media (max-width: 767px) {
  .notif-panel {
    top: auto;
    bottom: calc(76px + 8px);
    right: 12px;
    left: 12px;
    width: auto;
    max-width: none;
    max-height: 75vh;
    border-radius: 18px;
    z-index: var(--z-modal);
    transform: translateY(100%);
    transition: opacity 240ms cubic-bezier(0.16, 1, 0.3, 1), transform 240ms cubic-bezier(0.16, 1, 0.3, 1);
  }
  .notif-panel.is-open { transform: translateY(0); }
}

/* Sections */
.np-section { margin-bottom: 16px; }
.np-section:last-child { margin-bottom: 0; }
.np-section__title {
  margin: 0 0 8px 0;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--color-text-muted);
}

/* Cards */
.np-card {
  position: relative;
  padding: 12px 14px;
  background: var(--color-white);
  border: 1px solid var(--color-border);
  border-radius: 10px;
  margin-bottom: 8px;
}
.np-card:last-child { margin-bottom: 0; }
.np-card--pending {
  border-left: 3px solid var(--color-gold, #c9a961);
  padding-left: 11px;
}
.np-card--resolved {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding-right: 36px;
}
.np-card--resolved.is-unread { background: var(--color-cream); }
.np-card__who {
  display: block;
  font-weight: 600;
  color: var(--color-green);
  text-decoration: none;
  margin-bottom: 2px;
}
.np-card__who:hover { text-decoration: underline; }
.np-card__pid {
  font-family: monospace;
  font-size: 11px;
  color: var(--color-text-muted);
  font-weight: 500;
}
.np-card__action {
  font-size: 13px;
  color: var(--color-text);
  margin-bottom: 4px;
}
.np-card__msg {
  font-size: 13px;
  color: var(--color-text-muted);
  font-style: italic;
  margin: 4px 0;
  padding: 6px 10px;
  background: var(--color-cream);
  border-radius: 6px;
}
.np-card__time {
  font-size: 11px;
  color: var(--color-text-muted);
  margin-top: 4px;
}
.np-card__actions {
  display: flex;
  gap: 8px;
  margin-top: 10px;
}
.np-card__icon {
  flex-shrink: 0;
  width: 28px;
  height: 28px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 14px;
  font-weight: 700;
}
.np-card__icon--success  { background: #d4edda; color: #0a3d2e; }
.np-card__icon--rejected { background: #f8d7da; color: #900; }
.np-card__icon--info     { background: var(--color-cream-dark); color: var(--color-text); }
.np-card__body { flex: 1 1 auto; min-width: 0; }
.np-card__text {
  font-size: 13px;
  color: var(--color-text);
  line-height: 1.4;
}
.np-card__text strong { color: var(--color-green); font-weight: 600; }
/* Phase 4 Step 3 bug-round-2 — clickable actor name on resolved cards.
   Applied to both the <a> link and the <strong> fallback (when the actor
   user was hard-deleted and related_profile_id is NULL). Inline display
   so it sits with the sentence-template span on the same line. */
.np-card__actor {
  font-weight: 600;
  color: var(--color-green);
  text-decoration: none;
}
.np-card__actor:hover { text-decoration: underline; }

/* Buttons */
.np-btn {
  flex: 1 1 0;
  padding: 8px 12px;
  font-size: 13px;
  font-weight: 600;
  border-radius: 8px;
  border: none;
  cursor: pointer;
  font-family: inherit;
}
.np-btn--approve { background: var(--color-green); color: #fff; }
.np-btn--approve:hover { background: var(--color-green-mid, #14654d); }
.np-btn--reject  { background: var(--color-cream-dark); color: var(--color-text); }
.np-btn--reject:hover { background: var(--color-border); }

/* Dismiss X — resolved cards only */
.np-card__dismiss {
  position: absolute;
  top: 6px;
  right: 6px;
  margin: 0;
}
.np-dismiss {
  width: 24px;
  height: 24px;
  border: none;
  background: transparent;
  color: var(--color-text-muted);
  font-size: 18px;
  line-height: 1;
  cursor: pointer;
  border-radius: 50%;
  padding: 0;
  display: flex;
  align-items: center;
  justify-content: center;
}
.np-dismiss:hover { background: var(--color-cream-dark); color: var(--color-text); }

/* Empty state */
.np-empty { text-align: center; padding: 32px 16px; }
.np-empty__icon { font-size: 40px; margin-bottom: 12px; opacity: 0.5; }
.np-empty__title {
  margin: 0 0 8px 0;
  font-size: 14px;
  font-weight: 600;
  color: var(--color-text);
}
.np-empty__body {
  margin: 0;
  font-size: 13px;
  color: var(--color-text-muted);
  line-height: 1.5;
}
