/* ============================================================================
 * site-feedback.css — the persistent feedback / help / account bar.
 *
 * WHY A SEPARATE STYLESHEET, not a <style> block and not JS-injected CSS:
 * vercel.json's style-src-elem carries no 'unsafe-inline' — the only inline CSS
 * a browser applies on this site is a <style> whose sha256 is listed in the
 * policy, and scripts/csp-hashes.js hashes <style> elements built by JS too. A
 * same-origin <link rel=stylesheet> needs no hash, so the bar can ship on ten
 * pages without touching vercel.json. Every rule the bar needs lives here.
 *
 * The two page palettes disagree about variable names (site.css uses
 * --color-*, the dashboard and survey use --text/--muted/--border), so nothing
 * here depends on a page variable: the colours are literal, chosen against the
 * near-black both palettes paint (#0a0e17 / #0a0e1a).
 * ========================================================================== */

:root {
  /* The bar's own height, without the iOS home-indicator inset. The spacer
     element the script appends and the survey CTA offset below both read it,
     so the three can never disagree about how tall the bar is. */
  --pl-fb-height: 44px;
}

/* ─── The bar ─────────────────────────────────────────────────────────────── */

.pl-fb {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  /* Above the survey's own fixed results CTA (z-index 100) and the fixed page
     headers (100); below every modal (1000), toast (2000) and the skip link,
     so an open dialog still covers this bar instead of fighting it. */
  z-index: 120;
  background: rgba(10, 13, 24, 0.94);
  border-top: 1px solid rgba(255, 255, 255, 0.11);
  /* MOBILE-7: fixed to the viewport, so with viewport-fit=cover the bar would
     sit under the iOS home indicator. env() is 0 where there are no insets. */
  padding-bottom: env(safe-area-inset-bottom, 0px);
  font-family: inherit;
  color: #e8ebff;
}

@supports (backdrop-filter: blur(8px)) {
  .pl-fb { backdrop-filter: blur(10px); }
}

.pl-fb-inner {
  height: var(--pl-fb-height);
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 10px;
  padding: 0 max(12px, env(safe-area-inset-right, 0px)) 0 max(12px, env(safe-area-inset-left, 0px));
}

/* The strip of page the fixed bar covers. Appended as the last element in the
   document by site-feedback.js, so the real last element of every page stays
   scrollable into view instead of hiding behind the bar. */
.pl-fb-spacer {
  height: calc(var(--pl-fb-height) + env(safe-area-inset-bottom, 0px));
  flex: none;
  pointer-events: none;
}

/* ─── The toggle ──────────────────────────────────────────────────────────── */

.pl-fb-toggle {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  /* 44px is Apple's minimum tap target and the bar is exactly that tall, so the
     control fills it rather than floating inside it. */
  min-height: var(--pl-fb-height);
  padding: 0 14px;
  background: transparent;
  border: 0;
  border-radius: 10px;
  color: #dfe3ff;
  font: inherit;
  font-size: 13px;
  font-weight: 600;
  line-height: 1;
  cursor: pointer;
}

.pl-fb-toggle:hover { background: rgba(255, 255, 255, 0.07); }
.pl-fb-toggle[aria-expanded="true"] { background: rgba(255, 255, 255, 0.10); }

.pl-fb-icon {
  font-size: 15px;
  line-height: 1;
}

/* ─── The menu ────────────────────────────────────────────────────────────── */

.pl-fb-menu {
  position: absolute;
  right: max(12px, env(safe-area-inset-right, 0px));
  bottom: calc(100% - 1px);
  min-width: 232px;
  max-width: calc(100vw - 24px);
  margin-bottom: 6px;
  padding: 6px;
  background: #161a2b;
  border: 1px solid #2c3660;
  border-radius: 12px;
  box-shadow: 0 12px 32px rgba(0, 0, 0, 0.55);
  display: flex;
  flex-direction: column;
  gap: 2px;
  /* The script toggles the `hidden` property; `display:flex` above would win
     over the UA's [hidden] rule without this. */
}

.pl-fb-menu[hidden] { display: none; }

.pl-fb-item {
  display: block;
  padding: 10px 12px;
  border-radius: 8px;
  color: #e8ebff;
  font-size: 14px;
  line-height: 1.35;
  text-decoration: none;
  background: transparent;
  border: 0;
  text-align: left;
  font-family: inherit;
  cursor: pointer;
}

.pl-fb-item:hover { background: #20264a; }

.pl-fb-sep {
  height: 1px;
  margin: 4px 6px;
  border: 0;
  background: #2c3660;
}

/* ─── Focus ───────────────────────────────────────────────────────────────── */
/* Both :focus and :focus-visible: the requirement is a focus state that is
   always visible, and :focus alone is what older WebKit honours. */

.pl-fb-toggle:focus,
.pl-fb-item:focus,
.pl-fb-report:focus {
  outline: 3px solid #9aa8ff;
  outline-offset: 2px;
}

.pl-fb-toggle:focus-visible,
.pl-fb-item:focus-visible,
.pl-fb-report:focus-visible {
  outline: 3px solid #9aa8ff;
  outline-offset: 2px;
}

/* ─── "Report an error" at the foot of the person modal ───────────────────── */
/* Static markup in partyline_DASHBOARD.html's #repModal, so it works for every
   person card that opens that modal — candidates, incumbents, local
   officeholders, certified filings. It sits after #modalBody so the close
   button stays the dialog's first focusable element. */

.pl-fb-report-row {
  display: flex;
  justify-content: flex-end;
  margin-top: 18px;
  padding-top: 14px;
  border-top: 1px solid #2c3660;
}

.pl-fb-report {
  flex: none;
  align-self: center;
  padding: 8px 12px;
  border: 1px solid #2c3660;
  border-radius: 10px;
  background: transparent;
  color: #cfd6ff;
  font-size: 13px;
  font-weight: 600;
  text-decoration: none;
  white-space: nowrap;
}

.pl-fb-report:hover { background: #20264a; }

/* ─── Page-specific collisions ────────────────────────────────────────────── */
/* partyline_SURVEY.html's #stickyResultsCta is fixed at bottom:0 (inline style,
   hence !important) with z-index 100. Lift it by exactly the bar's height so
   neither covers the other. Scoped to the class the script adds, so if the
   script never runs the CTA keeps sitting on the bottom edge. */

body.pl-fb-on #stickyResultsCta {
  bottom: calc(var(--pl-fb-height) + env(safe-area-inset-bottom, 0px)) !important;
}

/* ─── Narrow screens (390px is the reference width) ───────────────────────── */

@media (max-width: 420px) {
  .pl-fb-inner { padding-left: 8px; padding-right: 8px; }
  .pl-fb-toggle { padding: 0 10px; font-size: 12.5px; }
  .pl-fb-menu {
    right: 8px;
    left: 8px;
    min-width: 0;
    max-width: none;
  }
  .pl-fb-report { padding: 8px 10px; font-size: 12px; }
}

/* ─── Motion ──────────────────────────────────────────────────────────────── */

.pl-fb-toggle,
.pl-fb-item,
.pl-fb-report {
  transition: background-color 0.15s ease;
}

@media (prefers-reduced-motion: reduce) {
  .pl-fb,
  .pl-fb-menu,
  .pl-fb-toggle,
  .pl-fb-item,
  .pl-fb-report {
    transition: none !important;
    animation: none !important;
  }
}

/* Printing a ballot worksheet should not print a floating bar over it. */
@media print {
  .pl-fb,
  .pl-fb-spacer { display: none !important; }
}
