/* ========================================================================
   KOSIS · Edit Profile modal · v2.2
   ------------------------------------------------------------------------
   Depends on kosis-brand.css (loaded first, exposes --ks-* tokens).
   Self-contained: no overrides of brand classes, only additions.

   v1.1 (Session 13): the "Edit choir info" modal reuses this entire shell.
   Section 14 adds the group-pill dropdown menu + square choir-avatar preview;
   Section 15 adds the location + public-contact lines for the Home About card.
   v1.2 (Session 15): Section 16 adds the avatar file-type info tooltip used by
   both the edit-profile and edit-choir modals.
   v1.3 (Session 15 fix): mobile overflow guards — the modal can never scroll
   sideways, and the tooltip bubble is clamped to the viewport. See Section 17.
   v1.4 (Session 15 fix 2): hint row no longer wraps the (i) on mobile, and the
   mobile sticky footer's spacing is corrected (no stray right/bottom gap).
   v1.5 (Session 15 fix 3): on mobile the floating (i) tooltip is dropped
   entirely (it clipped off-screen); the format list shows inline instead. The
   sticky footer now fills the body width edge-to-edge with no bottom band.
   v1.6 (Session 15 fix 4): (i) restored on mobile + tap-toggle via kosis.js.
   v1.7 (Session 15 fix 5): on mobile the open bubble is pinned to the VIEWPORT
   (fixed, centered, inset 16px) so it can never clip off either edge — the
   earlier icon-anchored bubble ran off the left on narrow screens. Footer keeps
   the no-negative-margin spacing (no gap beside Save).
   v1.8 (Session 15 PR2): Section 18 adds the quiet "Remove photo" text button
   used by both modals (disabled when no photo exists).
   v1.9 (Session 17): Section 19 adds the Maps location picker (choir modal) and
   the small embedded map on the Home About card.
   v2.0 (Session 17b): Home map is satellite view, clickable (opens Google Maps
   in a new tab) with a "View on Google Maps" link below it.
   v2.1 (Session 17c): Home map gains a Satellite/Map view toggle; the choir
   modal picker uses Google's built-in map-type switcher.
   v2.2 (Session 17d): the choir location picker is now a unified card — search
   field + map + caption in one bordered container, responsive map height.
   ======================================================================== */


/* ---- 1. Backdrop + dialog shell ------------------------------------ */
.ks-modal-backdrop {
  position: fixed;
  inset: 0;
  background: rgba(31, 41, 82, 0.55);
  display: none;
  align-items: flex-start;
  justify-content: center;
  z-index: 1000;
  padding: 48px 16px;
  overflow-y: auto;
}
.ks-modal-backdrop.is-open { display: flex; }

.ks-modal {
  background: var(--ks-cream);
  border-radius: var(--ks-radius-md);
  width: 100%;
  max-width: 480px;
  box-shadow: 0 20px 60px rgba(31, 41, 82, 0.25);
  position: relative;
  overflow: hidden;
}
/* Belt-and-braces: nothing inside the form may push horizontal width. Inputs
   with long values and the tooltip bubble are the usual culprits on phones. */
.ks-modal__body { max-width: 100%; }
.ks-modal__body * { max-width: 100%; box-sizing: border-box; }

/* Sub-views: only one is .is-active at any time */
.ks-modal__view { display: none; flex-direction: column; }
.ks-modal__view.is-active { display: flex; }


/* ---- 2. Header (close + back buttons) ------------------------------ */
.ks-modal__header {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  padding: 22px 24px 8px 24px;
}
.ks-modal__header .ks-h2 {
  flex: 1;
  margin: 0;
  padding-bottom: 8px;
}

.ks-modal__close,
.ks-modal__back {
  background: transparent;
  border: none;
  color: var(--ks-slate);
  cursor: pointer;
  font-size: 22px;
  line-height: 1;
  padding: 2px 8px;
  font-family: var(--ks-font-sans);
  transition: color 120ms;
}
.ks-modal__close:hover,
.ks-modal__back:hover { color: var(--ks-navy); }
.ks-modal__back { font-size: 26px; padding-left: 0; }


/* ---- 3. Body + footer ---------------------------------------------- */
.ks-modal__body {
  padding: 4px 24px 12px 24px;
  display: flex;
  flex-direction: column;
  gap: var(--ks-space-lg);
}

.ks-modal__footer {
  display: flex;
  justify-content: flex-end;
  gap: var(--ks-space-sm);
  padding: 16px 0 4px 0;
  margin-top: var(--ks-space-md);
  border-top: 0.5px solid var(--ks-border);
}


/* ---- 4. Avatar field ----------------------------------------------- */
.ks-avatar-field {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
  padding: var(--ks-space-md) 0 var(--ks-space-sm) 0;
}

.ks-avatar-preview {
  width: 112px;
  height: 112px;
  border-radius: 50%;
  background: var(--ks-parchment);
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  border: 0.5px solid var(--ks-border);
}
.ks-avatar-preview img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.ks-avatar-initials {
  font-family: var(--ks-font-serif);
  font-size: 38px;
  font-weight: 500;
  color: var(--ks-gold);
}

.ks-avatar-upload-btn {
  cursor: pointer;
  padding: 6px 16px;
  font-size: 11px;
}

.ks-avatar-hint {
  font-size: 10px;
  color: var(--ks-slate);
  font-style: italic;
}


/* ---- 5. Fieldsets (the "NAME / SETTINGS / CALENDAR" groups) ------- */
.ks-fieldset {
  border: none;
  padding: 0;
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.ks-fieldset__legend {
  font-family: var(--ks-font-sans);
  font-size: 10px;
  font-weight: 600;
  letter-spacing: var(--ks-track-mid);
  text-transform: uppercase;
  color: var(--ks-slate);
  padding: 0;
  margin: 0;
  position: relative;
  padding-bottom: 6px;
}
.ks-fieldset__legend::after {
  content: "";
  display: block;
  width: 20px;
  height: 1px;
  background: var(--ks-gold);
  margin-top: 4px;
}


/* ---- 6. Row layout (label · control, with subtle dividers) -------- */
.ks-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--ks-space-md);
  padding: 10px 0;
  border-bottom: 0.5px solid var(--ks-border);
  min-height: 36px;
}
.ks-row:last-child { border-bottom: none; }

.ks-row__label {
  margin-bottom: 0;
  flex-shrink: 0;
  text-transform: none;
  letter-spacing: 0;
  font-size: 12px;
  color: var(--ks-navy);
  font-weight: 500;
}

.ks-row__control,
.ks-row select.ks-input {
  flex: 1;
  max-width: 60%;
  border: none;
  background: transparent;
  text-align: right;
  padding-right: 0;
  color: var(--ks-navy);
  font-weight: 500;
}
.ks-row__control:focus { outline: none; }

.ks-row__stack {
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.ks-row__value {
  font-size: 12px;
  color: var(--ks-navy);
  font-weight: 500;
}

.ks-row__link {
  background: transparent;
  border: none;
  color: var(--ks-sage);
  font-family: var(--ks-font-sans);
  font-weight: 600;
  font-size: 12px;
  letter-spacing: 0.5px;
  text-transform: uppercase;
  cursor: pointer;
  padding: 4px 0;
}
.ks-row__link:hover { text-decoration: underline; }

/* Visible "Manage" action for the Notifications row. The plain text link read
   as easy-to-miss, so this is a bordered pill in the brand sage — clearly a
   button, while staying secondary to the modal's primary Save. */
.ks-row__managebtn {
  background: transparent;
  border: 1px solid var(--ks-sage);
  color: var(--ks-sage);
  font-family: var(--ks-font-sans);
  font-weight: 600;
  font-size: 12px;
  letter-spacing: 0.4px;
  text-transform: uppercase;
  cursor: pointer;
  padding: 6px 16px;
  border-radius: 999px;
  transition: background 120ms, color 120ms;
}
.ks-row__managebtn:hover {
  background: var(--ks-sage);
  color: var(--ks-cream);
}

.ks-row__hint {
  font-size: 11px;
  color: var(--ks-muted);
  font-style: italic;
}

.ks-row--stub { opacity: 0.72; }


/* ---- 7. Danger styling (account deletion) -------------------------- */
/* Brand book has no danger token; #B85450 is a sanctioned brick that
   sits well next to navy/gold/cream. Promote to brand if it stays. */
.ks-btn--danger-ghost {
  background: transparent;
  color: #B85450;
  border: 0.8px solid #B85450;
  align-self: flex-start;
  padding: 6px 14px;
  font-size: 11px;
}
.ks-btn--danger-ghost:hover {
  background: #B85450;
  color: var(--ks-cream);
  filter: none;
}

.ks-btn--danger {
  background: #B85450;
  color: var(--ks-cream);
}

.ks-ep-delete-trigger { margin-top: var(--ks-space-sm); }


/* ---- 8. Stub views ------------------------------------------------- */
.ks-ep-stub {
  font-size: 13px;
  color: var(--ks-navy);
}
.ks-ep-stub p {
  margin: 0 0 var(--ks-space-md) 0;
  line-height: 1.55;
}
.ks-ep-stub .ks-quote {
  display: block;
  text-align: center;
  margin: var(--ks-space-md) 0;
}


/* ---- 9. Flash banner ---------------------------------------------- */
.ks-flash {
  position: fixed;
  top: 16px;
  right: 16px;
  z-index: 1100;
  padding: 10px 16px;
  border-radius: var(--ks-radius-sm);
  font-size: 12px;
  font-weight: 500;
  box-shadow: 0 4px 16px rgba(31, 41, 82, 0.15);
  animation: ks-flash-in 200ms ease-out, ks-flash-out 200ms ease-in 4.5s forwards;
}
.ks-flash--ok    { background: var(--ks-sage);  color: var(--ks-cream); }
.ks-flash--error { background: #B85450;         color: var(--ks-cream); }

@keyframes ks-flash-in  { from { opacity: 0; transform: translateY(-8px); } to { opacity: 1; } }
@keyframes ks-flash-out { to   { opacity: 0; transform: translateY(-8px); } }


/* ---- 11. Sidebar avatar in photo mode ----------------------------- */
/* Used by the director pill in sidebar.php when the user has uploaded
   an avatar. Coexists with the original .admin-avatar (initials) style
   from kosis-dashboard.css — this modifier only kicks in when the
   photo class is present. */
.admin-avatar.admin-avatar--photo {
  padding: 0;
  background: transparent;
  overflow: hidden;
}
.admin-avatar.admin-avatar--photo img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}


/* ---- 12. Notifications subview ------------------------------------ */
.ks-notifications-intro {
  font-size: 12px;
  line-height: 1.5;
  color: var(--ks-slate);
  margin: 0 0 var(--ks-space-md);
}

.ks-notif-list {
  display: flex;
  flex-direction: column;
}

/* Header row: two narrow channel columns to the right */
.ks-notif-head {
  display: grid;
  grid-template-columns: 1fr 60px 60px;
  gap: 12px;
  padding: 0 0 8px 0;
  border-bottom: 0.5px solid var(--ks-border);
}
.ks-notif-head__col {
  font-size: 10px;
  font-weight: 600;
  letter-spacing: var(--ks-track-mid);
  text-transform: uppercase;
  color: var(--ks-slate);
  text-align: center;
}

/* Each row: label + help text on the left, two checkboxes on the right */
.ks-notif-row {
  display: grid;
  grid-template-columns: 1fr 60px 60px;
  gap: 12px;
  align-items: center;
  padding: 12px 0;
  border-bottom: 0.5px solid var(--ks-border);
}
.ks-notif-row:last-child {
  border-bottom: none;
}

.ks-notif-row__label {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}
.ks-notif-row__title {
  font-size: 13px;
  font-weight: 500;
  color: var(--ks-navy);
}
.ks-notif-row__help {
  font-size: 11px;
  color: var(--ks-slate);
  line-height: 1.4;
}

/* Checkbox cell: centered, clickable target is the whole label */
.ks-notif-cell {
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  padding: 6px;
  border-radius: var(--ks-radius-sm);
  transition: background 120ms;
}
.ks-notif-cell:hover {
  background: var(--ks-parchment);
}
.ks-notif-cell input[type="checkbox"] {
  width: 16px;
  height: 16px;
  accent-color: var(--ks-sage);
  cursor: pointer;
}

/* Director-controlled email: when a user isn't allowed to self-enable email,
   the EMAIL checkboxes are disabled and shown muted with a not-allowed cursor.
   The accompanying notice explains why. */
.ks-notif-cell--locked { cursor: not-allowed; }
.ks-notif-cell--locked:hover { background: transparent; }
.ks-notif-cell--locked input[type="checkbox"] {
  cursor: not-allowed;
  opacity: 0.4;
}
.ks-notif-emaillocked {
  background: var(--ks-parchment);
  border: 0.5px solid var(--ks-border);
  border-radius: var(--ks-radius-sm);
  padding: 10px 12px;
  color: var(--ks-slate);
}
.ks-notif-emaillocked strong { color: var(--ks-navy); }


/* ---- 13. Push enable banner -------------------------------------- */
.ks-push-banner {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 14px 16px;
  background: var(--ks-parchment);
  border: 0.5px solid var(--ks-border);
  border-radius: var(--ks-radius-sm);
  margin-bottom: var(--ks-space-md);
}
.ks-push-banner__text {
  display: flex;
  flex-direction: column;
  gap: 2px;
  flex: 1;
  min-width: 0;
}
.ks-push-banner__title {
  font-size: 12px;
  font-weight: 600;
  color: var(--ks-navy);
}
.ks-push-banner__hint {
  font-size: 11px;
  color: var(--ks-slate);
  line-height: 1.4;
}
.ks-push-banner__cta {
  flex-shrink: 0;
  padding: 6px 14px;
  font-size: 11px;
}
.ks-push-banner__cta:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

/* State variants — leftmost border indicates status at a glance */
.ks-push-banner--granted        { border-left: 3px solid var(--ks-sage); }
.ks-push-banner--blocked,
.ks-push-banner--error,
.ks-push-banner--unsupported,
.ks-push-banner--not-configured { border-left: 3px solid #B85450; }


/* ---- 10. Responsive ----------------------------------------------- */
@media (max-width: 540px) {
  .ks-modal-backdrop {
    padding: 0;
    align-items: stretch;
  }
  /* Modal becomes a full-viewport flex column on mobile.
     height:100dvh is the modern fix for iOS Safari's collapsing toolbar;
     100vh is the fallback for older browsers. */
  .ks-modal {
    border-radius: 0;
    max-width: none;
    height: 100vh;
    height: 100dvh;
    display: flex;
    flex-direction: column;
  }
  /* Active view becomes the flex column that fills the modal vertically. */
  .ks-modal__view.is-active {
    display: flex;
    flex-direction: column;
    flex: 1;
    min-height: 0;
  }
  .ks-modal__header {
    flex-shrink: 0;
  }
  /* Body (the form) scrolls; footer inside it sticks to the bottom edge. */
  .ks-modal__body {
    flex: 1;
    min-height: 0;
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
  }
  /* (Mobile sticky footer is defined in Section 17 — single source of truth.) */
  .ks-row__control,
  .ks-row select.ks-input {
    max-width: 55%;
  }
  .ks-grid--2 { grid-template-columns: 1fr; }
  .ks-flash {
    top: 8px;
    right: 8px;
    left: 8px;
  }
  /* Tighter notification grid on phones */
  .ks-notif-head,
  .ks-notif-row {
    grid-template-columns: 1fr 48px 48px;
    gap: 8px;
  }
  .ks-notif-row__help {
    display: none;  /* save vertical space; title-only on phones */
  }
}


/* ---- 14. Session 13 — Edit choir info -----------------------------
   The modal reuses the whole shell above (.ks-modal-backdrop / .ks-modal /
   .ks-avatar-field / .ks-fieldset / .ks-row). These are the only
   feature-specific styles:
     (a) the group-pill dropdown menu (Edit choir info + Settings), styled to
         match the user-profile dropdown; the gold-outline pill box itself is
         unchanged (its styling stays in kosis-dashboard.css).
     (b) a square choir-avatar preview (a choir reads as a square tile). */

/* (a) Group-pill as a menu trigger. Only managers get .group-pill--menu, so the
   pointer affordance + chevron never appear for members. The chevron rotates
   when the menu is open, exactly like the user-profile pill. */
.group-pill--menu {
  cursor: pointer;
  position: relative;
}
.group-pill--menu .kosis-pill-chevron {
  flex-shrink: 0;
  opacity: 0.6;
  transition: transform 0.2s, opacity 0.2s;
}
.group-pill--menu.open .kosis-pill-chevron {
  transform: rotate(90deg);
  opacity: 1;
}

/* The dropdown itself — fixed-positioned (JS sets top/left from the pill),
   matching the .kosis-profile-menu treatment from the profile widget. */
.kosis-choir-menu {
  display: none;
  position: fixed;
  z-index: 9999;
  background: #fff;
  border: 1px solid #e2e8f0;
  border-radius: 10px;
  box-shadow: 0 8px 28px rgba(31, 41, 82, 0.18);
  min-width: 210px;
  padding: 6px 0;
}
.kosis-choir-menu.open { display: block; }

/* Menu items reuse the .kosis-menu-item class from the profile widget, so they
   inherit hover/typography. These rules only add the disabled "Settings" state
   and its "Soon" badge. */
.kosis-menu-item--disabled {
  opacity: 0.55;
  cursor: default;
}
.kosis-menu-item--disabled:hover {
  background: transparent;
}
.kosis-menu-soon {
  margin-left: auto;
  font-size: 0.66rem;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--ks-gold);
  border: 1px solid var(--ks-gold);
  border-radius: 999px;
  padding: 1px 7px;
}

/* (b) Square choir avatar preview — overrides the round .ks-avatar-preview
   only inside the choir modal. */
.ks-choir-avatar-preview {
  border-radius: var(--ks-radius-md);
}


/* ---- 15. Session 13 — choir location + contact on the Home About card ----
   The location line and the public (external) contact links shown under the
   choir description. Lives here (rather than kosis-pages.css) because this
   sheet is loaded on every dashboard page including Home, keeping the whole
   Session-13 surface in one file. */
.ks-card-location {
  display: flex;
  align-items: center;
  gap: 6px;
  margin: 8px 0 0;
  font-size: 13px;
  color: var(--ks-slate);
}
.ks-card-location svg {
  flex-shrink: 0;
  color: var(--ks-gold);
}

/* Public contact links (external email / phone / website). Each is a real
   mailto: / tel: / external link. Internal contact is intentionally NOT shown
   here — it's members-only business info. */
.ks-card-contact {
  display: flex;
  flex-direction: column;
  gap: 4px;
  margin: 8px 0 0;
}
.ks-card-contact__item {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 13px;
  color: var(--ks-sage);
  text-decoration: none;
  width: fit-content;
}
.ks-card-contact__item:hover {
  text-decoration: underline;
}
.ks-card-contact__item svg {
  flex-shrink: 0;
  color: var(--ks-gold);
}


/* ---- 16. Avatar hint + info tooltip (file-type help) --------------------
   A small "(i)" affordance next to the avatar hint that reveals the list of
   accepted image formats on hover or keyboard focus. Pure CSS — the tooltip
   text lives in a data-tip attribute and is mirrored in aria-label for screen
   readers. Used by BOTH the edit-profile and edit-choir modals. */
.ks-avatar-hint-row {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
}

.ks-info-tip {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 15px;
  height: 15px;
  border-radius: 50%;
  border: 0.5px solid var(--ks-slate);
  color: var(--ks-slate);
  font-family: var(--ks-font-serif);
  font-size: 10px;
  font-style: italic;
  font-weight: 600;
  line-height: 1;
  cursor: help;
  flex-shrink: 0;
  transition: border-color 120ms, color 120ms;
}
.ks-info-tip:hover,
.ks-info-tip:focus-visible {
  border-color: var(--ks-gold);
  color: var(--ks-gold);
  outline: none;
}

/* The bubble: hidden until hover/focus. Anchored so its RIGHT edge lines up
   with the icon and it opens LEFTWARD over the hint text. The icon sits at the
   right end of a centered hint line, so a center-anchored bubble would spill
   off the right of the modal (the misalignment seen in testing). Right-
   anchoring keeps the whole bubble inside the modal on desktop. */
.ks-info-tip::after {
  content: attr(data-tip);
  position: absolute;
  bottom: calc(100% + 8px);
  right: -2px;
  left: auto;
  transform: translateY(4px);
  width: max-content;
  max-width: 240px;
  background: var(--ks-navy);
  color: var(--ks-cream);
  font-family: var(--ks-font-sans);
  font-size: 11px;
  font-style: normal;
  font-weight: 400;
  line-height: 1.45;
  text-align: left;
  padding: 8px 10px;
  border-radius: var(--ks-radius-sm);
  box-shadow: 0 8px 24px rgba(31, 41, 82, 0.28);
  opacity: 0;
  pointer-events: none;
  transition: opacity 140ms, transform 140ms;
  z-index: 20;
}
/* Little pointer triangle — sits under the icon (the bubble's right end). */
.ks-info-tip::before {
  content: "";
  position: absolute;
  bottom: calc(100% + 3px);
  right: 3px;
  left: auto;
  transform: translateY(4px);
  border: 5px solid transparent;
  border-top-color: var(--ks-navy);
  opacity: 0;
  pointer-events: none;
  transition: opacity 140ms, transform 140ms;
  z-index: 20;
}
.ks-info-tip:hover::after,
.ks-info-tip:focus-visible::after,
.ks-info-tip.is-open::after,
.ks-info-tip:hover::before,
.ks-info-tip:focus-visible::before,
.ks-info-tip.is-open::before {
  opacity: 1;
  transform: translateY(0);
}


/* ---- 17. Mobile fixes (v1.7) -------------------------------------------
   On phones the modal is full-screen (Section 10).

   (a) Never allow horizontal scroll inside the modal.
   (b) The "(i)" tooltip stays visible and is tappable (kosis.js toggles
       .is-open). The OPEN bubble is pinned to the VIEWPORT — position:fixed,
       centered horizontally, 16px inset both sides — so it is always fully on
       screen no matter where the small icon sits. (Icon-anchoring ran the wide
       bubble off the left edge on narrow screens.) The pointer triangle is
       hidden on mobile since the bubble no longer touches the icon.
   (c) The sticky footer sits INSIDE the body's padding box (no negative
       margins). Cancel / Save align to the same 24px right inset as the fields
       above, so there is no stray gap to the right of Save. */
@media (max-width: 540px) {
  .ks-modal { overflow-x: hidden; }

  .ks-avatar-hint-row {
    flex-wrap: nowrap;
    justify-content: center;
    max-width: 100%;
    padding: 0 8px;
  }

  /* (b) Pin the open bubble to the viewport, centered, so it can't clip. */
  .ks-info-tip::after {
    position: fixed;
    left: 16px;
    right: 16px;
    bottom: auto;
    top: 96px;                 /* just below the avatar area */
    margin: 0 auto;
    width: auto;
    max-width: calc(100vw - 32px);
    white-space: normal;
    transform: translateY(-4px);
  }
  .ks-info-tip.is-open::after {
    transform: translateY(0);
  }
  /* The little pointer triangle would point at nothing now — hide it. */
  .ks-info-tip::before { display: none; }

  /* (c) Body scrolls; drop its bottom padding so the footer sits flush. */
  .ks-modal__body {
    flex: 1;
    min-height: 0;
    overflow-y: auto;
    overflow-x: hidden;
    -webkit-overflow-scrolling: touch;
    padding-bottom: 0;
  }
  /* Footer inside the body padding box — no negative margins. */
  .ks-modal__footer {
    position: sticky;
    bottom: 0;
    background: var(--ks-cream);
    margin: var(--ks-space-md) 0 0;
    padding: 12px 0;
    padding-bottom: calc(env(safe-area-inset-bottom, 0px) + 12px);
    border-top: 0.5px solid var(--ks-border);
    z-index: 1;
  }
}


/* ---- 18. Remove-photo button (Session 15 PR2) --------------------------
   A quiet text button under the avatar upload control, in both modals. It is
   always shown but disabled when there is no photo to remove. Clicking it sets
   a hidden remove_photo=1 field and resets the preview to initials; the handler
   clears the stored avatar and logs "Photo: removed". Brick-red on hover to
   signal a destructive action, matching .ks-btn--danger-ghost's palette. */
.ks-avatar-remove-btn {
  background: transparent;
  border: none;
  color: var(--ks-slate);
  font-family: var(--ks-font-sans);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.3px;
  cursor: pointer;
  padding: 2px 4px;
  margin-top: -4px;
  transition: color 120ms;
}
.ks-avatar-remove-btn:hover:not(:disabled),
.ks-avatar-remove-btn:focus-visible:not(:disabled) {
  color: #B85450;
  text-decoration: underline;
  outline: none;
}
.ks-avatar-remove-btn:disabled {
  opacity: 0.4;
  cursor: not-allowed;
}


/* ---- 19. Maps location picker + Home map embed (Session 17) -------------
   The interactive picker lives inside the Edit-choir-info modal under the
   Location field; it is hidden until the Google Maps JS API has loaded (the
   script un-hides it), so if Maps fails to load the plain text input simply
   stays and nothing empty shows. The Home About card shows a small read-only
   embedded map (.ks-card-map) when coordinates are pinned. */
/* Unified location picker card: search field + map + caption in one bordered
   container, so it reads as a single "set your location" control rather than a
   stack of separate rows. The map height is responsive — roomy on desktop, but
   capped so it never dominates the full-screen modal on a phone. */
.ks-locpicker {
  margin-top: 4px;
  border: 0.5px solid var(--ks-border);
  border-radius: var(--ks-radius-sm);
  overflow: hidden;
  background: var(--ks-cream);
}
/* Search field sits on top of the card, borderless, with a divider under it. */
.ks-locpicker__search {
  width: 100%;
  box-sizing: border-box;
  border: none;
  border-bottom: 0.5px solid var(--ks-border);
  background: transparent;
  padding: 10px 12px;
  font-family: var(--ks-font-sans);
  font-size: 13px;
  color: var(--ks-navy);
}
.ks-locpicker__search::placeholder {
  color: var(--ks-muted);
}
.ks-locpicker__search:focus {
  outline: none;
  border-bottom-color: var(--ks-gold);
}
/* The interactive map. Responsive height: comfortable to pan + pin on desktop,
   capped on small screens. Hidden until the Maps JS API reports ready. */
.ks-locpicker__map {
  width: 100%;
  height: clamp(240px, 38vh, 360px);
  background: var(--ks-parchment);
}
.ks-locpicker__map[hidden] {
  display: none;
}
/* Caption under the map. */
.ks-locpicker__hint {
  font-size: 11px;
  color: var(--ks-slate);
  font-style: italic;
  margin: 0;
  padding: 8px 12px;
  background: var(--ks-cream);
}

/* Home About card: small embedded satellite map under the location/contact
   lines. position:relative so the click overlay can sit on top of the iframe. */
.ks-card-map {
  position: relative;
  margin: 10px 0 0;
  border-radius: var(--ks-radius-sm);
  overflow: hidden;
  border: 0.5px solid var(--ks-border);
  line-height: 0;            /* kill the iframe's inline-frame descender gap */
}
.ks-card-map iframe {
  display: block;
  width: 100%;
}
/* Transparent overlay — the iframe captures pointer events, so this sits above
   it and turns the whole map into a single link that opens Google Maps. */
.ks-card-map__overlay {
  position: absolute;
  inset: 0;
  z-index: 2;
  cursor: pointer;
}
/* Satellite/Map view toggle, top-right over the map. Above the overlay (z-index
   3 > 2) so the buttons remain clickable while the rest of the map opens Maps. */
.ks-map-toggle {
  position: absolute;
  top: 8px;
  right: 8px;
  z-index: 3;
  display: inline-flex;
  background: var(--ks-cream);
  border: 0.5px solid var(--ks-border);
  border-radius: var(--ks-radius-sm);
  overflow: hidden;
  box-shadow: 0 1px 4px rgba(31, 41, 82, 0.18);
}
.ks-map-toggle__btn {
  appearance: none;
  border: none;
  background: transparent;
  font-family: var(--ks-font-sans);
  font-size: 11px;
  font-weight: 600;
  color: var(--ks-slate);
  padding: 4px 10px;
  cursor: pointer;
  line-height: 1.4;
  transition: background 120ms, color 120ms;
}
.ks-map-toggle__btn + .ks-map-toggle__btn {
  border-left: 0.5px solid var(--ks-border);
}
.ks-map-toggle__btn:hover {
  background: var(--ks-parchment);
}
.ks-map-toggle__btn.is-active {
  background: var(--ks-navy);
  color: var(--ks-cream);
}
/* "View on Google Maps" link below the map. */
.ks-card-map__link {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin: 8px 0 0;
  font-size: 12px;
  font-weight: 600;
  color: var(--ks-sage);
  text-decoration: none;
  line-height: 1.2;
}
.ks-card-map__link:hover {
  text-decoration: underline;
}
.ks-card-map__link svg { flex-shrink: 0; color: var(--ks-gold); }
.ks-card-map__ext { font-size: 13px; }

/* Google's Places Autocomplete dropdown renders in a .pac-container appended to
   <body>. The modal backdrop sits at a high z-index, so lift the suggestions
   above it or they'd be unclickable behind the modal. */
.pac-container {
  z-index: 1200 !important;
}
