:root {
  color-scheme: light;
  --paper: #fdf5ef;
  --surface: #ffffff;
  --line: #dfe5df;
  --leaf: #46674f;
  --leaf-dark: #294c35;
  --plum: #67445e;
  --yellow: #fff176;
  --orange: #ffa500;
  --focus: #2457d6;
  font-family: Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  background: var(--paper);
}

/* The staff pages' own ink and grey. They used to sit on :root, which loads
   after tokens.css and so overrode the design system for every page that
   links both — the finder wore a cooler, greener grey than the rest of the
   site on its lede, its titles and its count. Here they reach the pages that
   load this file alone, and nothing else. */
body:not(.map-page) {
  --ink: #29332f;
  --muted: #68736e;
  color: var(--ink);
}

* { box-sizing: border-box; }
html, body { margin: 0; min-height: 100%; }
body { background: var(--paper); }
button, input, select, textarea { font: inherit; }
a { color: var(--leaf-dark); }

/* The finder page loads tokens.css and site.css and takes its bar and footer
   from there. These rules are the old chrome, still worn by the staff pages,
   which load this file alone. */
body:not(.map-page) .site-header {
  min-height: 64px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 20px;
  padding: 12px 22px;
  background: var(--paper);
  border-bottom: 1px solid var(--line);
}

body:not(.map-page) .wordmark {
  color: var(--leaf-dark);
  font-family: Georgia, "Times New Roman", serif;
  font-size: 24px;
  font-weight: 700;
  text-decoration: none;
  letter-spacing: -0.02em;
}
body:not(.map-page) .wordmark span { color: var(--plum); font-weight: 400; }
body:not(.map-page) .site-header nav { display: flex; gap: 18px; font-size: 14px; }
body:not(.map-page) .site-header nav a { text-decoration: none; }
body:not(.map-page) .site-header nav a:hover { text-decoration: underline; }

#sfm-container { position: relative; background: var(--surface); }
.map-controls { flex: 1 1 auto; border-bottom: 0; }
.map-controls {
  min-height: 66px;
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 11px 18px;
  background: var(--paper);
  border-bottom: 1px solid var(--line);
}
.map-controls select,
.map-controls input {
  width: 210px;
  height: 42px;
  padding: 8px 12px;
  color: var(--ink);
  background: #fff;
  border: 1px solid #cfd7d0;
  border-radius: 7px;
}
.map-controls input { width: 250px; }
.map-controls :focus-visible,
body:not(.map-page) .filter-toggle:focus-visible,
body:not(.map-page) .location-control:focus-visible { outline: 3px solid color-mix(in srgb, var(--focus) 35%, transparent); outline-offset: 1px; }
.result-count { margin-left: auto; color: var(--muted); font-size: 13px; }
.filter-toggle { display: none; }

#sfm-map { width: 100%; height: calc(100vh - 130px); min-height: 520px; background: #abd3e0; }
.map-error {
  position: absolute;
  inset: 90px 20px auto;
  z-index: 1000;
  max-width: 520px;
  margin: auto;
  padding: 14px 18px;
  color: #7b2525;
  background: #fff5f5;
  border: 1px solid #e5b6b6;
  border-radius: 8px;
}

.marker-cluster div {
  width: 34px;
  height: 34px;
  margin: 3px;
  display: grid;
  place-items: center;
  border-radius: 50%;
  box-shadow: 0 2px 7px rgb(55 48 12 / 24%);
}
.marker-cluster span { font-weight: 700; color: #594914; }
.leaflet-popup-content { min-width: 230px; max-width: min(360px, 72vw); margin: 16px 18px; line-height: 1.48; }
.popup-row { margin: 0 0 7px; overflow-wrap: anywhere; }
.popup-row:last-child { margin-bottom: 0; }
.popup-label { font-weight: 700; }
.sangha-detail-link { display: inline-block; margin-top: 5px; font-weight: 700; }
.card-page-link { margin: 12px 0 0; }
.email-reveal {
  appearance: none;
  padding: 0;
  color: #006fae;
  background: none;
  border: 0;
  text-decoration: underline;
  cursor: pointer;
}
.intro-message { margin-top: 4px; }
.intro-toggle {
  appearance: none;
  padding: 0;
  color: #006fae;
  background: none;
  border: 0;
  text-decoration: underline;
  cursor: pointer;
  font: inherit;
}
.intro-dialog {
  width: min(420px, calc(100vw - 32px));
  max-height: calc(100vh - 48px);
  padding: 0;
  border: 1px solid #aebbb0;
  border-radius: 10px;
  color: var(--ink);
}
.intro-dialog::backdrop { background: rgb(20 30 24 / 42%); }
.intro-dialog-header {
  display: flex;
  justify-content: space-between;
  gap: 16px;
  align-items: flex-start;
  padding: 18px 20px;
  border-bottom: 1px solid var(--line);
}
.intro-dialog-header h2 { margin: 0 0 4px; color: var(--leaf-dark); font: 700 22px/1.2 Georgia, serif; }
.intro-dialog-header p { margin: 0; color: var(--muted); font-size: 14px; }
.intro-dialog-close {
  appearance: none;
  padding: 0;
  color: var(--leaf-dark);
  background: none;
  border: 0;
  text-decoration: none;
  cursor: pointer;
}
.intro-dialog form {
  padding: 18px 20px;
  overflow: auto;
  max-height: calc(100vh - 140px);
}
.intro-note { margin: 0 0 12px; font-size: 14px; color: #4a5a50; }
.intro-field { display: block; margin-bottom: 12px; }
.intro-label { display: block; font-weight: 700; font-size: 14px; margin-bottom: 4px; }
.intro-field input,
.intro-field textarea {
  width: 100%;
  box-sizing: border-box;
  padding: 7px 9px;
  border: 1px solid #cbd4cd;
  border-radius: 6px;
  font: inherit;
  color: var(--ink, #1f2a24);
  background: #fff;
}
.intro-field textarea { resize: vertical; min-height: 6rem; }
.intro-submit {
  appearance: none;
  min-height: 38px;
  padding: 8px 14px;
  border: 1px solid var(--leaf-dark, #2f4a3a);
  border-radius: 6px;
  color: #fff;
  background: var(--leaf-dark, #2f4a3a);
  cursor: pointer;
  font: inherit;
}
.intro-submit:disabled { opacity: .55; cursor: wait; }
.intro-dialog .form-status { margin: 0 0 10px; font-size: 14px; min-height: 1.4rem; }
.intro-dialog .form-status:empty { min-height: 0; margin: 0; }
.intro-dialog .form-status.ok { color: #2f5a40; }
.intro-dialog .form-status.bad { color: #8a3a2a; }
.trap {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}
.intro-page-main {
  min-height: calc(100vh - 64px);
  display: grid;
  place-items: start center;
  padding: 32px 18px 48px;
  background: var(--paper);
}
.intro-page-panel {
  width: min(520px, 100%);
  padding: 28px 24px 32px;
  background: #fff;
  border: 1px solid var(--line);
  border-radius: 12px;
  box-shadow: 0 8px 24px rgb(40 55 45 / 7%);
}
.intro-page-panel h1 { margin: 0 0 8px; color: var(--leaf-dark); font: 700 28px/1.15 Georgia, serif; }
.intro-page-lede { margin: 0 0 6px; font-size: 18px; font-weight: 600; }
.intro-page-email { margin: 0 0 14px; color: var(--muted); font-size: 14px; }
.intro-page-error { margin: 0; color: #8a3a2a; line-height: 1.5; }
.intro-page-panel .intro-form { padding: 0; max-height: none; overflow: visible; }
.location-control {
  width: 34px;
  height: 34px;
  display: grid;
  place-items: center;
  padding: 0;
  color: var(--leaf-dark);
  background: #fff;
  border: 2px solid rgb(0 0 0 / 20%);
  border-radius: 4px;
  cursor: pointer;
  box-shadow: none;
}
.location-control svg { width: 19px; height: 19px; fill: currentColor; }

.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;
}

.editor-page { min-height: 100vh; }
.editor-shell { padding: 24px; }
.editor-intro { max-width: 880px; margin-bottom: 18px; }
.editor-intro h1 { margin: 0 0 6px; font: 700 32px/1.15 Georgia, serif; color: var(--leaf-dark); }
.editor-intro p { margin: 0; color: var(--muted); }
.panel {
  max-width: 620px;
  padding: 24px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 12px;
  box-shadow: 0 8px 24px rgb(40 55 45 / 7%);
}
.panel h2 { margin-top: 0; }
.panel form { display: flex; gap: 10px; flex-wrap: wrap; }
.panel input { min-width: 260px; flex: 1; }
.field-input,
.panel input,
.toolbar input,
.toolbar select {
  min-height: 38px;
  padding: 7px 9px;
  border: 1px solid #cbd4cd;
  border-radius: 6px;
  background: #fff;
  color: var(--ink);
}
.primary-button,
.secondary-button,
.save-button {
  min-height: 38px;
  padding: 8px 14px;
  border-radius: 6px;
  border: 1px solid var(--leaf-dark);
  cursor: pointer;
}
.primary-button, .save-button { color: #fff; background: var(--leaf-dark); }
.secondary-button { color: var(--leaf-dark); background: #fff; }
.primary-button:disabled, .save-button:disabled { opacity: .55; cursor: wait; }
.editor-toolbar {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  margin-bottom: 10px;
}
.editor-toolbar .status { margin-left: auto; color: var(--muted); font-size: 13px; }
.grid-wrap {
  max-height: calc(100vh - 235px);
  overflow: auto;
  background: #fff;
  border: 1px solid #bdc7bf;
  box-shadow: 0 2px 10px rgb(38 55 43 / 6%);
}
.sheet-grid { width: max-content; min-width: 100%; border-collapse: separate; border-spacing: 0; font-size: 13px; }
.sheet-grid th,
.sheet-grid td { padding: 0; border-right: 1px solid #d8ddd9; border-bottom: 1px solid #d8ddd9; vertical-align: top; }
.sheet-grid th {
  position: sticky;
  top: 0;
  z-index: 3;
  min-width: 150px;
  padding: 8px 9px;
  text-align: left;
  color: #33423a;
  background: #edf2ed;
  font-weight: 650;
  white-space: nowrap;
}
.sheet-grid th:first-child,
.sheet-grid td:first-child { position: sticky; left: 0; z-index: 2; min-width: 86px; background: #f7f9f7; }
.sheet-grid th:first-child { z-index: 4; background: #e4ebe5; }
.sheet-grid input,
.sheet-grid select,
.sheet-grid textarea {
  width: 100%;
  min-width: 150px;
  min-height: 36px;
  padding: 8px;
  border: 0;
  border-radius: 0;
  color: var(--ink);
  background: transparent;
}
.sheet-grid textarea { width: 280px; min-height: 70px; resize: vertical; }
.sheet-grid input:focus,
.sheet-grid select:focus,
.sheet-grid textarea:focus { position: relative; z-index: 1; outline: 2px solid #2b73d2; outline-offset: -2px; background: #fff; }
.sheet-grid [readonly], .sheet-grid :disabled { color: #6f7672; background: #f2f4f2; }
.row-actions { padding: 5px !important; }
.row-action-buttons { display: grid; gap: 5px; }
.save-button { min-height: 31px; padding: 5px 9px; font-size: 12px; }
.details-button { min-height: 30px; padding: 4px 8px; font-size: 12px; }
.row-dirty td:first-child { background: #fff5cd; }
.notice { margin: 10px 0; padding: 10px 12px; border-radius: 6px; background: #eef6ef; color: #31543b; }
.error-notice { background: #fff0f0; color: #842c2c; }
.record-detail-open .editor-shell { padding: 0; }
.record-detail-open .editor-intro { display: none; }
.record-detail-open #editor-notice { margin: 12px 24px 0; }
.record-detail-view { min-height: calc(100vh - 64px); background: #f4f6f3; }
.record-detail-header {
  position: sticky;
  top: 0;
  z-index: 5;
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center;
  gap: 18px;
  min-height: 74px;
  padding: 12px 24px;
  background: rgb(255 255 255 / 96%);
  border-bottom: 1px solid #bdc7bf;
  box-shadow: 0 3px 12px rgb(38 55 43 / 7%);
  backdrop-filter: blur(8px);
}
.record-detail-heading { min-width: 0; }
.record-detail-heading span { color: var(--muted); font-size: 12px; font-weight: 650; letter-spacing: .04em; text-transform: uppercase; }
.record-detail-heading h2 { margin: 2px 0 0; overflow: hidden; color: var(--leaf-dark); font: 700 25px/1.15 Georgia, serif; text-overflow: ellipsis; white-space: nowrap; }
.record-detail-header .save-button { min-width: 92px; min-height: 40px; font-size: 14px; }
.record-detail-form {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 14px 16px;
  width: 100%;
  max-width: 1800px;
  margin: 0 auto;
  padding: 22px 24px 38px;
}
.record-detail-field { display: grid; min-width: 0; gap: 6px; align-content: start; color: #33423a; font-size: 13px; font-weight: 650; }
.record-detail-field.is-wide { grid-column: span 2; }
.record-detail-field input,
.record-detail-field select,
.record-detail-field textarea {
  width: 100%;
  min-width: 0;
  min-height: 40px;
  padding: 8px 10px;
  color: var(--ink);
  background: #fff;
  border: 1px solid #c3cec5;
  border-radius: 6px;
  font-weight: 400;
}
.record-detail-field textarea { min-height: 88px; resize: vertical; }
.record-detail-edit-link { font-weight: 500; }
.record-detail-field input:focus,
.record-detail-field select:focus,
.record-detail-field textarea:focus { outline: 3px solid color-mix(in srgb, var(--focus) 28%, transparent); border-color: var(--focus); }
.record-detail-field [readonly], .record-detail-field :disabled { color: #6f7672; background: #e9ede9; }
.public-url-field { padding: 14px; background: #fff8f5; border: 1px solid #d8beb5; border-radius: 8px; }
.public-url-row { display: grid; grid-template-columns: auto minmax(180px, 1fr) auto; align-items: center; gap: 8px; }
.public-url-row > span { color: var(--muted); overflow-wrap: anywhere; font-weight: 400; }
.public-url-field .field-help { margin: 2px 0 0; font-weight: 400; }
.meeting-editor-shell { width: min(1440px, 100%); margin: 0 auto; padding: 24px; }
.meeting-editor-heading {
  position: sticky;
  top: 0;
  z-index: 10;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
  margin: -24px -24px 18px;
  padding: 18px 24px;
  background: rgb(253 245 239 / 96%);
  border-bottom: 1px solid var(--line);
  backdrop-filter: blur(8px);
}
.meeting-editor-heading h1 { margin: 2px 0 5px; color: var(--leaf-dark); font: 700 30px/1.15 Georgia, serif; }
.meeting-editor-heading p { max-width: 780px; margin: 0; color: var(--muted); }
.meeting-editor-kicker { color: var(--plum) !important; font-size: 12px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; }
.meeting-editor-heading-actions, .meeting-editor-footer, .meeting-card-actions { display: flex; align-items: center; gap: 8px; }
.meeting-editor-heading-actions a { display: inline-flex; align-items: center; text-decoration: none; }
.meeting-editor-help { margin-bottom: 16px; padding: 14px 16px; color: #31543b; background: #eef6ef; border: 1px solid #c9ddcd; border-radius: 9px; line-height: 1.5; }
.meeting-editor-help strong { display: block; }
.meeting-schedule-mode {
  display: grid; grid-template-columns: minmax(260px, .8fr) minmax(360px, 1.2fr); gap: 22px;
  margin-bottom: 18px; padding: 18px; background: #fff; border: 1px solid #cbd5cc; border-radius: 11px;
}
.meeting-schedule-mode h2 { margin: 0 0 12px; color: var(--leaf-dark); font: 700 20px/1.25 Georgia, serif; }
.meeting-schedule-mode p { margin: 10px 0 0; color: var(--muted); line-height: 1.45; }
.meeting-mode-checkbox { display: flex; align-items: center; gap: 10px; font-weight: 700; }
.meeting-mode-checkbox input { width: 20px; height: 20px; accent-color: var(--leaf); }
.meeting-description-field { display: grid; gap: 6px; }
.meeting-description-field > span, .meeting-generated-description strong { color: var(--leaf-dark); font-weight: 700; }
.meeting-generated-description strong span { color: var(--muted); font-weight: 400; }
.meeting-description-field textarea { width: 100%; min-height: 116px; resize: vertical; }
.meeting-description-field small { color: var(--muted); line-height: 1.4; }
.meeting-generated-description {
  margin-bottom: 16px; padding: 14px 16px; background: #f7f4ed; border: 1px solid #ddd4bf; border-radius: 9px;
}
.meeting-generated-description p { margin: 5px 0 0; line-height: 1.5; }
.meeting-cards { display: grid; gap: 16px; }
.meeting-card { padding: 18px; background: #fff; border: 1px solid #cbd5cc; border-radius: 11px; box-shadow: 0 5px 18px rgb(38 55 43 / 6%); }
.meeting-card-header { display: flex; align-items: flex-start; justify-content: space-between; gap: 18px; margin-bottom: 16px; padding-bottom: 13px; border-bottom: 1px solid var(--line); }
.meeting-card-header span { color: var(--plum); font-size: 12px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; }
.meeting-card-header h2 { max-width: 900px; margin: 3px 0 0; color: var(--leaf-dark); font-size: 19px; line-height: 1.35; }
.meeting-fields { display: grid; grid-template-columns: repeat(4, minmax(160px, 1fr)); gap: 13px 15px; }
.meeting-field { display: grid; min-width: 0; gap: 5px; color: #33423a; font-size: 13px; font-weight: 650; }
.meeting-field.is-wide { grid-column: span 2; }
.meeting-field input, .meeting-field select, .meeting-field textarea, .meeting-exdate-list input {
  width: 100%;
  min-width: 0;
  min-height: 40px;
  padding: 8px 9px;
  color: var(--ink);
  background: #fff;
  border: 1px solid #bdc9bf;
  border-radius: 6px;
  font-weight: 400;
}
.meeting-field textarea { resize: vertical; }
.meeting-field input:focus, .meeting-field select:focus, .meeting-field textarea:focus, .meeting-exdate-list input:focus { outline: 3px solid color-mix(in srgb, var(--focus) 25%, transparent); border-color: var(--focus); }
.meeting-recurrence { margin-top: 17px; padding: 16px; background: #f7f9f6; border: 1px solid #dce4dc; border-radius: 8px; }
.meeting-recurrence[hidden] { display: none; }
.recurrence-basics, .recurrence-ending { grid-template-columns: repeat(4, minmax(150px, 1fr)); }
.meeting-weekdays { display: flex; flex-wrap: wrap; gap: 8px 15px; margin: 16px 0; padding: 11px 12px; border: 1px solid #d1dbd2; border-radius: 7px; }
.meeting-weekdays legend { padding: 0 5px; color: #33423a; font-size: 13px; font-weight: 650; }
.meeting-weekdays label { display: inline-flex; align-items: center; gap: 5px; font-size: 13px; }
.meeting-exceptions { margin-top: 16px; padding-top: 14px; border-top: 1px solid #d7dfd8; }
.meeting-exceptions > div:first-child { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.meeting-exceptions > div:first-child span { flex: 1 1 360px; color: var(--muted); font-size: 13px; }
.meeting-exdate-list { display: grid; gap: 8px; margin-top: 10px; }
.meeting-exdate-list > div { display: grid; grid-template-columns: minmax(220px, 360px) auto; gap: 8px; justify-content: start; }
.meeting-imported-note { margin-top: 16px; padding: 12px 14px; background: #fff8e8; border: 1px solid #e4d2a6; border-radius: 7px; }
.meeting-imported-note strong { color: #674f24; font-size: 13px; }
.meeting-imported-note p { margin: 4px 0 0; white-space: pre-wrap; color: #645b48; line-height: 1.45; }
.meeting-empty-state { padding: 36px 24px; text-align: center; background: #fff; border: 1px dashed #b9c6bb; border-radius: 10px; }
.meeting-empty-state h2 { margin: 0 0 6px; color: var(--leaf-dark); }
.meeting-empty-state p { margin: 0; color: var(--muted); }
.meeting-editor-footer { justify-content: space-between; margin-top: 18px; padding-bottom: 24px; }
.audit-shell { max-width: 1500px; margin: 0 auto; }
.audit-toolbar { display: flex; align-items: center; gap: 10px; margin-bottom: 10px; }
.audit-toolbar .status { margin-left: auto; color: var(--muted); font-size: 13px; }
.audit-table-wrap { overflow: auto; background: #fff; border: 1px solid #bdc7bf; }
.audit-table { width: 100%; border-collapse: collapse; font-size: 13px; }
.audit-table th,
.audit-table td { padding: 10px; border-bottom: 1px solid #d8ddd9; text-align: left; vertical-align: top; }
.audit-table th { position: sticky; top: 0; z-index: 1; color: #33423a; background: #edf2ed; white-space: nowrap; }
.audit-table td:nth-child(1),
.audit-table td:nth-child(3),
.audit-table td:nth-child(5),
.audit-table td:nth-child(6) { white-space: nowrap; }
.audit-actions { display: flex; gap: 6px; white-space: nowrap; }
.compact-button { min-height: 30px; padding: 4px 8px; font-size: 12px; }
.compact-button:disabled { opacity: .55; cursor: not-allowed; }
.undo-button { color: #7b2525; border-color: #a85c5c; }
.audit-load-more { margin-top: 12px; }
.audit-dialog { width: min(980px, calc(100vw - 32px)); max-height: calc(100vh - 48px); padding: 0; border: 1px solid #aebbb0; border-radius: 10px; color: var(--ink); }
.audit-dialog::backdrop { background: rgb(20 30 24 / 42%); }
.audit-dialog-header { display: flex; justify-content: space-between; gap: 20px; align-items: flex-start; padding: 18px 20px; border-bottom: 1px solid var(--line); }
.audit-dialog-header h2 { margin: 0 0 4px; color: var(--leaf-dark); }
.audit-dialog-header p { margin: 0; color: var(--muted); font-size: 13px; }
.audit-detail-wrap { max-height: calc(100vh - 180px); overflow: auto; }
.audit-detail-table { width: 100%; border-collapse: collapse; table-layout: fixed; }
.audit-detail-table th,
.audit-detail-table td { padding: 10px 12px; border-bottom: 1px solid var(--line); text-align: left; vertical-align: top; }
.audit-detail-table th { position: sticky; top: 0; background: #edf2ed; }
.audit-detail-table th:first-child { width: 22%; }
.audit-detail-table pre { margin: 0; white-space: pre-wrap; overflow-wrap: anywhere; font: inherit; }
.roles-shell { max-width: 1280px; margin: 0 auto; }
.roles-toolbar { display: flex; align-items: center; gap: 10px; margin-bottom: 12px; }
.roles-toolbar .status { margin-left: auto; color: var(--muted); font-size: 13px; }
.website-build-info { margin: 22px 0 0; color: var(--muted); font-size: 12px; text-align: right; }
.website-build-info a { color: inherit; font-family: ui-monospace, SFMono-Regular, Consolas, monospace; font-weight: 700; }
.clone-production-panel { display: flex; align-items: center; justify-content: space-between; gap: 24px; margin: 18px 0 28px; padding: 18px 20px; background: #fff8f5; border: 1px solid #d8beb5; border-radius: 10px; }
.clone-production-panel[hidden] { display: none; }
.clone-production-panel h2 { margin: 0 0 5px; color: #6f332c; }
.clone-production-panel p { max-width: 780px; margin: 0; color: var(--muted); }
.clone-production-panel button { flex: 0 0 auto; }
.role-add-panel { margin: 18px 0 28px; padding: 20px; background: #fff; border: 1px solid var(--line); border-radius: 10px; }
.role-add-panel h2 { margin: 0 0 14px; color: var(--leaf-dark); }
.role-add-panel form { display: grid; grid-template-columns: repeat(3, minmax(180px, 1fr)); gap: 14px; align-items: start; }
.role-add-panel label { display: grid; gap: 5px; font-weight: 600; }
.role-add-panel input, .role-add-panel select { min-height: 38px; padding: 7px 9px; border: 1px solid #cbd4cd; border-radius: 6px; background: #fff; color: var(--ink); }
.role-add-panel fieldset { grid-column: 1 / -1; }
.role-add-panel .primary-button { justify-self: start; }
.role-section { margin-top: 26px; }
.role-section h2 { margin: 0 0 5px; color: var(--leaf-dark); }
.role-section > p { margin: 0 0 10px; color: var(--muted); }
.role-count { color: var(--muted); font: 500 15px/1 sans-serif; }
.role-table-wrap { overflow: auto; background: #fff; border: 1px solid #bdc7bf; }
.role-table { width: 100%; border-collapse: collapse; font-size: 14px; }
.role-table th, .role-table td { padding: 10px 12px; border-bottom: 1px solid #d8ddd9; text-align: left; vertical-align: top; }
.role-table th { color: #33423a; background: #edf2ed; white-space: nowrap; }
.role-table th:nth-child(1) { width: 20%; }
.role-table th:nth-child(2) { width: 25%; }
.role-table th:nth-child(4) { width: 100px; }
.tab-tags { display: flex; flex-wrap: wrap; gap: 5px; }
.tab-tags span { padding: 3px 7px; border-radius: 999px; color: #31543b; background: #eaf2eb; font-size: 12px; white-space: nowrap; }
.muted-cell, .empty-cell, .field-help { color: var(--muted); }
.role-dialog { width: min(760px, calc(100vw - 32px)); max-height: calc(100vh - 48px); padding: 0; border: 1px solid #aebbb0; border-radius: 10px; color: var(--ink); }
.role-dialog::backdrop { background: rgb(20 30 24 / 42%); }
.role-dialog-header { display: flex; justify-content: space-between; gap: 20px; align-items: flex-start; padding: 18px 20px; border-bottom: 1px solid var(--line); }
.role-dialog-header h2 { margin: 0 0 4px; color: var(--leaf-dark); }
.role-dialog-header p { margin: 0; color: var(--muted); }
.role-dialog form { padding: 18px 20px; }
.role-dialog-fields { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; margin-bottom: 16px; }
.role-dialog-fields label { display: grid; gap: 5px; font-weight: 600; }
.role-dialog-fields input { min-height: 38px; padding: 7px 9px; border: 1px solid #cbd4cd; border-radius: 6px; color: var(--ink); background: #fff; }
.role-dialog fieldset, .role-add-panel fieldset { min-width: 0; padding: 12px; border: 1px solid var(--line); border-radius: 7px; }
.field-help { margin: 0 0 10px; font-size: 13px; }
.tab-checkboxes { display: grid; grid-template-columns: repeat(auto-fit, minmax(170px, 1fr)); gap: 8px 14px; max-height: 340px; overflow: auto; }
.tab-checkboxes label { display: flex; align-items: flex-start; gap: 7px; font-weight: 400; }
.tab-checkboxes input { min-height: auto; margin-top: 3px; }
.role-dialog-actions { display: flex; justify-content: space-between; gap: 12px; margin-top: 16px; }
.danger-button { color: #842c2c; border-color: #a85c5c; }
.secondary-button:disabled { opacity: .55; cursor: wait; }
.api-clients-heading { display: flex; align-items: flex-end; justify-content: space-between; gap: 18px; margin-bottom: 10px; }
.api-clients-heading h2 { margin-bottom: 5px; }
.api-clients-heading p { margin: 0; color: var(--muted); }
.api-client-table { min-width: 1180px; }
.api-client-table th:nth-child(1), .api-client-table th:nth-child(2) { width: auto; }
.api-client-table th:nth-child(4) { width: auto; }
.api-client-table td:nth-child(n+4):nth-child(-n+9) { white-space: nowrap; }
.api-client-actions { display: flex; gap: 6px; white-space: nowrap; }
.checkbox-field { display: flex !important; align-items: center; align-self: end; min-height: 38px; gap: 9px !important; }
.checkbox-field input { width: 18px; min-height: 18px; accent-color: var(--leaf); }
.api-secret-dialog { width: min(680px, calc(100vw - 32px)); }
.api-secret-content { padding: 18px 20px; }
.api-secret-value { display: block; padding: 14px; overflow-wrap: anywhere; color: #24392b; background: #f1f5f1; border: 1px solid #c7d2c9; border-radius: 7px; font-size: 14px; user-select: all; }
.api-secret-content .field-help { margin-top: 10px; }
.role-dialog .form-status { min-height: 1.25rem; color: #8a3a2a; }

.filter-set-shell { max-width: 1680px; margin: 0 auto; }
.filter-set-toolbar {
  position: sticky;
  top: 0;
  z-index: 8;
  display: flex;
  align-items: end;
  gap: 9px;
  flex-wrap: wrap;
  margin: -8px -8px 16px;
  padding: 10px 8px;
  background: rgb(251 250 245 / 95%);
  border-bottom: 1px solid var(--line);
  backdrop-filter: blur(8px);
}
.filter-set-toolbar > a,
.filter-set-toolbar > button,
.roles-toolbar > a { display: inline-flex; align-items: center; text-decoration: none; }
.filter-set-toolbar .status { margin-left: auto; align-self: center; color: var(--muted); font-size: 13px; }
.existing-filter-set { display: grid; min-width: min(420px, 100%); gap: 4px; color: #33423a; font-size: 12px; font-weight: 650; }
.existing-filter-set select { min-height: 38px; padding: 7px 9px; color: var(--ink); background: #fff; border: 1px solid #cbd4cd; border-radius: 6px; }
.filter-set-card { margin: 0 0 16px; padding: 18px; background: #fff; border: 1px solid #cfd8d0; border-radius: 10px; box-shadow: 0 4px 14px rgb(38 55 43 / 5%); }
.filter-set-card h2 { margin: 0 0 4px; color: var(--leaf-dark); }
.filter-set-card p { margin: 0; color: var(--muted); }
.filter-set-details-card { display: grid; grid-template-columns: minmax(280px, 1.2fr) minmax(280px, 1fr); gap: 20px; }
.filter-set-description { display: grid; gap: 6px; color: #33423a; font-weight: 650; }
.filter-set-description input { min-height: 42px; padding: 8px 10px; color: var(--ink); background: #fff; border: 1px solid #bdc9bf; border-radius: 6px; font-weight: 400; }
.filter-set-details-card .field-help { margin-top: 6px; }
.field-label { display: block; margin-bottom: 6px; color: #33423a; font-weight: 650; }
.filter-set-card-heading { display: flex; align-items: center; justify-content: space-between; gap: 18px; margin-bottom: 14px; }
.filter-result-actions { display: flex; align-items: center; justify-content: flex-end; gap: 14px; flex-wrap: wrap; }
.filter-result-membership-filter { display: inline-flex; align-items: center; gap: 7px; color: #33423a; font-size: 13px; font-weight: 600; }
.filter-result-membership-filter input { margin: 0; }
.filter-controls { display: grid; grid-template-columns: repeat(5, minmax(170px, 1fr)); gap: 10px; align-items: start; }
.excel-filter { position: relative; min-width: 0; }
.excel-filter > summary {
  min-height: 40px;
  padding: 9px 34px 9px 11px;
  overflow: hidden;
  color: #33423a;
  background: #f8faf8;
  border: 1px solid #bdc9bf;
  border-radius: 6px;
  cursor: pointer;
  font-weight: 600;
  text-overflow: ellipsis;
  white-space: nowrap;
  list-style: none;
}
.excel-filter > summary::-webkit-details-marker { display: none; }
.excel-filter > summary::after { content: '▾'; position: absolute; top: 10px; right: 12px; color: var(--muted); }
.excel-filter[open] > summary { border-color: var(--focus); outline: 2px solid color-mix(in srgb, var(--focus) 18%, transparent); }
.excel-filter-menu {
  position: absolute;
  top: calc(100% + 5px);
  left: 0;
  z-index: 20;
  width: max(100%, 270px);
  padding: 10px;
  background: #fff;
  border: 1px solid #aebbb0;
  border-radius: 7px;
  box-shadow: 0 12px 30px rgb(32 48 38 / 18%);
}
.filter-set-details-card .excel-filter-menu { position: static; width: 100%; margin-top: 5px; box-shadow: 0 8px 22px rgb(32 48 38 / 12%); }
.excel-filter-search { width: 100%; min-height: 36px; padding: 7px 8px; border: 1px solid #cbd4cd; border-radius: 5px; }
.excel-filter-actions { display: flex; gap: 12px; padding: 8px 1px 6px; border-bottom: 1px solid var(--line); }
.excel-filter-action { padding: 0; color: var(--leaf-dark); background: transparent; border: 0; cursor: pointer; font-size: 12px; text-decoration: underline; }
.excel-filter-options { display: grid; gap: 5px; max-height: 260px; padding-top: 8px; overflow: auto; }
.excel-filter-options label { display: flex; align-items: flex-start; gap: 7px; min-width: 0; font-size: 13px; overflow-wrap: anywhere; }
.excel-filter-options input { flex: 0 0 auto; margin-top: 2px; }
.filter-result-grid-wrap { max-height: 540px; overflow: auto; border: 1px solid #bdc7bf; }
.filter-result-grid { width: 100%; border-collapse: separate; border-spacing: 0; font-size: 13px; }
.filter-result-grid th,
.filter-result-grid td { padding: 8px 10px; border-right: 1px solid #d8ddd9; border-bottom: 1px solid #d8ddd9; text-align: left; vertical-align: top; }
.filter-result-grid th { position: sticky; top: 0; z-index: 2; color: #33423a; background: #edf2ed; white-space: nowrap; }
.filter-result-grid th:first-child,
.filter-result-grid td:first-child { width: 58px; text-align: center; }
.filter-result-grid td:nth-child(2) { min-width: 220px; font-weight: 600; }
.filter-result-grid td:not(:nth-child(2)) { min-width: 135px; }
.filter-result-grid tr.search-result-selected td { background: #edf7ee; }
.filter-result-grid tr.search-result-deselected td { background: #fff0ee; }
.filter-set-dialog { width: min(1320px, calc(100vw - 30px)); max-height: calc(100vh - 36px); padding: 0; color: var(--ink); border: 1px solid #aebbb0; border-radius: 10px; }
.filter-set-dialog::backdrop { background: rgb(20 30 24 / 42%); }
.filter-set-dialog-header { display: flex; align-items: flex-start; justify-content: space-between; gap: 18px; padding: 16px 18px; border-bottom: 1px solid var(--line); }
.filter-set-dialog-header h2 { margin: 0 0 4px; color: var(--leaf-dark); }
.filter-set-dialog-header p { margin: 0; color: var(--muted); }
.filter-set-dialog-body { max-height: calc(100vh - 140px); overflow: auto; }
.login-shell { width: min(960px, 100%); margin: 0 auto; }
.login-options-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 18px; }
.login-option { max-width: none; }
.login-option p { color: var(--muted); line-height: 1.55; }
.login-option .primary-button { display: inline-flex; align-items: center; text-decoration: none; }
.login-magic-form { display: grid !important; grid-template-columns: 1fr auto; align-items: end; }
.login-magic-form label { grid-column: 1 / -1; font-weight: 600; }
.login-magic-form input { min-width: 0; width: 100%; }
.login-options-grid + .notice { margin-top: 16px; }
.account-panel { max-width: none; }
.account-kicker { margin: 0 0 4px; color: var(--muted); font-size: 13px; text-transform: uppercase; letter-spacing: .06em; }
.account-panel h2 { overflow-wrap: anywhere; }
.account-panel > p:not(.account-kicker) { color: var(--muted); }
.account-actions { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; margin: 22px 0; }
.account-action { display: grid; gap: 4px; min-height: 104px; padding: 18px; color: var(--ink); background: #f8fbf8; border: 1px solid #cad6cb; border-radius: 9px; text-decoration: none; }
.account-action:hover { border-color: var(--leaf); background: #f0f7f1; }
.account-action:focus-visible { outline: 3px solid color-mix(in srgb, var(--focus) 35%, transparent); outline-offset: 2px; }
.account-action strong { color: var(--leaf-dark); font-size: 17px; }
.account-action span { color: var(--muted); line-height: 1.45; }
.new-sangha-shell, .review-sangha-shell { width: min(1280px, 100%); margin: 0 auto; }
.signed-in-note { margin: 0 0 18px; padding: 12px 14px; color: #31543b; background: #eef6ef; border-radius: 8px; }
.new-sangha-form { display: grid; gap: 18px; }
.required-fields-note { margin: 0; color: var(--muted); font-size: 13px; text-align: right; }
.required-marker { color: #9b2f2f; font-weight: 800; }
.new-sangha-form > fieldset,
.review-sangha-groups { min-width: 0; margin: 0; padding: 18px; background: #fff; border: 1px solid #cbd5cc; border-radius: 10px; }
.new-sangha-form > fieldset > legend { padding: 0 6px; color: var(--leaf-dark); font: 700 21px/1.2 Georgia, serif; }
.new-sangha-fields { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 14px 16px; }
.new-sangha-fields > label,
.tag-field { display: grid; align-content: start; gap: 6px; color: #33423a; font-size: 13px; font-weight: 650; }
.new-sangha-fields > label.is-wide { grid-column: 1 / -1; }
.new-sangha-fields input,
.new-sangha-fields textarea,
.tag-entry input { width: 100%; min-width: 0; min-height: 40px; padding: 8px 10px; color: var(--ink); background: #fff; border: 1px solid #c3cec5; border-radius: 6px; font: inherit; }
.new-sangha-fields textarea { resize: vertical; }
.new-sangha-fields small, .tag-field small { color: var(--muted); font-weight: 400; line-height: 1.35; }
.new-sangha-types { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 7px 12px; min-width: 0; margin: 0; padding: 10px 12px; border: 1px solid #d6ddd7; border-radius: 7px; }
.new-sangha-types legend { padding: 0 4px; color: #33423a; font-size: 13px; font-weight: 650; }
.new-sangha-types label { display: flex; align-items: flex-start; gap: 7px; font-size: 13px; }
.new-sangha-types input { width: auto; min-height: auto; margin-top: 2px; }
.tag-entry { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 7px; }
.tag-list { display: flex; flex-wrap: wrap; gap: 6px; min-height: 24px; }
.editable-tag { display: inline-flex; align-items: center; gap: 6px; padding: 4px 7px 4px 10px; color: #31543b; background: #edf7ee; border: 1px solid #bfd3c2; border-radius: 999px; font-weight: 600; }
.editable-tag button { appearance: none; padding: 0 2px; color: #5e2b2b; background: transparent; border: 0; cursor: pointer; font-size: 18px; line-height: 1; }
.embedded-meeting-fieldset #meeting-editor-panel { display: grid; gap: 16px; }
.embedded-meeting-fieldset .meeting-schedule-mode { margin: 0; }
.new-sangha-actions, .review-sangha-actions { display: flex; justify-content: flex-end; flex-wrap: wrap; gap: 12px; padding: 2px 0 18px; }
.new-sangha-success { max-width: 720px; margin: 24px auto; }
.review-sangha-form { padding: 20px 0; }
.review-sangha-meeting-link { display: flex; justify-content: flex-end; }
.review-sangha-meeting-link a { text-decoration: none; }
.review-sangha-groups { margin-bottom: 18px; }
.review-sangha-groups h2 { margin: 0 0 5px; color: var(--leaf-dark); }
.review-sangha-groups-heading { display: flex; align-items: flex-start; justify-content: space-between; gap: 18px; margin-bottom: 14px; }
.review-sangha-groups-heading p { margin: 0; color: var(--muted); }
.review-sangha-groups-heading a { flex: 0 0 auto; text-decoration: none; }
.review-sangha-group-options { display: grid; grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); gap: 8px 14px; }
.review-sangha-group-options label { display: flex; align-items: flex-start; gap: 8px; padding: 9px 10px; background: #f8fbf8; border: 1px solid #d3ddd4; border-radius: 7px; }
.review-sangha-group-options input { flex: 0 0 auto; margin-top: 3px; }
.pending-sanghas { display: grid; gap: 10px; }
.pending-sangha-card { display: flex; align-items: center; justify-content: space-between; gap: 18px; padding: 14px 16px; background: #fff8e8; border: 1px solid #e4d2a6; border-radius: 8px; }
.pending-sangha-card h3 { margin: 0 0 4px; color: var(--leaf-dark); }
.pending-sangha-card p { margin: 0; color: var(--muted); }
.pending-sangha-card a { flex: 0 0 auto; text-decoration: none; }
[hidden] { display: none !important; }

@media (max-width: 700px) {
  /* The staff pages keep the older chrome. These were on the bare selector and
     so reached the finder too, stacking its three section links into three
     lines where every other public page keeps them on one. */
  body:not(.map-page) .site-header { align-items: flex-start; padding: 12px 14px; }
  body:not(.map-page) .site-header nav { flex-direction: column; gap: 4px; text-align: right; }
  .filter-toggle {
    display: block;
    position: absolute;
    top: 12px;
    left: 12px;
    z-index: 1001;
    padding: 8px 12px;
    background: #fff;
    border: 1px solid #cfd7d0;
    border-radius: 6px;
  }
  .map-controls {
    display: none;
    position: absolute;
    inset: 0 auto auto 0;
    z-index: 1000;
    width: min(300px, calc(100vw - 24px));
    padding: 60px 16px 18px;
    flex-direction: column;
    align-items: stretch;
    box-shadow: 3px 6px 20px rgb(0 0 0 / 16%);
  }
  .map-controls.is-open { display: flex; }
  .map-controls select, .map-controls input { width: 100%; }
  .result-count { margin-left: 0; }
  .editor-shell { padding: 16px 10px; }
  .editor-intro h1 { font-size: 27px; }
  .grid-wrap { max-height: calc(100vh - 280px); }
  .record-detail-open #editor-notice { margin: 10px 12px 0; }
  .record-detail-header { grid-template-columns: auto 1fr auto; gap: 10px; min-height: 66px; padding: 10px 12px; }
  .record-detail-heading span { display: none; }
  .record-detail-heading h2 { font-size: 19px; }
  .record-detail-header .secondary-button,
  .record-detail-header .save-button { min-width: auto; min-height: 38px; padding: 7px 10px; }
  .record-detail-form { grid-template-columns: 1fr; gap: 12px; padding: 16px 12px 28px; }
  .record-detail-field.is-wide { grid-column: span 1; }
  .public-url-row { grid-template-columns: 1fr; }
  .meeting-editor-shell { padding: 14px 10px; }
  .meeting-editor-heading { position: static; align-items: stretch; flex-direction: column; gap: 14px; margin: -14px -10px 14px; padding: 16px 12px; }
  .meeting-editor-heading h1 { font-size: 25px; }
  .meeting-editor-heading-actions { align-items: stretch; }
  .meeting-editor-heading-actions > * { flex: 1; justify-content: center; }
  .meeting-card { padding: 14px 12px; }
  .meeting-schedule-mode { grid-template-columns: 1fr; padding: 14px 12px; }
  .meeting-card-header { align-items: stretch; flex-direction: column; }
  .meeting-card-actions { flex-wrap: wrap; }
  .meeting-fields, .recurrence-basics, .recurrence-ending { grid-template-columns: 1fr; }
  .meeting-field.is-wide { grid-column: span 1; }
  .meeting-exdate-list > div { grid-template-columns: 1fr auto; }
  .audit-toolbar { align-items: stretch; flex-wrap: wrap; }
  .audit-toolbar .status { width: 100%; margin-left: 0; }
  .audit-dialog-header { align-items: stretch; }
  .audit-detail-table { min-width: 680px; }
  .roles-toolbar { align-items: stretch; flex-wrap: wrap; }
  .roles-toolbar .status { width: 100%; margin-left: 0; }
  .clone-production-panel { align-items: stretch; flex-direction: column; }
  .clone-production-panel button { align-self: flex-start; }
  .role-add-panel form { grid-template-columns: 1fr; }
  .role-table { min-width: 720px; }
  .role-dialog-header { align-items: stretch; }
  .role-dialog-fields { grid-template-columns: 1fr; }
  .api-clients-heading { align-items: stretch; flex-direction: column; }
  .api-clients-heading button { align-self: flex-start; }
  .filter-set-toolbar { align-items: stretch; }
  .filter-set-toolbar .status { width: 100%; margin-left: 0; }
  .existing-filter-set { width: 100%; min-width: 0; }
  .filter-set-details-card { grid-template-columns: 1fr; }
  .filter-controls { grid-template-columns: 1fr; }
  .excel-filter-menu { position: static; width: 100%; margin-top: 5px; box-shadow: 0 8px 22px rgb(32 48 38 / 12%); }
  .filter-set-card-heading { align-items: stretch; flex-direction: column; }
  .filter-result-grid { min-width: 980px; }
  .login-options-grid, .account-actions { grid-template-columns: 1fr; }
  .login-magic-form { grid-template-columns: 1fr; }
  .new-sangha-fields { grid-template-columns: 1fr; }
  .new-sangha-fields > label.is-wide { grid-column: span 1; }
  .new-sangha-types { grid-template-columns: 1fr; }
  .pending-sangha-card { align-items: stretch; flex-direction: column; }
  .pending-sangha-card a { text-align: center; }
}

/* ---- the finder page ---------------------------------------
   index.html now loads tokens.css and site.css, so the bar, the
   footer, the type and the colours are the site's own. What is
   left here is the part no other page has: the filter row, the
   map, and the cards. Everything below is written in tokens, and
   scoped to .map-page so the staff pages keep the older chrome
   above. */
/* Every part of the box is the same height, so it is said once. */
.map-page { --box-height: clamp(460px, 68vh, 860px); }
/* The finder sits in a section of its own now, and the section's own padding
   is what keeps the dark band of the footer off the bottom of the table. */
.map-page #sfm-container { position: relative; background: transparent; }

/* ---- the welcome ------------------------------------------------
   Every other page opens with a kicker, a title and a line under it, and
   then gets on with itself. This one opens with a letter, because what it
   is offering is a way of finding people rather than a page to read. The
   greeting and the photograph sit side by side so that both of them and
   the top of the directory are on the first screen: stacked, the welcome
   alone was two screens of scrolling before anything could be searched. */
.map-page .welcome {
  display: grid;
  /* The letter is set to the measure it wants to be read at and the
     photograph to a size that ends near where the letter does; the space
     left over goes between them, with each held to the gutter it is nearest.
     Sized as fractions of the width instead, the photograph grew with the
     window until it was half again the height of the words beside it. Both
     measures are in rem so that the column and the text's own max-width
     cannot disagree — in `ch` they were worked out at two different font
     sizes and did. */
  grid-template-columns: minmax(0, 30rem) minmax(0, 26rem);
  justify-content: space-between;
  gap: clamp(1.5rem, 4vw, 3rem);
  /* Aligned at the top, not the middle: centred, neither the top edge nor the
     bottom lined up with anything, and two ragged edges read as a mistake
     where one reads as a decision. */
  align-items: start;
  /* The room under it is the room the section below has over it, so the rule
     between them sits in the middle of its own space rather than clinging to
     the letter. Above it there is only the gap between the title and the
     greeting: the room that keeps the page off the bar is the head's now. */
  padding-block: clamp(1.5rem, 3.5vw, 2.2rem) clamp(2.2rem, 6vw, 3.4rem);
}
/* The letter is set a little larger than body copy — it is the first thing
   read and there is not much of it. In `em`, because the site's body is 17px
   and `1rem` is 16: written in rem this was a size *smaller* than the page
   around it. One size and no clamp, because the clamp it replaces sat on its
   floor at every width under about 1200 and so was only ever one size
   anyway. */
.map-page .welcome-words {
  max-width: 30rem;
  font-size: 1.08em;
  line-height: 1.65;
}
.map-page .welcome-words p:last-child { margin-bottom: 0; }
.map-page .welcome figure.photo { margin: 0; max-width: none; }

/* Under 900px — the same width at which the finder itself gives up its second
   column — there is no room for two, so the letter takes the width and the
   photograph follows it. It is held to a size a tablet can take in at a
   glance: at the full width of that screen it is a billboard, and the
   directory below it is a scroll away for no reason. */
@media (max-width: 900px) {
  .map-page .welcome { grid-template-columns: minmax(0, 1fr); }
  .map-page .welcome figure.photo { max-width: 30rem; }
}

/* The page's head: the kicker says what plumline does, the title is the name.
   Its room above comes from here rather than from the welcome below it, which
   used to be the first thing on the page. */
.map-page .page-head {
  padding-block: clamp(2.4rem, 6vw, 3.6rem) 0;
}
.map-page .page-head h1 { margin-bottom: 0; }
/* The finder's own heading is a section's, not the page's: the page is called
   plumline and this says what this part of it is for. */
.map-page #finder > .wrap > h2 {
  margin-bottom: 1rem;
}

.map-page .controls-row {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.5rem 0.7rem;
  max-width: var(--maxw);
  margin: 0 auto;
  padding: 0.2rem 20px 1rem;
  background: transparent;
  border-bottom: 0;
}
.map-page .map-controls {
  /* The filters share their line with the coordinator's link and nothing else;
     the kinds, the count and the views have a row of their own below. */
  flex: 1 1 20rem;
  /* Four controls with minimum widths come to more than a 1000px window, and
     without this they simply ran off the side of it. */
  flex-wrap: wrap;
  min-width: 0;
  min-height: 0;
  gap: 0.5rem;
  padding: 0;
  background: transparent;
  border-bottom: 0;
}
.map-page .map-controls select,
.map-page .map-controls input {
  /* The browser's own control drew its own corners — rounder than the field
     beside it in Safari — so the menu is drawn here instead, arrow and all,
     and every box on the row has the same corner. */
  appearance: none;
  -webkit-appearance: none;
  width: auto;
  min-width: 9rem;
  height: 2.25rem;
  padding: 0.25rem 0.65rem;
  color: var(--ink);
  /* Both sit lighter than the page they are on, never darker. */
  background: var(--card);
  border: 1px solid var(--rule);
  /* The same corner as the boxes you tick — the smallest the page has — on
     every control in the row. */
  border-radius: var(--radius-xs);
  font: inherit;
  font-size: 0.95rem;
}
.map-page .map-controls select {
  padding-right: 2rem;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 8'%3E%3Cpath d='M1.5 1.75L6 6.25l4.5-4.5' fill='none' stroke='%236f685e' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 0.7rem center;
  background-size: 0.7rem;
}
/* A menu is a thing you press, so it stands a little out of the page; a field
   is a thing you put words into, so it sits a little in. The same amount,
   the other way round. */
.map-page .map-controls select { box-shadow: var(--lift); }
.map-page .map-controls select::-ms-expand { display: none; }
.map-page .map-controls input { box-shadow: var(--sink); }
.map-page .map-controls input:focus-visible,
.map-page .map-controls select:focus-visible {
  outline: 2.5px solid var(--accent);
  outline-offset: 1px;
}
.map-page .map-controls input { flex: 1 1 12rem; min-width: 0; }
.map-page .map-controls label { display: flex; min-width: 0; flex: 0 1 auto; }
/* Beside the map there is no affinity menu, and the name field takes the room
   it leaves rather than the row keeping a gap where it was. */
.map-page .map-controls label[hidden] { display: none; }
/* The search box is the last of them, and takes whatever the line has left
   once the three menus have what they need. */
.map-page .map-controls label:last-of-type { flex: 1 1 12rem; }
/* margin-left: auto in the older rule above pushed this to the right; here it
   belongs at the start of the map's own column. */
/* The section's own brown rather than a grey: it is the one line of text
   sitting on the page's cream with nothing around it, and a neutral grey
   reads as a different temperature from everything beside it. */
.map-page .result-count { margin: 0; color: var(--sect-text); font-size: 0.88rem; }

/* The scope bar: what narrows the box, attached to the top of it. The count
   is the answer to the three controls beside it, so it stands at the end of
   the same line. */
.map-page .scope-bar {
  position: relative;
  grid-column: 1 / -1;
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.5rem 0.7rem;
  padding: 0.6rem 1rem;
  /* A pale band, lit from above. The controls on it keep their own faces, so
     they read as sitting on the bar rather than in it. */
  background-image: linear-gradient(var(--bar-lit), var(--bar-shade));
  border-bottom: 1px solid var(--rule);
}
/* A medium grey, taken a little towards the ink: the page's own --muted comes
   in at 4.1:1 on this band, under the 4.5 small text has to hold. */
/* Only the view with a list to step aside has anything to expand. */
.map-page:not(.view-local) .map-expand { display: none; }
.map-page .map-expand {
  margin-left: auto;
  padding: 0.3em 0.9em;
  color: var(--ink);
  background: var(--card);
  border: 1px solid var(--rule);
  border-radius: var(--radius-xs);
  box-shadow: var(--lift);
  font: inherit;
  font-size: 0.88rem;
  font-weight: 500;
  cursor: pointer;
}
.map-page .map-expand:hover { border-color: var(--clay); background: var(--ground-2); }
.map-page .map-expand:focus-visible { outline: 2.5px solid var(--accent); outline-offset: 2px; }
/* With the button in the bar, the count follows it rather than being the thing
   pushed to the end of the line. */
.map-page .scope-bar .map-expand ~ .result-count { margin-left: 0; }
.map-page .scope-bar .result-count {
  margin-left: auto;
  padding-left: 0.5rem;
  color: color-mix(in srgb, var(--muted) 85%, var(--ink));
  white-space: nowrap;
}

/* The toggle and the coordinators' way in sit beside the filters, not inside
   them: below 700px the filters collapse behind the Filters button and these
   must not collapse with them. */
/* One control in three parts rather than three buttons: a track, and the view
   you are in sitting in it. */
/* The same corner as the menus and the field it shares a row with: it was the
   one pill among boxes. */
/* One control, not three buttons floating in a tray: the segments run edge to
   edge inside it, so the one you are in reaches the control's own border
   instead of sitting in from it. The lift belongs to the control, the way it
   belongs to a menu. */
.map-page .view-toggle {
  display: inline-flex;
  align-items: stretch;
  gap: 0;
  /* The same height as the menus on the row above it. */
  height: 2.25rem;
  padding: 0;
  overflow: hidden;
  background: var(--card);
  border: 1px solid var(--rule);
  border-radius: var(--radius-xs);
  box-shadow: var(--lift);
}
/* A segment you have not chosen wears the menus' own surface; one line
   divides it from the next. */
.map-page .view-toggle button {
  font-family: var(--font);
  font-size: 0.92rem;
  font-weight: 500;
  padding: 0.3em 1.05em;
  color: var(--ink);
  background: var(--card);
  border: 0;
  border-radius: 0;
  cursor: pointer;
  transition: background 0.12s ease, color 0.12s ease;
}
.map-page .view-toggle button + button { border-left: 1px solid var(--rule); }
.map-page .view-toggle button:hover:not(.is-active):not([disabled]) { color: var(--sect-text); background: var(--card); }
/* The one you are in is filled, corner to corner. */
.map-page .view-toggle button.is-active {
  color: var(--on-accent);
  background: var(--accent-strong);
  border-color: var(--accent-strong);
}
.map-page .view-toggle button[disabled] { opacity: 0.5; cursor: default; }
.map-page .view-toggle button:focus-visible { outline: 2.5px solid var(--accent); outline-offset: -1px; }
.map-page .directory-nav { display: flex; flex-wrap: wrap; gap: 0.3rem 1rem; margin-left: auto; font-size: 0.92rem; }
/* Underlined and left underlined: it is the one link on a row of controls,
   and without the line it was read as a label. */
.map-page .directory-nav a { text-decoration: underline; text-underline-offset: 0.2em; }
.map-page .finder-directory-link {
  margin-top: 1rem;
  margin-bottom: 0;
  text-align: center;
}
.map-page .finder-directory-link a {
  font-weight: 600;
  text-decoration: underline;
  text-underline-offset: 0.2em;
}

/* The map no longer fills the window — the page has a bar above it and a
   footer below, and a band reads as part of a page where a full screen does
   not. */
.map-page #sfm-map {
  height: var(--box-height);
  min-height: 0;
  background: var(--ground-2);
  border-block: 1px solid var(--rule);
  /* Leaflet stacks its own panes from 400 up. Left in the page's own stacking
     order those beat the site header's 50 and the map slid over the bar as
     soon as anybody scrolled; a stacking context of its own keeps Leaflet's
     numbers inside the map, where they mean something. */
  position: relative;
  z-index: 0;
}
.map-page .map-error {
  position: static;
  inset: auto;
  max-width: min(var(--maxw), calc(100% - 40px));
  margin: 1rem auto 0;
  color: var(--unwhole-text);
  background: var(--unwhole-soft);
  border: 1px solid var(--unwhole);
  border-radius: var(--radius-sm);
}

/* Split: the list in a column beside the map, both inside the page's own
   width. The list scrolls on its own so the map stays put while you read. */
/* ---- the box, and the two shapes it takes ------------------------
   One container holds a view: the map with its list beside it, or the table
   with the sangha beside that. One edge, one line down the middle, the
   controls' corner and lift, and the same measure as the words above it —
   those are var(--maxw) wide with a 20px gutter inside them, so the box is
   that gutter narrower rather than running out past them. The row the edge
   cuts in half is what says the list carries on. */
.map-page #sfm-views {
  display: grid;
  gap: 0;
  align-items: stretch;
  width: min(calc(100% - 40px), calc(var(--maxw) - 40px));
  margin: 0 auto;
  padding: 0;
  background: var(--card);
  border: 1px solid var(--rule);
  border-radius: var(--radius-xs);
  box-shadow: var(--lift);
  overflow: hidden;
}
/* The map takes the wider half; the table takes the narrower one, because a
   line of columns needs less room than a map does. */
.map-page.view-local #sfm-views { grid-template-columns: minmax(19rem, 24rem) 1fr; }
/* The pane holds one sangha and stops growing once it has room for one; the
   table holds four columns and every pixel it does not get comes out of them.
   Split in fractions, the pane took 459px at every width over 1120 and the
   table's Languages column was left with 87 — enough for "Engl…" on four
   lines in five. */
.map-page.view-table #sfm-views { grid-template-columns: minmax(0, 1fr) minmax(20rem, 22rem); }
.map-page.view-table .sangha-cards:not([hidden]) {
  display: block;
  max-width: none;
  max-height: var(--box-height);
  overflow-y: auto;
  margin: 0;
  padding: 0;
  background: transparent;
}
/* Both regions can be given focus by hand when a panel closes under the
   reader; neither draws a ring for it, because arriving there is not an
   error and a ring around a whole column reads as one. */
.map-page .sangha-cards:focus,
.map-page .sangha-cards:focus-visible,
.map-page .detail-pane:focus,
.map-page .detail-pane:focus-visible { outline: none; }
.map-page .detail-pane {
  max-height: var(--box-height);
  overflow-y: auto;
  padding: 1.3rem 1.4rem 1.5rem;
  border-left: 1px solid var(--rule);
}
/* A real table, and sized like one. It was a grid of <button>s, and a grid or
   a flex box set on a table or its rows takes the table semantics away in
   every browser — which is the whole of why it is a table now (#37). So the
   columns are sized the way a table's are: `table-layout: fixed`, and a width
   on each column. Each cell is cut where it runs out rather than wrapping, so
   every line is one line.

   All leads with the name, then the kind, then the languages. Online leads
   with the two questions left when every sangha is online — the language and
   when it meets — and the name follows. Which columns there are, and in what
   order, is app.js's; these are the widths that order needs. */
.map-page .sangha-table {
  width: 100%;
  table-layout: fixed;
  /* Separate rather than collapsed: a collapsed table drops the borders of a
     sticky head, and the head has to hold its line over the rows passing
     underneath it. */
  border-collapse: separate;
  border-spacing: 0;
}
.map-page .sangha-table th,
.map-page .sangha-table td {
  padding: 0.55rem 0.5rem;
  text-align: left;
  font-weight: 400;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.map-page .sangha-table th:first-child,
.map-page .sangha-table td:first-child { padding-left: 1rem; }
.map-page .sangha-table th:last-child,
.map-page .sangha-table td:last-child { padding-right: 1rem; }
/* Kind is a fixed measure because it is a fixed vocabulary: 9.5rem is what
   "Lay Practice Centre" needs, which is 180 sanghas. "Monastic Practice
   Centre" wants half as much again and is one sangha in 1,497, so it is the
   one label that is cut. The name and the languages share what is left. */
.map-page .sangha-table .line-name { width: 47%; }
.map-page .sangha-table .line-kind { width: 9.5rem; }
.map-page .sangha-table .line-languages { width: 34%; }
.map-page.view-online .sangha-table .line-languages { width: 23%; }
.map-page.view-online .sangha-table .line-when { width: 27%; }
.map-page.view-online .sangha-table .line-name { width: 50%; }

/* The head stays put while the rows go under it. Its padding is the cells'
   own, moved onto the button inside it, so the button is the full height of
   the band while its text starts exactly where a cell's does. */
.map-page .sangha-table thead th {
  position: sticky;
  top: 0;
  z-index: 1;
  padding: 0;
  background: var(--ground-2);
  border-bottom: 1px solid var(--rule);
}
/* Each heading is the control that sorts by its column: pressed once it
   sorts, pressed again it turns round. The arrow says which way to anyone
   looking, and `aria-sort` on the heading says it to everyone else. */
.map-page .head-sort {
  display: block;
  width: 100%;
  min-width: 0;
  padding: 0.55rem 0.5rem;
  text-align: left;
  color: var(--muted);
  background: transparent;
  border: 0;
  font: inherit;
  font-size: 0.78rem;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  cursor: pointer;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.map-page .head-cell:first-child .head-sort { padding-left: 1rem; }
.map-page .head-cell:last-child .head-sort { padding-right: 1rem; }
.map-page .head-sort:hover { color: var(--ink); }
.map-page .head-sort:focus-visible { outline: 2.5px solid var(--accent); outline-offset: -3px; }
.map-page .head-cell[data-sorted] .head-sort { color: var(--sect-text); }
.map-page .head-cell[data-sorted="up"] .head-sort::after { content: " \2191"; }
.map-page .head-cell[data-sorted="down"] .head-sort::after { content: " \2193"; }

.map-page .sangha-line {
  font-size: 0.92rem;
  color: var(--ink);
  cursor: pointer;
}
.map-page .sangha-line th,
.map-page .sangha-line td { border-bottom: 1px solid var(--rule); }
/* The name cell carries the control, because a row is not a control and a
   button in every cell would be four tab stops where one is wanted. It is
   drawn as the text it replaced. */
.map-page .line-choose {
  display: block;
  width: 100%;
  min-width: 0;
  padding: 0;
  text-align: left;
  font: inherit;
  color: inherit;
  background: transparent;
  border: 0;
  cursor: pointer;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.map-page .line-choose:focus-visible { outline: 2.5px solid var(--accent); outline-offset: 2px; }
.map-page .sangha-line .line-kind,
.map-page .sangha-line .line-when,
.map-page .sangha-line .line-languages { color: var(--muted); }
.map-page .sangha-line:hover th,
.map-page .sangha-line:hover td { background: var(--sect-soft); }
/* The one you are looking at is filled, like the segment you are in. */
.map-page .sangha-line.is-selected th,
.map-page .sangha-line.is-selected td,
.map-page .sangha-line.is-selected:hover th,
.map-page .sangha-line.is-selected:hover td {
  color: var(--on-accent);
  background: var(--accent-strong);
  border-bottom-color: var(--accent-strong);
}
.map-page .sangha-line.is-selected .line-kind,
.map-page .sangha-line.is-selected .line-when,
.map-page .sangha-line.is-selected .line-languages { color: var(--on-accent); }
.map-page.view-table .list-more { display: block; margin: 1rem auto 1.2rem; }

/* Under 900px there is no room for a table and a pane beside it: the pane
   goes below the table, and the table keeps the two columns that fit. */
@media (max-width: 900px) {
  .map-page.view-table #sfm-views { grid-template-columns: minmax(0, 1fr); }
  .map-page.view-table .sangha-cards:not([hidden]) { max-height: 22rem; }
  .map-page .detail-pane { max-height: none; border-left: 0; border-top: 1px solid var(--rule); }
  /* Two columns, and the languages are the ones that go: All keeps the name
     and the kind, Online the name and when it meets. The name leads here
     whatever the order of the wide table, because somebody scrolling a phone
     finds the sangha by its name first — and both of those are app.js's doing
     now. A column can be hidden from the stylesheet; a column cannot be moved
     from it, since a table's columns are the order they are written in. */
  .map-page .sangha-table .line-name { width: 63%; }
  .map-page .sangha-table .line-kind,
  .map-page .sangha-table .line-when { width: 37%; }
  .map-page.view-online .sangha-table .line-name { width: 63%; }
  .map-page.view-online .sangha-table .line-when { width: 37%; }
}

/* Expanded: the list steps aside and the map takes the whole box. */
.map-page.view-local.map-wide #sfm-views { grid-template-columns: minmax(0, 1fr); }
.map-page.view-local.map-wide .sangha-cards { display: none; }
.map-page.view-local.map-wide #sfm-map { grid-column: 1; border-left: 0; }

/* Inside the box the map has no edges of its own; the one line between it and
   the list is what divides the two halves. */
.map-page.view-local #sfm-map {
  grid-column: 2;
  grid-row: 2;
  height: var(--box-height);
  border: 0;
  border-left: 1px solid var(--rule);
  border-radius: 0;
  box-shadow: none;
}
.map-page.view-local .sangha-cards:not([hidden]) {
  grid-column: 1;
  grid-row: 2;
  /* minmax(0, 1fr), not 1fr: a grid track's automatic minimum is its content,
     and the address line does not wrap, so the column grew past the page and
     took a horizontal scrollbar with it. */
  grid-template-columns: minmax(0, 1fr);
  gap: 0;
  max-height: var(--box-height);
  overflow-y: auto;
  padding: 0;
  margin: 0;
  max-width: none;
  background: transparent;
}
/* In the box the rows are one list rather than a stack of small panels: no
   box of their own, and a line between one and the next. The kind's colour
   stays on the left edge, where it was. */
.map-page.view-local .sangha-row {
  background: transparent;
  border: 0;
  border-bottom: 1px solid var(--rule);
  border-radius: 0;
  padding: 0.7rem 1rem 0.75rem;
}
.map-page.view-local .sangha-row:last-of-type { border-bottom: 0; }
.map-page.view-local .list-more { margin: 0.9rem 0 1.1rem; }
.map-page.view-local .cards-empty { min-height: 0; padding: 2rem 1rem; }

/* An online sangha has no address and no pin, so the cards are the only place
   it can appear (#36). They carry every match, local sanghas included, in the
   panel shape the rest of the site uses for a list of things. */
.map-page .sangha-cards:not([hidden]) {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(19rem, 1fr));
  min-width: 0;
  /* Rows, so they sit closer together than the cards did. */
  gap: 0.5rem;
  align-content: start;
  align-items: start;
  max-width: var(--maxw);
  margin: 0 auto;
  padding: 1.4rem 20px 2.4rem;
}
/* A row. The list beside the map is a list of names, not a stack of panels:
   the name, and one line under it saying what kind of sangha it is and where
   or when it meets. Everything else is in the panel the row opens. */
.map-page .sangha-row {
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
  width: 100%;
  min-width: 0;
  margin: 0;
  padding: 0.65rem 0.9rem 0.7rem;
  text-align: left;
  font: inherit;
  color: var(--ink);
  background: var(--card);
  border: 1px solid var(--rule);
  border-radius: var(--radius-sm);
  cursor: pointer;
}
.map-page .sangha-row:hover { background: var(--sect-soft); }
.map-page .sangha-row:focus-visible { outline: 2.5px solid var(--accent); outline-offset: 2px; }
/* One line each, cut with an ellipsis: a row that wraps is a row that makes
   the list a different height everywhere it happens. */
/* Quiet: a list of two hundred names is read by scanning, and every one of
   them set bold and every kind set in its own colour made a wall. The map
   keeps the colours — that is where they tell you something. */
.map-page .row-name {
  min-width: 0;
  color: var(--ink);
  font-size: 1rem;
  font-weight: 400;
  line-height: 1.35;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
/* The second line is what a name is checked against, not what is read, so it
   is set smaller than the name above it. It stays on --muted: the page's grey
   is 5.5:1 on the card, and anything lighter stops holding the 4.5 small text
   has to hold. */
.map-page .row-meta {
  display: flex;
  min-width: 0;
  align-items: baseline;
  gap: 0.35rem;
  font-size: 0.8rem;
  line-height: 1.45;
}
/* On the hover fill the page's grey is 4.4:1, under what small text has to
   hold, so it takes the same step towards the ink the scope bar's count does. */
.map-page .sangha-row:hover .row-meta,
.map-page .sangha-line:hover .line-kind,
.map-page .sangha-line:hover .line-when,
.map-page .sangha-line:hover .line-languages { color: color-mix(in srgb, var(--muted) 85%, var(--ink)); }
.map-page .row-rest {
  min-width: 0;
  color: var(--muted);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
/* No separator in front of it: the row's second line begins with where the
   sangha is. The middot that used to sit here divided that from the kind, and
   the kind has gone. */

/* The panel a row or a pin opens: the sangha in full, over the page rather
   than pushing the list apart under it. `popover` puts it in the top layer,
   so it clears the map without a z-index of its own. */
.map-page .sangha-panel {
  display: none;
  width: min(30rem, calc(100vw - 2rem));
  /* The panel does not scroll — the tail is drawn outside its edge and would
     be clipped away. What is inside it scrolls. */
  overflow: visible;
  padding: 1.5rem 1.4rem 1.4rem;
  color: var(--ink);
  background: var(--card);
  border: 1px solid var(--rule);
  border-radius: var(--radius-xs);
  /* It takes the page's corner like everything else; what lifts it off the
     page is the shadow, and only the shadow — deeper and wider than anything
     else here carries, because it is the one thing that floats. */
  box-shadow: 0 6px 16px color-mix(in srgb, var(--charcoal) 13%, transparent),
              0 28px 64px color-mix(in srgb, var(--charcoal) 20%, transparent);
}
@supports selector(:popover-open) {
  .map-page .sangha-panel:popover-open { display: block; }
}
/* Where `popover` is not understood the panel is shown by hand, and placed by
   hand with it. */
.map-page .sangha-panel.is-open {
  display: block;
  position: fixed;
  top: 50%;
  left: 50%;
  z-index: 2000;
  transform: translate(-50%, -50%);
}
/* Where it has been placed beside a row, it is placed in full: the centring
   above would move it half its own width and height off that spot. */
.map-page .sangha-panel.is-open[data-tail] { transform: none; }
/* No dimming behind it: it is a panel beside the row you pressed, not a
   light box over the page. It carries a little more shadow instead, since
   nothing else separates it from what is underneath. */
.map-page .sangha-panel::backdrop { background: transparent; }
.map-page .panel-scroll { max-height: min(30rem, 72vh); overflow-y: auto; }
/* The way out, spoken above 700px and drawn below it. Outside the scrolling
   part, so on a phone it is at the foot of the panel wherever the reader has
   got to in the sangha. */
.map-page .panel-close {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}
@media (max-width: 700px) {
  .map-page .panel-close {
    position: static;
    display: block;
    width: 100%;
    height: auto;
    margin: 1rem 0 0;
    padding: 0.5em 1.1em;
    overflow: visible;
    clip: auto;
    color: var(--ink);
    background: var(--card);
    border: 1.5px solid var(--rule);
    border-radius: var(--radius-xs);
    box-shadow: var(--lift);
    font: inherit;
    font-weight: 500;
    cursor: pointer;
  }
  .map-page .panel-close:hover { border-color: var(--clay); background: var(--ground-2); }
}
/* Nothing inside closes it — Escape, a press outside, or the row again — so
   the panel itself takes the focus when it opens. It draws no ring for that:
   the panel arriving is what says where you are, and a ring around the whole
   of it reads as an error. */
.map-page .sangha-panel:focus,
.map-page .sangha-panel:focus-visible { outline: none; }
/* The tail: a small square of the panel's own surface, turned on its corner
   and pushed half out of the edge, with the two sides that show carrying the
   panel's border. It sits level with the middle of the row that opened the
   panel, so the two are read as one thing. */
.map-page .sangha-panel[data-tail]::before {
  content: "";
  position: absolute;
  top: var(--tail-top, 2rem);
  width: 0.75rem;
  height: 0.75rem;
  margin-top: -0.375rem;
  background: var(--card);
  border: 1px solid var(--rule);
  transform: rotate(45deg);
}
.map-page .sangha-panel[data-tail="left"]::before {
  left: -0.4rem;
  border-top: 0;
  border-right: 0;
}
.map-page .sangha-panel[data-tail="right"]::before {
  right: -0.4rem;
  border-bottom: 0;
  border-left: 0;
}

/* Two lines of name, however long it is, so one card is never taller than
   its neighbour. */
.map-page .card-title {
  margin: 0;
  font-size: 1.1rem;
  font-weight: 600;
  color: var(--ink);
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  line-clamp: 2;
  overflow: hidden;
}
.map-page .card-detail {
  /* Two columns: the labels, and everything that answers them. Alipasha,
     29 Aug — Where, When and Contact each began wherever its own label ended,
     so the card had three left edges. The label column takes the width of the
     longest label on that card, so a card without Affinities is not indented
     for one, and it is `max-content` rather than a measure written down here,
     which would be a guess that another word breaks. */
  display: grid;
  grid-template-columns: max-content minmax(0, 1fr);
  align-items: baseline;
  gap: 0.5rem;
  padding: 0.2rem 1.3rem 1.2rem;
  border-top: 1px solid var(--rule);
  margin-top: 0.2rem;
  padding-top: 0.9rem;
}
/* A line is not a box of its own here: its label and its value are the two
   cells of the row, which is what lets every line on the card share one pair
   of columns. */
.map-page .card-line { display: contents; }
.map-page .card-line > .card-label,
.map-page .card-line > .card-value { margin: 0; font-size: 0.95rem; line-height: 1.55; overflow-wrap: anywhere; }
/* "When:" is a label like any other on the card, so it keeps its line: the
   first time the sangha meets sits beside it, and any others line up under
   that rather than under the label. */
.map-page .card-meetings { margin: 0; padding: 0; list-style: none; font-size: 0.95rem; line-height: 1.5; }
.map-page .card-meetings li { margin: 0 0 0.15rem; }
/* Which zone the times are in belongs to the times, so it sits under them in
   the same column rather than out under the labels. */
.map-page .card-zone {
  grid-column: 2;
  margin: -0.2rem 0 0;
  color: var(--muted);
  font-size: 0.82rem;
}
.map-page .card-label { font-weight: 600; }
/* Read, not pressed. Nothing here is a control, so the chips are set as one
   line of small text with dots between them rather than as pills, which look
   like buttons and cost a card three lines of its height. */
.map-page .card-tags {
  display: flex;
  flex-wrap: wrap;
  gap: 0 0.45rem;
  margin: 0;
  padding: 0;
  list-style: none;
  font-size: 0.82rem;
  line-height: 1.5;
}
.map-page .card-tags li { padding: 0; color: var(--muted); background: none; border: 0; }
.map-page .card-tags li + li::before { content: "\00b7"; margin-right: 0.45rem; color: var(--muted); opacity: 0.5; }
/* ---- a colour per kind of sangha ---------------------------------
   One class carries the colour, and both the chip on the card and the
   pin on the map wear it, so the two are never read as different
   things. */
/* One colour for all of them, and it is the finder's own clay. Alipasha,
   29 Aug: a family per kind — berry for local, sage for lay, clay for
   monastic, indigo for online — asked the reader to learn four colours to be
   told something the label beside them already says, and put four families on
   one page. The darker step, because the lighter one on the map's own tones
   measures about 3:1 and a dot nobody can pick out is not a dot. */
.map-page .kind-local-sangha,
.map-page .kind-lay-practice-centre,
.map-page .kind-monastic-practice-centre,
.map-page .kind-online-sangha {
  --kind: var(--clay-text);
  --kind-mid: var(--clay);
  --kind-soft: var(--clay-soft);
  --kind-text: var(--clay-text);
}

.map-page .card-tags .chip-kind { color: var(--kind-text); font-weight: 600; }

/* The marker is a dot drawn by the page, not an image from a CDN — which is
   also why the shadow the CSP refused is gone. */
.map-page .sangha-pin .pin-dot {
  display: block;
  width: 24px;
  height: 24px;
  border-radius: 50%;
  background: var(--kind, var(--clay-text));
  border: 3px solid var(--card);
  /* A thin dark edge as well as the pale ring, so the dot holds its shape on
     pale ground and on dark. */
  box-shadow: 0 1px 3px rgb(46 42 38 / 55%), 0 0 0 1px rgb(46 42 38 / 22%);
}
.map-page .leaflet-marker-icon:focus-visible .pin-dot { outline: 2.5px solid var(--accent); outline-offset: 2px; }

/* A cluster is not a kind of sangha, so it wears the site's accent rather than
   any family's colour, with the same ring and edge the pins have. */
.map-page .sangha-cluster {
  display: grid;
  place-items: center;
  border-radius: 50%;
  color: var(--on-accent);
  background: var(--accent-strong);
  border: 3px solid var(--card);
  box-shadow: 0 1px 3px rgb(46 42 38 / 55%), 0 0 0 1px rgb(46 42 38 / 22%);
  font-family: var(--font);
  font-weight: 600;
  font-size: 0.85rem;
  line-height: 1;
}
.map-page .sangha-cluster.cluster-many { font-size: 0.95rem; }
.map-page .sangha-cluster:hover { background: var(--accent-strong-hover); }
.map-page .sangha-cluster:focus-visible { outline: 2.5px solid var(--accent); outline-offset: 2px; }
.map-page .card-tags .chip-rest { color: var(--muted); }
/* The sangha's own words run the width of the card: there is no label in
   front of them, and an indent with nothing to its left is a margin. */
.map-page .card-description {
  grid-column: 1 / -1;
  margin: 0;
  color: var(--muted);
  font-size: 0.95rem;
  line-height: 1.55;
}
/* Four lines of a sangha's own words, and a way to the rest. Some of them run
   to a page. */
.map-page .card-description.is-clamped {
  display: -webkit-box;
  -webkit-line-clamp: 4;
  -webkit-box-orient: vertical;
  line-clamp: 4;
  overflow: hidden;
}
.map-page .card-more {
  grid-column: 1 / -1;
  justify-self: start;
  margin: 0;
  padding: 0;
  font: inherit;
  font-size: 0.9rem;
  color: var(--sect-text);
  background: none;
  border: 0;
  text-decoration: underline;
  cursor: pointer;
}
.map-page .card-more:focus-visible { outline: 2.5px solid var(--accent); outline-offset: 2px; border-radius: var(--radius-xs); }
.map-page .card-contact > .card-value { margin-top: 0.2rem; }
.map-page .card-contact > .card-label { margin-top: 0.2rem; }
/* Last on the card, and under a rule: who stands behind the sangha is not how
   you reach it, and the line says so before it is read. */
/* Who stands behind the sangha keeps its own line across both columns: it is
   the one label long enough to push every value on the card to the right, and
   it is not one of the things being compared with the others. */
.map-page .card-support {
  grid-column: 1 / -1;
  margin: 0.35rem 0 0;
  padding-top: 0.85rem;
  border-top: 1px solid var(--rule);
  font-size: 0.95rem;
  overflow-wrap: anywhere;
}
/* The sangha itself, drawn once and shown two ways: inside the panel a row or
   a pin opens, and inside the pane beside a table. Both of those draw their
   own surface, so the card brings only its contents. */
.map-page .card-open { position: relative; background: transparent; border: 0; }
.map-page .card-open .card-head { display: flex; flex-direction: column; gap: 0.45rem; }
.map-page .card-open .card-detail { padding: 0.9rem 0 0; margin-top: 0.75rem; }
.map-page .card-open .card-title { font-size: 1.05rem; }
/* Nothing matched: the box keeps its height, says so in the middle of it, and
   offers the way back. */
.map-page .cards-empty {
  display: grid;
  place-content: center;
  justify-items: center;
  gap: 0.9rem;
  min-height: 12rem;
  margin: 0;
  padding: 2rem 1.4rem;
  color: var(--muted);
  text-align: center;
}
.map-page .cards-empty-line { margin: 0; }
/* And the pane beside the table goes while there is nothing to put in it,
   rather than standing there as an empty column with a line down its side. */
.map-page.no-matches.view-table #sfm-views { grid-template-columns: minmax(0, 1fr); }
.map-page.no-matches .detail-pane { display: none; }
/* The way to the rest of the list, on a row of its own however many columns
   the list has. */
.map-page .list-more {
  grid-column: 1 / -1;
  justify-self: center;
  margin: 0.4rem 0 0.2rem;
  font-size: 0.95rem;
}
.map-page .email-reveal { color: var(--sect-text); font: inherit; }

@media (max-width: 700px) {
  /* A phone screen is 844px tall, and the page was spending 580 of them before
     the map began. The words stay — they say what the page is for — but they
     are set at reading size rather than at the size a landing page gives
     them. */
  .map-page .controls-row { padding: 0 12px 0.8rem; }
  .map-page .scope-bar { padding: 0.5rem 0.7rem; }
  .map-page .map-controls.is-open {
    position: absolute;
    inset: 2.9rem auto auto 0;
    z-index: 1000;
    width: min(20rem, calc(100vw - 24px));
    padding: 1rem;
    background: var(--card);
    border: 1px solid var(--rule);
    border-radius: var(--radius-xs);
    box-shadow: var(--lift);
  }
  .map-page .map-controls select, .map-page .map-controls input { width: 100%; }
  .map-page .result-count { margin-left: 0; }
  .map-page .filter-toggle {
    position: static;
    padding: 0.5em 1.1em;
    color: var(--ink);
    background: var(--card);
    border: 1.5px solid var(--rule);
    border-radius: var(--radius-pill);
    font: inherit;
    font-size: 0.92rem;
  }
  .map-page #sfm-map { height: clamp(380px, 62vh, 620px); }
  .map-page .sangha-cards:not([hidden]) { grid-template-columns: 1fr; padding: 1.1rem 12px 2rem; }
  /* No room for two columns on a phone: split stacks, the map first, and the
     list runs on below it rather than scrolling inside a box. */
  /* One column on a phone: the scope bar, the map under it, the list under
     that. The box stays — it is the same container, and the other two views
     keep theirs — but the list inside it runs down the page rather than
     scrolling in a box of its own, which on a touch screen is a trap. */
  .map-page.view-local #sfm-views,
  .map-page.view-table #sfm-views {
    display: block;
    width: calc(100% - 24px);
  }
  .map-page.view-local #sfm-map {
    height: clamp(300px, 45vh, 460px);
    border: 0;
    border-bottom: 1px solid var(--rule);
    border-radius: 0;
  }
  .map-page.view-local .sangha-cards:not([hidden]),
  .map-page.view-table .sangha-cards:not([hidden]) {
    max-height: none;
    overflow: visible;
    padding: 0;
  }
  /* Freed of the box, the table is paged instead — app.js draws twenty-four
     of it below this width, for the same reason the list beside the map is
     paged: a phone scrolls the page, not a box inside it. */
  /* No pane here. It would sit under the end of a table that runs down the
     page, which is where Christian found it (#37): the row was at 685px and
     what pressing it changed began at 1,742. The panel shows the sangha
     instead, the way a row beside the map does. */
  .map-page.view-table .detail-pane { display: none; }
  /* The link sits under the views rather than off at the right of a line it
     no longer shares with them. */
  .map-page .controls-row { justify-content: flex-start; }
  .map-page .directory-nav { margin-left: 0; }
  /* A phone's map already has the box to itself, with the list under it. */
  .map-page .map-expand { display: none; }
  .map-page .scope-bar .map-expand ~ .result-count { margin-left: auto; }
}
