/* ══════════════════════════════════════════════════════════════════════════
   crm-marketing.css — THE FIT, AND NOTHING ELSE.

   The design is upstream's and arrives in the two ported sheets:
     crm-marketing-vendor.css   the containers, the cards, the popup
     crm-marketing-home.css     the home screen itself

   This file is MRG's, it loads last, and it holds only the handful of rules
   that exist because the screen is inside a CRM rather than inside a hub. If a
   rule here could equally well live upstream, it belongs upstream — a fix in
   this file is a fix VisionOne never gets and MRG keeps forever
   ([[feedback_ported_file_features_go_upstream]]).

   Every selector is scoped to the marketing view or to a class only the
   marketing tab renders. Nothing here may reach another CRM tab.
   ══════════════════════════════════════════════════════════════════════════ */

/* ── 1 · "NOT CONNECTED" IS NOT "WE COULD NOT READ IT" ─────────────────────
   Tyler, 2026-08-07: *"They're not going to have social media. Just add social
   media for now, but it's not linked."*

   Upstream has one banner for an unreachable source and it is amber, because an
   outage is something to go and fix. Social publishing here is not broken — it
   was never wired, and there is no /api/social on this host by design. Dressing
   that in warning amber would send somebody hunting for a fault that does not
   exist, so the same component goes quiet and grey: still an explanation, no
   longer an alarm. The tiles behind it keep upstream's em dash either way,
   which is the part that actually matters — a zero would claim they posted
   nothing rather than admit we do not know.
   The markup is emitted by crm-marketing-home.js's healthBanner(), as an
   asserted substitution in tools/port-marketing-home.cjs. */
#crmViewMarketing .mh-src-down--off {
  background: var(--surf-2, #f8fafc);
  border-color: var(--border, #e2e8f0);
  border-left-color: var(--ink4, #94a3b8);
  color: var(--ink2, #475569);
}
#crmViewMarketing .mh-src-down--off svg { color: var(--ink4, #94a3b8); }
@media (prefers-color-scheme: dark) {
  #crmViewMarketing .mh-src-down--off {
    background: #171f2b; border-color: #2b384a; border-left-color: #64748b; color: #cbd5e1;
  }
}

/* ── 1b · THE BLOCK THAT REPLACED THAT STRIP, AND THE GREY RAIL ────────────
   Tyler, 2026-08-10: *"You need to put a big tab on here or go gray when they
   click it that it's not connected to anything… All this is just not set up
   yet."*

   The strip above is the right component for "a feed we normally read did not
   answer". It is the WRONG component for "this whole section has never been
   attached to anything" — on a screen where every tile already reads em dash,
   one quiet line of grey text under a heading is indistinguishable from the
   emptiness it is trying to explain. So the state gets the weight of a card and
   sits above the content instead of beside it.

   ⚠️ STILL GREY, STILL NOT AMBER. Bigger is not the same as louder: the whole
   point is that nobody should go looking for a fault. The size says "read
   this", the colour says "not an alarm".
   ⚠️ NO `position` OR `overflow` HERE. This block is inserted as the first
   child of a `.ph-sub` that may hold a sticky sub-header, and either property
   would break it ([[reference_overflow_breaks_sticky]]). */
#crmViewMarketing .crm-unwired {
  display: flex;
  gap: 14px;
  align-items: flex-start;
  margin: 0 0 16px;
  padding: 16px 18px;
  border: 1px solid var(--border, #e2e8f0);
  border-left: 3px solid var(--ink4, #94a3b8);
  border-radius: 10px;
  background: var(--surf-2, #f8fafc);
  color: var(--ink2, #475569);
}
#crmViewMarketing .crm-unwired-icon {
  flex: 0 0 auto;
  width: 34px; height: 34px;
  display: flex; align-items: center; justify-content: center;
  border-radius: 8px;
  background: var(--surf-3, #eef2f7);
  color: var(--ink4, #94a3b8);
}
#crmViewMarketing .crm-unwired-icon svg { width: 19px; height: 19px; }
#crmViewMarketing .crm-unwired-body { min-width: 0; }
#crmViewMarketing .crm-unwired-title {
  display: flex; align-items: center; gap: 9px; flex-wrap: wrap;
  font-size: 14px; font-weight: 700;
  color: var(--ink, #0f172a);
  margin-bottom: 5px;
}
#crmViewMarketing .crm-unwired-chip {
  font-size: 10px; font-weight: 700; letter-spacing: .04em; text-transform: uppercase;
  padding: 2px 8px; border-radius: 9px;
  background: var(--surf-3, #e8edf3);
  color: var(--ink3, #64748b);
  border: 1px solid var(--border, #e2e8f0);
}
#crmViewMarketing .crm-unwired-text {
  margin: 0; font-size: 12.5px; line-height: 1.55;
}
#crmViewMarketing .crm-unwired-foot {
  margin: 7px 0 0; font-size: 11.5px; line-height: 1.5;
  color: var(--ink3, #64748b);
}
#crmViewMarketing .crm-unwired-foot b { color: var(--ink2, #475569); }

/* The rail item and the surface options say it before the click. Deliberately
   NOT `pointer-events:none` — the screens stay openable so you can see what the
   section will look like once a network is attached. */
#crmMktSidebar .ph-sb-item.crm-unwired-rail { opacity: .62; }
#crmMktSidebar .ph-sb-item.crm-unwired-rail.is-active { opacity: 1; }
#crmMktSidebar .ph-sb-item.crm-unwired-rail::after {
  content: '';
  width: 6px; height: 6px; margin-left: auto; flex: 0 0 auto;
  border-radius: 50%;
  background: var(--ink4, #94a3b8);
}
#crmMktContent .crm-mkt-bar.crm-unwired-bar .crm-unwired-opt { opacity: .68; }
#crmMktContent .crm-mkt-bar.crm-unwired-bar .crm-unwired-opt.is-active { opacity: 1; }

@media (prefers-color-scheme: dark) {
  #crmViewMarketing .crm-unwired {
    background: #171f2b; border-color: #2b384a; border-left-color: #64748b; color: #cbd5e1;
  }
  #crmViewMarketing .crm-unwired-icon { background: #1f2a38; color: #94a3b8; }
  #crmViewMarketing .crm-unwired-title { color: #e8eef6; }
  #crmViewMarketing .crm-unwired-chip { background: #1f2a38; color: #94a3b8; border-color: #2b384a; }
  #crmViewMarketing .crm-unwired-foot { color: #94a3b8; }
  #crmViewMarketing .crm-unwired-foot b { color: #cbd5e1; }
}

/* Phones: the icon column is the first thing to go — the words are the point. */
@media (max-width: 640px) {
  #crmViewMarketing .crm-unwired { padding: 13px 14px; gap: 11px; }
  #crmViewMarketing .crm-unwired-icon { display: none; }
}

/* ── 2 · THE TWO CREATE BUTTONS, AT THE TOP OF THE RAIL ────────────────────
   Upstream styles `.ph-sb-add` in marketing-hub-tasks.css, as
   `.ph-sidebar .ph-sb-add` — a selector the porter refuses on sight, because
   anything naming `.ph-sidebar` would reach the six OTHER rails in this file
   and repaint the whole CRM to win one button. So the rules are restated here
   against this rail only. Same intent, no blast radius.

   🚨 2026-08-11 — THEY MOVED TO THE TOP AND THEY WEAR THE CRM'S OWN BUTTON.
   Tyler: *"inside the MRG CRM, the new campaign buttons will be at the top.
   Use the same exact design as the CRM uses."*

   The design being matched is `.ph-sb-item.ph-qa-btn` in `crm.css` — the CRM's
   quick action: a bordered pill that fills with the theme blue on hover.
   ⚠️ RESTATED, NOT REUSED BY ADDING THE CLASS. These buttons are HARVESTED out
   of upstream's Home rail by tools/port-marketing-hub.cjs and re-emitted
   verbatim, precisely so a rename over there lands here for free — bolting a
   second class onto that markup would mean hand-writing it, which is how a
   ported feature drifts into being a different one
   ([[feedback_ported_file_features_go_upstream]]). So the CRM's own tokens are
   applied to the class upstream already ships, and this note is the thing that
   says the two are meant to look identical.

   ⚠️ AND THEY MUST NOT LOOK LIKE THE SIX SECTIONS BELOW THEM. A rail item is
   navigation; a create is an action. At the foot that distinction cost nothing.
   At the top, a button that reads as the first nav item is a button people
   press expecting a screen. The border and the tint are the whole difference. */
#crmMktSidebar .ph-sb-add {
  background: transparent;
  color: var(--c-blue, #2563eb);
  border: 1px solid var(--border, #e2e8f0);
  border-radius: 7px;
  font-weight: 700;
  font-size: 11.5px;
  padding: 7px 9px;
  cursor: pointer;
  transition: background .15s, color .15s, border-color .15s;
}
#crmMktSidebar .ph-sb-add:hover {
  background: var(--c-blue-bg, #e6f3ff);
  color: var(--c-blue, #2563eb);
  border-color: var(--c-blue, #2563eb);
}
/* ⚠️ THE RAIL PUTS A TOP MARGIN ON EVERY `.ph-sb-item + .ph-sb-item`, so two
   creates in a row would sit further apart than the pair sits from the divider
   under them. Tightened so they read as one block. */
#crmMktSidebar .ph-sb-add + .ph-sb-add { margin-top: 5px !important; }
#crmMktSidebar .ph-sb-add .ph-sb-icon {
  font-size: 15px;
  font-weight: 800;
  line-height: 1;
  color: inherit;
}
/* The divider separates CREATE from NAVIGATE now rather than hanging off the
   end of the list, so it has to breathe on both sides. */
#crmMktSidebar .ph-sb-divider { margin: 10px 6px 2px; }

/* ── 3 · THE RECIPIENT FACE IN THE SEND RECEIPT ────────────────────────────
   crm-marketing-send.js's faceHtml() hands the platform receipt popup a real
   CRM photo instead of letting it draw initials. The popup is loaded from
   apps.mrgcentral.net and brings its own stylesheet, but this span is OURS —
   it is in the HTML our adapter returns, so nothing over there styles it.
   Unstyled it renders as a raw full-size image mid-sentence. */
.mh-rcpt-face {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  overflow: hidden;
  flex-shrink: 0;
  background: var(--surf-2, #f1f5f9);
  vertical-align: middle;
}
.mh-rcpt-face img { width: 100%; height: 100%; object-fit: cover; display: block; }

/* ── 4 · THE PIECE POPUP HAS TO WIN ────────────────────────────────────────
   .wk-rr-overlay arrives from marketing-hub-review.css at z-index 1000000,
   which is above everything the CRM stacks ([[reference_work_zindex_tiers]]) —
   restated as a floor rather than trusted, because it is the difference
   between a popup and a popup somebody opened behind the top nav. The
   `display:none` guard is the other half of the trap: `hidden` ALONE DOES NOT
   HIDE THIS element, since an author `display:flex` outranks the UA
   stylesheet's `[hidden]{display:none}`, and what is left behind is an
   invisible full-viewport layer that eats every click on the page
   ([[reference_hidden_attr_loses_to_author_display]]). Both callers set the
   inline style too; this is the backstop for the one that forgets. */
.wk-rr-overlay { z-index: 1000000; }
.wk-rr-overlay[hidden] { display: none !important; }

/* ── 5 · THE VIEW ITSELF ───────────────────────────────────────────────────
   .ch-view is `display:flex; flex-direction:column` in crm.css, and crm.js's
   switchView() then sets `style.display='flex'` INLINE — so a stylesheet rule
   trying to make this a block would lose to the attribute and is not worth
   writing. It does not need to: `.ph-hub` is a grid, and a grid inside a
   column-flex parent still stretches to full width on the cross axis. Measured
   in a browser rather than reasoned about — ~/_pwverify/mrg-crm-marketing.cjs
   asserts the rail and the focus panel are side by side, which is the thing
   that would break if this were ever wrong.

   The min-height is real: the hub's own panel sits in a page that always has
   content below it, and here it is the last thing in .ch-shell. Without a floor
   an empty marketing tab is a nav bar over 200px of nothing. */
#crmViewMarketing .ph-hub { min-height: 60vh; }

/* ── 6 · 🚨 "NOTHING HERE", IN THE MIDDLE, WHERE IT BELONGS ────────────────
   Tyler, 2026-08-07, looking at a card view: *"it says there's nothing here
   that should show in the middle still."*

   TWO separate faults produced that, and only the second one is upstream's:

   1 · THIS BUILD DOES NOT LOAD marketing-hub-home.css. That sheet is the only
       place `.mh-home-empty` is styled — and it is NOT a Home-only class:
       marketing-hub-performance.js writes it into #mhPerfGrid as its own empty
       state. Home is deliberately absent here (tools/port-marketing-hub.cjs,
       *"not home"*), so the block arrived with no padding, no centring and no
       colours at all — bare text hanging in the corner of a card grid.
       ⚠️ That is a HOST fault, not a design one: the rules below are upstream's
       three, verbatim, re-homed because of which sheets this build links. They
       are not an improvement and must not become one
       ([[feedback_ported_file_features_go_upstream]]). If upstream ever moves
       them into marketing-hub.css — where they belong, since Performance uses
       them — delete this block and let the port carry them.

   2 · IT IS A GRID ITEM. `#mhPerfGrid` is `.rp-card-list`, which vendored
       work.css declares `display:grid; grid-template-columns:repeat(3,1fr)`,
       and the empty block is written into it as an ordinary child — so
       `text-align:center` centres it inside the LEFT THIRD of the panel.
       Nothing about it is data-dependent, which is why it reads as a rendering
       bug: it is one. It has to span every column.
       ⚠️ Fixed UPSTREAM too, in marketing-hub-home.css — marketing.runmai.app
       has the identical bug on its own Home board.
   ────────────────────────────────────────────────────────────────────────── */
#crmViewMarketing .mh-home-empty { padding: 34px 20px; text-align: center; }
#crmViewMarketing .mh-home-empty-title { font-size: 13px; font-weight: 700; color: var(--ink2, #475569); }
#crmViewMarketing .mh-home-empty-sub { font-size: 11px; color: var(--ink4, #94a3b8); margin-top: 4px;
  max-width: 52ch; margin-left: auto; margin-right: auto; line-height: 1.5; }

/* The span. Scoped to the grid containers, because the same block is reused by
   the LIST views, which are not grids — `grid-column` is inert there, but the
   min-height would not be. */
#crmViewMarketing .rp-card-list > .mh-home-empty,
#crmViewMarketing .mh-home-grid > .mh-home-empty {
  grid-column: 1 / -1;
  display: flex; flex-direction: column;
  align-items: center; justify-content: center;
  min-height: 200px;
}

/* ── 7 · A TILE WHOSE VALUE IS A NAME, NOT A NUMBER ────────────────────────
   Performance's "Best Performer" / "Top Channel" tiles print a campaign name in
   the slot the `.ax-card` face typesets for digits — 28px, bold — so "August
   tooling capacity" rendered at headline size and ran out of its own tile.

   ⚠️ UPSTREAM ALREADY FIXES THIS and the port is RIGHT to drop the rule:
   `.ax-card-val.mhp-val-word` names `ax-card-val`, which crm.css genuinely owns
   and styles for every other tab in this CRM, so the blocklist cannot let it
   through ([[reference_vendoring_a_whole_hub_into_one_rail]]). Restated here,
   verbatim, scoped to this view — the same re-homing as §6. Not an improvement,
   and it must not become one: if crm.css ever stops owning `.ax-card-val`,
   delete this and let the port carry it.
   ────────────────────────────────────────────────────────────────────────── */
#crmViewMarketing .ax-card-val.mhp-val-word {
  font-size: 14px; line-height: 1.25; letter-spacing: -.01em;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

/* ── 8 · 🚨 THE SURFACE BAR — WHERE THE 35 RAIL ITEMS WENT ─────────────────
   Tyler, 2026-08-10: *"I don't want to have to scroll on the left side, so you
   can't have all these different options again. Each one gets its own option."*

   The rail is five sections now (tools/port-marketing-hub.cjs), and every
   surface those 35 items used to open is an option in this bar. It is MRG's
   arrangement, so it is MRG's CSS — upstream still has five real rails and
   needs none of this.

   ⚠️ ONE bar is visible at a time and the default is `display:none`, NOT the
   `hidden` attribute: `.crm-mkt-bar` is a flex row, and an author `display`
   rule outranks the UA stylesheet's `[hidden]{display:none}`
   ([[reference_hidden_attr_loses_to_author_display]]). A hidden-attribute
   version of this shipped five stacked bars.
   ────────────────────────────────────────────────────────────────────────── */
#crmMktContent > .crm-mkt-bar { display: none; }
#crmMktContent > .crm-mkt-bar.is-on {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 14px;
  margin: 0 0 2px;
  background: var(--surf, #fff);
  border: 1px solid var(--border, #eef0f3);
  border-radius: var(--radius-sm, 10px);
  box-shadow: var(--shadow-sm);
  /* Sticky like the rail beside it. `.ph-content` sets no overflow, which is the
     only reason this works at all ([[reference_overflow_breaks_sticky]]). */
  position: sticky; top: 60px; z-index: 3;
}
.crm-mkt-eyebrow {
  font-size: 9px; font-weight: 800; letter-spacing: .08em; text-transform: uppercase;
  color: var(--ink3, #8d8d8d); white-space: nowrap;
}
.crm-mkt-eyebrow::after {
  content: ''; display: inline-block; width: 1px; height: 12px;
  background: var(--border, #eef0f3); margin-left: 10px; vertical-align: -2px;
}
.crm-mkt-bar-spacer { flex: 1; }

/* ── the picker ── */
.crm-mkt-drop { position: relative; }
.crm-mkt-drop-btn {
  display: inline-flex; align-items: center; gap: 7px;
  padding: 6px 10px 6px 11px;
  font: inherit; font-size: 12.5px; font-weight: 700; color: var(--ink, #161616);
  background: var(--bg2, #f8fafc);
  border: 1px solid var(--border, #eef0f3);
  border-radius: 9px; cursor: pointer;
  transition: background var(--wt-transition), border-color var(--wt-transition);
}
.crm-mkt-drop-btn:hover { background: var(--surf, #fff); border-color: var(--c-blue-soft, #cbd5f5); }
.crm-mkt-drop-btn svg { flex-shrink: 0; opacity: .55; transition: transform var(--wt-transition); }
.crm-mkt-drop.is-open .crm-mkt-drop-btn { background: var(--surf, #fff); border-color: var(--c-blue, #004b7c); }
.crm-mkt-drop.is-open .crm-mkt-drop-btn svg { transform: rotate(180deg); }
.crm-mkt-drop-val { white-space: nowrap; }

.crm-mkt-menu {
  display: none;
  position: absolute; top: calc(100% + 6px); left: 0; min-width: 232px;
  max-height: min(70vh, 460px); overflow-y: auto;
  padding: 6px;
  background: var(--surf, #fff);
  border: 1px solid var(--border, #eef0f3);
  border-radius: 12px; box-shadow: var(--shadow-lg);
  z-index: 40;
}
.crm-mkt-drop.is-open .crm-mkt-menu { display: block; }
.crm-mkt-opt {
  display: flex; align-items: center; gap: 9px; width: 100%;
  padding: 7px 9px; margin: 0;
  font: inherit; font-size: 12px; font-weight: 600; color: var(--ink2, #525252);
  text-align: left; background: none; border: 0; border-radius: 8px; cursor: pointer;
}
.crm-mkt-opt:hover { background: var(--bg2, #f8fafc); color: var(--ink, #161616); }
.crm-mkt-opt.is-active { background: var(--c-blue-bg, #e6f3ff); color: var(--c-blue, #004b7c); font-weight: 700; }
.crm-mkt-opt-ico { display: inline-flex; width: 15px; height: 15px; flex-shrink: 0; }
.crm-mkt-opt-ico svg {
  width: 15px; height: 15px; fill: none; stroke: currentColor; stroke-width: 2;
  stroke-linecap: round; stroke-linejoin: round;
}

/* ── the section's own action, moved off the rail ── */
.crm-mkt-act {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 6px 12px;
  font: inherit; font-size: 12px; font-weight: 700; color: #fff;
  background: var(--c-blue, #004b7c);
  border: 1px solid var(--c-blue, #004b7c);
  border-radius: 9px; cursor: pointer; white-space: nowrap;
}
.crm-mkt-act:hover { filter: brightness(1.12); }
.crm-mkt-act-plus { font-size: 15px; font-weight: 700; line-height: 1; }

/* The phone gets the bar as two rows rather than a squeezed one
   ([[reference_app_mobile_shared_phone_layer]]). */
@media (max-width: 760px) {
  #crmMktContent > .crm-mkt-bar.is-on { flex-wrap: wrap; position: static; }
  .crm-mkt-bar-spacer { flex-basis: 100%; height: 0; }
  .crm-mkt-drop-btn, .crm-mkt-act { flex: 1; justify-content: center; }
}

/* ══════════════════════════════════════════════════════════════════════════
   PERFORMANCE OWNS ITS OWN FILTER BAR NOW, SO THE SEAM'S IS HIDDEN.
   ══════════════════════════════════════════════════════════════════════════
   Tyler, 2026-08-11: *"I don't like that there's a filter for Performance and
   then a filter for Period. It should just have an overall better filter
   design."*

   He was looking at two stacked strips: this seam bar (`PERFORMANCE ▸
   Overview`) and, directly beneath it, the panel's own PERIOD row. Both narrow
   the same report. The surface picker now leads the panel's single
   `.mhp-filterbar`, so this bar has nothing left to say.

   ⚠️ HIDDEN, NOT DELETED, AND THAT IS DELIBERATE. The options in here still
   carry `data-mhp-surface`, and marketing-hub-performance.js still lights them
   in render() and still switches on them through one delegated handler — so
   the two pickers cannot disagree, and anything that programmatically clicks a
   seam option (or a future re-port of the porter's bar) keeps working. Only the
   duplicate row of controls is gone.

   ⚠️ THE SEAM STILL NEEDS THIS BAR IN THE DOM. crm-marketing.js's
   MutationObserver re-lights the rail item and the active option off
   `.crm-mkt-bar` state; removing the element would break the "bar follows the
   active panel" contract for every OTHER section too, because that observer is
   shared.

   ⚠️ ONLY THE PERFORMANCE BAR. Every other section still needs its dropdown —
   this is the one section whose surfaces became a filter rather than a nav.
   ══════════════════════════════════════════════════════════════════════════ */
#crmMktContent > .crm-mkt-bar[data-mkt-bar="performance"] { display: none !important; }

/* == AND TEMPLATES, FOR A DIFFERENT REASON, BY THE SAME MECHANISM ============
   2026-08-20: the Templates section is ONE surface now (Tyler: *"I want only
   card views ... There's not going to be a list view for this"*), so its bar has
   no picker and no action left in it -- just a 9px grey eyebrow holding 40px of
   sticky height above a panel that already carries its own heading, and a
   divider rule (`.crm-mkt-eyebrow::after`) drawing a separator between the
   eyebrow and nothing.

   THE ELEMENT STAYS IN THE DOM for exactly the reason the Performance one does:
   crm-marketing.js's MutationObserver re-lights the RAIL ITEM off
   `.crm-mkt-bar[data-mkt-bar]` state, and that observer is shared by all six
   sections. Removing the node would take the rail's highlight with it.
   It also carries `data-mkt-subs`, which is how `templates-library` is mapped to
   this section at all now that there are no options to learn it from. */
#crmMktContent > .crm-mkt-bar[data-mkt-bar="templates"] { display: none !important; }

/* ══════════════════════════════════════════════════════════════════════════
   🚨 THE MARKETING HUB'S DESIGN TOKENS, WHICH THE PORTER DROPS ON PURPOSE

   Tyler, 2026-08-11, on a campaign profile: *"it looks absolutely terrible."*
   Measured, not guessed: `.mc-detail-field-val` computed to
   **rgb(255,255,255) on a rgb(244,245,247) page** — white text on a white
   background — and `.mc-detail-field`'s own surface was rgba(255,255,255,.06),
   i.e. invisible. Every value on CAMPAIGN DETAILS was a ghost. That is the
   thing the screenshot was showing.

   ── THE CAUSE IS ONE LINE OF THE PORTER, AND IT IS CORRECT ────────────────
       const GLOBAL = /^(:root|html|body|\*|a|p|…)\b/i;
       if (sels.some((s) => touchesHost(s) || GLOBAL.test(s))) { drop }
   A `:root` rule from the hub would repaint the WHOLE CRM, so the porter throws
   it away. But the hub's entire design-token block lives in that `:root` — so
   `--ink1`, `--glass1..3` and `--border1` arrive UNDEFINED here, and 44
   declarations across the vendored sheets fall through to their second
   argument. Those fallbacks were written for a dark surface
   (`var(--ink1, #fff)`), so on MRG's light CRM they render white on white.

   🚫 DO NOT FIX THIS BY EDITING THE FALLBACKS UPSTREAM. There are 44 of them in
   marketing-hub-campaigns.css alone and the same trap is armed in all sixteen
   other vendored sheets — a fallback is only ever a symptom here. One scoped
   token block is the cause fixed once, and a re-port cannot undo it because
   this file is MRG's own, not vendored output.

   ── WHY ONLY FOURTEEN ─────────────────────────────────────────────────────
   ~/_pwverify/_mrgtok.cjs reads every token the hub's :root defines plus every
   token any vendored sheet consumes (122), resolves each one against the live
   MRG page, and prints the holes. `--ink2`, `--ink3`, `--c-red`, `--c-green`
   and the rest are ALREADY defined by crm.css and are deliberately left alone —
   MRG's values winning is what makes the tab look native, and re-declaring them
   here would repaint a screen that is already right. Re-run that probe after any
   crm.css change rather than adding tokens speculatively.

   ── AND WHY THE OVERLAY SELECTORS ─────────────────────────────────────────
   ⚠️ `#crmViewMarketing` ALONE IS NOT ENOUGH, and this is the half that is easy
   to miss: the campaign builder and the piece builder `document.body.append`
   their overlays, so they are NOT descendants of the marketing view and would
   have kept every ghosted field. That matters here specifically — the popup is
   the other thing Tyler called terrible.
   ══════════════════════════════════════════════════════════════════════════ */
#crmViewMarketing,
.cb-overlay, .mh-modal-overlay, .mh-air-drawer-overlay, .mhpk-overlay,
.bf-ap-overlay, .tp-overlay, .tp-delete-overlay,
.wk-modal-overlay, .wk-designer-overlay, .wk-qa-overlay, .wk-rr-overlay {
  /* Ink. The one that was white on white. */
  --ink1: #161616;

  /* Surfaces. The hub's own LIGHT values — rgba(0,0,0,.04), not the
     rgba(255,255,255,.06) the fallbacks assume. A tinted-black wash reads as a
     faint card on a light page; a tinted-white one is invisible on it. */
  --glass1: rgba(0,0,0,.04);
  --glass2: rgba(0,0,0,.06);
  --glass3: rgba(0,0,0,.08);
  --border1: #e0e0e0;
  --wt-card-bg: #ffffff;
  --bg: #f8f9fa;
  --bg-s: #f3f4f6;
  --shadow: 0 2px 10px rgba(0,0,0,0.05);

  /* Orange is the only accent pair crm.css has no opinion about. */
  --c-orange: #ba4e00;
  --c-orange-bg: #fff2e8;

  /* The hub's own identity colour, used by the campaign chip and the piece
     tiles. Kept because a marketing surface reading as marketing is the point. */
  --mh-accent: #6366f1;
  --mh-gradient: linear-gradient(135deg, #6366f1 0%, #4f46e5 55%, #4338ca 100%);

  --ease: all 0.2s cubic-bezier(0.2,0.8,0.2,1);
}

/* ══════════════════════════════════════════════════════════════════════════
   🚨 EVERY DROPDOWN IN THIS TAB WAS AN UNSTYLED BROWSER BUTTON

   Tyler, 2026-08-11: *"Not to mention, the pop-up looks terrible."* He is right,
   and it was not a taste problem. Measured on the New Campaign builder: the
   Type / Status / Service-line controls were 44×19 and 79×19 px, background
   rgb(240,240,240), border 2px with radius 0 — the USER-AGENT DEFAULT BUTTON,
   sitting beside 656×34 styled inputs.

   wk-form-controls.js was working correctly. It replaces each <select> with a
   `<button class="wk-cs-btn">` and hides the original (display:none, 0×0,
   confirmed). The button simply had NO CSS here at all.

   ── THE CAUSE IS ONE ID-SCOPED RULE IN crm.css, AND IT IS WORTH UNDERSTANDING ─
       crm.css:13259
       #crmFilterOv .wk-cs-btn, #crmSegmentModal .wk-cs-btn { display:none !important }
   That is this CRM's own fix for the doubled-dropdown bug in the filter builder
   and the segment modal. But the porter's blocklist drops any upstream rule whose
   subject appears ANYWHERE in crm.css, on the premise that "the host already
   styles those elements". Naming `.wk-cs-btn` in that one narrow override was
   therefore read as the host owning `.wk-cs-btn` globally, and it deleted all
   FIVE upstream rules that style the button — `.wk-cs-btn`, `:hover`,
   `:focus-visible`, `.is-open`, `:disabled` — while `.wk-cs-btn-label` and
   `-caret` survived because they are different class names. That asymmetry is the
   fingerprint: a label styled correctly inside a naked box.

   🚨 THE BLAST RADIUS WAS THE WHOLE TAB, not this popup. Every enhanced select
   across all 42 marketing surfaces rendered as a UA button.

   📌 THE DURABLE FIX IS IN THE PORTER, AND IT IS NOT MADE HERE: `touchesHost()`
   should not treat an ID-SCOPED host selector as owning the class globally —
   `#crmFilterOv .wk-cs-btn` says nothing about `.wk-cs-btn` anywhere else. That
   edit was deliberately NOT made in this pass because a parallel session has
   tools/port-marketing-hub.cjs open. Until it lands, these rules live here.
   ⚠️ When it does land, the vendored copy will carry these rules again and this
   block becomes redundant — identical values, so harmless, but delete it then.

   Scoped to the marketing view and the hub's overlay roots ONLY, so crm.css's
   `#crmFilterOv` / `#crmSegmentModal` override is untouched and the doubled
   dropdown does not come back where it was fixed.
   ══════════════════════════════════════════════════════════════════════════ */
#crmViewMarketing .wk-cs-btn,
.cb-overlay .wk-cs-btn, .mh-modal-overlay .wk-cs-btn,
.mh-air-drawer-overlay .wk-cs-btn, .mhpk-overlay .wk-cs-btn,
.bf-ap-overlay .wk-cs-btn, .tp-overlay .wk-cs-btn,
.wk-modal-overlay .wk-cs-btn, .wk-designer-overlay .wk-cs-btn,
.wk-qa-overlay .wk-cs-btn, .wk-rr-overlay .wk-cs-btn {
  display: inline-flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  min-height: 36px;
  padding: 0 10px 0 12px;
  border: 1px solid var(--border, #e2e8f0);
  border-radius: 10px;
  background: #fff;
  color: var(--ink, #0f172a);
  font: inherit;
  font-size: 13px;
  font-weight: 500;
  cursor: pointer;
  text-align: left;
  transition: border-color .15s, background .15s, box-shadow .15s;
  width: 100%;
}
#crmViewMarketing .wk-cs-btn:hover:not(:disabled),
.cb-overlay .wk-cs-btn:hover:not(:disabled),
.mh-modal-overlay .wk-cs-btn:hover:not(:disabled),
.mhpk-overlay .wk-cs-btn:hover:not(:disabled),
.bf-ap-overlay .wk-cs-btn:hover:not(:disabled) {
  border-color: #cbd5e1;
  background: #f8fafc;
}
#crmViewMarketing .wk-cs-btn:focus-visible,
.cb-overlay .wk-cs-btn:focus-visible,
.mh-modal-overlay .wk-cs-btn:focus-visible,
.mhpk-overlay .wk-cs-btn:focus-visible,
.bf-ap-overlay .wk-cs-btn:focus-visible,
#crmViewMarketing .wk-cs-btn.is-open,
.cb-overlay .wk-cs-btn.is-open,
.mh-modal-overlay .wk-cs-btn.is-open,
.mhpk-overlay .wk-cs-btn.is-open,
.bf-ap-overlay .wk-cs-btn.is-open {
  outline: none;
  border-color: #6366f1;
  box-shadow: 0 0 0 3px rgba(99, 102, 241, .18);
}
#crmViewMarketing .wk-cs-btn:disabled,
.cb-overlay .wk-cs-btn:disabled,
.mh-modal-overlay .wk-cs-btn:disabled,
.mhpk-overlay .wk-cs-btn:disabled,
.bf-ap-overlay .wk-cs-btn:disabled { opacity: .55; cursor: not-allowed; }

/* ══════════════════════════════════════════════════════════════════════════
   THE NARROWING BAR STANDS IN THE SECTION BAR NOW

   Tyler, 2026-08-21: *"there's nowhere for me to set or change that filter …
   make sure that that shows for all of them when I go to Pieces and Approvals.
   Next to Overview, it also shows that filter … because then it just looks
   like it's a hidden filter."*

   crm-marketing.js moves `#mhPerfScope` — the four pickers, the chips and the
   note — into whichever section's bar is open (`dockScope`). These rules are
   only about how it SITS there; every control inside it is still styled by
   marketing-hub-performance.css, so the two homes cannot drift apart.
   ══════════════════════════════════════════════════════════════════════════ */

/* 🚨 A BAR HOLDING THE PICKERS MAY NOT BE THE HIDDEN ONE. Templates' bar was
   display:none for being an empty 40px eyebrow (see above) — it is not empty
   any more, and it is the section a filter is most likely to look hidden on,
   because nothing on that wall obeys it. Specificity beats the rule above
   rather than editing it: that rule is still right about a bar with nothing in
   it, which is what this one is again the moment the group moves away. */
#crmMktContent > .crm-mkt-bar.is-on.crm-mkt-bar--scope {
  display: flex !important;
  flex-wrap: wrap;
  row-gap: 6px;
}

/* A section bar that has grown a second row is no longer a single-line strip,
   so its own dropdown and eyebrow ride at the top of it rather than floating in
   the middle of the chips. */
#crmMktContent > .crm-mkt-bar.is-on.crm-mkt-bar--scope { align-items: flex-start; }
#crmMktContent > .crm-mkt-bar.is-on.crm-mkt-bar--scope > .crm-mkt-eyebrow,
#crmMktContent > .crm-mkt-bar.is-on.crm-mkt-bar--scope > .crm-mkt-drop { margin-top: 1px; }

/* ══ AND PERFORMANCE'S OWN BAR IS STICKY, for the same reason the section bar
   already is: Tyler set a filter, scrolled the report, and had *"nowhere to set
   or change"* it — the controls were 900px above the rows they were narrowing.
   `top: 60px` is the CRM header, the value `.crm-mkt-bar.is-on` uses.
   ⚠️ z-index ABOVE that bar's 3: on Performance the seam bar is hidden, but the
   panel's tiles and chart are painted after this in document order. ══ */
#crmMktContent .mhp-filterbar {
  position: sticky; top: 60px; z-index: 4;
}

@media (max-width: 760px) {
  /* The section bar drops out of sticky below 760px (see the media query
     above), so this one follows it — a sticky strip on a phone eats a third of
     the screen. */
  #crmMktContent .mhp-filterbar { position: static; }
}
