/* Campaign room — the campaign dashboard.
 *
 * Part of the campaign stylesheet, split by area so a change to one screen
 * is a change to one file. No rule here draws a box: the room is built from
 * whitespace and single hairlines between rows.
 */

/* ---------- dashboard ---------- */

/* The sticky head has to be an opaque, full-bleed band or the list scrolls
   *through* it — which is what made the header and the code rows overlap.
   The negative margin plus matching padding lets the paper reach the screen
   edges while the content inside stays on the sheet's gutter. */
.mcamp__dashhead {
    position: sticky;
    top: 0;
    z-index: 30;
    background: var(--mc-paper);
    margin: 0 calc(-1 * var(--mc-gutter));
    padding: 0 var(--mc-gutter) var(--mc-2);
    box-shadow: 0 1px 0 var(--mc-line);
}

#mobile-campaign-overlay .mcamp__dashhead,
.mcamp.mcamp .mcamp__dashhead {
    background-color: var(--mc-paper) !important;
}

.mcamp__dashbar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--mc-2);
    padding: var(--mc-5) 0 var(--mc-4);
}

/* Edit is the everyday action and leads. Pause is occasional. Ending is
   irreversible, so it is the quietest of the three rather than a third
   equal-weight button inviting a mis-tap. */
.mcamp__dashactions {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: var(--mc-2);
    padding: var(--mc-4) 0;
}

.mcamp__dashactions .mcamp__btn {
    min-height: 44px;
}

/* Five tabs do not fit a phone at the old spacing, and the last one sat
   half-cut with nothing to say it was scrollable. A tighter gap fits them,
   and the row is allowed to run to the screen edge so a partially visible
   tab reads as "more this way" rather than as a clipping bug. */
.mcamp__tabs {
    display: flex;
    gap: 18px;
    overflow-x: auto;
    padding: var(--mc-2) 0 0;
    margin-right: calc(var(--mc-gutter) * -1);
    padding-right: var(--mc-gutter);
    scrollbar-width: none;
    -webkit-overflow-scrolling: touch;
}

.mcamp__tabs::-webkit-scrollbar { display: none; }

.mcamp__tab {
    flex: 0 0 auto;
    /* The tabs are the most-tapped control in the room and sat at 42px. The
       underline still hugs the label — only the reach grew. */
    min-height: 44px;
    border: 0;
    background: transparent;
    color: var(--mc-faint);
    font-family: 'IBM Plex Mono', ui-monospace, monospace;
    font-size: 10px;
    letter-spacing: 1.4px;
    text-transform: uppercase;
    padding: var(--mc-2) 0 var(--mc-3);
    cursor: pointer;
    white-space: nowrap;
    border-bottom: 2px solid transparent;
}

.mcamp__tab.is-on { color: var(--mc-ink); border-bottom-color: var(--mc-ink); }

.mcamp__remaining {
    display: flex;
    flex-direction: column;
    gap: var(--mc-3);
    padding: var(--mc-6) 0;
}

.mcamp__huge {
    font-family: 'Barlow Condensed', sans-serif;
    font-weight: 700;
    font-size: 96px;
    line-height: 0.82;
    letter-spacing: -3px;
}

.mcamp__bar {
    height: 6px;
    border-radius: 100px;
    background: var(--mc-line);
    display: flex;
    overflow: hidden;
}

.mcamp__bar--sm { height: 6px; margin-top: var(--mc-2); }
.mcamp__bar--xs { height: 5px; flex: 1; }
.mcamp__bar-fill { background: var(--mc-ink); }
.mcamp__bar-hatch { background: var(--mc-faint); }

.mcamp__bar-legend {
    display: flex;
    justify-content: space-between;
    font-family: 'IBM Plex Mono', ui-monospace, monospace;
    font-size: 9px;
    letter-spacing: 1px;
    color: var(--mc-mute);
}

.mcamp__split { display: flex; height: 6px; border-radius: 100px; overflow: hidden; background: var(--mc-line); }

.mcamp__metrics {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: var(--mc-5) var(--mc-3);
    padding: var(--mc-4) 0 var(--mc-6);
}

.mcamp__metric-value {
    font-family: 'Barlow Condensed', sans-serif;
    font-weight: 700;
    font-size: 40px;
    line-height: 0.95;
    letter-spacing: -1px;
    margin-top: var(--mc-1);
}

.mcamp__metric-value.is-big { font-size: 48px; }

.mcamp__metric-foot {
    grid-column: span 2;
    font-size: 12px;
    color: var(--mc-mute);
    line-height: 1.6;
    padding-top: var(--mc-1);
}

.mcamp__funnel {
    display: flex;
    flex-direction: column;
    gap: var(--mc-4);
    padding: var(--mc-3) 0 var(--mc-6);
}

.mcamp__funnel-label { font-size: 13px; color: var(--mc-body); }

.mcamp__funnel-value {
    font-family: 'Barlow Condensed', sans-serif;
    font-weight: 700;
    font-size: 20px;
}

.mcamp__activity { display: flex; gap: var(--mc-3); padding: var(--mc-3) 0; }
.mcamp__activity + .mcamp__activity { border-top: 1px solid var(--mc-line); }

.mcamp__activity-time {
    font-family: 'IBM Plex Mono', ui-monospace, monospace;
    font-size: 9.5px;
    color: var(--mc-faint);
    width: 60px;
    flex: 0 0 60px;
    padding-top: 3px;
}

.mcamp__activity-text { font-size: 13.5px; line-height: 1.45; }

.mcamp__coderow + .mcamp__coderow { border-top: 1px solid var(--mc-line); }

.mcamp__coderow-head {
    display: flex;
    align-items: center;
    gap: var(--mc-3);
    width: 100%;
    padding: var(--mc-3) 0;
    border: 0;
    background: transparent;
    text-align: left;
    font: inherit;
    cursor: pointer;
}

.mcamp__code {
    display: block;
    font-family: 'IBM Plex Mono', ui-monospace, monospace;
    font-size: 13px;
    letter-spacing: 0.4px;
}

.mcamp__code.is-struck { text-decoration: line-through; color: var(--mc-faint); }

.mcamp__cardno {
    width: 34px;
    flex: 0 0 34px;
    height: 34px;
    border-radius: 9px;
    background: var(--mc-wash);
    display: flex;
    align-items: center;
    justify-content: center;
    font-family: 'Barlow Condensed', sans-serif;
    font-weight: 700;
    font-size: 15px;
}

.mcamp__detail {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: var(--mc-3);
    padding: 0 0 var(--mc-4) 46px;
}

.mcamp__detail-value { font-size: 13px; margin-top: 2px; }

.mcamp__more {
    width: 100%;
    border: 0;
    background: transparent;
    padding: var(--mc-4) 0;
    font: inherit;
    font-size: 13px;
    color: var(--mc-mute);
    cursor: pointer;
}

.mcamp__athletes { display: flex; flex-direction: column; padding-bottom: var(--mc-6); }
.mcamp__athlete + .mcamp__athlete { border-top: 1px solid var(--mc-line); }

.mcamp__athlete-head {
    display: flex;
    gap: var(--mc-3);
    align-items: center;
    width: 100%;
    padding: var(--mc-4) 0;
    border: 0;
    background: transparent;
    text-align: left;
    font: inherit;
    cursor: pointer;
}

.mcamp__athlete-red {
    font-family: 'Barlow Condensed', sans-serif;
    font-weight: 700;
    font-size: 30px;
    line-height: 1;
}

.mcamp__athlete-body { padding-bottom: var(--mc-4); }

.mcamp__claimant {
    display: flex;
    justify-content: space-between;
    gap: var(--mc-3);
    padding: var(--mc-2) 0;
}

.mcamp__claimant + .mcamp__claimant { border-top: 1px solid var(--mc-line); }

.mcamp__link { padding: var(--mc-5) 0; }
.mcamp__link + .mcamp__link { border-top: 1px solid var(--mc-line); }

.mcamp__link-total {
    font-family: 'Barlow Condensed', sans-serif;
    font-weight: 700;
    font-size: 30px;
    line-height: 1;
}

.mcamp__link-stats {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: var(--mc-3);
    margin-top: var(--mc-4);
}

.mcamp__link-stat { font-family: 'Barlow Condensed', sans-serif; font-weight: 700; font-size: 20px; }

.mcamp__attr { display: flex; align-items: center; gap: var(--mc-2); }
.mcamp__attr-name { font-size: 12.5px; width: 104px; flex: 0 0 104px; color: var(--mc-body); }
.mcamp__attr-n { font-family: 'IBM Plex Mono', ui-monospace, monospace; font-size: 10px; width: 24px; text-align: right; }

.mcamp__redemption { display: flex; gap: var(--mc-3); padding: var(--mc-4) 0; }
.mcamp__redemption + .mcamp__redemption { border-top: 1px solid var(--mc-line); }


/* ── Disclosure rows ────────────────────────────────────────────────────────
   Messaging has five settings and every one of them has a usable default, so
   showing five open editors made the owner scroll past work already done. A
   row states what the setting currently says; only the one you disagree with
   needs opening. Same hairline-between-rows idiom as the rest of the room. */
.mcamp__disc {
    border-bottom: 1px solid var(--mc-line);
}

.mcamp__disc-head {
    appearance: none;
    -webkit-appearance: none;
    background: none;
    border: 0;
    border-radius: 0;
    width: 100%;
    display: flex;
    align-items: center;
    gap: 14px;
    padding: 17px 0;
    text-align: left;
    font: inherit;
    color: inherit;
    cursor: pointer;
}

.mcamp__disc-label {
    font-family: 'IBM Plex Mono', ui-monospace, monospace;
    font-size: 9.5px;
    letter-spacing: 1.3px;
    text-transform: uppercase;
    color: var(--mc-mute);
    display: block;
}

.mcamp__disc-value {
    display: block;
    margin-top: 5px;
    font-size: 15px;
    line-height: 1.35;
    color: var(--mc-ink);
    /* One line. The full text lives inside; this is a reminder, not a copy. */
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* A chevron drawn from a rotated corner, so no glyph and no SVG namespace
   trouble inside an overlay built with innerHTML. */
.mcamp__disc-mark {
    flex: 0 0 auto;
    width: 7px;
    height: 7px;
    margin-right: 2px;
    border-right: 1.5px solid var(--mc-mute);
    border-bottom: 1.5px solid var(--mc-mute);
    transform: rotate(-45deg);
    transition: transform 140ms ease;
}

.mcamp__disc.is-open .mcamp__disc-mark {
    transform: rotate(45deg);
}

.mcamp__disc.is-open .mcamp__disc-value {
    color: var(--mc-mute);
}

.mcamp__disc-body {
    padding: 2px 0 22px;
}

/* The host app forces its own ink and ground onto everything under a dark
   theme, so these have to be restated at id strength to survive it. */
#mobile-campaign-overlay .mcamp__disc-head {
    background: none !important;
}

#mobile-campaign-overlay .mcamp__disc-value {
    color: var(--mc-ink) !important;
}

#mobile-campaign-overlay .mcamp__disc.is-open .mcamp__disc-value,
#mobile-campaign-overlay .mcamp__disc-label {
    color: var(--mc-mute) !important;
}

/* ── Who is driving it ──────────────────────────────────────────────────────
   A name, its number, and a bar for the share. Reusing the code-row here put
   the ticker and its breakdown on one line with no gap between them; this is
   stacked on purpose, because the split reads as a caption to the number
   rather than as a competing value. */
.mcamp__tapper {
    padding: 15px 0 17px;
    border-bottom: 1px solid var(--mc-line);
}

.mcamp__tapper-top {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 14px;
}

.mcamp__tapper-who {
    font-family: 'Barlow Condensed', sans-serif;
    font-weight: 700;
    font-size: 21px;
    line-height: 1.1;
    letter-spacing: 0.2px;
    color: var(--mc-ink);
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* Link names are prose, not tickers, so they take the body face. */
.mcamp__tapper-who--sm {
    font-family: inherit;
    font-weight: 500;
    font-size: 15px;
}

.mcamp__tapper-n {
    flex: 0 0 auto;
    font-family: 'Barlow Condensed', sans-serif;
    font-weight: 700;
    font-size: 26px;
    line-height: 1;
    color: var(--mc-ink);
}

.mcamp__tapper-bar {
    margin-top: 9px;
    height: 3px;
    background: var(--mc-line);
    overflow: hidden;
}

.mcamp__tapper-bar i {
    display: block;
    height: 100%;
    background: var(--mc-ink);
    min-width: 3px;
}

.mcamp__tapper-split {
    margin-top: 8px;
    font-size: 12.5px;
    line-height: 1.4;
    color: var(--mc-mute);
}

/* Restated at id strength: the host app repaints ink and ground under a dark
   theme and would otherwise flatten the bar into its own track. */
#mobile-campaign-overlay .mcamp__tapper-who,
#mobile-campaign-overlay .mcamp__tapper-n {
    color: var(--mc-ink) !important;
}

#mobile-campaign-overlay .mcamp__tapper-split {
    color: var(--mc-mute) !important;
}

#mobile-campaign-overlay .mcamp__tapper-bar {
    background: var(--mc-line) !important;
}

#mobile-campaign-overlay .mcamp__tapper-bar i {
    background: var(--mc-ink) !important;
}

/* The sponsor's mark in a list row. Same treatment as the dashboard header —
   a campaign is recognised by its logo far faster than by the first letter of
   the sponsor's name. */
.mcamp__row-mark--logo {
    background: transparent;
    padding: 0;
    overflow: hidden;
}

.mcamp__row-mark--logo img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
    border-radius: 10px;
}

#mobile-campaign-overlay .mcamp__row-mark--logo {
    background: transparent !important;
}

/* ── An athlete's funnel ────────────────────────────────────────────────────
   Four stages on one line under the name. Where the number stops is the whole
   point, so a zero is drawn rather than dropped — a gap between CLAIMED and
   IN WALLET is a campaign leaking, and hiding it would hide the leak. */
.mcamp__funnel {
    /* Four equal columns rather than flex: the labels differ in width, and
       letting them size themselves stacked the row into four lines on a
       phone. A grid keeps one line at any width. */
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 10px;
    margin-top: 13px;
}

.mcamp__funnel-step {
    display: block;
    min-width: 0;
}

.mcamp__funnel-n {
    display: block;
    font-family: 'Barlow Condensed', sans-serif;
    font-weight: 700;
    font-size: 19px;
    line-height: 1;
    color: var(--mc-ink);
}

.mcamp__funnel-label {
    display: block;
    margin-top: 4px;
    font-family: 'IBM Plex Mono', ui-monospace, monospace;
    font-size: 8px;
    letter-spacing: 0.8px;
    color: var(--mc-mute);
    white-space: nowrap;
}

/* A stage nobody reached is present but quiet, so the eye lands on the
   numbers that exist without losing where they ran out. */
.mcamp__funnel-step.is-zero .mcamp__funnel-n {
    color: var(--mc-line);
}

/* The unit rides under the headline figure rather than beside it, so the
   number stays the thing you read first. */
.mcamp__tapper-unit {
    display: block;
    font-family: 'IBM Plex Mono', ui-monospace, monospace;
    font-size: 8.5px;
    font-weight: 400;
    letter-spacing: 1.1px;
    text-transform: uppercase;
    color: var(--mc-mute);
    text-align: right;
    margin-top: 4px;
}

#mobile-campaign-overlay .mcamp__funnel-n {
    color: var(--mc-ink) !important;
}

#mobile-campaign-overlay .mcamp__funnel-step.is-zero .mcamp__funnel-n {
    color: var(--mc-line) !important;
}

#mobile-campaign-overlay .mcamp__funnel-label,
#mobile-campaign-overlay .mcamp__tapper-unit {
    color: var(--mc-mute) !important;
}

/* ── Banners ────────────────────────────────────────────────────────────────
   A status change is one tap whose only visible effect is on another screen:
   the pill it pulls down lives in the athlete's header. Without a line saying
   what happened the button reads as broken even when it worked — and every
   failure in this dashboard was being written to state and never shown at
   all. Both are said here, in the one place an owner is already looking. */
.mcamp__banner {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 14px;
    margin: 0 0 var(--mc-3);
    padding: 13px 0 13px 13px;
    font-size: 13.5px;
    line-height: 1.5;
    color: var(--mc-body);
    /* A rule down the left rather than a box around it, matching the rest of
       the room — nothing here draws a rectangle. */
    box-shadow: inset 2px 0 0 var(--mc-ink);
}

.mcamp__banner--bad {
    box-shadow: inset 2px 0 0 #d23b32;
}

#mobile-campaign-overlay .mcamp__banner {
    color: var(--mc-body) !important;
    background: transparent !important;
}
