/*
 * bugs.css — Bugs & Features Tab
 */

/* ── Wrapper ───────────────────────────── */
.bugs-wrap {
  min-height: calc(100vh - var(--nav-h));
  padding: 28px 32px 60px;
  max-width: 800px;
  margin: 0 auto;
  display: flex;
  flex-direction: column;
  align-items: center;
}

/* ── Page title ─────────────────────────── */
.bugs-page-title {
  font-family: var(--font-display);
  font-size: clamp(24px, 3.5vw, 38px);
  font-weight: 700;
  letter-spacing: -0.02em;
  color: var(--text-primary);
  line-height: 1.1;
  text-align: center;
  margin-bottom: 28px;
}

/* ── Filter bar (kept for backward compat) */
.bugs-filter-btn {
  background: rgba(255,255,255,0.04);
  border: 1px solid rgba(255,255,255,0.08);
  border-radius: 20px;
  color: var(--text-muted);
  font-family: var(--font-body);
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  padding: 5px 14px;
  cursor: pointer;
  transition: all var(--t-base) var(--ease-out);
}

.bugs-filter-btn.active {
  background: rgba(56,189,248,0.10);
  border-color: rgba(56,189,248,0.35);
  color: var(--accent-cyan);
}

/* ── Submit form card — centrepiece ────── */
.bugs-form-card {
  width: 100%;
  background: var(--glass-2);
  border: 1px solid var(--glass-border);
  border-radius: var(--r-lg);
  backdrop-filter: blur(16px) saturate(1.6);
  -webkit-backdrop-filter: blur(16px) saturate(1.6);
  padding: 28px 28px 24px;
  animation: card-rise 0.5s var(--ease-spring) 0.05s both;
}

.bugs-field {
  margin-bottom: 16px;
}

.bugs-field-label {
  display: block;
  font-size: 9px;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--text-muted);
  margin-bottom: 7px;
}

.bugs-input,
.bugs-select,
.bugs-textarea {
  width: 100%;
  background: rgba(4,5,15,0.6);
  border: 1.5px solid rgba(255,255,255,0.10);
  border-radius: var(--r-sm);
  color: var(--text-primary);
  font-family: var(--font-body);
  font-size: 12px;
  padding: 11px 14px;
  outline: none;
  transition: border-color 0.25s var(--ease-smooth), box-shadow 0.25s var(--ease-smooth);
  caret-color: var(--accent-cyan);
  box-sizing: border-box;
}

.bugs-input:focus,
.bugs-select:focus,
.bugs-textarea:focus {
  border-color: rgba(56,189,248,0.55);
  box-shadow: 0 0 0 3px rgba(56,189,248,0.10);
}

.bugs-textarea {
  resize: vertical;
  min-height: 90px;
  line-height: 1.55;
}

/* Type toggle */
.bugs-type-row {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 7px;
}

.bugs-type-btn {
  background: rgba(255,255,255,0.04);
  border: 1.5px solid rgba(255,255,255,0.08);
  border-radius: var(--r-sm);
  color: var(--text-muted);
  font-family: var(--font-body);
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  padding: 9px 6px;
  cursor: pointer;
  text-align: center;
  transition: all var(--t-base) var(--ease-out);
}

/* Icon + label. These three buttons carried 🐛 / ✦ / ↑ as their icons; the bug was
   a true emoji, which renders as a different picture on every OS and is what
   CLAUDE.md rules out ("inline SVG icons, never emoji"). Swapped for inline SVG,
   so they now need a row box — text-align alone no longer centres two children. */
.bugs-type-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 5px;
}
.bugs-type-ic { flex: 0 0 auto; }

.bugs-type-btn:hover { background: rgba(255,255,255,0.08); }
.bugs-type-btn.active[data-type="bug"]         { background: rgba(251,113,133,0.12); border-color: rgba(251,113,133,0.5); color: var(--accent-rose); }
.bugs-type-btn.active[data-type="feature"]     { background: rgba(45,212,191,0.12);  border-color: rgba(45,212,191,0.5);  color: var(--accent-teal); }
.bugs-type-btn.active[data-type="improvement"] { background: rgba(129,140,248,0.12); border-color: rgba(129,140,248,0.5); color: var(--accent-violet); }

/* Priority */
.bugs-prio-row {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 7px;
}

.bugs-prio-btn {
  background: rgba(255,255,255,0.04);
  border: 1.5px solid rgba(255,255,255,0.08);
  border-radius: var(--r-sm);
  color: var(--text-muted);
  font-family: var(--font-body);
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  padding: 8px 6px;
  cursor: pointer;
  text-align: center;
  transition: all var(--t-base) var(--ease-out);
}

.bugs-prio-btn:hover { background: rgba(255,255,255,0.08); }
.bugs-prio-btn.active[data-prio="low"]    { background: rgba(45,212,191,0.10);  border-color: rgba(45,212,191,0.4);  color: var(--accent-teal); }
.bugs-prio-btn.active[data-prio="medium"] { background: rgba(251,191,36,0.10);  border-color: rgba(251,191,36,0.4);  color: var(--accent-amber); }
.bugs-prio-btn.active[data-prio="high"]   { background: rgba(251,113,133,0.12); border-color: rgba(251,113,133,0.5); color: var(--accent-rose); }

/* Cancel + Submit sit side-by-side so new users always see a clear way
   out without having to scroll up or hunt for the nav. Submit grows to
   fill the remaining width so it stays the obvious primary action. */
.bugs-actions-row {
  display: flex;
  align-items: stretch;
  gap: 10px;
  margin-top: 4px;
}
.bugs-actions-row .bugs-submit-btn { flex: 1 1 auto; margin-top: 0; }

.bugs-cancel-btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 0 18px;
  background: rgba(255, 255, 255, 0.03);
  border: 1.5px solid rgba(255, 255, 255, 0.12);
  border-radius: var(--r-sm);
  color: var(--text-muted);
  font-family: var(--font-body);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  cursor: pointer;
  transition: all var(--t-base) var(--ease-spring);
}
.bugs-cancel-btn:hover {
  background: rgba(255, 255, 255, 0.06);
  border-color: rgba(255, 255, 255, 0.22);
  color: var(--text-primary);
  transform: translateY(-1px);
}
.bugs-cancel-btn:active { transform: scale(0.97); }
html[data-theme="light"] .bugs-cancel-btn {
  background: rgba(0, 0, 0, 0.03);
  border-color: rgba(0, 0, 0, 0.12);
  color: rgba(30, 41, 59, 0.78);
}
html[data-theme="light"] .bugs-cancel-btn:hover {
  background: rgba(0, 0, 0, 0.06);
  border-color: rgba(0, 0, 0, 0.22);
  color: #0f172a;
}

.bugs-submit-btn {
  width: 100%;
  padding: 14px;
  margin-top: 4px;
  background: rgba(56,189,248,0.10);
  border: 1.5px solid rgba(56,189,248,0.35);
  border-radius: var(--r-sm);
  color: var(--accent-cyan);
  font-family: var(--font-body);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  cursor: pointer;
  transition: all var(--t-base) var(--ease-spring);
}

.bugs-submit-btn:hover {
  background: rgba(56,189,248,0.18);
  border-color: rgba(56,189,248,0.65);
  box-shadow: 0 0 24px rgba(56,189,248,0.18);
  transform: translateY(-1px);
}

.bugs-submit-btn:active { transform: scale(0.98); }

.bugs-form-note {
  text-align: center;
  font-size: 9px;
  color: var(--text-dim);
  letter-spacing: 0.06em;
  margin: 12px 0 0;
  line-height: 1.5;
}

/* ── Employee-only test notification button ── */
.bugs-test-notif-btn {
  width: 100%;
  margin-top: 10px;
  padding: 8px;
  font-size: 9px;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--text-dim);
  background: none;
  border: 1px dashed rgba(255,255,255,0.10);
  border-radius: var(--r-xs);
  cursor: pointer;
  outline: none;
  transition: all 0.2s ease;
}

/* Same emoji swap as the type buttons — ⚡ became an inline SVG bell. */
.bugs-test-notif-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
}
.bugs-tn-ic { flex: 0 0 auto; }

.bugs-test-notif-btn:hover {
  color: var(--accent-violet);
  border-color: rgba(129,140,248,0.30);
  background: rgba(129,140,248,0.05);
}

.bugs-test-notif-btn:disabled {
  opacity: 0.5;
  cursor: default;
}

/* ── Recently completed strip ──────────── */
.bugs-resolved-section {
  width: 100%;
  margin-top: 28px;
}

.bugs-resolved-hdr {
  display: flex;
  align-items: center;
  gap: 7px;
  font-size: 9px;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--text-dim);
  margin-bottom: 10px;
}

.bugs-resolved-strip {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.bugs-resolved-pill {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 9px 14px;
  background: var(--glass-2);
  border: 1px solid var(--glass-border);
  border-radius: var(--r-md);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  transition: background var(--t-fast) var(--ease-out);
}

.bugs-resolved-pill:hover {
  background: rgba(255,255,255,0.05);
}

.bugs-resolved-dot {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  flex-shrink: 0;
  opacity: 0.85;
}

.bugs-resolved-title {
  font-size: 12px;
  font-weight: 500;
  color: var(--text-secondary);
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.bugs-resolved-meta {
  font-size: 9px;
  color: var(--text-dim);
  letter-spacing: 0.04em;
  white-space: nowrap;
  font-family: 'Courier New', monospace;
  flex-shrink: 0;
}

.bugs-resolved-empty {
  font-size: 11px;
  color: var(--text-dim);
  letter-spacing: 0.06em;
  opacity: 0.7;
  padding: 4px 0;
}

/* ── Bug card (kept — used by admin/dev manage view) */
.bugs-list-empty {
  text-align: center;
  color: var(--text-muted);
  font-size: 12px;
  letter-spacing: 0.08em;
  padding: 48px 0;
}

.bug-card {
  background: var(--glass-2);
  border: 1px solid var(--glass-border);
  border-left: 3px solid transparent;
  border-radius: var(--r-md);
  padding: 16px 18px;
  backdrop-filter: blur(16px);
  -webkit-backdrop-filter: blur(16px);
  transition: transform var(--t-fast) var(--ease-spring), box-shadow var(--t-base) var(--ease-smooth);
  animation: card-rise 0.4s var(--ease-spring) both;
}

.bug-card:hover {
  transform: translateX(4px);
  box-shadow: 0 8px 32px rgba(0,0,0,0.25);
}

.bug-card.type-bug         { border-left-color: var(--accent-rose); }
.bug-card.type-feature     { border-left-color: var(--accent-teal); }
.bug-card.type-improvement { border-left-color: var(--accent-violet); }

.bug-card.status-resolved { opacity: 0.55; }

.bug-card-header {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 8px;
  flex-wrap: wrap;
}

.bug-type-badge {
  font-size: 8px;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  padding: 2px 8px;
  border-radius: 100px;
  border: 1px solid;
}

.type-bug .bug-type-badge         { color: var(--accent-rose);   background: rgba(251,113,133,0.10); border-color: rgba(251,113,133,0.3); }
.type-feature .bug-type-badge     { color: var(--accent-teal);   background: rgba(45,212,191,0.10);  border-color: rgba(45,212,191,0.3); }
.type-improvement .bug-type-badge { color: var(--accent-violet); background: rgba(129,140,248,0.10); border-color: rgba(129,140,248,0.3); }

.bug-priority-badge {
  font-size: 8px;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  padding: 2px 8px;
  border-radius: 100px;
  border: 1px solid;
}

.prio-low    { color: var(--accent-teal);   background: rgba(45,212,191,0.08);  border-color: rgba(45,212,191,0.25); }
.prio-medium { color: var(--accent-amber);  background: rgba(251,191,36,0.08);  border-color: rgba(251,191,36,0.25); }
.prio-high   { color: var(--accent-rose);   background: rgba(251,113,133,0.10); border-color: rgba(251,113,133,0.3); }

.bug-status-badge {
  font-size: 8px;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--text-dim);
  padding: 2px 8px;
  background: rgba(255,255,255,0.05);
  border: 1px solid rgba(255,255,255,0.08);
  border-radius: 100px;
}

.status-resolved .bug-status-badge { color: var(--accent-emerald); background: rgba(52,211,153,0.08); border-color: rgba(52,211,153,0.25); }
.status-in-progress .bug-status-badge { color: var(--accent-amber); background: rgba(251,191,36,0.08); border-color: rgba(251,191,36,0.25); }

.bug-time {
  font-size: 9px;
  color: var(--text-dim);
  letter-spacing: 0.04em;
  margin-left: auto;
}

.bug-title {
  font-size: 13px;
  font-weight: 600;
  color: var(--text-primary);
  letter-spacing: 0.01em;
  margin-bottom: 5px;
}

.bug-desc {
  font-size: 11px;
  color: var(--text-muted);
  line-height: 1.55;
  margin-bottom: 10px;
}

.bug-actions {
  display: flex;
  gap: 6px;
  flex-wrap: wrap;
  margin-top: 10px;
  padding-top: 10px;
  border-top: 1px solid var(--glass-border);
}

.bug-action-btn {
  font-size: 9px;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  padding: 4px 12px;
  border-radius: var(--r-xs);
  cursor: pointer;
  transition: all var(--t-fast) var(--ease-out);
  background: rgba(255,255,255,0.05);
  border: 1px solid rgba(255,255,255,0.10);
  color: var(--text-muted);
}

.bug-action-btn:hover          { background: rgba(255,255,255,0.10); color: var(--text-secondary); }
.bug-action-btn.resolve:hover  { background: rgba(52,211,153,0.12);  border-color: rgba(52,211,153,0.4); color: var(--accent-emerald); }
.bug-action-btn.progress:hover { background: rgba(251,191,36,0.10);  border-color: rgba(251,191,36,0.4); color: var(--accent-amber); }
.bug-action-btn.reopen:hover   { background: rgba(56,189,248,0.10);  border-color: rgba(56,189,248,0.4); color: var(--accent-cyan); }
.bug-action-btn.delete:hover   { background: rgba(251,113,133,0.10); border-color: rgba(251,113,133,0.4); color: var(--accent-rose); }

/* ── Light mode ────────────────────────── */
html[data-theme="light"] .bugs-form-card,
html[data-theme="light"] .bug-card,
html[data-theme="light"] .bugs-resolved-pill {
  background: rgba(255,255,255,0.55);
  border-color: rgba(130,100,200,0.15);
}

html[data-theme="light"] .bugs-input,
html[data-theme="light"] .bugs-select,
html[data-theme="light"] .bugs-textarea {
  background: rgba(255,255,255,0.7);
  border-color: rgba(130,100,200,0.22);
  color: var(--text-primary);
}

/* Translucent-white button/badge surfaces + borders vanish on the light page.
   Lift the glass fills to the light glass tokens and give the borders the
   purple-tint token so filter/type/priority/action controls stay visible. */
html[data-theme="light"] .bugs-filter-btn,
html[data-theme="light"] .bugs-type-btn,
html[data-theme="light"] .bugs-prio-btn,
html[data-theme="light"] .bug-action-btn,
html[data-theme="light"] .bug-status-badge {
  background: var(--glass-1);
  border-color: var(--glass-border);
}
html[data-theme="light"] .bugs-type-btn:hover,
html[data-theme="light"] .bugs-prio-btn:hover,
html[data-theme="light"] .bug-action-btn:hover {
  background: var(--glass-2);
}
html[data-theme="light"] .bugs-resolved-pill:hover {
  background: var(--glass-3);
}
/* dashed test-notif outline was rgba(255,255,255,.10) — invisible on white */
html[data-theme="light"] .bugs-test-notif-btn {
  border-color: var(--glass-border-2);
}
/* harsh black card-hover shadow → soft cool shadow */
html[data-theme="light"] .bug-card:hover {
  box-shadow: 0 8px 32px rgba(80,90,160,0.14);
}

/* Screenshot thumbnails: 0.06-white hairline disappears; give it the token. */
html[data-theme="light"] .bug-screenshot img,
html[data-theme="light"] .dv-detail-screenshot img {
  border-color: var(--glass-border);
}

/* Upload zone: light-sky prompt text is invisible on white; the "Processing…"
   overlay is a dark surface fill (not a full-screen scrim) — flip to light. */
html[data-theme="light"] .bugs-upload-prompt {
  color: var(--text-secondary);
}
html[data-theme="light"] .bugs-upload-zone.is-busy::after {
  color: var(--accent-cyan);
  background: rgba(255,255,255,0.82);
}

/* ════════════════════════════════════════════════════════════════════════════
   Screenshot upload + lightbox
   ════════════════════════════════════════════════════════════════════════════ */

.bugs-upload-zone {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 110px;
  padding: 16px;
  border: 1.5px dashed rgba(56, 189, 248, 0.30);
  border-radius: 10px;
  background: rgba(56, 189, 248, 0.03);
  cursor: pointer;
  transition: background 0.18s ease, border-color 0.18s ease, transform 0.18s ease;
  outline: none;
}
.bugs-upload-zone:hover,
.bugs-upload-zone:focus-visible {
  border-color: rgba(56, 189, 248, 0.65);
  background: rgba(56, 189, 248, 0.07);
}
.bugs-upload-zone.is-dragover {
  border-color: rgba(56, 189, 248, 0.95);
  border-style: solid;
  background: rgba(56, 189, 248, 0.14);
  transform: scale(1.005);
  box-shadow: 0 0 0 4px rgba(56, 189, 248, 0.10),
              inset 0 0 24px rgba(56, 189, 248, 0.10);
}
.bugs-upload-zone.is-busy {
  pointer-events: none;
  opacity: 0.7;
}
.bugs-upload-zone.is-busy::after {
  content: 'Processing…';
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-body);
  font-size: 11px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: rgba(56, 189, 248, 0.95);
  background: rgba(8, 14, 22, 0.78);
  border-radius: 9px;
}

.bugs-upload-prompt {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  color: rgba(186, 230, 253, 0.78);
}
/* The `hidden` HTML attribute is just UA `display: none` — my class rules
   above (display: flex / inline-block) win on specificity unless we
   re-assert this with class + attribute selectors. */
.bugs-upload-prompt[hidden],
.bugs-upload-preview[hidden] { display: none !important; }
.bugs-upload-prompt svg {
  color: rgba(56, 189, 248, 0.75);
  margin-bottom: 2px;
}
.bugs-upload-title {
  font-family: var(--font-body);
  font-size: 13px;
  letter-spacing: 0.04em;
}
.bugs-upload-title strong { color: rgba(56, 189, 248, 1); font-weight: 700; }
.bugs-upload-hint {
  font-family: var(--font-body);
  font-size: 10px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-dim);
}

.bugs-upload-preview {
  position: relative;
  display: inline-block;
  max-width: 100%;
}
.bugs-upload-preview img {
  max-width: 100%;
  max-height: 220px;
  display: block;
  border-radius: 8px;
  border: 1px solid rgba(56, 189, 248, 0.20);
  box-shadow: 0 6px 20px rgba(0, 0, 0, 0.35);
}
.bugs-upload-remove {
  position: absolute;
  top: -8px;
  right: -8px;
  width: 24px;
  height: 24px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  background: rgba(251, 113, 133, 0.95);
  border: 1.5px solid rgba(8, 14, 22, 0.94);
  color: #04050f;
  cursor: pointer;
  box-shadow: 0 4px 14px rgba(0, 0, 0, 0.40);
  transition: transform 0.18s ease;
}
.bugs-upload-remove:hover { transform: scale(1.08); }

/* ── Screenshot on the bug card ───────────────────────────────────────── */
.bug-screenshot {
  margin-top: 10px;
}
.bug-screenshot img {
  max-width: 100%;
  max-height: 260px;
  display: block;
  border-radius: 8px;
  border: 1px solid rgba(255, 255, 255, 0.06);
  cursor: zoom-in;
  transition: border-color 0.18s ease, transform 0.18s ease;
}
.bug-screenshot img:hover {
  border-color: rgba(56, 189, 248, 0.45);
  transform: translateY(-1px);
}

/* ── Lightbox ──────────────────────────────────────────────────────────── */
.bug-shot-lightbox {
  position: fixed;
  inset: 0;
  z-index: 2000;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(2, 4, 12, 0.82);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  opacity: 0;
  transition: opacity 0.18s ease;
  padding: 32px;
}
.bug-shot-lightbox.is-open { opacity: 1; }
.bug-shot-lightbox img {
  max-width: calc(100vw - 64px);
  max-height: calc(100vh - 64px);
  border-radius: 10px;
  box-shadow: 0 30px 80px rgba(0, 0, 0, 0.65);
  transform: scale(0.96);
  transition: transform 0.22s cubic-bezier(0.22, 1, 0.36, 1);
}
.bug-shot-lightbox.is-open img { transform: scale(1); }
.bug-shot-close {
  position: absolute;
  top: 18px;
  right: 18px;
  width: 36px;
  height: 36px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.06);
  border: 1px solid rgba(255, 255, 255, 0.10);
  color: var(--text-primary);
  cursor: pointer;
  transition: background 0.18s ease, transform 0.18s ease;
}
.bug-shot-close:hover {
  background: rgba(251, 113, 133, 0.20);
  transform: rotate(90deg);
}

/* Dev tab bug-detail modal screenshot — same look as the bugs-tab card */
.dv-detail-screenshot {
  margin-top: 6px;
}
.dv-detail-screenshot img {
  max-width: 100%;
  max-height: 320px;
  display: block;
  border-radius: 8px;
  border: 1px solid rgba(255, 255, 255, 0.06);
  cursor: zoom-in;
  transition: border-color 0.18s ease, transform 0.18s ease;
}
.dv-detail-screenshot img:hover {
  border-color: rgba(56, 189, 248, 0.45);
  transform: translateY(-1px);
}

@media (prefers-reduced-motion: reduce) {
  .bugs-upload-zone.is-dragover { transform: none; }
  .bug-screenshot img:hover { transform: none; }
  .bug-shot-close:hover { transform: none; }
  .bug-shot-lightbox img { transform: none; }
  .dv-detail-screenshot img:hover { transform: none; }
}

/* ── Light-mode overrides for JS-injected inline styles (bugs.js) ──────────────
   bugs.js hardcodes the DARK-mode accent hex (#38bdf8 cyan / #34d399 emerald) as
   SVG stroke/fill presentation attributes on the two decorative eyebrow icons it
   injects. Those tints are too pale on the light glass card, so remap them to the
   darkened light-palette accents. Scoped to the bugs containers so no other
   .page-eyebrow icon is touched. CSS stroke/fill beat SVG presentation attrs
   without !important; dark mode is untouched. */
html[data-theme="light"] .bugs-wrap .page-eyebrow svg circle,
html[data-theme="light"] .bugs-wrap .page-eyebrow svg line {
  stroke: var(--accent-cyan, #0284c7);
}
html[data-theme="light"] .bugs-wrap .page-eyebrow svg circle[fill] {
  fill: var(--accent-cyan, #0284c7);
}
html[data-theme="light"] .bugs-resolved-hdr svg polyline {
  stroke: var(--accent-emerald, #059669);
}

/* ── MOBILE (2026-07-06 overhaul) — scoped, desktop untouched ─────────────── */

/* iOS focus-zoom guard: 16px form inputs on touch/phone */
@media (max-width: 768px), (pointer: coarse) {
  .bugs-input,
  .bugs-select,
  .bugs-textarea { font-size: 16px; }
}

@media (max-width: 768px) {
  /* 100dvh viewport + tighter phone padding */
  .bugs-wrap {
    min-height: calc(100vh - var(--nav-h));
    min-height: calc(100dvh - var(--nav-h));
    padding: 20px 14px 48px;
  }
  .bugs-form-card { padding: 18px 16px 16px; }

  /* Screenshot lightbox: full-bleed, dvh-safe, no GPU blur */
  .bug-shot-lightbox {
    padding: 12px;
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
    background: rgba(2, 4, 12, 0.94);
  }
  .bug-shot-lightbox img {
    max-width: calc(100vw - 24px);
    max-height: calc(100vh - 24px);
    max-height: calc(100dvh - 24px);
  }
  .bug-shot-close {
    width: 44px;
    height: 44px;
    top: calc(10px + env(safe-area-inset-top, 0px));
    right: calc(10px + env(safe-area-inset-right, 0px));
  }

  /* Drop always-on backdrop blurs (non-lite mode) — big scroll-jank saver */
  .bugs-form-card,
  .bugs-resolved-pill,
  .bug-card {
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
    background: rgba(10, 13, 30, 0.92);
  }
  html[data-theme="light"] .bugs-form-card,
  html[data-theme="light"] .bugs-resolved-pill,
  html[data-theme="light"] .bug-card {
    background: rgba(255, 255, 255, 0.92);
  }
}

/* Touch targets */
@media (pointer: coarse) {
  .bugs-upload-remove { width: 36px; height: 36px; top: -10px; right: -10px; }
  .bug-action-btn { padding: 10px 14px; min-height: 40px; }
  .bugs-type-btn,
  .bugs-prio-btn { min-height: 44px; }
  /* Desktop-only upload hint (drag/paste copy) is noise on touch */
  .bugs-upload-hint { display: none; }
}

/* ── LEGIBILITY FLOOR ON THE FORM'S OWN CONTROLS (2026-08-02 mobile pass) ───
   Audited at 375px: every control label on this form rendered UNDER the 12px
   floor — .bugs-type-btn (Bug / Feature / Improvement) 10px, .bugs-prio-btn
   (Low / Medium / High) 10px, .bugs-cancel-btn 10px, .bugs-test-notif-btn 9px,
   .bugs-resolved-hdr ("RECENTLY COMPLETED") 9px. These are the interactive
   labels of the app's feedback form, read at arm's length under grow-room
   lights, so 9px is not a style choice — it is the smallest text on the screen
   sitting on the largest targets.

   Why the global floor in src/styles/5-utilities/mobile-native.css §1 does not reach them: that
   rule matches naming conventions (-label, -meta, -sub, -hint, …) and these are
   -btn and -hdr. Widening the global substring list to -btn would apply a floor
   to every button in the app, including the icon-only ones that deliberately
   use font-size:0 to hide their text — the exact trap §1 documents. So the fix
   belongs at the source, here, where the scope is one component.

   letter-spacing comes DOWN as the size goes UP, and that is load-bearing, not
   tidiness: these are uppercase labels in a 3-up row. Measured at 375px the
   TYPE row gives each button ~88px of inner width, and "IMPROVEMENT" at 12px
   with the desktop's 0.08em tracking needs ~94px — it would wrap to two lines
   and re-introduce the ragged row this is meant to fix. 0.02em brings it to
   ~86px and it stays on one line. Desktop keeps the wide tracking; it has the
   room for it. */
@media (max-width: 768px) {
  .bugs-type-btn,
  .bugs-prio-btn,
  .bugs-cancel-btn {
    font-size: 12px;
    letter-spacing: 0.02em;
  }
  .bugs-type-btn { padding-inline: 4px; }
  .bugs-test-notif-btn { font-size: 12px; letter-spacing: 0.06em; }
  .bugs-resolved-hdr   { font-size: 12px; letter-spacing: 0.10em; }
}

/* ── RECENTLY COMPLETED strip: stop deleting information on the phone ───────
   Verified at 375px (2026-08-02). Desktop renders each completed item as one
   row: "<full title>            7/26 9:01 AM · Tony". The phone rendered a dot
   and a one-line title ellipsized at ~34 characters — "add day of cycle of all
   rooms to main dahsboard fo…" — with the who/when gone entirely, because
   .bugs-resolved-title is white-space:nowrap and src/styles/5-utilities/mobile.css:744 sets
   .bugs-resolved-meta { display:none }. Nothing on the pill opens a detail
   view, so that was deletion, not deferral.

   Fix: the pill becomes two rows on the phone — the whole title, wrapped and
   clamped at 3 lines so one runaway report can't own the screen, then the meta
   beneath it at the 12px legibility floor (it was 9px).

   The meta rule carries the extra .bugs-resolved-pill class ON PURPOSE:
   src/styles/5-utilities/mobile.css is linked AFTER src/features/bugs/bugs.css (index.html:75 vs :119), so a
   bare .bugs-resolved-meta here would lose the display:none tie on order.
   Widened from 480px to 768px to match this file's other mobile blocks.
   Desktop (>768px) keeps the single-row layout untouched. */
@media (max-width: 768px) {
  .bugs-resolved-pill {
    flex-wrap: wrap;
    align-items: flex-start;
    row-gap: 3px;
  }
  .bugs-resolved-dot { margin-top: 6px; }
  .bugs-resolved-title {
    white-space: normal;
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 3;
    line-height: 1.35;
  }
  .bugs-resolved-pill .bugs-resolved-meta {
    display: block;
    width: 100%;
    padding-left: 17px;
    font-size: 12px;
    white-space: normal;
  }
}

/* LIGHT-MODE CONTRAST (2026-07-30 audit) — the report form's segmented buttons
   and submit CTA kept their dark-canvas slate on the light surface (1.68–3.69:1).
   These are the primary controls of the form, so they need AA, not decoration. */
html[data-theme="light"] .bugs-type-btn,
html[data-theme="light"] .bugs-prio-btn { color: rgba(19, 16, 58, 0.80); border-color: rgba(19, 16, 58, 0.16); }
html[data-theme="light"] .bugs-type-btn:hover,
html[data-theme="light"] .bugs-prio-btn:hover { background: rgba(19, 16, 58, 0.06); }
/* NOT white — the submit button's light-mode surface is pale, so forcing white
   text made it 1.27:1 (worse than the 3.22:1 it started at). Dark ink on the
   pale surface is the readable pairing. */
html[data-theme="light"] .bugs-submit-btn { color: rgba(19, 16, 58, 0.92); }
html[data-theme="light"] .bugs-form strong,
html[data-theme="light"] .bugs-empty strong { color: rgba(19, 16, 58, 0.88); }

/* ══════════════════════════════════════════════════════════════════════════════
   BUGS & FEATURES · PHONE, ROUND 2  (2026-08-03) — the form is the page
   ══════════════════════════════════════════════════════════════════════════════
   This tab is one long form plus a completed-work strip. On a phone the form is
   1.4 screens tall, so at no point while filling it in can the user see the
   button that submits it. Everything below follows from that.

   CASCADE NOTE — src/features/bugs/bugs.css is index.html:75 and src/styles/5-utilities/mobile-native.css is the
   last <link>, so mobile-native wins any tie on these class-level selectors.
   Only two of its rules reach this component (§13 border-radius:14px and §14's
   surface/contrast lift on [class*="-card"]), and nothing here contests them, so
   plain class selectors are still correct — no #tab-bugs prefix needed. Rules
   that DO have to beat a later sheet say so at the rule.

   OBSERVED, BY EYE, AT 375x667
   ----------------------------
   1. THE THIRD TYPE BUTTON WRAPPED. The row is repeat(3, 1fr) = three 101px
      buttons; "IMPROVEMENT" at the 12px floor needs ~91px of the 99px interior
      once its arrow and tracking are counted, so it broke onto a second line and
      the whole row grew to 50px with one ragged label in it. This passed every
      automated check — no overflow, no sub-12px text, target over 44px.
   2. SUBMIT REPORT WAS NEVER ON SCREEN WITH THE FIELDS. It sits at y≈830 on a
      667px screen: fill the title, scroll, attach a photo, scroll, pick a
      priority, scroll again to find the button.
   3. THE UPLOAD ZONE'S HINT WAS DELETED ON TOUCH. A `@media (pointer: coarse)`
      rule set .bugs-upload-hint { display: none }. Its text — "PNG / JPG
      screenshot — auto-compressed if large" — is the ONLY place the app says a
      big photo will be compressed rather than rejected, and a phone camera photo
      is exactly the case that needs it. Restored inline beside the prompt.
   ══════════════════════════════════════════════════════════════════════════ */

/* (3) Undo the coarse-pointer deletion of the upload hint. This has to sit
   AFTER the `@media (pointer: coarse)` block above — same specificity, later
   wins — which is why it is here and not merged into it. */
@media (pointer: coarse) {
  .bugs-upload-hint {
    display: block;
    font-size: 12px;
    letter-spacing: 0.04em;
    text-transform: none;
    line-height: 1.35;
  }
}

@media (max-width: 768px) {
  /* ── (1) Type row: proportional, not equal ────────────────────────────────
     The three labels are 3, 7 and 11 characters. Equal thirds is the wrong
     division for that: it starves the longest and wastes the shortest. The
     ratio below gives BUG 85px, FEATURE 95px and IMPROVEMENT 121px out of the
     same 315px, and nowrap makes the failure mode loud (a clipped label) rather
     than silent (a second line that still passes every audit).
     Desktop keeps repeat(3, 1fr) — at 800px the equal thirds are 260px each and
     the ratio would only make the row look lopsided. */
  .bugs-type-row { grid-template-columns: 0.85fr 0.95fr 1.2fr; gap: 7px; }
  .bugs-type-btn {
    white-space: nowrap;
    padding: 9px 4px;
    min-height: 48px;
    display: flex;
    align-items: center;
    justify-content: center;
  }
  .bugs-prio-btn { min-height: 48px; }

  /* ── (2) The submit control docks to the thumb ────────────────────────────
     .bugs-form-card becomes a flex column purely so the actions row can be
     ordered last; every other child keeps its authored order (0). Once it is
     genuinely the final child, `position: sticky; bottom` pins it to the bottom
     of the viewport for the whole time the form is on screen and releases it
     naturally when the card's own end scrolls into view — so the button is
     reachable from the first field onward and never floats over content that
     comes after it.
     The 60px offset is #mnav's height; env(safe-area-inset-bottom) clears the
     home indicator. The gradient (not a flat fill) is what stops the fields
     underneath from looking cut off as they pass behind it.
     ⚠ This is deliberately NOT the generic §14(b) rule in mobile-native.css:
     that one matches [class*="-actions"]:has(> [class*="primary"]) and this
     form's buttons are .bugs-submit-btn / .bugs-cancel-btn, so it never applied
     here. */
  .bugs-form-card { display: flex; flex-direction: column; }
  /* ⚠ THE LAST THING ABOVE THE DOCKED BAR MUST BE INERT, NOT A CONTROL.
     A `bottom`-anchored sticky element rides UP out of its flow position by
     (flowBottom − stickyLine), and there is no way to bound that in CSS: the
     rise is whatever the distance is between the card's end and the dock line,
     which changes with viewport height and scroll. Everything the bar passes
     over is therefore coverable, and the design above accepts that for
     PARAGRAPHS ("content passes under a toolbar"). It is not acceptable for a
     button.

     MEASURED at 390x844 (Pixel / iPhone-14 class — the single most common
     phone size) with the page at its INITIAL scroll position:
         .bugs-actions-row   pinned  y = 712..784
         #bugs-test-notif-btn        y = 714..758
         elementFromPoint(centre of the button) -> #bugs-submit-btn
     i.e. Test Notification was completely covered and completely untappable
     the moment the tab opened, with nothing on screen to say so. Scrolling
     200px released the bar and it worked again — which is exactly the kind of
     "sometimes the button does nothing" that never gets reported as a bug.
     375x667 did not show it (the card runs past the fold there, so the button
     is below the viewport instead of under the bar), which is why an audit at
     one size missed it.

     The fix is the order, not the geometry: the dev-only Test Notification
     button swaps places with the form note, so the last thing the bar can
     reach is the note — a sentence, which is what the bar was designed to
     pass over. Reading order is unharmed: Priority -> Test Notification ->
     "Reports sync across all devices…" -> Cancel / Submit. Nothing moves on
     desktop; both rules are inside this phone band and neither `order` has any
     effect until .bugs-form-card becomes a flex column, which also only
     happens here. */
  .bugs-test-notif-btn { order: 7; }
  .bugs-form-note      { order: 8; margin-bottom: 4px; }
  .bugs-actions-row {
    order: 9;
    position: sticky;
    /* --mnav-h is published on :root by src/styles/5-utilities/mobile-native.css §4 (60px) and
       re-published as 46px in its landscape band §11. Custom properties resolve
       from the winning :root declaration no matter which sheet reads them, so
       referencing the variable — rather than the 60 it happens to equal right
       now — is what keeps this bar glued to the tab bar in both orientations.
       The literal 60px it replaced left a 14px gap in landscape. */
    bottom: calc(var(--mnav-h, 60px) + env(safe-area-inset-bottom, 0px));
    z-index: 4;
    margin: 0 -16px -16px;
    padding: 12px 16px calc(12px + env(safe-area-inset-bottom, 0px));
    /* An OPAQUE bar with a hairline rule, NOT a gradient scrim. The gradient
       version sliced whatever scrolled behind it through the middle of a text
       line — the upload hint rendered as "auto-compressed if / larg" with the
       rest faded — which reads as a rendering fault, not as chrome. A solid bar
       with a top rule is unambiguous: content passes UNDER a toolbar. It also
       doubles as the form's footer divider once the bar releases at the end of
       the card, which is where it comes to rest. */
    /* The exact opaque composite of the card's own mobile surface:
       src/styles/5-utilities/mobile-native.css §14 gives [class*="-card"] a
       color-mix(--col-indigo 82%, transparent) fill over the --col-void page,
       so mixing the same 82% against --col-void reproduces it with no alpha.
       Opaque is load-bearing — a translucent bar shows the fields ghosting
       through. Both tokens flip with the theme, so light mode needs no override
       (the earlier draft hard-coded a light fill and would have gone stale the
       moment the palette moved). */
    background: color-mix(in srgb, var(--col-indigo, #0f1535) 82%, var(--col-void, #04050f));
    border-top: 1px solid var(--glass-border, rgba(255, 255, 255, 0.09));
    border-radius: 0 0 14px 14px;
  }
  .bugs-submit-btn { min-height: 48px; }
  .bugs-cancel-btn { min-height: 48px; }

  /* ── Density ──────────────────────────────────────────────────────────────
     Desktop's 28px page-title margin and 16px field rhythm are ~90px of air on
     a screen that only has 667. The rhythm stays a rhythm — it just gets the
     phone's spacing step instead of the monitor's. */
  .bugs-page-title { margin-bottom: 14px; }
  .bugs-field { margin-bottom: 12px; }
  .bugs-field-label { margin-bottom: 5px; }
  .bugs-upload-zone { min-height: 88px; padding: 12px; }
  .bugs-upload-prompt { gap: 3px; }
  .bugs-resolved-section { margin-top: 18px; }
}

/* ── LANDSCAPE PHONE: the dock comes off ────────────────────────────────────
   A phone on its side is ~290px of usable height once both bars are drawn. A
   docked action bar costs ~70px of that AND, measured at 667x375, it parked
   directly over the TITLE field — the docked SUBMIT covered the input the user
   was filling in. The thumb-zone argument does not survive that: in landscape
   the whole form is within a thumb-flick anyway. So the bar reverts to a normal
   form footer here, keeping only the reorder (it stays the last thing in the
   card) and the hairline that separates it.
   Same band as src/styles/5-utilities/mobile-native.css §11 and src/departments/cultivation/css/
   calendar.css, so all three agree on what a phone on its side means. */
@media (max-width: 900px) and (max-height: 480px) and (orientation: landscape) and (pointer: coarse) {
  .bugs-actions-row {
    position: static;
    margin: 0;
    padding: 12px 0 0;
    background: none;
    border-radius: 0;
  }
}

/* ── THE "Working…" PILL MUST NOT PARK ON THE SUBMIT BUTTON ─────────────────
   The global status pill (.tbusy) is bottom-docked on phones at
   `bottom: var(--mnav-clear)` = --mnav-h + safe-area + 12px = 72px. That was
   the right call in general — it used to be top-centred and printed over page
   titles. But it is the SAME bottom strip THIS tab docks its action bar in,
   and the two land exactly on top of each other.

   MEASURED at 390x844 with the pill forced on:
       .bugs-actions-row      y = 712..784   (h 72, position:sticky)
       .tbusy                 y = 736..772
       elementFromPoint(pill centre) -> BUTTON.bugs-submit-btn "SUBMIT REPORT"
       vertical overlap        36px — the pill is entirely inside the bar
   The pill is pointer-events:none so the tap still lands, but the primary CTA
   of the tab is unreadable — covered by "Still working — Google Sheets is
   taking a while…" — for the whole duration of a slow poll, which on this app
   is routine. A user cannot tell a covered button from a disabled one, so the
   rational move is to stop pressing it.

   CASCADE — this took two attempts, so it is written down. The pill has THREE
   owners and none of them is reachable by load order:
     • src/shared/platform/loading-indicator.js INJECTS <style id="tbusy-style"> at runtime, so
       it lands after every <link> and cannot be outranked on order;
     • src/styles/5-utilities/mobile-v2.css fights it with `top:54px !important`;
     • src/styles/5-utilities/mobile-native.css §(nav clearance) is the one that actually wins:
       `.tbusy { top:auto !important; bottom: var(--mnav-clear) !important }`.
   The first version of this rule had no !important and lost silently — the
   measured overlap stayed at exactly 36px and everything LOOKED applied
   (the rule is present and parsed in the CSSOM; it just never wins). Because
   the incumbent is !important, the override has to be !important too — and
   `body:has(#tab-bugs.active) .tbusy` is (1,2,1) against a bare `.tbusy`
   (0,1,0), so between two !important declarations this one takes it.
   ⚠ Do not strip the !important below thinking specificity alone is enough.

   The lift is exactly the bar's own height (48px min-height + 2x12px padding
   = 72px) plus 10px of air, expressed with the same --mnav-h / safe-area
   tokens the bar itself uses, so the two stay glued together if the nav
   height changes.

   Scoped to this tab only: no other tab of mine docks a control down there
   (verified — Permissions reports zero sticky/fixed elements at 390x844), and
   a bottom-anchored toast floating over ordinary scrollable content is the
   correct native idiom, so it is left alone everywhere else. If :has() is
   unsupported the rule simply does not apply and behaviour is today's — no
   regression path. Nothing here exists above 768px. */
@media (max-width: 768px) {
  body:has(#tab-bugs.active) .tbusy {
    bottom: calc(var(--mnav-h, 60px) + env(safe-area-inset-bottom, 0px) + 82px) !important;
  }
}
/* Landscape: .bugs-actions-row reverts to position:static above, so there is
   nothing down there to clear and an 82px lift would strand the pill in the
   middle of a 375px-tall viewport. Hand it straight back to the global
   --mnav-clear the rest of the app uses. Same band as the revert above. */
@media (max-width: 900px) and (max-height: 480px) and (orientation: landscape) and (pointer: coarse) {
  body:has(#tab-bugs.active) .tbusy {
    bottom: var(--mnav-clear, calc(var(--mnav-h, 46px) + env(safe-area-inset-bottom, 0px) + 12px)) !important;
  }
}

/* ── Light-theme contrast (2026-08-24) ───────────────────────────────────────
   The upload hint bolds 'Click', 'drag' and 'paste' in sky-400 (#38bdf8), which is
   1.88:1 on light — the three words the instruction depends on were the least
   readable part of it. */
html[data-theme="light"] .bugs-upload-title strong { color: var(--accent-cyan); }
