/* /css/pages/promote-run.css — layout only for /ads.
 *
 * This page composes foundation devices and adds NO component of its own.
 * Everything here is grid, width and position. If a rule in this file starts
 * describing what something LOOKS like (a border, a radius, a type scale),
 * it belongs in the system instead, because the next page will need it too.
 *
 * The one exception is the ad-slot preview, which is a picture of YouTube's
 * own chrome rather than a CollabPals component. It is deliberately NOT
 * promoted to the system: it imitates somebody else's interface, and a device
 * that copies a third party's look must never become a thing other pages
 * reach for by habit.
 */

.promo-wrap { max-width: 1120px; margin: 0 auto; }

/* Wizard 2-column shell: the steps on the left, the live summary rail on the
   right (the shared .fnd-rail), matching the /create-collab wizard. Below 860px
   the rail hides and the action bar carries the step, exactly like create-collab
   on a phone. */
.promo-layout {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 320px;
  gap: var(--fnd-s5);
  align-items: start;
}
.promo-rail { position: sticky; top: var(--fnd-s5); }
@media (max-width: 860px) {
  .promo-layout { grid-template-columns: minmax(0, 1fr); }
  .promo-rail { display: none; }
}
/* The step counter lives in the summary rail on desktop, so the action bar does
   not repeat it (create-collab's bar carries no step text either). Below 860px
   the rail is hidden, so the bar keeps the step label as the only progress cue. */
@media (min-width: 861px) {
  .promo-page .fnd-actionbar-info { display: none; }
}
/* The wizard bar sits IN-FLOW on desktop, the foundation default: a plain last
   row under the step content, no floating card, no shadow. (Founder, 2026-08-31:
   the floating rounded bar read as a stray box that did not conform.) The one
   reason it used to float on desktop — a long refund disclosure that buried the
   Pay button below the scroll — no longer holds: that disclosure is now a
   collapsed accordion, so the total and Pay sit right under the budget choice,
   above the fold, with the fine print below. Mobile keeps the foundation's
   fixed thumb-zone bar. Nothing to override here; the foundation rule wins. */

/* THE CARD FOOTER MATCHES THE CARD, NOT THE PAGE. The system's .fnd-card-foot
   is painted --fnd-paper, which is the page colour, so on a white card the
   button strip at the bottom dissolves into the page behind it: it reads as a
   button floating on the background rather than sitting inside the card. Repaint
   it the card's own white so the footer is clearly part of the card. Scoped to
   this page on purpose, since other pages use the page-coloured foot by design. */
.promo-page .fnd-card-foot { background: var(--fnd-card); }

/* The chosen video's thumbnail in the summary rail (sidebar). Sits under the
   video name and only appears once a video is set. Full width of the rail
   column, held to a 16:9 frame so it never distorts. */
.promo-rail-thumb {
  display: block;
  width: 100%;
  max-width: 160px;
  aspect-ratio: 16 / 9;
  object-fit: cover;
  border-radius: var(--fnd-r-xs);
  margin-top: 8px;
}
.promo-rail-thumb[hidden] { display: none; }

/* NOTE on the checkout modal height: the Stripe form fits inside the system
   modal's standard height (measured 620px form in a 730px panel) and scrolls if
   taller. It reads shorter than the OLD-library NCM checkout only because NCM is
   pre-redesign; the two match once NCM migrates. A page must NEVER restyle a
   popup (design-system rule), so if foundation modals should be taller for
   checkout that belongs on the shared .fnd-modal component, not here. */

/* The clickable goal cards on step one carry an arrow that nudges right on
   hover, so they read as "tap to continue" rather than "select an option". The
   coming-soon tile is muted and shows no arrow, so it plainly does nothing. */
/* Both goal cards stand the same height even though the coming-soon tile has an
   extra "coming soon" line. grid-auto-rows equalises the rows; the flex + centre
   below then centres each card's content within that shared height. */
.promo-goals { grid-auto-rows: 1fr; }
.promo-goal { display: flex; align-items: center; justify-content: space-between; gap: var(--fnd-s4); width: 100%; height: 100%; text-align: left; cursor: pointer; }
.promo-goal-go { flex: none; color: var(--fnd-text-soft); transition: transform 150ms ease, color 150ms ease; }
.promo-goal:hover .promo-goal-go { transform: translateX(3px); color: var(--fnd-text); }
.promo-goal--soon { cursor: default; opacity: .62; }
/* A plain muted label, deliberately NOT .fnd-choice-tag: the system's tag
   alignment injects a spacer into the sibling card and knocks its text off
   centre. This just reads "coming soon" and triggers nothing. */
.promo-goal-soon { display: inline-block; align-self: flex-start; margin-bottom: 4px; font-size: 12px; font-weight: 700; letter-spacing: .03em; text-transform: uppercase; color: var(--fnd-text-soft); }

/* ------------------------------------------------------------------
   THE AD SLOT PREVIEW
   ------------------------------------------------------------------ */
.promo-preview { margin-top: var(--fnd-s5); container-type: inline-size; container-name: promo-preview; }

/* The wizard's main column is now ~615px (the summary rail takes 320px), too
   narrow for the old 300px-frame + text split, which crushed the copy into a
   ~290px strip that wrapped badly and left dead space under the frame. So the
   preview STACKS by default (frame above a full-width explanation) and only goes
   side-by-side when the card is genuinely wide enough to carry both. */
.promo-preview__grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--fnd-s4);
  align-items: start;
}
@container promo-preview (min-width: 620px) {
  .promo-preview__grid { grid-template-columns: 300px minmax(0, 1fr); gap: var(--fnd-s6); align-items: center; }
  .promo-preview__frame { max-width: none; }
}

.promo-preview__frame {
  position: relative;
  aspect-ratio: 16 / 9;
  max-width: 340px;
  border-radius: var(--fnd-r-xs);
  overflow: hidden;
  background: #000;
  /* Rounding a container changes its LAYOUT, not just its clipping, so the
     image is told to fill rather than left to size itself. */
  box-shadow: 0 10px 30px rgba(0, 0, 0, .45);
}
.promo-preview__frame img { display: block; width: 100%; height: 100%; object-fit: cover; }

/* YouTube's own marks, not ours. Hardcoded because they are a picture of
   somebody else's interface and must not drift with our tokens. */
.promo-preview__ad {
  position: absolute; left: 8px; top: 8px;
  background: #FFD400; color: #111;
  font-size: 12px; font-weight: 800;
  padding: 2px 6px; border-radius: 3px;
}
.promo-preview__skip {
  position: absolute; right: 0; bottom: 16px;
  background: rgba(0, 0, 0, .72); color: #fff;
  font-size: 13px; padding: 7px 11px;
  border: 1px solid rgba(255, 255, 255, .35); border-right: 0;
  border-radius: 3px 0 0 3px;
}
.promo-preview__bar {
  position: absolute; left: 0; right: 0; bottom: 0;
  height: 4px; background: rgba(255, 255, 255, .25);
}
.promo-preview__bar span { display: block; height: 100%; width: 38%; background: #FFD400; }

@media (max-width: 720px) {
  .promo-preview__grid { grid-template-columns: minmax(0, 1fr); gap: var(--fnd-s4); }
}

/* ------------------------------------------------------------------
   THE CHOSEN VIDEO
   ------------------------------------------------------------------ */
.promo-chosen { display: flex; gap: var(--fnd-s4); align-items: center; }
.promo-chosen__media { flex: 0 0 180px; }
.promo-chosen__media .fnd-media { width: 180px; height: 101px; }
.promo-chosen__body { min-width: 0; }
.promo-chosen__title { margin: 0 0 6px; font-weight: 700; }
.promo-chosen__note  { margin: 0; }

/* A phone gets the picture at full width. A 180px thumbnail beside two lines
   of text at 375px leaves neither of them readable. */
@media (max-width: 560px) {
  .promo-chosen { display: block; }
  .promo-chosen__media { margin-bottom: var(--fnd-s3); }
  .promo-chosen__media .fnd-media { width: 100%; height: auto; aspect-ratio: 16 / 9; }
}

/* ------------------------------------------------------------------
   THE PACKAGE LADDER
   Four across is a desktop-only shape. Two across is the tablet answer, and
   one is the phone answer: four price tiles side by side at 375px would each
   be 80px wide and the price would wrap away from its own label.
   ------------------------------------------------------------------ */
/* Two wide cards per row, not four narrow ones. The budget step shares its
   width with the summary rail, so four columns squeezed each card until the
   price and the view estimate wrapped down a stack of one- and two-word lines.
   A 2x2 grid gives every card room to read cleanly, the same layout the guest
   buy page uses. */
/* minmax(0, 1fr), NOT 1fr: a bare 1fr is minmax(auto, 1fr), whose auto floor is
   the column's min-content, and the nowrap view range ("12,000 to 32,000") made
   that floor wide enough to push the whole grid ~53px past its card box on the
   narrower buy-youtube-views card. minmax(0,...) lets the columns shrink to the
   container. The view number is sized (below) to fit even the tightest cell. */
.promo-packs { display: grid; gap: var(--fnd-s3); grid-template-columns: repeat(2, minmax(0, 1fr)); }

/* THE TILE, REBUILT TO SELL THE OUTCOME (founder, 2026-08-28).
   The tile used to lead with the package name and the dollar, and buried the
   view estimate in a muted subtitle. A buyer of "views" reads the price first
   and never sees what the price buys. So the estimated view range is now the
   hero, "real views on your video" names it in plain words, and the price gets
   its own confident line beneath, on a rule, so it is clear without dethroning
   the number they are actually shopping for. */
.promo-packs .fnd-choice-b { gap: 0; }

/* The system's own choice tag carries the selling label ("Most popular",
   "Best value"). --sell only tints the two we want the eye to land on green;
   it is a colour on the system component, NOT a re-drawn pill, so the tag keeps
   its shared size and alignment. */
.promo-packs .fnd-choice-tag--sell { color: var(--fnd-ok); font-weight: 700; }

/* The hero: the view range. Kept on ONE line always (a range broken across two
   lines, or an en dash jammed between the numbers, reads amateur), so it uses
   the word "to" and never wraps. Tabular figures keep the digits steady. */
.promo-pack-views {
  display: block; font-size: 25px; line-height: 1.05; font-weight: 800;
  letter-spacing: -.02em; color: var(--fnd-text);
  font-variant-numeric: tabular-nums; white-space: nowrap;
}
.promo-pack-for { display: block; margin-top: 3px; font-size: 14px; font-weight: 600; color: var(--fnd-text); }

/* The price, given back its presence: its own line, full ink, on a rule, with
   the run length quiet beside it. Clear, not hidden, but under the outcome. */
.promo-pack-price {
  display: block; margin-top: 11px; padding-top: 10px;
  border-top: 1px solid var(--fnd-rule);
  font-size: 17px; font-weight: 800; color: var(--fnd-text);
}
/* The run length on its OWN muted line, never jammed onto the price as
   "$25 for 7 days" (which reads like a rental: $25 every 7 days, then what?).
   A separate "Runs for 7 days" line is a plain fact about the ad, not the price. */
.promo-pack-run { display: block; margin-top: 3px; font-size: 13px; font-weight: 500; color: var(--fnd-text-soft); }

/* The trust line above the ladder. A buyer's top fear here is "is this bots?",
   so this is a readable, calm reassurance in the system's success green rather
   than grey fine print. It leads with the fear-buster and the shield reads as
   safety. (founder, 2026-08-30: the old 13px line was too small for its job.) */
.promo-packs-clarity {
  display: flex; gap: 11px; align-items: flex-start;
  margin: 0 0 16px; font-size: 15px; line-height: 1.55; color: var(--fnd-text);
  background: var(--fnd-ok-soft); border-radius: 12px; padding: 13px 15px;
}
.promo-packs-clarity i { color: var(--fnd-ok); font-size: 18px; margin-top: 1px; flex: none; }
.promo-packs-clarity b { font-weight: 800; }

/* Step-1 "back to the picker" affordance (founder, 2026-08-30): the ads flow
   hides the wizard action bar on step 1, so give members an explicit way back
   to the Create Campaign grid, like the other create flows have. */
.promo-step1-back { margin-top: var(--fnd-s5); }

@media (max-width: 460px) { .promo-packs { grid-template-columns: minmax(0, 1fr); } }

.promo-split { margin-top: var(--fnd-s4); }

/* ------------------------------------------------------------------
   TWO-COLUMN CHECKOUT (founder, 2026-08-28)
   Config on the left, a live order panel pinned on the right so the price
   and the Pay button never scroll away. Below 820px the panel hides and a
   fixed pay bar takes over. Replaces the long-scroll single column.
   ------------------------------------------------------------------ */
.promo-head2 { margin-bottom: var(--fnd-s5); }
/* The system caps .fnd-h2 at 20ch for readability, which wrapped this 27-char
   question onto two lines on desktop where there is plenty of room. It is a
   question, not a paragraph, so it reads as one line. Matched with the same
   two-class weight as `.fnd .fnd-h2` and loaded later so it wins; the font is
   nudged down just enough that the whole question also fits one line on a phone. */
.fnd-h2.promo-viewsq { max-width: none; white-space: nowrap; font-size: clamp(18px, 5.4vw, var(--fnd-t-h2)); }
.promo-2col { display: grid; grid-template-columns: minmax(0, 1fr) 340px; gap: var(--fnd-s6); align-items: start; }
.promo-config { min-width: 0; display: flex; flex-direction: column; gap: var(--fnd-s5); }

/* The video is a slim strip on top, not a step. */
.promo-eyebrow { margin: 0 0 var(--fnd-s2); font-size: 12px; font-weight: 800; letter-spacing: .04em; text-transform: uppercase; color: var(--fnd-text-soft); }

/* WHITE CARDS (founder: the tan fill read unfinished). The background is the one
   bit of appearance the page owns here; scoped to the wizard so it never changes
   .fnd-choice anywhere else. */
.promo-page .promo-packs .fnd-choice { background: var(--fnd-card); }

/* ------------------------------------------------------------------
   TWO-STEP WIZARD (founder, 2026-08-29)
   Step 1 = how many views. Step 2 = the video and payment. Centred, one clean
   decision per screen. Replaces the two-column layout above (whose rules are
   left in place but no longer used).
   ------------------------------------------------------------------ */
.promo-wizard { max-width: 560px; margin: 0 auto; }
.promo-stepn { margin: 0 0 6px; font-size: 12px; font-weight: 800; letter-spacing: .05em; text-transform: uppercase; color: var(--fnd-text-soft); }

/* Step 2 order summary: one clean band, what they get over what they pay. */
.promo-summary { margin-top: var(--fnd-s5); padding: var(--fnd-s5); background: var(--fnd-card); border: 1px solid var(--fnd-rule); border-radius: var(--fnd-r); }
.promo-summary__get { font-size: 24px; font-weight: 800; letter-spacing: -.02em; color: var(--fnd-text); line-height: 1.1; }
.promo-summary__get small { display: block; margin-top: 3px; font-size: 13px; font-weight: 600; color: var(--fnd-text-soft); }
.promo-summary__row { display: flex; justify-content: space-between; align-items: baseline; margin-top: var(--fnd-s4); padding-top: var(--fnd-s4); border-top: 1px solid var(--fnd-rule); }
.promo-summary__row-l { font-size: 15px; color: var(--fnd-text); }
.promo-summary__row-v { font-size: 24px; font-weight: 800; color: var(--fnd-text); }
.promo-summary__run { margin: 4px 0 0; text-align: right; font-size: 12px; color: var(--fnd-text-soft); }

/* The fee and refund terms as a quiet disclosure, not a wall of six bullets. */
.promo-terms2 { margin-top: var(--fnd-s4); border: 1px solid var(--fnd-rule); border-radius: var(--fnd-r-xs); }
.promo-terms2 > summary { list-style: none; cursor: pointer; padding: var(--fnd-s3) var(--fnd-s4); font-size: 13px; font-weight: 600; color: var(--fnd-text); }
.promo-terms2 > summary::-webkit-details-marker { display: none; }
.promo-terms2 > summary::after { content: "\203A"; float: right; color: var(--fnd-text-soft); transition: transform 150ms ease; }
.promo-terms2[open] > summary::after { transform: rotate(90deg); }
.promo-terms2__body { padding: 0 var(--fnd-s4) var(--fnd-s4); }
.promo-terms2 .promo-terms { margin: var(--fnd-s2) 0 0; }
.promo-terms2 .promo-worth { margin-top: 0; }

/* The refund line and error box sit quiet above the pay action. */
.promo-wizard .promo-ack { margin-top: var(--fnd-s4); }

/* Step navigation: Back on the left, the primary (Continue / Pay) on the right. */
.promo-nav { display: flex; align-items: center; gap: var(--fnd-s4); margin-top: var(--fnd-s6); }
.promo-nav__go { margin-left: auto; min-width: 220px; }
/* On a phone the nav is NOT sticky: the app already has a fixed bottom tab bar,
   and a second sticky bar would collide with it. Each step is short (the terms
   are collapsed), so the button sits at the end of the content and is in reach. */
@media (max-width: 560px) {
  .promo-nav { margin-top: var(--fnd-s5); }
  .promo-nav__go { flex: 1 1 auto; min-width: 0; margin-left: var(--fnd-s3); }
}

/* THE ORDER PANEL. Sticky, so it and Pay ride down the page as they scroll. */
.promo-order2 {
  position: sticky; top: var(--fnd-s5);
  background: var(--fnd-card); border: 1px solid var(--fnd-rule);
  border-radius: var(--fnd-r); padding: var(--fnd-s5);
  box-shadow: 0 10px 30px rgba(22, 20, 26, .07);
}
.promo-order2__h { margin: 0 0 var(--fnd-s4); font-size: 12px; font-weight: 800; letter-spacing: .04em; text-transform: uppercase; color: var(--fnd-text-soft); }
.promo-order2__h i { color: var(--fnd-ok); margin-right: 4px; }
.promo-order2__get { font-size: 24px; font-weight: 800; letter-spacing: -.02em; color: var(--fnd-text); line-height: 1.1; }
.promo-order2__get small { display: block; margin-top: 3px; font-size: 13px; font-weight: 600; color: var(--fnd-text-soft); }
.promo-order2__row { display: flex; justify-content: space-between; align-items: baseline; margin-top: var(--fnd-s4); padding-top: var(--fnd-s4); border-top: 1px solid var(--fnd-rule); }
.promo-order2__row-l { font-size: 14px; color: var(--fnd-text); }
.promo-order2__row-v { font-size: 22px; font-weight: 800; color: var(--fnd-text); }
.promo-order2__run { margin: 3px 0 0; text-align: right; font-size: 12px; color: var(--fnd-text-soft); }
.promo-order2__pay { width: 100%; margin-top: var(--fnd-s4); }
.promo-order2__trust { list-style: none; margin: var(--fnd-s4) 0 0; padding: 0; display: flex; flex-direction: column; gap: 6px; }
.promo-order2__trust li { font-size: 12px; line-height: 1.45; color: var(--fnd-text-soft); }
.promo-order2__trust i { color: var(--fnd-ok); margin-right: 6px; }

/* THE MOBILE PAY BAR. Hidden on desktop; the sticky panel does its job there. */
.promo-paybar { display: none; }

@media (max-width: 820px) {
  .promo-2col { grid-template-columns: minmax(0, 1fr); }
  .promo-order2 { display: none; }
  .promo-paybar {
    display: flex; align-items: center; justify-content: space-between; gap: var(--fnd-s4);
    position: fixed; left: 0; right: 0; bottom: 0; z-index: 60;
    background: var(--fnd-card); border-top: 1px solid var(--fnd-rule);
    padding: var(--fnd-s3) var(--fnd-s4);
    box-shadow: 0 -6px 20px rgba(22, 20, 26, .10);
  }
  .promo-paybar__info { display: flex; flex-direction: column; min-width: 0; }
  .promo-paybar__total { font-size: 18px; font-weight: 800; color: var(--fnd-text); }
  .promo-paybar__run { font-size: 12px; color: var(--fnd-text-soft); }
  .promo-paybar .fnd-btn { flex: 0 0 auto; }
  .promo-page .page-container { padding-bottom: 84px; }
}

/* ------------------------------------------------------------------
   THE FOCUS RING, FIXED LOCALLY
   The tile already draws its own ring via .fnd-choice:has(input:focus-visible),
   and the browser draws a SECOND square one around the 20px radio inside it.
   The founder saw the square and called it ugly, correctly.
   This belongs in foundation-members.css beside the radio's own rule, because
   it is true of every .fnd-choice on the site and not just this page. It is
   scoped here only because that file repaints pages other tabs are working on
   right now, and a shared-stylesheet edit is not something to slip into a
   page build. Move it and delete this block.
   ------------------------------------------------------------------ */
.promo-page .fnd-choice input[type="radio"]:focus,
.promo-page .fnd-choice input[type="radio"]:focus-visible { outline: none; }

/* ------------------------------------------------------------------
   THE THREE PLACES AN AD CAN RUN
   A list, not a paragraph, because the reader scans and the three
   placements ARE the offer. Bold leads each line so the bold words
   alone still say what you get.
   ------------------------------------------------------------------ */
.promo-places { margin: 0 0 var(--fnd-s3); padding: 0; list-style: none; }
.promo-places li { position: relative; padding-left: 20px; margin-bottom: 6px; }
.promo-places li::before {
  content: ""; position: absolute; left: 0; top: .55em;
  width: 6px; height: 6px; border-radius: 50%;
  background: currentColor; opacity: .45;
}

/* ------------------------------------------------------------------
   THE CUSTOM AMOUNT
   Sits under the four tiles, not among them. Quiet by default.
   ------------------------------------------------------------------ */
.promo-custom-toggle { margin: var(--fnd-s3) 0 0; }
.promo-custom { margin-top: var(--fnd-s3); }
.promo-custom .fnd-input { max-width: 220px; width: 100%; }

/* ------------------------------------------------------------------
   SPACING, FIXED IN TWO PLACES THE FOUNDER CAUGHT BY EYE

   1. THE HEADING BELONGED TO THE WRONG THING. The gap from the tabs to
      the step heading was SMALLER than the gap from that heading to the
      card it names. Proximity is what tells a reader what goes with
      what, so the heading read as part of the tab bar rather than as
      the title of the content under it. The two gaps are now the other
      way round, which is the only arrangement that means anything.

   2. AN INK BLOCK'S HEADING NEEDS MORE AIR THAN A PAPER ONE, because
      the surface behind it is doing work of its own. The card title sat
      almost touching the list it introduces.
   ------------------------------------------------------------------ */
.promo-page .promo-wrap .fnd-pagehead { margin-top: var(--fnd-s6); margin-bottom: var(--fnd-s3); }
.promo-page .promo-wrap .fnd-tabs { margin-bottom: 0; }

.promo-preview .fnd-card-t { margin: 0 0 var(--fnd-s3); }
.promo-preview .promo-places + p { margin: 0; }

/* ------------------------------------------------------------------
   THE LINE THAT DEFENDS THE FEE, and the terms under it.
   The paragraph sits directly beneath the total because that is the
   number it is answering. The terms are a LIST, not prose: four bold
   leads a reader can take in without reading a sentence.
   ------------------------------------------------------------------ */
/* Lighter, per founder: the justification steps down from body weight to a
   quiet 14px, and the terms sit off in a faint footnote zone under a hairline,
   so the fee split reads as the content and this reads as the fine print it is.
   Nothing is hidden or trimmed (it is chargeback + Google-policy cover). */
.promo-worth { margin: var(--fnd-s3) 0 0; font-size: 14px; line-height: 1.5; color: var(--fnd-text-soft); }
.promo-worth b { color: var(--fnd-text); }

.promo-terms { margin: var(--fnd-s4) 0 0; padding: var(--fnd-s4) 0 0; list-style: none;
             border-top: 1px solid var(--fnd-rule);
             font-size: var(--fnd-t-meta); color: var(--fnd-text-soft); }
.promo-terms li { position: relative; padding-left: 20px; margin-bottom: 6px; line-height: 1.45; }
.promo-terms li b { font-weight: 600; }
.promo-terms li:last-child { margin-bottom: 0; }
.promo-terms li::before {
  content: ""; position: absolute; left: 0; top: .55em;
  width: 6px; height: 6px; border-radius: 50%;
  background: currentColor; opacity: .35;
}

/* ==================================================================
   YOUR ADS: one order card, in every state
   ==================================================================
   Layout only. Every visible part of these cards is a foundation
   device (.fnd-card, .fnd-badge, .fnd-media--play, .fnd-tasklist,
   .fnd-stats, .fnd-meter, .fnd-receipt), so what is left here is the
   two-column head and the rhythm between the bands. If this block
   ever starts describing colour, weight or borders, something is
   being repainted that should have been composed.
   ================================================================== */
.promo-orders { display: grid; gap: var(--fnd-s4); }
.promo-paid   { margin-bottom: var(--fnd-s4); }

.promo-order__badge { margin: 0 0 var(--fnd-s3); }

/* The thumbnail keeps a fixed column so a two-line title never squeezes
   it, and the picture is the tap target for the shared player. */
.promo-order__head {
  display: grid;
  grid-template-columns: 104px minmax(0, 1fr);
  gap: var(--fnd-s3);
  align-items: start;
}
.promo-order__head .fnd-media { width: 104px; }

/* The title IS the card's title device (.fnd-card-t). Only its rhythm
   is this page's business; its type is the system's.

   TWO LINES, THEN AN ELLIPSIS. A real member title ran to four lines on
   a phone and pushed the whole status of the order below the fold,
   which is the one thing this card exists to show. Two lines is what
   YouTube itself gives a title in a list, the full text is on the
   thumbnail's label for a screen reader, and the video is one tap away. */
.promo-order__t {
  /* Self-contained title type, so this class carries the card-title look on
     its own. The status card pairs it with .fnd-card-t (same values, no visual
     change); the /activity detail popup uses it WITHOUT .fnd-card-t, because a
     card-title class outside a .fnd-card is a section heading in disguise. */
  font-family: var(--fnd-display-font);
  font-weight: 700;
  font-size: var(--fnd-t-h3);
  letter-spacing: -.012em;
  margin: 0;
  line-height: 1.25;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.promo-order__meta {
  margin: 6px 0 0;
  font-size: var(--fnd-t-meta);
  color: var(--fnd-text-soft);
}

/* Each band below the head is separated by the card's own rule rather
   than by a gap, so a long card reads as one object with sections and
   not as a stack of loose boxes. */
.promo-order__part { border-top: 1px solid var(--fnd-rule); }

.promo-order__meter,
.promo-order__where,
.promo-order__delta,
.promo-order__refund { margin-top: var(--fnd-s4); }
.promo-order__where,
.promo-order__delta  { margin-bottom: 0; }
.promo-order__wait   { margin-top: var(--fnd-s4); margin-bottom: 0; }
.promo-order__more   { margin-top: var(--fnd-s4); }

.promo-placements { margin-top: var(--fnd-s4); }
.promo-placements .fnd-card-body p { margin: 0; }

/* A 375px phone loses 20px of thumbnail so the title still gets two
   comfortable lines rather than four cramped ones. */
@media (max-width: 560px) {
  .promo-order__head { grid-template-columns: 84px minmax(0, 1fr); }
  .promo-order__head .fnd-media { width: 84px; }
}

/* The "See all the numbers" toggle is a .fnd-textbtn, which deliberately
   does not reserve 44px because the rows it usually sits in have no
   vertical room. This row does. .fnd-hit is the system's own answer:
   padding grows the border box to a real 44px tap target and an equal
   negative margin hands the space straight back, so nothing moves. The
   device does nothing until an axis is named, which is this line. */
.promo-order .fnd-card-foot .fnd-textbtn { --fnd-hit-y: 15px; }

/* The one line under the ad list. Not a card: it is a way out, not a
   thing to read, and giving it a card's edges would make it compete
   with the orders above it. */
.promo-help {
  margin: var(--fnd-s5) 0 0;
  font-size: var(--fnd-t-meta);
  color: var(--fnd-text-soft);
}
/* .fnd-hit does nothing until an axis is named. Same trap as the
   "See all the numbers" toggle: the class alone reads as fixed and the
   control still measures 16px. */
.promo-help .fnd-textbtn { --fnd-hit-y: 15px; }


.promo-notyet { margin-top: var(--fnd-s4); }

/* ── SWAP RECOVERY (?swap=<REF>) ──────────────────────────────────────────
   The screen the rejection email links to: point a paid order Google would not
   run at a different video. ONE card. The card body owns its rhythm as a flex
   column with a gap (spec 29g), so its rows never touch. Layout only; every
   surface is a foundation device. */
/* Full content width, so the screen matches the "Your ads" cards and the rest
   of /ads rather than sitting as a narrow off-centre column. */
.promo-swap { width: 100%; }
/* Standard breathing room at the top of EVERY /ads surface (wizard, swap screen,
   Your-ads tab). It lives on the page container, NOT the title, on purpose: the
   wizard has a summary rail in a second column, so spacing the title alone pushes
   it BELOW the rail and the rail floats above it. Spacing the whole container
   shifts the title and the rail down together, so they stay top-aligned while the
   page gets the same breathing room other pages have. The .fnd-pagehead component
   ships margin-top:0, which is why /ads owns this in one place. */
.promo-page .page-container { padding-top: var(--fnd-s6); }
.promo-swap__body {
    display: flex;
    flex-direction: column;
    gap: var(--fnd-s4, 16px);
}
.promo-swap__row {
    display: flex;
    gap: var(--fnd-s3, 12px);
    align-items: center;
}
.promo-swap__was { opacity: .7; }
.promo-swap__row .fnd-media { width: 120px; flex: 0 0 120px; }
.promo-swap__meta { min-width: 0; }
.promo-swap__t {
    font-weight: 600;
    margin: 6px 0 0;
    word-break: break-word;
    overflow-wrap: break-word;
}
/* The two actions sit side by side and wrap cleanly on a narrow phone. */
.promo-swap__foot {
    display: flex;
    flex-wrap: wrap;
    gap: var(--fnd-s3, 12px);
    align-items: center;
}
.promo-swap__back {
    margin-top: var(--fnd-s4, 16px);
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 6px;
}
@media (max-width: 767px) {
    .promo-swap__foot .fnd-btn { width: 100%; }
    .promo-swap__row .fnd-media { width: 96px; flex-basis: 96px; }
}

/* Refund disclosure line that sits at the pay action. A passive line, not a
   required tick, so it never blocks the pay button; the order records that it
   was shown (refund_policy_shown_at). Quiet by design: it discloses, it does
   not sell. */
.promo-ack {
    margin-top: 16px;
    font-size: 13px;
    line-height: 1.5;
    color: var(--fnd-ink-3, #6E6878);
}
.promo-ack a { color: inherit; text-decoration: underline; }

/* ── RAIL POLISH (founder, 2026-08-27) ────────────────────────────────────
   Two small conformance fixes on the summary rail. */

/* The rail-head badge holds a YouTube ICON, not a photo. .fnd-avatar centres a
   cover image, but an icon child needs explicit centring or it sits top-left of
   the circle. Scoped to /ads; the same gap on other icon-in-avatar spots is one
   for the design-system pass. */
.promo-page .fnd-rail-head .fnd-avatar {
  display: inline-flex;
  align-items: center;
  justify-content: center;
}

/* Every thumbnail carries the standard hairline (foundation .fnd-media::before,
   founder rule 2026-08-14). The rail thumbnail is a bare <img>, and an <img>
   cannot paint a ::before, so it mirrors the exact same 1px ink line as a ring
   that follows its radius. A near-white thumbnail has no edge of its own and
   vanishes into the card without it. */
.promo-rail-thumb { box-shadow: 0 0 0 1px rgba(22, 20, 26, .14); }

/* ══ MY YOUTUBE ADS — COMPACT ROWS (founder, 2026-08-28) ═══════════════════
   The /activity "My YouTube Ads" tab is a list of compact rows, one per ad.
   Tapping a row opens its detail popup (templates/ads/_order-detail.twig). The
   popup itself reuses the .promo-order__* classes above, so it needs no CSS of
   its own; only the row does. Built from foundation tokens, no new colours. */
.promo-rows { display: flex; flex-direction: column; gap: var(--fnd-s3); }

.promo-row {
  display: flex; align-items: center; gap: var(--fnd-s4);
  width: 100%; text-align: left; font: inherit; color: inherit;
  background: var(--fnd-card); border: 1px solid var(--fnd-rule);
  border-radius: var(--fnd-r); padding: var(--fnd-s3) var(--fnd-s4);
  cursor: pointer; transition: transform 150ms ease, box-shadow 150ms ease, border-color 150ms ease;
}
.promo-row:hover {
  transform: translateY(-1px);
  box-shadow: 0 4px 14px rgba(16, 14, 20, .08);
  border-color: var(--fnd-text-soft);
}
.promo-row:active { transform: translateY(0); }

.promo-row__thumb {
  width: 64px; height: 40px; flex: 0 0 auto;
  border-radius: var(--fnd-r-xs); object-fit: cover;
  background: var(--fnd-paper-2);
  box-shadow: 0 0 0 1px rgba(22, 20, 26, .14);
}
.promo-row__main { flex: 1 1 auto; min-width: 0; display: block; }
.promo-row__t {
  display: block; font-weight: 700; font-size: 15px; color: var(--fnd-text);
  margin: 0 0 3px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.promo-row__sub {
  display: flex; align-items: center; gap: 7px;
  font-size: var(--fnd-t-meta); color: var(--fnd-text-soft); white-space: nowrap;
}
.promo-row__dot { width: 8px; height: 8px; border-radius: 50%; flex: 0 0 auto; }
.promo-row__dot--run   { background: var(--fnd-ok); }
.promo-row__dot--fin   { background: var(--fnd-text-soft); }
.promo-row__dot--stop  { background: var(--fnd-warn); }
.promo-row__dot--build { background: var(--fnd-warn); }

.promo-row__views { flex: 0 0 auto; text-align: right; line-height: 1.15; }
.promo-row__views b { display: block; font-size: 16px; color: var(--fnd-text); }
.promo-row__views span { font-size: 12px; color: var(--fnd-text-soft); }

.promo-row__chev { flex: 0 0 auto; color: var(--fnd-text-soft); font-size: 14px; }

/* ============================================================
   GEO TARGETING CONTROL (the "reach-line") — /ads, guest, and
   /buy-youtube-views. Foundation paper surface; system tokens only.
   Rendered by templates/ads/_geo_picker.twig, driven by
   /js/ads-geo-picker.js. Sits above the budget tiles.
   ============================================================ */
.geo { margin: 0 0 18px; }
.geo__label {
  display: flex; align-items: center; gap: 7px;
  font-size: 13px; font-weight: 700; color: var(--fnd-ink); margin: 0 0 9px;
}
.geo__label i { color: var(--fnd-text-faint); font-size: 12px; }

.geo__row {
  width: 100%; display: flex; align-items: center; gap: 13px; text-align: left;
  background: var(--fnd-paper-2); border: 1.5px solid var(--fnd-rule);
  border-radius: var(--fnd-r); padding: 12px 13px; cursor: pointer;
  transition: border-color .15s ease, box-shadow .15s ease, transform .08s ease;
}
.geo__row:hover { border-color: var(--fnd-text-faint); box-shadow: 0 6px 16px -12px rgba(28,25,23,.3); }
.geo__row:active { transform: scale(.995); }
.geo__flag {
  flex: 0 0 auto; width: 42px; height: 42px; border-radius: 12px;
  background: var(--fnd-paper); border: 1px solid var(--fnd-rule);
  display: flex; align-items: center; justify-content: center; font-size: 22px; line-height: 1;
}
.geo__sel { flex: 1 1 auto; min-width: 0; }
.geo__country {
  display: block; font-size: 15.5px; font-weight: 700; color: var(--fnd-ink);
  letter-spacing: -.01em; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.geo__hint { display: block; font-size: 12.5px; color: var(--fnd-text-faint); margin-top: 1px; }
/* The Edit affordance IS the shared .fnd-chip-btn pill (foundation members);
   this only positions it and colours the chevron. The pill look, border, hover
   and 44px tap target all come from the component. */
.geo__edit { flex: 0 0 auto; }
.geo__edit i { font-size: 12px; color: var(--fnd-text-faint); }
.geo__note {
  display: flex; gap: 7px; font-size: 12.5px; color: var(--fnd-text-soft);
  margin: 10px 2px 0; line-height: 1.5;
}
.geo__note i { color: var(--fnd-accent); margin-top: 2px; flex: 0 0 auto; }
.geo__note b { color: var(--fnd-ink); }

/* The sheet that opens on Edit, in place under the row. */
.geo-sheet {
  margin-top: 12px; padding: 14px; border: 1.5px solid var(--fnd-rule);
  border-radius: var(--fnd-r); background: var(--fnd-paper);
}
.geo-sheet__search {
  display: flex; align-items: center; gap: 9px; background: var(--fnd-paper-2);
  border: 1.5px solid var(--fnd-rule); border-radius: 12px; padding: 0 13px;
  color: var(--fnd-text-faint); margin-bottom: 12px;
}
.geo-sheet__search i { font-size: 13px; flex: 0 0 auto; }
.geo-sheet__search input {
  flex: 1 1 auto; border: none; background: transparent; outline: none;
  font: inherit; font-size: 14px; color: var(--fnd-ink); padding: 11px 0;
}
.geo-sheet__search input::placeholder { color: var(--fnd-text-faint); }
/* The wrapper is the field, so the focus ring belongs on the wrapper, in the
   page's own ink. Kill the global input focus glow (an off-theme indigo box
   shadow bled onto this bare input and read as a big highlighted rectangle). */
.geo-sheet__search input:focus { box-shadow: none; }
.geo-sheet__search:focus-within {
  border-color: var(--fnd-ink);
  box-shadow: 0 0 0 3px var(--fnd-edge);
}

/* A selectable option row, NOT a green banner (founder, 2026-08-31): neutral
   when unpicked, soft-green with a filled check when picked, so it plainly
   toggles and clears the instant a country is chosen. */
.geo-world {
  width: 100%; display: flex; align-items: center; gap: 12px; text-align: left;
  background: var(--fnd-paper); border: 1.5px solid var(--fnd-rule);
  border-radius: 13px; padding: 12px 13px; cursor: pointer; margin-bottom: 4px;
  transition: border-color .15s ease, background-color .15s ease, box-shadow .15s ease, transform .08s ease;
}
.geo-world:hover { border-color: var(--fnd-text-faint); box-shadow: 0 6px 16px -12px rgba(28,25,23,.3); }
.geo-world:active { transform: scale(.995); }
.geo-world.is-on { border-color: var(--fnd-ok); background: var(--fnd-ok-soft); }
.geo-world__box {
  flex: 0 0 auto; width: 22px; height: 22px; border-radius: 6px;
  border: 2px solid var(--fnd-text-faint); background: var(--fnd-paper);
  display: flex; align-items: center; justify-content: center; color: var(--fnd-paper); font-size: 12px;
}
.geo-world__box i { opacity: 0; }
.geo-world.is-on .geo-world__box { background: var(--fnd-ok); border-color: var(--fnd-ok); }
.geo-world.is-on .geo-world__box i { opacity: 1; }
.geo-world__globe {
  width: 34px; height: 34px; border-radius: 10px; background: var(--fnd-paper-2);
  border: 1px solid var(--fnd-rule); display: flex; align-items: center;
  justify-content: center; font-size: 19px; flex: 0 0 auto;
}
.geo-world__t { flex: 1 1 auto; min-width: 0; }
.geo-world__t b { font-size: 14.5px; color: var(--fnd-ink); display: block; }
.geo-world__t small { font-size: 12.5px; color: var(--fnd-text-faint); font-weight: 500; }
.geo-world__tag {
  margin-left: auto; flex: 0 0 auto; font-size: 12px; font-weight: 700;
  letter-spacing: .03em; text-transform: uppercase; color: var(--fnd-ok);
}

.geo-sheet__label {
  font-size: 12px; font-weight: 700; letter-spacing: .09em; text-transform: uppercase;
  color: var(--fnd-text-faint); margin: 16px 2px 2px;
}
.geo-list { max-height: 320px; overflow-y: auto; -webkit-overflow-scrolling: touch; }
.geo-opt {
  display: flex; align-items: center; gap: 12px; width: 100%; text-align: left;
  padding: 12px 4px; cursor: pointer; background: none; border: none;
  border-bottom: 1px solid var(--fnd-edge); font: inherit;
}
.geo-opt:last-child { border-bottom: none; }
.geo-opt__box {
  flex: 0 0 auto; width: 22px; height: 22px; border-radius: 6px;
  border: 2px solid var(--fnd-text-faint); background: var(--fnd-paper);
  display: flex; align-items: center; justify-content: center; color: var(--fnd-paper); font-size: 12px;
}
.geo-opt.is-on .geo-opt__box { background: var(--fnd-ink); border-color: var(--fnd-ink); }
.geo-opt__box i { opacity: 0; }
.geo-opt.is-on .geo-opt__box i { opacity: 1; }
.geo-opt__flag { font-size: 20px; line-height: 1; flex: 0 0 auto; }
.geo-opt__name { font-size: 15px; color: var(--fnd-ink); font-weight: 500; }
.geo-opt.is-on .geo-opt__name { font-weight: 700; }
.geo-opt__tag { margin-left: auto; font-size: 12px; color: var(--fnd-text-faint); }
.geo-list__empty { font-size: 13px; color: var(--fnd-text-soft); padding: 14px 4px; margin: 0; }

.geo-sheet__foot { display: flex; justify-content: flex-end; margin-top: 12px; }

.geo-divider { height: 1px; background: var(--fnd-edge); margin: 16px 0; }

@media (max-width: 767px) {
  .geo__flag { width: 38px; height: 38px; font-size: 20px; }
  .geo__country { font-size: 15px; }
  .geo__edit { padding: 8px 12px; }
  .geo-opt { padding: 13px 4px; }        /* keep the tap target at 44px+ on a phone */
  /* The "Most views" pill squeezes the Worldwide line into a word-per-line wrap
     on a narrow phone, and the line itself already says "the most views for your
     money", so the pill is dropped here rather than left to break the layout. */
  .geo-world__tag { display: none; }
  .geo-world__t small { white-space: normal; }
}

/* ============================================================
   ADS PAY-STEP REDESIGN (founder, 2026-08-31). Gated on adsGeo.enabled.
   Sidebar receipt with Pay, green "real views", quiet countries link.
   ============================================================ */

/* Video step has no receipt, so the layout collapses to one column. */
.promo-layout--solo { grid-template-columns: minmax(0, 1fr); }

/* "real views" made prominent on each tile: green and bold. */
.promo-pack-for--rv {
  display: inline-flex; align-items: center; gap: 6px; margin-top: 3px;
  color: var(--fnd-ok); font-weight: 700; font-size: 15px; letter-spacing: .005em;
}
.promo-pack-for--rv i { font-size: 14px; flex: 0 0 auto; }

/* The quiet "Choose specific countries" advanced link under the tiles. */
.geo-adv { margin: 14px 0 0; }
.geo-adv__link {
  display: flex; align-items: center; gap: 11px; width: 100%; text-align: left;
  background: var(--fnd-paper-2); border: 1.5px solid var(--fnd-rule);
  border-radius: var(--fnd-r-sm); padding: 11px 13px; cursor: pointer;
  font: inherit; transition: border-color .15s ease, box-shadow .15s ease;
}
.geo-adv__link:hover { border-color: var(--fnd-text-faint); box-shadow: 0 6px 16px -12px rgba(28,25,23,.3); }
.geo-adv__link > i { color: var(--fnd-text-faint); font-size: 15px; flex: 0 0 auto; }
.geo-adv__c { flex: 1 1 auto; min-width: 0; }
.geo-adv__c b { display: block; font-size: 14px; font-weight: 700; color: var(--fnd-ink); }
.geo-adv__c small { display: block; font-size: 12.5px; color: var(--fnd-text-faint); margin-top: 1px; }
.geo-adv__go { flex: 0 0 auto; color: var(--fnd-text-faint); font-size: 12px; }

/* The modal reuses the shared .fnd-modal + the geo device styles; the country
   list keeps its own base max-height and scrolls inside the modal body. */

/* ---------- THE RECEIPT (sidebar on desktop, stacks on mobile) ---------- */
.promo-rcpt {
  position: sticky; top: var(--fnd-s5);
  background: var(--fnd-card); border: 1px solid var(--fnd-rule);
  border-radius: var(--fnd-r); padding: var(--fnd-s5);
}
.promo-rcpt__hd {
  font-family: var(--fnd-display-font); font-weight: 800; font-size: 17px;
  line-height: 1.25; letter-spacing: -.01em; color: var(--fnd-ink); margin: 0 0 5px;
}
.promo-rcpt__sub { font-size: 13px; color: var(--fnd-text-soft); line-height: 1.5; margin: 0 0 15px; }
.promo-rcpt__rows { margin: 0 0 4px; }
.promo-rcpt__row {
  display: flex; align-items: flex-start; justify-content: space-between; gap: 12px;
  padding: 11px 0; border-top: 1px solid var(--fnd-edge);
}
.promo-rcpt__k { font-size: 13px; color: var(--fnd-text-faint); font-weight: 600; }
.promo-rcpt__v { font-size: 14px; color: var(--fnd-ink); font-weight: 700; text-align: right; }
.promo-rcpt__edit {
  display: block; margin-top: 2px; margin-left: auto; background: none; border: none;
  padding: 0; font: inherit; font-size: 12px; font-weight: 700; color: var(--fnd-accent); cursor: pointer;
}
.promo-rcpt__row--total { border-top: 1px solid var(--fnd-edge); }
.promo-rcpt__row--total .promo-rcpt__k { font-size: 14px; color: var(--fnd-ink); }
.promo-rcpt__total { font-family: var(--fnd-display-font); font-size: 23px; font-weight: 800; color: var(--fnd-ink); }
.promo-rcpt__pay { width: 100%; margin-top: 12px; }
.promo-rcpt__back { display: block; margin: 10px auto 0; }
.promo-rcpt__trust { display: flex; gap: 8px; font-size: 12px; color: var(--fnd-text-soft); line-height: 1.45; margin: 12px 2px 0; }
.promo-rcpt__trust i { color: var(--fnd-ok); margin-top: 2px; flex: 0 0 auto; }

@media (max-width: 860px) {
  /* On a phone the sidebar column is gone; the receipt flows inline below the
     tiles and stops being sticky, carrying the Pay button at the bottom. */
  .promo-rcpt { position: static; margin-top: var(--fnd-s4); }
}

/* Video step (redesign): Continue sits in the card footer next to "Pick a
   different video" (founder, 2026-08-31), so it is high with the video, not far
   below the ad-placement picture. Wraps on a narrow phone. */
.promo-video-foot { display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; }

/* The one recommended tile carries a "Most popular" ribbon instead of a chip;
   the other editorial labels are dropped as clutter. Absolutely positioned so it
   never shifts the tile's content or misaligns the row. */
.promo-packs .fnd-choice { position: relative; }
.promo-pop-ribbon {
  position: absolute; top: -11px; left: 50%; transform: translateX(-50%);
  background: var(--fnd-ink); color: var(--fnd-on-ink);
  font-size: 12px; font-weight: 700; letter-spacing: .01em;
  padding: 4px 12px; border-radius: 999px; white-space: nowrap; z-index: 2;
  box-shadow: 0 2px 8px rgba(28,25,23,.18);
}

/* The receipt's two secondary links need a >=24px tap area on a phone (the
   sweep measured them at 19px / 28px). Padding grows the hit box without
   changing where they sit. */
.promo-rcpt__edit { padding: 4px 0 4px 8px; }
.promo-rcpt__back { min-height: 24px; padding: 6px 12px; }
