/* ===== Nav bar ===== */
.nav {
  position: sticky;
  top: 0;
  z-index: 200;
  background: var(--brand-primary);
  height: var(--nav-height);
  color: #fff;
}
.nav-inner {
  max-width: var(--page-max);
  margin: 0 auto;
  padding: 0 24px;
  height: 100%;
  display: flex;
  align-items: center;
  gap: 20px;
}
.nav-logo {
  display: inline-flex;
  align-items: center;
  flex: none;
}
.nav-logo .nav-logo-mark {
  width: 28px;
  height: 28px;
}
.mobile-drawer-header .nav-logo-mark {
  width: 25px;
  height: 25px;
}
.nav-center {
  position: relative;
  display: flex;
  align-items: stretch;
  gap: 4px;
  flex: 1;
  justify-content: center;
  align-self: stretch;
}
.nav-underline {
  position: absolute;
  bottom: 4.8px; /* renders 4px above the bar bottom at 0.8333 global zoom */
  height: 2px;
  background: #fff;
  border-radius: 2px 2px 0 0;
  transition: left var(--dur-slow) var(--ease-out), width var(--dur-slow) var(--ease-out);
  will-change: left, width;
}
.nav-underline.no-anim {
  transition: none;
}
.nav-right {
  display: flex;
  align-items: center;
  gap: 14px;
  margin-left: auto;
  flex: none;
}
.nav-link {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  color: rgba(255, 255, 255, 0.92);
  font-size: 14px;
  font-weight: 500;
  padding: 9px 10px;
  border-radius: 10px;
  text-decoration: none;
  position: relative;
  align-self: center;
  transition: background var(--dur-fast) var(--ease-out), color var(--dur-fast) var(--ease-out);
}
/* The overflow control is a <button> wearing a class written for <a>. An
   anchor is transparent and inherits its font; a button is not and does not,
   so the user agent supplied a grey ButtonFace box with a bevelled border --
   and, because the rule above sets a white colour, a white glyph sitting on
   a near-white box. It read as a blank white square in the navigation bar. */
button.nav-link {
  background: none;
  border: 0;
  margin: 0;
  font: inherit;
  font-size: 14px;
  font-weight: 500;
  /* inherit, not normal: a button's own line-height left it 27px tall
     against the links' 34px, so it sat visibly short of its neighbours. */
  line-height: inherit;
  appearance: none;
  -webkit-appearance: none;
  cursor: pointer;
}
/* Its only content is a glyph where every neighbour has a line of text, so
   left to itself it stands six pixels shorter than the links beside it --
   visible as a hover highlight that does not line up. A link measures its
   9px padding top and bottom around one line of text, so that is what this
   asks for -- in ems, so it follows the font rather than going stale if the
   nav type ever changes. (Stretching to the row was worse: 50px, the full
   height of the bar.) */
button.nav-link {
  min-height: calc(1.6em + 18px);
}
.nav-link:hover {
  color: #fff;
  background: rgba(255, 255, 255, 0.15);
}
.nav-link .nav-icon {
  width: 15px;
  height: 15px;
}
.nav-link.active {
  color: #fff;
}
.nav-link.active.sub-page {
  border: 1px solid rgba(255, 255, 255, 0.9);
  padding: 0 12px;
  height: 34px;
  align-self: center;
  border-radius: 10px;
}
.nav-burger {
  display: none;
  background: none;
  border: none;
  color: #fff;
  cursor: pointer;
  padding: 8px;
  margin-left: auto;
  border-radius: 10px;
  transition: background var(--dur-fast) var(--ease-out);
}
.nav-burger:hover {
  background: rgba(255, 255, 255, 0.15);
}
.nav-burger svg {
  width: 22px;
  height: 22px;
}
.nav-search-btn,
.nav-avatar-btn {
  background: none;
  border: none;
  color: #fff;
  cursor: pointer;
  padding: 9px;
  display: inline-flex;
  align-items: center;
  border-radius: 10px;
  transition: background var(--dur-fast) var(--ease-out);
}
.nav-search-btn:hover,
.nav-avatar-btn:hover {
  background: rgba(255, 255, 255, 0.15);
}
.nav-search-btn svg {
  width: 18px;
  height: 18px;
}
.nav-avatar {
  width: 34px;
  height: 34px;
  border-radius: 50%;
  background: var(--avatar-gold);
  color: #fff;
  font-size: 14px;
  font-weight: 600;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}

/* Avatar dropdown */
.avatar-menu {
  /* Fixed, not absolute. This element is rendered at the end of <body>, so
     it has no positioned ancestor: "absolute" anchored it to the top of the
     document, and once the page was scrolled the menu opened somewhere up
     above the viewport. The nav it belongs to is sticky at the top, so
     matching it to the viewport is also what keeps the two together. */
  position: fixed;
  top: calc(var(--nav-height) - 12px);
  right: 24px;
  /* Never wider than the screen it opens on. */
  max-width: calc(100vw - 32px);
  /* max(), so a viewport that reports an implausible height cannot collapse
     the menu to nothing -- it should always be at least readable. */
  max-height: max(240px, calc(100vh - var(--nav-height) - 24px));
  overflow-y: auto;
  background: var(--surface);
  color: var(--text-primary);
  border: 1px solid var(--border);
  border-radius: 12px;
  box-shadow: 0 8px 24px rgba(16, 24, 40, 0.12);
  min-width: 320px;
  z-index: 300;
  display: none;
}
.avatar-menu.open {
  display: block;
}
.avatar-menu-header {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 16px;
  border-bottom: 1px solid var(--border);
}
.avatar-menu-header .menu-avatar {
  width: 44px;
  height: 44px;
  border-radius: 50%;
  background: var(--avatar-gold);
  color: #fff;
  font-weight: 600;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: none;
}
.avatar-menu-header .menu-email {
  font-size: 16px;
  color: var(--text-primary);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.avatar-menu-section {
  padding: 8px 0;
}
.avatar-menu-row {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 14px;
  margin: 0 8px;
  border-radius: 8px;
  color: var(--text-primary);
  font-size: 15px;
  text-decoration: none;
}
.avatar-menu-row:hover {
  background: var(--surface-subtle);
}
.avatar-menu-row svg {
  width: 18px;
  height: 18px;
  color: var(--text-muted);
}
.avatar-menu-divider {
  height: 1px;
  background: var(--border);
}

/* Mobile slide-over */
.mobile-overlay {
  position: fixed;
  inset: 0;
  background: rgba(15, 42, 82, 0.4);
  z-index: 400;
  display: none;
}
.mobile-overlay.open {
  display: block;
}
.mobile-drawer {
  position: fixed;
  top: 0;
  bottom: 0;
  right: 0;
  width: 320px;
  max-width: 85vw;
  background: var(--surface);
  z-index: 410;
  display: none;
  flex-direction: column;
}
.mobile-drawer.open {
  display: flex;
}
.mobile-drawer-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 20px;
  border-bottom: 1px solid var(--border);
}
.mobile-drawer-close {
  background: none;
  border: none;
  font-size: 28px;
  color: var(--text-muted);
  cursor: pointer;
}
.mobile-nav {
  padding: 12px 0;
}
.mobile-nav-link {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 14px 20px;
  color: var(--text-primary);
  font-size: 16px;
  font-weight: 500;
  text-decoration: none;
}
.mobile-nav-link:hover {
  background: var(--surface-subtle);
}
.mobile-nav-link.active {
  color: var(--brand-primary);
}
.mobile-nav-link .nav-icon {
  width: 20px;
  height: 20px;
  color: var(--text-muted);
}

/* ===== Badges ===== */
.badge {
  display: inline-flex;
  align-items: center;
  white-space: nowrap;
  font-size: 12px;
  font-weight: 500;
  line-height: 1;
  padding: 5px 9px;
  border-radius: var(--radius-badge);
  color: #fff;
}
.badge-row {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}

/* ===== Cards ===== */
.card-grid {
  display: grid;
  gap: var(--grid-gutter);
}
.card-row {
  display: flex;
  gap: 20px;
}
.teacher-card,
.school-card {
  background: var(--surface);
  border: var(--card-border);
  border-radius: var(--radius-card);
  box-shadow: var(--card-shadow);
  overflow: hidden;
  display: block;
  color: var(--text-primary);
  text-decoration: none;
  transition: box-shadow var(--dur-base) var(--ease-out),
    transform var(--dur-base) var(--ease-out),
    border-color var(--dur-base) var(--ease-out);
}
.teacher-card .card-body {
  background: var(--surface-subtle);
}
.teacher-card:hover,
.school-card:hover {
  box-shadow: 0 10px 24px rgba(16, 24, 40, 0.1);
  /* A small lift reads as "this is pickable" far more clearly than a shadow
     change alone. Kept to 2px: the page renders at 0.8333 zoom, so larger
     offsets look exaggerated and can nudge text off the pixel grid. */
  transform: translateY(-2px);
}
/* Settle back to the resting state on press, so a click feels like it
   physically depresses the card rather than releasing into a hover. */
.teacher-card:active,
.school-card:active {
  transform: translateY(0);
  box-shadow: var(--card-shadow);
  transition-duration: var(--dur-fast);
}
/* Keyboard focus deserves the same affordance as hover. */
.teacher-card:focus-visible,
.school-card:focus-visible {
  box-shadow: 0 10px 24px rgba(16, 24, 40, 0.1);
  transform: translateY(-2px);
}
.teacher-card .photo,
.school-card .logo-area {
  aspect-ratio: 4 / 3;
  background: var(--surface-subtle);
  position: relative;
  overflow: hidden;
}
.teacher-card .photo img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  border-radius: 12px 12px 0 0;
}
.school-card .logo-area img {
  width: 100%;
  height: 100%;
  object-fit: contain;
  padding: 16px;
  background: var(--surface);
}
.photo-placeholder,
.logo-placeholder {
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--text-muted);
}
.photo-placeholder svg,
.logo-placeholder svg {
  width: 48px;
  height: 48px;
}
.badge-overlay {
  position: absolute;
  top: 8px;
  left: 8px;
  right: 8px;
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  z-index: 5;
}
.card-body {
  padding: var(--card-padding);
}
.card-title {
  font-size: 20px;
  font-weight: 600;
  line-height: 1.3;
  color: var(--text-primary);
}
.school-card .card-title-block {
  min-height: 2.6em; /* two lines */
}
.card-ks {
  margin: 8px 0 0;
}
.card-meta {
  margin-top: 12px;
}
.card-meta .meta-label {
  font-size: 15px;
  color: var(--text-muted);
}
.card-meta .meta-value {
  font-size: 15px;
  color: var(--text-primary);
}
.card-meta .meta-value.locked a,
.locked-value a {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 15px;
  color: var(--text-muted);
}
.card-meta .meta-value.locked a:hover,
.locked-value a:hover {
  color: var(--brand-primary);
}
.card-meta .meta-value.locked svg,
.locked-value svg {
  width: 16px;
  height: 16px;
}
.locked-value {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 15px;
  color: var(--text-muted);
}
.locked-note {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  margin-top: 16px;
  font-size: 14px;
  color: var(--text-muted);
}
.locked-note svg {
  width: 16px;
  height: 16px;
}
.card-distance {
  font-size: 15px;
  color: var(--text-muted);
  margin-top: 6px;
}
.card-distance.profile {
  font-size: 15px;
}
.travel-note {
  color: var(--text-muted);
}
.card-rating {
  margin-top: 12px;
}
.stars {
  display: inline-flex;
  gap: 2px;
}
.stars svg {
  width: 18px;
  height: 18px;
}
.star-filled {
  fill: var(--star-filled);
  color: var(--star-filled);
}
.star-empty {
  fill: var(--star-empty);
  color: var(--star-empty);
}

/* School card requirements */
.school-card-login {
  cursor: default;
}

/* ===== Hero ===== */
.hero {
  background: linear-gradient(100deg, #FBFBFD 0%, #F0EFFA 55%, #E8E6F7 100%);
  min-height: 120px;
  display: flex;
  align-items: center;
}
.hero-inner {
  max-width: var(--page-max);
  margin: 0 auto;
  padding: 40px 24px;
  width: 100%;
  display: flex;
  align-items: center;
  gap: 28px;
  justify-content: space-between;
}
.hero-greeting {
  display: flex;
  align-items: center;
  gap: 28px;
}
.hero-logo {
  flex: none;
}
.hero-emblem {
  flex: none;
  border-radius: 50%;
  object-fit: cover;
}
.hero-avatar {
  width: 64px;
  height: 64px;
  border-radius: 50%;
  background: var(--avatar-gold);
  color: #fff;
  font-weight: 600;
  font-size: 24px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: none;
}
.hero-line1 {
  color: var(--brand-primary);
  font-size: 17px;
  font-weight: 500;
}
.hero-headline {
  font-size: 40px;
  font-weight: 600;
  line-height: 1.25;
  color: var(--text-primary);
  max-width: 1100px;
}
.hero-search {
  flex: none;
  width: 360px;
  max-width: 100%;
  border: none;
  background: transparent;
  padding: 0;
}
.hero-search-inner {
  display: flex;
  align-items: center;
  gap: 10px;
  background: var(--surface-subtle);
  border-radius: var(--radius-pill);
  padding: 12px 18px;
  cursor: pointer;
  transition: background var(--dur-fast) var(--ease-out);
}
.hero-search:hover .hero-search-inner,
.hero-search-inner:hover {
  background: var(--surface-input);
}
.hero-search-inner svg {
  width: 20px;
  height: 20px;
  color: var(--text-muted);
}
.hero-search-inner span {
  color: var(--text-muted);
  font-size: 16px;
}

/* ===== Join cards ===== */
.join-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 20px;
}
.join-card {
  display: flex;
  align-items: center;
  gap: 18px;
  background: var(--surface-subtle);
  border: var(--card-border);
  border-radius: var(--radius-card);
  padding: 28px;
  color: var(--text-primary);
  text-decoration: none;
  transition: background var(--dur-fast) var(--ease-out), box-shadow var(--dur-fast) var(--ease-out);
}
.join-card:hover {
  color: var(--text-primary);
  background: var(--surface-input);
  box-shadow: var(--card-shadow);
}
.join-card .join-icon {
  width: 32px;
  height: 32px;
  color: var(--brand-primary);
  flex: none;
}
.join-card .join-label {
  font-size: 20px;
  font-weight: 500;
  flex: 1;
}
.join-card .join-chevron {
  width: 20px;
  height: 20px;
  color: var(--text-muted);
}

/* ===== Stat cards ===== */
.stat-grid {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  gap: var(--grid-gutter);
}
.stat-card {
  background: var(--brand-primary);
  border-radius: var(--radius-card);
  color: #fff;
  padding: 28px;
}
.stat-card .stat-label {
  font-size: 15px;
  font-weight: 400;
  line-height: 1.4;
}
.stat-card .stat-value {
  font-size: 38px;
  font-weight: 600;
  line-height: 1.1;
  margin-top: 6px;
}

/* ===== Tabs ===== */
.tab-strip {
  position: relative;
  display: flex;
  gap: 24px;
  border-bottom: 1px solid var(--border);
  margin: 32px 0 24px;
}
.tab {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: 16px;
  font-weight: 500;
  color: var(--text-muted);
  padding: 12px 2px;
  text-decoration: none;
  position: relative;
}
.tab svg {
  width: 18px;
  height: 18px;
}
.tab.active {
  color: var(--text-primary);
}
.tab.active::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: -1px;
  height: 2px;
  background: var(--brand-primary);
  border-radius: 2px;
}

/* ===== Listing toolbar ===== */
.listing-toolbar {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
  margin-bottom: 24px;
}
.listing-toolbar .search-input-wrap {
  margin-left: auto;
  position: relative;
}
.listing-toolbar .search-input-wrap svg {
  position: absolute;
  left: 14px;
  top: 50%;
  transform: translateY(-50%);
  width: 18px;
  height: 18px;
  color: var(--text-muted);
}
.listing-search {
  padding-left: 40px;
  border-radius: var(--radius-pill);
}

/* Home listings section */
.listing-header-row {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 24px;
  margin-bottom: 16px;
}
.listing-titles .listing-title {
  font-size: 30px;
  font-weight: 600;
}
.listing-titles .listing-sub {
  color: var(--text-muted);
  font-size: 16px;
  font-weight: 400;
  margin: 4px 0 0;
}
.search-input-wrap {
  position: relative;
  width: 320px;
  max-width: 100%;
}
.search-input-wrap svg {
  position: absolute;
  left: 14px;
  top: 50%;
  transform: translateY(-50%);
  width: 18px;
  height: 18px;
  color: var(--text-muted);
}
.listing-search {
  background: var(--surface-subtle);
}
.listing-filters {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
  margin-bottom: 24px;
}
.filter-select-wrap {
  position: relative;
  display: inline-flex;
  align-items: center;
}
.filter-select-wrap .filter-caret {
  position: absolute;
  right: 14px;
  width: 16px;
  height: 16px;
  color: var(--text-muted);
  pointer-events: none;
}
.listing-empty {
  text-align: center;
  color: var(--text-muted);
  padding: 48px 0;
}

/* Listings grid swap states (enhanced by listings.js) */
.listings-panel {
  transition: opacity var(--dur-base) var(--ease-out), transform var(--dur-base) var(--ease-out);
}
.listings-panel.panel-loading {
  opacity: 0.4;
}

@media (prefers-reduced-motion: reduce) {
  .listings-panel {
    transition: none;
  }
}

/* ===== Grid breakpoints (teacher 6-col) ===== */
.teacher-grid {
  grid-template-columns: repeat(6, 1fr);
}
.school-grid {
  grid-template-columns: repeat(4, 1fr);
}

/* ===== Panels ===== */
.panel {
  background: var(--surface-subtle);
  border: var(--card-border);
  border-radius: var(--radius-card);
  padding: 28px;
}
.panel-outline {
  background: var(--surface);
  border: 1px solid var(--brand-primary);
  border-radius: var(--radius-card);
  padding: 28px;
}

/* ===== Learn more ===== */
.learn-content {
  max-width: 820px;
  margin: 0 auto;
  padding: 48px 24px;
}
.learn-content h1 {
  font-size: 28px;
  font-weight: 600;
}
.learn-content p {
  font-size: 15px;
}
.learn-buttons {
  display: flex;
  gap: 16px;
  justify-content: center;
  margin-bottom: 48px;
}
.learn-content h2 {
  font-size: 26px;
  font-weight: 600;
  margin: 48px 0 16px;
}
.learn-content h3 {
  font-size: 20px;
  font-weight: 600;
  margin: 0 0 8px;
}
.stat-panel-row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 20px;
  margin: 24px 0;
}
.stat-panel .stat-num {
  font-size: 34px;
  font-weight: 700;
  color: var(--brand-primary);
}
.stat-panel .stat-desc {
  font-size: 16px;
  color: var(--text-body);
}
.check-list {
  list-style: none;
  padding: 0;
  margin: 0;
}
.check-list li {
  display: flex;
  gap: 12px;
  align-items: flex-start;
  margin-bottom: 8px;
}
.check-list .tick {
  color: var(--brand-primary);
  font-size: 16px;
  font-weight: 600;
  width: 20px;
  flex: none;
}
.dot-list {
  list-style: none;
  padding: 0;
  margin: 0;
}
.dot-list li {
  position: relative;
  padding-left: 22px;
  margin-bottom: 8px;
}
.dot-list li::before {
  content: "";
  position: absolute;
  left: 2px;
  top: 10px;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--brand-primary);
}

/* ===== Footer ===== */
.footer {
  background: var(--surface-subtle);
  border-top: var(--card-border);
  padding: 40px 24px;
  margin-top: 64px;
}
.footer-inner {
  max-width: var(--page-max);
  margin: 0 auto;
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 16px;
}
.footer-links {
  display: flex;
  gap: 20px;
}
.footer-links a {
  color: var(--text-muted);
  font-size: 14px;
}
.footer-links a:hover {
  color: var(--brand-primary);
}

/* ===== Search overlay ===== */
.search-overlay {
  position: fixed;
  inset: 0;
  background: rgba(15, 42, 82, 0.5);
  z-index: 500;
  display: none;
  align-items: flex-start;
  justify-content: center;
  padding-top: 12vh;
}
.search-overlay.open {
  display: flex;
}
.search-panel {
  width: 900px;
  max-width: 92vw;
  background: var(--surface);
  border-radius: var(--radius-card);
  box-shadow: 0 24px 64px rgba(16, 24, 40, 0.25);
  padding: 24px;
}
.search-input-row {
  display: flex;
  align-items: center;
  gap: 12px;
  border-bottom: 1px solid var(--border);
  padding-bottom: 16px;
}
.search-input-row svg {
  width: 22px;
  height: 22px;
  color: var(--text-muted);
}
.search-input-row input {
  flex: 1;
  border: none;
  font-size: 20px;
  outline: none;
  color: var(--text-primary);
  background: none;
}
.search-empty {
  text-align: center;
  padding: 48px 0;
  color: var(--text-muted);
}
.search-empty svg {
  width: 60px;
  height: 60px;
  color: var(--text-muted);
  opacity: 0.5;
  margin: 0 auto 12px;
}
.search-results {
  margin-top: 12px;
}
.search-result-item {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 12px;
  border-radius: 8px;
  color: var(--text-primary);
  text-decoration: none;
}
.search-result-item:hover {
  background: var(--surface-subtle);
  color: var(--text-primary);
}

/* ===== Messages ===== */
.thread-list {
  list-style: none;
  margin: 0;
  padding: 0;
}
.thread-item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 16px;
  border: var(--card-border);
  border-radius: var(--radius-card);
  margin-bottom: 12px;
  text-decoration: none;
  color: var(--text-primary);
}
.thread-item.unread {
  background: var(--surface-subtle);
}
.thread-bubble {
  background: var(--surface-subtle);
  border: var(--card-border);
  border-radius: var(--radius-card);
  padding: 14px;
  margin-bottom: 10px;
}
.thread-bubble.mine {
  background: var(--brand-primary);
  border-color: var(--brand-primary);
  color: #fff;
}

/* ===== Unread badge on nav ===== */
.unread-dot {
  background: #fff;
  color: var(--brand-primary);
  border-radius: 999px;
  font-size: 12px;
  font-weight: 700;
  padding: 1px 6px;
  line-height: 1.4;
}

/* ===== Create-profile form (Checkpoint 6) ===== */
.profile-form-wrap {
  padding: 48px 24px;
}
.profile-form-card {
  max-width: 820px;
  margin: 0 auto;
  background: var(--surface-subtle);
  border-radius: 12px;
  padding: 40px;
}
.profile-form-card h1 {
  font-size: 34px;
  font-weight: 600;
  margin-bottom: 8px;
}
.profile-form-sub {
  color: var(--text-body);
  margin: 8px 0 28px;
}
.form-error-summary {
  background: #FDF0F0;
  border: 1px solid var(--danger);
  color: var(--danger);
  border-radius: 12px;
  padding: 16px 20px;
  margin-bottom: 24px;
  font-size: 15px;
}
.form-error-summary ul {
  margin: 6px 0 0;
  padding-left: 20px;
}
.profile-section {
  background: var(--surface);
  border: var(--card-border);
  border-radius: 12px;
  padding: 24px;
  margin-bottom: 20px;
}
.profile-section h2 {
  font-size: 20px;
  font-weight: 600;
  margin-bottom: 18px;
}
.profile-2col {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 16px;
}
.pt-1 {
  padding-top: 24px;
}
.field-hint {
  font-size: 14px;
  color: var(--text-muted);
  margin: 6px 0 0;
}
.doc-zone {
  margin-bottom: 18px;
}
.doc-label-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 8px;
}
.doc-req {
  color: var(--danger);
  font-size: 12px;
  font-weight: 600;
  text-transform: uppercase;
}
.doc-opt {
  color: var(--text-muted);
  font-size: 12px;
  font-weight: 500;
}
.staged-file {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-top: 8px;
  background: var(--surface-input);
  border-radius: 10px;
  padding: 10px 14px;
}
.staged-file[hidden] {
  display: none;
}
.staged-name {
  font-size: 14px;
  color: var(--text-primary);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.remove-file {
  background: none;
  border: none;
  color: var(--danger);
  font-size: 14px;
  cursor: pointer;
  flex: none;
  padding: 0;
}
[data-photo-preview] {
  width: 120px;
  height: 120px;
  border-radius: 50%;
  object-fit: cover;
  margin: 0 0 14px;
  display: block;
  background: var(--surface-input);
}
[data-photo-preview][hidden] {
  display: none;
}
.profile-submit {
  margin-top: 8px;
}
.profile-submit .btn {
  width: 100%;
}

/* ===== Responsive ===== */
@media (max-width: 1400px) {
  .teacher-grid { grid-template-columns: repeat(4, 1fr); }
}
@media (max-width: 1100px) {
  .teacher-grid { grid-template-columns: repeat(3, 1fr); }
  .school-grid { grid-template-columns: repeat(3, 1fr); }
}
@media (max-width: 900px) {
  .nav-burger { display: inline-flex; }
  .nav-center { display: none; }
  .nav-avatar { display: inline-flex; }
  .teacher-grid { grid-template-columns: repeat(2, 1fr); }
  .hero-inner { flex-direction: column; align-items: flex-start; }
  .hero-greeting { flex-direction: column; align-items: center; gap: 16px; }
  .hero-greeting > div { text-align: center; }
  .hero-headline { font-size: 28px; }
  .hero-search { width: 100%; }
}
@media (max-width: 800px) {
  .school-grid { grid-template-columns: repeat(2, 1fr); }
  .join-grid, .stat-grid, .stat-panel-row { grid-template-columns: 1fr; }
}
@media (max-width: 640px) {
  .teacher-grid, .school-grid { grid-template-columns: 1fr; }
  .avatar-menu { min-width: 280px; right: 12px; }
  .profile-form-card { padding: 24px 16px; }
  .profile-2col { grid-template-columns: 1fr; }
}
@media (max-width: 440px) {
  .teacher-grid, .school-grid { grid-template-columns: 1fr; }
}

/* ===== Login ===== */
.login-split {
  display: grid;
  grid-template-columns: 1.1fr 1fr;
  min-height: 100vh;
}
.login-left {
  display: flex;
  /* Column, because this is not a single card. The verify screen puts a
     resend form and a "back to log in" link under the card, and as a row
     they were laid out beside it -- squeezing the card and overlapping each
     other. The sign-in screen had the same fault, less visibly. */
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 40px 24px;
  position: relative;
}
/* Everything stacked under the card lines up with its edges. .login-back is
   absolutely positioned in the corner and is not part of the stack. */
.login-left > *:not(.login-back) {
  width: 100%;
  max-width: 560px;
}
.login-back {
  position: absolute;
  top: 24px;
  left: 24px;
  display: inline-flex;
  align-items: center;
  color: var(--brand-navy);
  font-size: 15px;
  font-weight: 500;
  text-decoration: none;
}
.login-back:hover {
  text-decoration: underline;
}
.login-card {
  background: var(--surface-subtle);
  border-radius: 12px;
  padding: 48px;
  width: 100%;
  max-width: 560px;
}
.login-title {
  text-align: center;
  font-size: 34px;
  font-weight: 600;
  color: var(--text-primary);
}
.login-sub {
  text-align: center;
  font-size: 16px;
  color: var(--text-muted);
  margin: 6px 0 28px;
}
.login-sso {
  width: 100%;
  justify-content: center;
  font-size: 16px;
  margin-bottom: 12px;
}
.login-divider {
  height: 1px;
  background: var(--border);
  margin: 24px 0;
}
.login-continue {
  width: 100%;
  margin-top: 16px;
}
.login-footer {
  text-align: center;
  font-size: 16px;
  color: var(--text-body);
  margin-top: 20px;
}
.login-footer a {
  text-decoration: underline;
  color: var(--brand-primary);
}
.login-right {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 40px;
  background: linear-gradient(160deg, #FFFFFF 0%, #EDEBF9 100%);
}
@media (max-width: 900px) {
  .login-split { grid-template-columns: 1fr; }
  .login-right { display: none; }
}

/* ===== Streaming listings skeleton =====
   /find-a-teacher streams: the shell and this placeholder are flushed before
   the database is queried, then the real grid arrives in the same response.

   The swap is done with :has() rather than JavaScript so it also works with
   JS disabled, and so the placeholder cannot outlive the content if a script
   fails to load. Browsers without :has() simply show the skeleton above the
   results for the brief moment both exist -- degraded, not broken. */
.listings-stream:has(.listings-loaded) .listing-skeleton {
  display: none;
}

.skeleton-line {
  display: block;
  border-radius: 6px;
  /* Two stops of a moving gradient: the light band sweeps across, which reads
     as "working" rather than "stuck", without the cost of an animated image. */
  background: linear-gradient(
    90deg,
    var(--surface-subtle) 25%,
    #EDEEF0 37%,
    var(--surface-subtle) 63%
  );
  background-size: 400% 100%;
  animation: skeleton-sweep 1.4s ease-in-out infinite;
}
.skeleton-count {
  width: 140px;
  height: 14px;
  margin: 0 0 20px 0;
}
.skeleton-card {
  background: var(--surface);
  border: var(--card-border);
  border-radius: var(--radius-card);
  box-shadow: var(--card-shadow);
  overflow: hidden;
}
.skeleton-photo {
  /* Matches .teacher-card .photo so the grid does not jump when the real
     cards replace these -- the whole point is to reserve the right space. */
  aspect-ratio: 4 / 3;
  background: linear-gradient(
    90deg,
    var(--surface-subtle) 25%,
    #EDEEF0 37%,
    var(--surface-subtle) 63%
  );
  background-size: 400% 100%;
  animation: skeleton-sweep 1.4s ease-in-out infinite;
}
.skeleton-body {
  background: var(--surface-subtle);
  padding: var(--card-padding);
}
.skeleton-name {
  width: 70%;
  height: 15px;
  margin-bottom: 10px;
}
.skeleton-meta {
  width: 45%;
  height: 12px;
}

@keyframes skeleton-sweep {
  from { background-position: 100% 50%; }
  to { background-position: 0 50%; }
}

/* A sweeping placeholder is exactly the kind of looping movement that causes
   problems for vestibular disorders, so hold it still and show a plain
   resting tone instead. The layout reservation still works. */
@media (prefers-reduced-motion: reduce) {
  .skeleton-line,
  .skeleton-photo {
    animation: none;
    background: var(--surface-subtle);
  }
}

/* Migration notice on the login card (people arriving from the old Softr
   site). Informational, not an error: a blue-tinted panel rather than the
   red/amber used for problems, so it reads as guidance and does not make a
   successful sign-in feel like a failure. */
.login-notice {
  background: #EEF1FD;
  border: 1px solid #C9D2F7;
  border-radius: var(--radius-input);
  padding: 12px 14px;
  margin: 0 0 20px 0;
  font-size: 14px;
  line-height: 1.5;
  color: var(--brand-navy);
}
.login-notice strong {
  display: block;
  margin-bottom: 2px;
  color: var(--brand-primary);
}

/* ===== Admin panel =====
   A sidebar layout rather than the site's top nav: the panel has nine
   sections with live queue counts, which a horizontal bar cannot show
   without becoming an overflow menu. Deliberately plainer than the public
   site -- this is a working tool, and density beats polish. */
.adm {
  display: grid;
  grid-template-columns: 220px 1fr;
  min-height: calc(100vh - var(--nav-height));
}
.adm-side {
  background: var(--brand-navy);
  padding: 20px 0;
  display: flex;
  flex-direction: column;
}
.adm-brand {
  color: #fff;
  font-weight: 600;
  font-size: 16px;
  padding: 0 20px 18px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.15);
  margin-bottom: 14px;
}
.adm-brand span {
  display: block;
  font-weight: 400;
  font-size: 12px;
  opacity: 0.7;
}
.adm-link {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 10px 20px;
  color: rgba(255, 255, 255, 0.85);
  text-decoration: none;
  font-size: 14px;
  transition: background var(--dur-fast) var(--ease-out),
    color var(--dur-fast) var(--ease-out);
}
.adm-link:hover {
  background: rgba(255, 255, 255, 0.08);
  color: #fff;
}
.adm-link.active {
  background: rgba(255, 255, 255, 0.12);
  color: #fff;
  /* An inset bar rather than a border, so the row does not shift by 3px
     when it becomes active. */
  box-shadow: inset 3px 0 0 var(--brand-primary);
}
.adm-count {
  background: var(--danger);
  color: #fff;
  border-radius: var(--radius-pill);
  font-size: 11px;
  font-weight: 600;
  padding: 2px 7px;
}
.adm-side-foot {
  margin-top: auto;
  padding: 16px 20px 0;
  border-top: 1px solid rgba(255, 255, 255, 0.15);
  color: rgba(255, 255, 255, 0.6);
  font-size: 12px;
  line-height: 1.5;
  word-break: break-all;
}
.adm-side-foot strong { color: rgba(255, 255, 255, 0.9); }

.adm-main { padding: 28px 32px; background: var(--surface-subtle); }
.adm-h { font-size: 24px; font-weight: 600; margin: 0 0 4px; }
.adm-sub { color: var(--text-muted); font-size: 14px; margin: 0 0 22px; }
.adm-muted { color: var(--text-muted); font-size: 13px; }

.adm-stats {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 16px;
  margin-bottom: 28px;
}
.adm-stat {
  background: var(--surface);
  border: var(--card-border);
  border-radius: var(--radius-card);
  padding: 16px 18px;
}
.adm-stat-l { color: var(--text-muted); font-size: 13px; }
.adm-stat-v { font-size: 28px; font-weight: 600; margin-top: 4px; }
/* Only ever red when there is genuinely something to do -- a number that is
   always red stops being read as a warning. */
.adm-stat-v.is-alert { color: var(--danger); }

.adm-panel {
  background: var(--surface);
  border: var(--card-border);
  border-radius: var(--radius-card);
  margin-bottom: 26px;
  overflow: hidden;
}
.adm-panel-h {
  padding: 14px 18px;
  border-bottom: 1px solid var(--border);
  font-weight: 600;
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 12px;
}
.adm-table { width: 100%; border-collapse: collapse; font-size: 14px; }
.adm-table th {
  text-align: left;
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: 0.4px;
  color: var(--text-muted);
  font-weight: 600;
  padding: 10px 18px;
  border-bottom: 1px solid var(--border);
}
.adm-table td { padding: 12px 18px; border-bottom: 1px solid var(--border); }
.adm-table tr:last-child td { border-bottom: none; }
.adm-row-warn { background: #FFFBF0; }

.adm-pill {
  font-size: 12px;
  padding: 3px 9px;
  border-radius: var(--radius-pill);
  font-weight: 500;
  display: inline-block;
}
.adm-pill-ok { background: #E3F5EC; color: #1D7A4C; }
.adm-pill-pending { background: #FFF3D6; color: #8A6100; }
.adm-pill-no { background: #FDE7E7; color: #A32C2C; }

.adm-actions { text-align: right; white-space: nowrap; }
.adm-inline { display: inline; }
.adm-btn {
  font-size: 13px;
  padding: 6px 12px;
  border-radius: 8px;
  border: 1px solid var(--border);
  background: var(--surface);
  color: var(--text-primary);
  cursor: pointer;
  text-decoration: none;
  display: inline-block;
  transition: background var(--dur-fast) var(--ease-out),
    border-color var(--dur-fast) var(--ease-out);
}
.adm-btn:hover { background: var(--surface-subtle); }
.adm-btn-ok {
  background: var(--brand-primary);
  color: #fff;
  border-color: var(--brand-primary);
}
.adm-btn-ok:hover { background: var(--brand-primary-hover); }
.adm-btn-no { color: var(--danger); border-color: #F0C9C9; }
.adm-btn-no:hover { background: #FDF3F3; }
.adm-input {
  font-size: 13px;
  padding: 6px 10px;
  border: 1px solid var(--border);
  border-radius: 8px;
  width: 210px;
  font-family: inherit;
}

.adm-empty { padding: 40px 18px; text-align: center; color: var(--text-muted); }
.adm-note {
  padding: 12px 18px;
  border-top: 1px solid var(--border);
  color: var(--text-muted);
  font-size: 13px;
  background: var(--surface-subtle);
}

@media (max-width: 900px) {
  /* Below this the sidebar would leave no room for the tables, so it becomes
     a horizontal strip above the content. */
  .adm { grid-template-columns: 1fr; }
  .adm-side { flex-direction: row; flex-wrap: wrap; padding: 12px; }
  .adm-brand, .adm-side-foot { display: none; }
  .adm-link { padding: 8px 12px; }
  .adm-link.active { box-shadow: inset 0 -3px 0 var(--brand-primary); }
  .adm-stats { grid-template-columns: repeat(2, 1fr); }
  .adm-main { padding: 20px 16px; }
  .adm-panel { overflow-x: auto; }
}
.adm-flash {
  background: #E7ECFD;
  border: 1px solid #C9D2F7;
  color: var(--brand-navy);
  border-radius: var(--radius-input);
  padding: 11px 14px;
  margin: 0 0 18px;
  font-size: 14px;
}
.adm-flash-error {
  background: #FDF3F3;
  border-color: #F0D5D5;
  color: #8A3A3A;
}

/* Resend-code form on the verify screen. Sits outside the verify form (forms
   cannot nest) so it needs to be pulled back under the card and centred. */
.login-resend {
  margin: -4px 0 10px;
  text-align: center;
}
.login-resend .btn {
  font-size: 14px;
  padding: 9px 18px;
}
/* Confirmation that a resend happened; without visible feedback the button
   looks inert and gets pressed repeatedly. */
.login-flash {
  background: #E3F5EC;
  border: 1px solid #BFE6D2;
  color: #1D7A4C;
  border-radius: var(--radius-input);
  padding: 9px 12px;
  margin: 0 0 14px;
  font-size: 14px;
  text-align: center;
}
.login-flash.is-error {
  background: #FDF3F3;
  border-color: #F0D5D5;
  color: #8A3A3A;
}

/* ===== Homepage promo banner: teachers free for life =====
   Deliberately the loudest thing on the page below the hero. It is the one
   offer with no qualifier attached, and the side of the marketplace that
   needs the least friction, so it gets the strongest surface on the site:
   a saturated brand panel against an otherwise near-white page.

   Gold carries "for life" because it is the only accent in the palette that
   is not already doing a job elsewhere -- indigo is interactive, navy is
   structural, amber is ratings. */
.promo-banner {
  position: relative;
  margin-top: 24px;
  border-radius: var(--radius-card);
  background: linear-gradient(105deg, #2B3AA8 0%, var(--brand-primary) 48%, #5B69E2 100%);
  color: #fff;
  overflow: hidden;
}
/* A flat fill this large reads as dead space; the sweep gives it a light
   source without becoming a second colour. */
.promo-banner::after {
  content: "";
  position: absolute;
  inset: 0;
  background: radial-gradient(62% 130% at 86% -10%, rgba(255, 255, 255, 0.20), transparent 62%);
  pointer-events: none;
}
.promo-banner-inner {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 28px;
  padding: 22px 30px;
}
/* Take the room the button is not using: otherwise the copy shrink-wraps to
   a narrow column and wraps three times with empty panel beside it. */
.promo-banner-text {
  flex: 1 1 auto;
  min-width: 0;
}
.promo-banner-eyebrow {
  display: inline-block;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--avatar-gold);
}
.promo-banner-title {
  /* Explicit, not inherited: base.css colours headings directly, and an
     element-level rule beats the panel's inherited white. */
  color: #fff;
  margin: 6px 0 0;
  font-size: clamp(22px, 2.4vw, 29px);
  font-weight: 700;
  line-height: 1.12;
  letter-spacing: -0.015em;
}
/* Not italic -- em is here for the meaning, the colour does the emphasis. */
.promo-banner-title em {
  font-style: normal;
  color: var(--avatar-gold);
}
.promo-banner-sub {
  margin: 6px 0 0;
  max-width: 60ch;
  font-size: 15px;
  line-height: 1.45;
  color: rgba(255, 255, 255, 0.88);
}
.promo-banner-cta {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 12px 22px;
  border-radius: var(--radius-pill);
  background: #fff;
  color: var(--brand-primary);
  font-size: 15px;
  font-weight: 600;
  text-decoration: none;
  white-space: nowrap;
  box-shadow: 0 8px 22px rgba(10, 16, 56, 0.22);
  transition: transform var(--dur-fast) var(--ease-out),
              box-shadow var(--dur-fast) var(--ease-out);
}
.promo-banner-cta:hover {
  transform: translateY(-1px);
  box-shadow: 0 12px 26px rgba(10, 16, 56, 0.28);
}
.promo-banner-chevron {
  width: 18px;
  height: 18px;
}
@media (max-width: 860px) {
  .promo-banner-inner {
    flex-direction: column;
    align-items: flex-start;
    gap: 18px;
    padding: 22px 20px;
  }
  .promo-banner-cta {
    width: 100%;
    justify-content: center;
  }
}
@media (prefers-reduced-motion: reduce) {
  .promo-banner-cta { transition: none; }
  .promo-banner-cta:hover { transform: none; }
}

/* ===== Legal pages (terms, privacy) =====
   Long documents nobody reads front to back: the job is to make a specific
   clause findable and legible, not to make the page attractive. Numbered
   clauses get breathing room so an eye scanning for "B4" can land on it. */
.legal-updated {
  color: var(--text-muted);
  font-size: 14px;
  margin-top: -4px;
}
.legal-toc {
  display: flex;
  flex-wrap: wrap;
  gap: 8px 10px;
  margin: 28px 0 8px;
  padding: 16px 18px;
  border: var(--card-border);
  border-radius: var(--radius-card);
  background: var(--surface-subtle);
}
.legal-toc a {
  font-size: 14px;
  font-weight: 500;
  color: var(--brand-primary);
  text-decoration: none;
  padding: 4px 10px;
  border-radius: var(--radius-pill);
  background: var(--surface);
  border: var(--card-border);
}
.legal-toc a:hover {
  text-decoration: underline;
}
.legal-clause {
  margin-top: 28px;
}
/* A jumped-to heading should not land flush against the navigation bar. */
.legal h2[id] {
  scroll-margin-top: calc(var(--nav-height) + 16px);
}
.legal-clause h3 {
  font-size: 17px;
}
.legal-list {
  margin: 10px 0 14px;
  padding-left: 22px;
  color: var(--text-body);
  line-height: 1.65;
}
.legal-list li {
  margin-bottom: 8px;
}
.legal-clause p {
  color: var(--text-body);
  line-height: 1.65;
}

/* ===== Our own dropdown (select.js) =====
   Replaces the operating system's menu on the listing filters. Below 820px
   -- a phone, or an iPad held in portrait -- it becomes a bottom sheet with
   rows a thumb can hit; above that it is an anchored menu. See select.js for
   why the native <select> is still underneath. */
.xsel {
  position: relative;
  display: inline-flex;
}
.xsel-trigger {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-pill);
  padding: 10px 14px 10px 18px;
  font: inherit;
  font-size: 15px;
  font-weight: 500;
  color: var(--text-primary);
  cursor: pointer;
  white-space: nowrap;
  transition: border-color var(--dur-fast) var(--ease-out),
              background var(--dur-fast) var(--ease-out);
}
.xsel-trigger:hover {
  border-color: var(--brand-primary-muted);
}
.xsel-trigger:focus-visible {
  outline: 2px solid var(--brand-primary);
  outline-offset: 2px;
}
/* A filter that is actually filtering should look different from one that
   is not -- otherwise the only way to know is to read every pill. */
.xsel-trigger.is-set {
  border-color: var(--brand-primary);
  background: #EEF0FD;
  color: var(--brand-primary);
}
.xsel-caret {
  width: 16px;
  height: 16px;
  color: var(--text-muted);
  transition: transform var(--dur-fast) var(--ease-out);
}
.xsel-trigger.is-set .xsel-caret { color: var(--brand-primary); }
.xsel-trigger[aria-expanded="true"] .xsel-caret { transform: rotate(180deg); }

.xsel-pop {
  position: absolute;
  top: calc(100% + 6px);
  left: 0;
  min-width: 100%;
  width: max-content;
  max-width: min(320px, calc(100vw - 32px));
  max-height: min(380px, 60vh);
  z-index: 60;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-card);
  box-shadow: 0 12px 32px rgba(16, 24, 40, 0.16);
  padding: 6px;
  overflow-y: auto;
  overscroll-behavior: contain;
  opacity: 0;
  transform: translateY(-4px);
  transition: opacity var(--dur-fast) var(--ease-out),
              transform var(--dur-fast) var(--ease-out);
}
.xsel-pop.is-up {
  top: auto;
  bottom: calc(100% + 6px);
  transform: translateY(4px);
}
.xsel-pop.is-right { left: auto; right: 0; }
.xsel-pop.is-shown { opacity: 1; transform: translateY(0); }
.xsel-head { display: none; }
.xsel-list {
  list-style: none;
  margin: 0;
  padding: 0;
}
.xsel-opt {
  padding: 9px 12px;
  border-radius: 8px;
  font-size: 15px;
  color: var(--text-body);
  cursor: pointer;
  white-space: nowrap;
}
.xsel-opt.is-active { background: var(--surface-subtle); }
.xsel-opt[aria-selected="true"] {
  color: var(--brand-primary);
  font-weight: 600;
}
.xsel-opt[aria-selected="true"].is-active { background: #EEF0FD; }

/* Bottom sheet: phones, and tablets held in portrait. */
.xsel-backdrop {
  position: fixed;
  inset: 0;
  z-index: 59;
  background: rgba(15, 23, 42, 0.42);
}
body.xsel-open { overflow: hidden; }
.xsel-pop.is-sheet {
  position: fixed;
  top: auto;
  left: 0;
  right: 0;
  bottom: 0;
  width: 100%;
  min-width: 0;
  /* The anchored menu caps itself at 320px; a sheet spans the screen. */
  max-width: none;
  max-height: 70vh;
  padding: 8px 12px calc(16px + env(safe-area-inset-bottom));
  border: 0;
  border-radius: 16px 16px 0 0;
  transform: translateY(100%);
  transition: transform var(--dur-base) var(--ease-out), opacity var(--dur-fast) var(--ease-out);
}
.xsel-pop.is-sheet.is-shown { transform: translateY(0); }
.xsel-pop.is-sheet .xsel-head {
  display: block;
  padding: 10px 10px 12px;
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text-muted);
  border-bottom: 1px solid var(--border);
  margin-bottom: 6px;
}
/* A touch target under about 44px is a target people miss. */
.xsel-pop.is-sheet .xsel-opt {
  padding: 14px 12px;
  font-size: 17px;
  min-height: 44px;
  display: flex;
  align-items: center;
}
/* A stylus or finger on a large screen still gets the anchored menu, so give
   those rows room too. */
@media (pointer: coarse) {
  .xsel-opt { padding: 12px; min-height: 44px; }
  .xsel-trigger { padding-top: 12px; padding-bottom: 12px; }
}
@media (prefers-reduced-motion: reduce) {
  .xsel-pop, .xsel-caret { transition: none; }
}

/* Secondary action on the sign-in card: "Email me a code instead" sits under
   the primary button and must not read as the main path. */
.login-alt {
  width: 100%;
  margin-top: 10px;
  font-size: 15px;
}

/* Account settings rows: a label and its control, side by side until the
   screen is too narrow for that to be readable. */
.setting-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 14px 0;
  border-bottom: 1px solid var(--border);
}
.setting-row:first-of-type { padding-top: 0; }
.setting-action {
  flex: 0 0 auto;
  font-size: 14px;
  padding: 9px 16px;
  text-decoration: none;
  white-space: nowrap;
}
.setting-form {
  padding: 16px 0 20px;
  border-bottom: 1px solid var(--border);
  max-width: 420px;
}
@media (max-width: 560px) {
  .setting-row { flex-direction: column; align-items: flex-start; gap: 10px; }
  .setting-action { width: 100%; text-align: center; }
}

/* A password-breach notice. Amber, not red: the password is accepted if the
   person says so, and colouring a choice like a failure makes the choice
   feel unavailable. */
.breach-warning {
  background: #FFF8E8;
  border: 1px solid #F0DCA8;
  border-radius: var(--radius-input);
  padding: 14px 16px;
  margin: 0 0 16px;
  color: #7A5B14;
  font-size: 14px;
  line-height: 1.5;
}
.breach-warning p { margin: 6px 0 0; }
.breach-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  margin-top: 14px;
}
.breach-actions .btn { font-size: 14px; padding: 10px 16px; }

/* ===== Contact page ===== */
.contact-primary {
  display: inline-block;
  margin: 20px 0 8px;
  padding: 16px 28px;
  border-radius: var(--radius-pill);
  background: var(--brand-primary);
  color: #fff;
  font-size: 20px;
  font-weight: 600;
  text-decoration: none;
  transition: transform var(--dur-fast) var(--ease-out),
              box-shadow var(--dur-fast) var(--ease-out);
}
.contact-primary:hover {
  transform: translateY(-1px);
  box-shadow: 0 10px 24px rgba(67, 83, 214, 0.26);
}
.contact-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: 18px;
  margin-top: 32px;
}
.contact-card {
  border: var(--card-border);
  border-radius: var(--radius-card);
  background: var(--surface-subtle);
  padding: 22px;
  display: flex;
  flex-direction: column;
}
.contact-card h2 {
  font-size: 19px;
  font-weight: 600;
  margin: 0 0 8px;
}
.contact-card p {
  margin: 0 0 10px;
  font-size: 15px;
  line-height: 1.55;
  color: var(--text-body);
}
.contact-hint {
  color: var(--text-muted) !important;
  font-size: 14px !important;
}
/* Pin the action to the bottom so the three cards' links line up even when
   the copy above them runs to different lengths. */
.contact-card > a {
  margin-top: auto;
  padding-top: 6px;
  font-weight: 600;
  color: var(--brand-primary);
}
@media (prefers-reduced-motion: reduce) {
  .contact-primary { transition: none; }
  .contact-primary:hover { transform: none; }
}

/* ===== Admin: account search, filtering and deletion ===== */
.adm-filters {
  display: flex;
  gap: 8px;
  margin-bottom: 12px;
  flex-wrap: wrap;
}
.adm-search {
  flex: 1 1 260px;
  max-width: 420px;
}
.adm-tabs {
  display: flex;
  gap: 6px;
  margin-bottom: 16px;
  flex-wrap: wrap;
}
.adm-tab {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 7px 14px;
  border: var(--card-border);
  border-radius: var(--radius-pill);
  background: var(--surface);
  color: var(--text-body);
  font-size: 14px;
  font-weight: 500;
  text-decoration: none;
}
.adm-tab:hover { border-color: var(--brand-primary-muted); }
.adm-tab.is-on {
  background: var(--brand-primary);
  border-color: var(--brand-primary);
  color: #fff;
}
/* Not .adm-count: the sidebar already owns that for its red "needs
   attention" badge, and reusing it here would paint these red too. */
.adm-tab-count {
  font-size: 12px;
  opacity: 0.75;
}
/* Deletion is folded away: it should take a deliberate click to even see
   the field, and sit visually apart from Save and Deactivate. */
/* The panel it sits in clips its contents (rounded corners around the
   table), so the confirm box needs somewhere to go that is not "wider
   table". Anchored to the button, over the row, with the clipping lifted
   on this page only. */
.adm-panel-overflow { overflow: visible; }
.adm-danger { display: inline-block; position: relative; }
.adm-danger > summary {
  cursor: pointer;
  list-style: none;
  display: inline-flex;
}
.adm-danger > summary::-webkit-details-marker { display: none; }
.adm-danger-form {
  position: absolute;
  right: 0;
  top: calc(100% + 6px);
  z-index: 30;
  width: 320px;
  max-width: calc(100vw - 32px);
  padding: 12px;
  border: 1px solid #F3D6D6;
  border-radius: var(--radius-input);
  background: #FDF3F3;
  box-shadow: 0 10px 28px rgba(16, 24, 40, 0.16);
  text-align: left;
  white-space: normal;
}
.adm-danger-form .adm-input { width: 100%; margin: 8px 0; }

/* The agreement line under a signup button. Quiet, but not hidden: it has
   to be legible to count as having been shown. */
.consent-line {
  margin: 12px 0 0;
  font-size: 13px;
  line-height: 1.5;
  color: var(--text-muted);
  text-align: center;
}
.consent-line a {
  color: var(--brand-primary);
  text-decoration: underline;
}
