/* ────────────────────────────────────────────────────────────────────
 * Spartan CRM — Email reminders top bar (WIP-V2.1-EMAIL-INTAKE-01)
 * Companion to modules/38-email-reminders-bar.js
 *
 * A-806 (Graham, 2026-09-14, video): "The notification bar is pulsing far too
 * much and is overwhelming. It needs to be a lot quieter."
 *
 * Escalation is now carried by STATIC weight, not by motion. Louder means a
 * deeper red, a thicker rule and a heavier ring — never a faster flash:
 *   Day 0-1  → .er-pulse-normal       static; a single soft breathing ring (6s)
 *   Day 2    → .er-pulse-super        deeper red + 2px inset rule, same 6s ring
 *   Day 3+   → .er-pulse-fullscreen   darkest red + 3px rule + a STATIC page tint
 *   critical → .er-pulse-extreme      as above, plus a solid left flag
 *
 * What was removed and why (all four were measured on the real page):
 *   · the 1.0s / 0.8s banner flashes — at 3 days old an ordinary unresolved
 *     reminder turned the whole CRM into a 1Hz strobe;
 *   · `transform: translateY(-1px)` on an infinite loop — the banner physically
 *     juddered up and down, which is half of the "jittery" report;
 *   · `er-fullscreen-flash` — a fixed inset:0 element repainting the ENTIRE
 *     viewport every frame, on top of (and therefore compounding) the jobs
 *     list's own animations;
 *   · `filter:` on <main> — a filter on that subtree forces a full-page repaint
 *     and makes <main> a containing block, so it also janked everything under it.
 *
 * The day-3+ state is still unmissable — it is the darkest red, the widest rule
 * and the only one that tints the page — it just no longer flashes.
 * All motion gated by prefers-reduced-motion: reduce.
 * ──────────────────────────────────────────────────────────────────── */

#email-reminders-root {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 9000; /* above the topbar (56px @ z 100-200) but below modals */
  pointer-events: none;
}
#email-reminders-root .er-banner {
  pointer-events: auto;
  display: grid;
  grid-template-columns: 40px 1fr auto;
  gap: 14px;
  align-items: center;
  padding: 10px 18px;
  /* A-806 — was linear-gradient(180deg, rgba(220,38,38,.95), rgba(250,204,21,.95))
     with color:#fff. The lower half of that gradient is plate yellow, and
     CLAUDE.md is explicit: #fff on #facc15 is 1.7:1 and the label is simply
     GONE. The subtitle and the action buttons sat exactly there. This is a
     SEMANTIC DANGER surface, not a brand surface, so it is the brand's own
     danger red — flat, so every pixel of text keeps the same ~6.5:1 it had at
     the top of the old gradient. */
  background: #dc2626;
  color: #fff;
  /* Never lead with system-ui (CLAUDE.md §type-is-a-metric): where Inter/Archivo
     is not installed it resolves ~19% wider than sans-serif and re-flows. */
  font-family: 'Archivo', sans-serif;
  font-size: 13px;
  border-bottom: 1px solid rgba(0,0,0,.18);
  box-shadow: 0 2px 10px -4px rgba(0,0,0,.35);
}

.er-icon {
  width: 36px;
  height: 36px;
  border-radius: 10px;
  background: rgba(255,255,255,.18);
  border: 1px solid rgba(255,255,255,.35);
  display: flex;
  align-items: center;
  justify-content: center;
  color: #fff;
  flex-shrink: 0;
}
.er-icon svg { width: 18px; height: 18px; }

.er-body { min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.er-h {
  display: flex;
  align-items: center;
  gap: 7px;
  font-family: 'Archivo Narrow', sans-serif;
  font-size: 10px;
  font-weight: 800;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: rgba(255,255,255,.92);
}
.er-sep { opacity: .5; }
.er-age { color: #fff; }
.er-priority { padding: 2px 6px; border-radius: 4px; background: rgba(255,255,255,.18); }
.er-priority-critical { background: #fff; color: #991B1B; }
.er-ai-tag {
  background: rgba(124,58,237,.45);
  border: 1px solid rgba(124,58,237,.6);
  color: #fff;
  padding: 2px 6px;
  border-radius: 4px;
}

.er-title {
  font-size: 14px;
  font-weight: 800;
  color: #fff;
  letter-spacing: -.005em;
  line-height: 1.25;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  max-width: 100%;
}
.er-text {
  font-size: 12px;
  color: rgba(255,255,255,.88);
  line-height: 1.35;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  max-width: 100%;
}

.er-actions {
  display: flex;
  align-items: center;
  gap: 6px;
  flex-shrink: 0;
}
.er-more,
.er-action {
  padding: 7px 11px;
  border-radius: 7px;
  font-family: 'Archivo Narrow', sans-serif;
  font-size: 11px;
  font-weight: 800;
  letter-spacing: .06em;
  text-transform: uppercase;
  cursor: pointer;
  border: 1px solid rgba(255,255,255,.35);
  background: rgba(255,255,255,.12);
  color: #fff;
  transition: background 150ms ease, transform 150ms ease;
}
.er-more:hover,
.er-action:hover { background: rgba(255,255,255,.22); transform: translateY(-1px); }
.er-action.er-resolve {
  background: #fff;
  color: #991B1B;
  border-color: #fff;
}
.er-action.er-resolve:hover { background: #FECACA; }

/* KNOWN, PRE-EXISTING, DELIBERATELY NOT FIXED HERE (A-806).
   The comment on this rule used to read "push the app down" — but the rule
   is `margin-top: 0`, which pushes nothing. It is dead. #email-reminders-root
   is position:fixed at z-index 9000, so while a reminder is up the banner
   covers the topbar and the module bar outright (measured at 1440x900: the
   whole JOB CRM / FACTORY CRM / ACCOUNTS row sits behind it).

   It is left alone on purpose. The chrome under it is a FIXED stack whose
   offsets come from MODULE_BAR_HEIGHT / TOPBAR_HEIGHT — JS globals re-derived
   per viewport tier by _spSyncChrome() and read by a dozen modules. Reserving
   space for the banner means threading its height through those globals, i.e.
   editing the A-668 responsive chain, which CLAUDE.md flags as load-bearing
   and silently breakable (every SpartanVP read is typeof-guarded, so a mistake
   there fails on phones and foldables while looking perfect on a desktop).
   Padding <body> alone is NOT a partial fix: it moves <main> but not the fixed
   bars, which opens a gap AND leaves them covered — strictly worse than this.

   Being dead, this rule causes no layout shift today, so it is not part of the
   "bumps up and down" report and nothing here depends on changing it. A real
   fix belongs in the shell-metrics layer with the A-668 gates run against it. */

/* ── Pulse keyframes — escalating ─────────────────────────────────── */
/* ONE shared ring, slow enough to read as breathing rather than blinking. No
   transform: the banner must never move. No colour flash: the alpha floor stays
   well above zero so it never reads as a strobe. */
@keyframes er-breathe {
  0%, 100% { box-shadow: 0 2px 10px -4px rgba(0,0,0,.35), 0 0 0 0   rgba(220,38,38,.30); }
  50%      { box-shadow: 0 2px 10px -4px rgba(0,0,0,.35), 0 0 0 7px rgba(220,38,38,0); }
}

/* A-806 — motion only during the boot window (see _spBootPulseWindow in
   modules/99-init.ts). No class, no motion: the safe direction is the quiet one. */
body.sp-boot-pulse .er-banner.er-pulse-normal,
body.sp-boot-pulse .er-banner.er-pulse-super,
body.sp-boot-pulse .er-banner.er-pulse-fullscreen,
body.sp-boot-pulse .er-banner.er-pulse-extreme { animation: er-breathe 2.5s ease-in-out infinite; }

/* Escalation = static weight. Deeper red, thicker rule, heavier left flag. */
.er-banner.er-pulse-super      { background: #c81e1e; box-shadow: inset 0 -2px 0 rgba(0,0,0,.22); }
.er-banner.er-pulse-fullscreen { background: #b01818; box-shadow: inset 0 -3px 0 rgba(0,0,0,.26); }
.er-banner.er-pulse-extreme    { background: #991B1B; box-shadow: inset 0 -3px 0 rgba(0,0,0,.3), inset 5px 0 0 #fff; }

/* ═══════════════════════════════════════════════════════════════════
   A-806 — AFTER THE BOOT BURST, THE BAR LOSES ITS COLOUR.

   Graham: "The notification bar needs to pulse for the first 5 seconds,
   then come to a stop and colour disappear just showing the notifications
   at the top."

   So the red surface above is the ALARM state and it lasts 5 seconds. Once
   _spBootPulseWindow (modules/99-init.ts) drops body.sp-boot-pulse, the bar
   settles into the quiet strip below: white, ink text, one hairline rule. The
   words, the counts and every action stay exactly where they were — you lose
   the colour, not the notification.

   Written as `body:not(.sp-boot-pulse)`, deliberately, so the QUIET state is
   what you get when the class is absent for any reason — a loader that skips
   99-init, an exception during boot. Same polarity as everywhere else in this
   change: a failure lands on calm, never on a permanent red alarm bar.

   Specificity note: `body:not(.sp-boot-pulse) .er-banner` is (0,2,1), which
   beats the escalation rules `.er-banner.er-pulse-super` etc. at (0,2,0), so
   the tier backgrounds are neutralised here without needing !important.
   ═══════════════════════════════════════════════════════════════════ */
body:not(.sp-boot-pulse) #email-reminders-root .er-banner,
body:not(.sp-boot-pulse) .er-banner.er-pulse-normal,
body:not(.sp-boot-pulse) .er-banner.er-pulse-super,
body:not(.sp-boot-pulse) .er-banner.er-pulse-fullscreen,
body:not(.sp-boot-pulse) .er-banner.er-pulse-extreme {
  background: #fff;
  color: var(--ink, #0A0A0A);
  border-bottom: 1px solid var(--s200, #E7E5E4);
  box-shadow: 0 1px 3px rgba(10, 10, 10, .06);
  animation: none;
}
/* Severity survives as a single hairline down the left edge — a pointer, not a
   colour wash. Danger red stays the brand's own semantic red (CLAUDE.md). */
body:not(.sp-boot-pulse) .er-banner            { box-shadow: inset 3px 0 0 var(--s300, #D6D3D1), 0 1px 3px rgba(10,10,10,.06); }
body:not(.sp-boot-pulse) .er-banner.er-pulse-super      { box-shadow: inset 3px 0 0 #f59e0b, 0 1px 3px rgba(10,10,10,.06); }
body:not(.sp-boot-pulse) .er-banner.er-pulse-fullscreen,
body:not(.sp-boot-pulse) .er-banner.er-pulse-extreme    { box-shadow: inset 3px 0 0 #dc2626, 0 1px 3px rgba(10,10,10,.06); }

body:not(.sp-boot-pulse) .er-icon {
  background: var(--s100, #F5F5F4);
  border-color: var(--s200, #E7E5E4);
  color: var(--s500, #78716C);
}
body:not(.sp-boot-pulse) .er-h      { color: var(--s500, #78716C); }
body:not(.sp-boot-pulse) .er-age    { color: var(--s600, #57534E); }
body:not(.sp-boot-pulse) .er-title  { color: var(--ink, #0A0A0A); }
body:not(.sp-boot-pulse) .er-text   { color: var(--s500, #78716C); }
body:not(.sp-boot-pulse) .er-priority {
  background: var(--s100, #F5F5F4);
  color: var(--s600, #57534E);
}
body:not(.sp-boot-pulse) .er-priority-critical {
  background: #fef2f2;
  color: #b91c1c;
}
body:not(.sp-boot-pulse) .er-ai-tag {
  background: #f5f3ff;
  border-color: #ddd6fe;
  color: #6d28d9;
}
body:not(.sp-boot-pulse) .er-more,
body:not(.sp-boot-pulse) .er-action {
  background: #fff;
  border-color: var(--s200, #E7E5E4);
  color: var(--s600, #57534E);
}
body:not(.sp-boot-pulse) .er-more:hover,
body:not(.sp-boot-pulse) .er-action:hover {
  background: var(--s50, #FAFAF9);
  border-color: var(--s300, #D6D3D1);
}
/* Mark resolved stays the primary action: ForgeOS PLATE, which per CLAUDE.md
   carries BLACK, never white. */
body:not(.sp-boot-pulse) .er-action.er-resolve {
  background: var(--fos-plate, #facc15);
  border-color: var(--fos-plate, #facc15);
  color: var(--fos-on-plate, #000);
}
body:not(.sp-boot-pulse) .er-action.er-resolve:hover { background: #eab308; }

/* ── Full-screen overlay (day 3+) ─────────────────────────────────── */
.er-fullscreen-overlay {
  position: fixed;
  inset: 0;
  z-index: 8900; /* below banner, above app */
  /* A-806 — was `animation: er-fullscreen-flash 1.0s infinite` on a fixed
     inset:0 box: a full-viewport repaint every frame, sitting over the jobs
     list and compounding its own animations. Now a STATIC wash — it still says
     "something is demanding your attention" without strobing the whole app. */
  background: rgba(220,38,38,.10);
  /* CRITICAL — visual attention ONLY, never a click-trap.
     This is a fixed inset:0 element. With pointer-events:auto it sat on top
     of the entire app at z-index 8900 and swallowed EVERY click: a day-3+
     reminder made the whole CRM unclickable (you could only reach the one job
     the overdue-payment reminder linked to, via the banner's "Open" button —
     which reads as "can't click any jobs except the production-hold one").
     The red tint + pulse still grab attention; the banner above (z-index 9000,
     pointer-events:auto) carries every action — Open / Snooze / Mark resolved.
     Clear the reminder there to remove the overlay. */
  pointer-events: none;
}

/* A-806 — the day-3+ page wash is part of the ALARM, so it leaves with it. After
   the 5s boot window the bar is a plain strip and the app behind it is its normal
   colour again ("colour disappear just showing the notifications at the top").
   Deliberately placed AFTER the base rule above, not before: the base rule is what
   the A-806 click-through guard (tests/email-reminders-overlay-clickthrough.test.js)
   reads to prove the overlay is still a full-screen, pointer-events:none visual,
   and it must stay the first .er-fullscreen-overlay rule in this file. */
body:not(.sp-boot-pulse) .er-fullscreen-overlay { display: none; }

/* When fullscreen-active body class is set, also tint the entire app
   subtly so the user knows something is demanding their attention. */
/* A-806 — `filter:` on <main> was doing two harmful things: it forced a
   full-page repaint of the largest subtree in the app, and it made <main> a
   containing block, which re-parents any position:fixed descendant. The static
   overlay wash above already carries the "attention" signal. */

@media (prefers-reduced-motion: reduce) {
  .er-banner,
  .er-banner.er-pulse-normal,
  .er-banner.er-pulse-super,
  .er-banner.er-pulse-fullscreen,
  .er-banner.er-pulse-extreme,
  .er-fullscreen-overlay {
    animation: none !important;
  }
  /* A-806 — escalation is static now, so reduced-motion needs no substitute
     glow; the deeper red + inset rule set above already survive. Only the
     breathing ring is suppressed, which is exactly what the user asked for. */
}

/* Narrower screens — stack actions + truncate title */
@media (max-width: 900px) {
  #email-reminders-root .er-banner {
    grid-template-columns: 36px 1fr;
    gap: 10px;
    padding: 10px 14px;
  }
  #email-reminders-root .er-actions {
    grid-column: 1 / -1;
    justify-content: flex-end;
    flex-wrap: wrap;
  }
  .er-title,
  .er-text { max-width: 100%; }
}
