/* feedback.css — the "Questions or Issues?" / "Improvement Suggestions?"
   widget, shared by every EZ Dev app.

   Built 2026-08-20 from Remailminder's hand-rolled version (public/index.html +
   app.js + style.css), which was the only copy in existence. Ethan's ask:
   "the lightbulb and question mark function should be the same in every app,
   just the color changes to match whatever app it is."

   WHY THIS IS SELF-SUFFICIENT (unlike splash.css, which leans on each app's
   own classes): the five apps do NOT share a class or variable vocabulary.
   Remailminder has --surface/--accent-ice, EZ Money has --raised/--gold-ice,
   EZ Pics has --surface-2/--brand, Paradigm Analytics has --purple-ice. A
   widget that assumed any of those would render unstyled in three apps out of
   five. So every rule here is namespaced .ezfb-* and every color reads a
   --ezfb-* variable, each of which FALLS BACK to the most common app var name
   and then to a literal dark-theme value.

   TO ADOPT THIS IN AN APP: serve /shared/feedback.css + /shared/feedback.js,
   call EZFeedback.mount(...), and set the handful of --ezfb-* variables below
   in that app's own stylesheet. Colors are the only thing an app should
   override — if you find yourself re-styling structure, fix it here instead so
   all five apps get it.

   House rules honored here: no emojis (real SVG icons, drawn in feedback.js),
   no visible scrollbars anywhere. */

:root {
  /* Accent = the app's color. This is the one an app really must set. */
  --ezfb-accent: var(--accent-ice, var(--brand, var(--primary, #A9E8BB)));
  /* Second accent for the question bubble, so the two FABs read as siblings
     rather than duplicates. Defaults to the main accent when an app has only
     one brand color. */
  --ezfb-accent-2: var(--accent-steel, var(--ezfb-accent));

  --ezfb-surface: var(--surface, var(--raised, #151719));
  --ezfb-surface-alt: var(--surface-alt, var(--bg, #0B0C0E));
  --ezfb-border: var(--border, #2B2F34);
  --ezfb-text: var(--text, #F2F4F6);
  --ezfb-text-muted: var(--text-muted, var(--muted, #98A0A8));
  --ezfb-text-faint: var(--text-faint, var(--ezfb-text-muted));
  --ezfb-danger: var(--danger, #C0564F);
  --ezfb-radius: var(--radius, 12px);
  --ezfb-radius-sm: var(--radius-sm, 10px);
  --ezfb-shadow: var(--shadow-lg, 0 8px 32px rgba(0,0,0,.45));

  /* The button label a person clicks to send. Its own vars because the
     "primary button" color is the one thing apps disagree on most (some use a
     near-white pill, some use the accent itself). */
  --ezfb-btn-bg: var(--primary, var(--ezfb-accent));
  --ezfb-btn-text: var(--primary-contrast, #0B0C0E);
}

/* ===== The floating buttons =====
   48px circle that widens into a pill on hover/focus, revealing its label.
   The expanded width is NOT hardcoded per app: feedback.js measures each
   label once at mount and sets --ezfb-fab-w on that button, because a fixed
   width is a magic number that goes wrong the moment the wording (or the
   font) changes. Vertical position is likewise set per button from its index
   (--ezfb-fab-bottom), so a third door can be added without touching CSS. */
.ezfb-fab {
  position: fixed;
  bottom: var(--ezfb-fab-bottom, 28px);
  right: 28px;
  width: 48px;
  height: 48px;
  border-radius: 999px;
  background: var(--ezfb-surface);
  border: 1.5px solid var(--ezfb-border);
  box-shadow: var(--ezfb-shadow);
  font-size: 14px;
  font-weight: 600;
  font-family: inherit;
  padding: 0;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: flex-start;
  overflow: hidden;
  transition: width 0.22s ease, box-shadow 0.15s ease;
  z-index: 50;
  color: var(--ezfb-text);
}

.ezfb-fab-icon {
  flex-shrink: 0;
  width: 48px;
  height: 48px;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--ezfb-accent);
}

/* The bulb READS high in its circle: all its visual mass (the glass globe) is
   in the upper two thirds, while the lower third is two thin lines. It is
   mathematically centred already, so this is an optical correction, not a
   geometric one — carried over from Remailminder, where Ethan reported it. */
.ezfb-fab-icon svg { transform: translateY(1px); }

.ezfb-fab-text {
  text-align: left;
  line-height: 1.25;
  white-space: nowrap;
  padding-right: 18px;
  opacity: 0;
  transition: opacity 0.12s ease;
}

.ezfb-fab:hover,
.ezfb-fab:focus-visible {
  width: var(--ezfb-fab-w, 232px);
  box-shadow: 0 12px 40px rgba(0,0,0,.16);
}

.ezfb-fab:hover .ezfb-fab-text,
.ezfb-fab:focus-visible .ezfb-fab-text {
  opacity: 1;
  transition: opacity 0.15s ease 0.08s;
}

/* The question door gets the second accent so the pair reads as two doors. */
.ezfb-fab--question .ezfb-fab-icon { color: var(--ezfb-accent-2); }

/* ===== Modal ===== */
.ezfb-overlay {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, .65);
  z-index: 200;
  display: none;
  align-items: center;
  justify-content: center;
  padding: 20px;
}

.ezfb-overlay.ezfb-open { display: flex; }

.ezfb-modal {
  background: var(--ezfb-surface);
  color: var(--ezfb-text);
  border-radius: var(--ezfb-radius);
  box-shadow: var(--ezfb-shadow);
  width: 100%;
  max-width: 420px;
  padding: 32px;
  position: relative;
  font-family: inherit;
  /* A long error + three thumbnails can outgrow a short window; scroll inside
     the card rather than clipping, with no visible bar (house rule). */
  max-height: calc(100vh - 40px);
  overflow-y: auto;
  scrollbar-width: none;
  -ms-overflow-style: none;
}

.ezfb-modal::-webkit-scrollbar { display: none; }

.ezfb-close {
  position: absolute;
  top: 16px;
  right: 16px;
  background: none;
  border: none;
  font-size: 22px;
  color: var(--ezfb-text-faint);
  cursor: pointer;
  line-height: 1;
  padding: 4px;
}

.ezfb-title {
  font-size: 22px;
  font-weight: 700;
  margin: 0 0 8px;
}

.ezfb-sub {
  font-size: 14px;
  color: var(--ezfb-text-muted);
  margin: 0 0 24px;
}

.ezfb-field { display: flex; flex-direction: column; gap: 6px; }

.ezfb-label {
  font-size: 13px;
  font-weight: 500;
  color: var(--ezfb-text-muted);
}

.ezfb-textarea {
  width: 100%;
  font-family: inherit;
  font-size: 15px;
  color: var(--ezfb-text);
  background: var(--ezfb-surface-alt);
  border: 1.5px solid var(--ezfb-border);
  border-radius: var(--ezfb-radius-sm);
  padding: 10px 14px;
  resize: vertical;
  scrollbar-width: none;
  -ms-overflow-style: none;
}

.ezfb-textarea::-webkit-scrollbar { display: none; }
.ezfb-textarea:focus { outline: none; border-color: var(--ezfb-accent); }

/* ===== Photo attach =====
   One row: a button that opens the file picker, plus the hint that you can
   paste or drop instead. The whole modal is the drop target (a small dashed
   box is easy to miss and easy to miss-aim at), and it only announces itself
   while something is actually being dragged over it. */
.ezfb-photos { margin-top: 14px; }

.ezfb-attach-row {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
}

.ezfb-attach-btn {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  font-family: inherit;
  font-size: 13px;
  font-weight: 600;
  color: var(--ezfb-text-muted);
  background: transparent;
  border: 1.5px dashed var(--ezfb-border);
  border-radius: var(--ezfb-radius-sm);
  padding: 8px 13px;
  cursor: pointer;
  transition: color 0.15s ease, border-color 0.15s ease;
}

.ezfb-attach-btn:hover {
  color: var(--ezfb-text);
  border-color: var(--ezfb-accent);
}

.ezfb-attach-btn svg { width: 16px; height: 16px; flex-shrink: 0; }

.ezfb-attach-hint {
  font-size: 12px;
  color: var(--ezfb-text-faint);
}

.ezfb-file-input { display: none; }

.ezfb-modal.ezfb-dragging {
  outline: 2px dashed var(--ezfb-accent);
  outline-offset: -6px;
}

.ezfb-thumbs {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  margin-top: 12px;
}

.ezfb-thumb {
  position: relative;
  width: 64px;
  height: 64px;
  border-radius: var(--ezfb-radius-sm);
  overflow: hidden;
  border: 1.5px solid var(--ezfb-border);
  background: var(--ezfb-surface-alt);
}

.ezfb-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }

/* Removing an attachment must be reachable without hovering — on a phone
   there is no hover, and a photo you cannot un-attach is a trap. */
.ezfb-thumb-x {
  position: absolute;
  top: 2px;
  right: 2px;
  width: 20px;
  height: 20px;
  border-radius: 999px;
  border: none;
  background: rgba(0, 0, 0, .68);
  color: #fff;
  font-size: 14px;
  line-height: 1;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
}

.ezfb-thumb-x:hover { background: var(--ezfb-danger); }

/* A photo still being downscaled shows as a dimmed tile, so a big HEIC off a
   phone doesn't look like nothing happened. */
.ezfb-thumb--busy { opacity: 0.45; }

.ezfb-error {
  /* Split out as its own vars because apps disagree on whether an error is a
     tinted panel (Remailminder) or plain red text — both look wrong in the
     other's theme. */
  background: var(--ezfb-error-bg, rgba(192, 86, 79, .12));
  border: 1px solid var(--ezfb-danger);
  color: var(--ezfb-error-text, var(--ezfb-danger));
  border-radius: var(--ezfb-radius-sm);
  padding: 10px 14px;
  font-size: 14px;
  margin-top: 12px;
  display: none;
  white-space: pre-line;
}

.ezfb-error.ezfb-shown { display: block; }

.ezfb-actions { margin-top: 16px; }

.ezfb-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  width: 100%;
  font-family: inherit;
  font-size: 15px;
  font-weight: 600;
  border-radius: var(--ezfb-radius-sm);
  padding: 11px 22px;
  border: none;
  cursor: pointer;
  transition: all 0.15s;
  background: var(--ezfb-btn-bg);
  color: var(--ezfb-btn-text);
}

/* Apps whose primary button changes color on hover (rather than just getting
   brighter) set --ezfb-btn-bg-hover and turn the filter off. */
.ezfb-btn:hover {
  background: var(--ezfb-btn-bg-hover, var(--ezfb-btn-bg));
  filter: var(--ezfb-btn-hover-filter, brightness(1.06));
  transform: translateY(-1px);
}
.ezfb-btn:active { transform: translateY(0); }
.ezfb-btn:disabled { opacity: 0.55; cursor: not-allowed; transform: none; filter: none; }

@media (max-width: 560px) {
  .ezfb-modal { padding: 26px 20px; }
  /* The pills are deliberately NOT collapsed on phones: they are right-anchored
     and ~260px fits, and that is exactly how Remailminder has behaved since
     the widget shipped. Left alone on purpose during the extraction. */
}
