:root {
  --pp-primary: #32B0C6;
  --pp-primary-hover: #2991A3;
  --pp-on-primary: #0b0b0b;
  --pp-accent-text: #2991A3;
  --pp-bg: #f5f4f6;
  --pp-surface: #ffffff;
  --pp-border: #e2e1e5;
  --pp-text: #16151a;
  --pp-muted: #6b6a71;
  --pp-danger: #b02a37;
  --pp-danger-soft: #fbe9eb;
  --pp-warning: #996a00;
  --pp-warning-soft: #fdf3e0;
  --pp-success: #1a7f4b;
  --pp-success-soft: #e7f5ee;
  --pp-info: #1c6fa8;
  --pp-info-soft: #e8f2f9;
  --pp-radius: 12px;
  --pp-radius-sm: 8px;
  --pp-shadow: 0 1px 3px rgba(16, 15, 20, .08), 0 6px 20px rgba(16, 15, 20, .05);
}

[data-bs-theme="dark"] {
  --pp-primary: #54C1D4;
  --pp-primary-hover: #6ccadb;
  --pp-on-primary: #111111;
  --pp-accent-text: #54C1D4;
  --pp-bg: #141414;
  --pp-surface: #1e1e1e;
  --pp-border: #2f2f2f;
  --pp-text: #ececee;
  --pp-muted: #9b9aa1;
  --pp-danger: #e35d6a;
  --pp-danger-soft: #3a1d20;
  --pp-warning: #e6b34d;
  --pp-warning-soft: #33290f;
  --pp-success: #4dbd8a;
  --pp-success-soft: #142c22;
  --pp-info: #63b3e8;
  --pp-info-soft: #14242f;
  --pp-shadow: 0 1px 3px rgba(0, 0, 0, .4);
}

body {
  background: var(--pp-bg);
  color: var(--pp-text);
  font-family: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  font-size: 16px;
}

a { color: var(--pp-accent-text); }
a:hover { color: var(--pp-primary-hover); }

.pp-shell { display: flex; min-height: 100vh; }

.pp-sidebar {
  width: 236px;
  flex: 0 0 236px;
  background: var(--pp-surface);
  border-right: 1px solid var(--pp-border);
  padding: 20px 14px;
  position: sticky;
  top: 0;
  height: 100vh;
  overflow-y: auto;
}

.pp-brand {
  display: flex;
  align-items: center;
  gap: 10px;
  font-weight: 700;
  font-size: 18px;
  color: var(--pp-text);
  text-decoration: none;
  padding: 4px 8px 20px;
}

/* The Potolo mark. An <img>, so it carries no background of its own: the logo
   already has its own shape and a teal tile behind it would fight with it. */
.pp-brand-mark {
  width: 30px;
  height: 30px;
  flex: 0 0 auto;
  object-fit: contain;
  display: block;
}

.pp-nav a {
  display: flex;
  align-items: center;
  gap: 11px;
  padding: 10px 12px;
  border-radius: var(--pp-radius-sm);
  color: var(--pp-text);
  text-decoration: none;
  font-size: 14.5px;
  margin-bottom: 2px;
  min-height: 44px;
}
.pp-nav a:hover { background: var(--pp-bg); color: var(--pp-text); }
.pp-nav a.active { background: var(--pp-primary); color: var(--pp-on-primary); font-weight: 600; }
.pp-nav a.active svg { stroke: var(--pp-on-primary); }

/* A count beside a nav link. Small, and only there when it is not zero, so an
   empty queue leaves no mark. */
.pp-badge {
  margin-left: auto;
  min-width: 20px;
  height: 20px;
  padding: 0 6px;
  border-radius: 999px;
  background: var(--pp-primary);
  color: var(--pp-on-primary);
  font-size: 12px;
  font-weight: 700;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.pp-nav a.active .pp-badge { background: var(--pp-on-primary); color: var(--pp-primary); }

.pp-main { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; }

.pp-topbar {
  height: 62px;
  border-bottom: 1px solid var(--pp-border);
  background: var(--pp-surface);
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 10px;
  padding: 0 18px;
  position: sticky; top: 0; z-index: 30;
}

.pp-content { padding: 24px 18px 60px; width: 100%; max-width: 1100px; margin: 0 auto; }

.pp-page-title { font-size: 24px; font-weight: 600; margin: 0; }
.pp-section-title { font-size: 18px; font-weight: 600; margin: 0 0 4px; }
.pp-meta { font-size: 13px; color: var(--pp-muted); }

.pp-card {
  background: var(--pp-surface);
  border: 1px solid var(--pp-border);
  border-radius: var(--pp-radius);
  box-shadow: var(--pp-shadow);
}
.pp-card-body { padding: 18px; }

.btn-pp-primary {
  background: var(--pp-primary);
  border: 1px solid var(--pp-primary);
  color: var(--pp-on-primary);
  border-radius: var(--pp-radius-sm);
  font-weight: 600;
  min-height: 44px;
  padding: 9px 16px;
}
.btn-pp-primary:hover, .btn-pp-primary:focus {
  background: var(--pp-primary-hover);
  border-color: var(--pp-primary-hover);
  color: var(--pp-on-primary);
}
.btn-pp-secondary {
  background: transparent;
  border: 1px solid var(--pp-border);
  color: var(--pp-text);
  border-radius: var(--pp-radius-sm);
  min-height: 44px;
  padding: 9px 16px;
}
.btn-pp-secondary:hover { background: var(--pp-bg); color: var(--pp-text); }

/* The advertisement itself, shown the way a viewer meets it. Held to a
   comfortable reading width so a tall image does not fill the whole screen,
   and given a dark backing so a creative with transparent edges still reads
   as one object rather than bleeding into the card. */
.pp-creative-stage {
  max-width: 640px;
  border-radius: var(--pp-radius-sm);
  overflow: hidden;
  background: #101316;
  border: 1px solid var(--pp-border);
}
.pp-creative-stage:has(iframe) { aspect-ratio: 16 / 9; }

.pp-creative-media {
  display: block;
  width: 100%;
  height: 100%;
  border: 0;
}
img.pp-creative-media {
  height: auto;
  max-height: 460px;
  object-fit: contain;
}

/* Taken out of the layout rather than faded, so the line it sits on does not
   hold an empty gap while nothing is happening. */
.htmx-indicator { display: none; }
.htmx-request .htmx-indicator,
.htmx-request.htmx-indicator { display: inline; }

/* The choice buttons are sized by the grid, not by their wording, so a long
   word breaks inside the button instead of spilling past its border. */
.btn-check + .btn-pp-secondary {
  white-space: normal;
  overflow-wrap: anywhere;
}
.btn-pp-danger {
  background: var(--pp-danger);
  border: 1px solid var(--pp-danger);
  color: #fff;
  border-radius: var(--pp-radius-sm);
  min-height: 44px;
  padding: 9px 16px;
}
.btn-pp-danger:hover { filter: brightness(.94); color: #fff; }

.btn[disabled], .btn.pp-busy { opacity: .62; pointer-events: none; }

.pp-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 12.5px;
  font-weight: 600;
  padding: 4px 10px;
  border-radius: 999px;
  white-space: nowrap;
}
.pp-chip::before { content: ""; width: 7px; height: 7px; border-radius: 50%; background: currentColor; }
.pp-chip-success { background: var(--pp-success-soft); color: var(--pp-success); }
.pp-chip-warning { background: var(--pp-warning-soft); color: var(--pp-warning); }
.pp-chip-info { background: var(--pp-info-soft); color: var(--pp-info); }
.pp-chip-muted { background: var(--pp-bg); color: var(--pp-muted); }
.pp-chip-neutral { background: var(--pp-bg); color: var(--pp-text); }

.pp-progress { height: 7px; background: var(--pp-border); border-radius: 999px; overflow: hidden; min-width: 90px; }
.pp-progress span { display: block; height: 100%; background: var(--pp-primary); }

.pp-filter-chip {
  display: inline-flex; align-items: center; gap: 7px;
  background: var(--pp-surface);
  border: 1px solid var(--pp-border);
  border-radius: 999px;
  padding: 5px 8px 5px 12px;
  font-size: 13px;
}
.pp-filter-chip button {
  border: 0; background: transparent; color: var(--pp-muted);
  line-height: 1; padding: 2px 4px; cursor: pointer; font-size: 15px;
}

.pp-search { position: relative; }
.pp-search input { padding-right: 68px; min-height: 44px; }
.pp-search .pp-search-spin {
  position: absolute; right: 38px; top: 50%; transform: translateY(-50%);
  display: none;
}
.pp-search.htmx-request .pp-search-spin { display: block; }
/* The clear button belongs to what is typed, not to what the server last sent,
   so it is always rendered and revealed the moment the field has anything in it. */
.pp-search .pp-search-clear {
  position: absolute; right: 10px; top: 50%; transform: translateY(-50%);
  border: 0; background: transparent; color: var(--pp-muted); cursor: pointer;
  display: none;
  font-size: 20px;
  line-height: 1;
  width: 32px;
  height: 32px;
  border-radius: 6px;
}
.pp-search .pp-search-clear:hover { color: var(--pp-text); background: var(--pp-bg); }
.pp-search-filled .pp-search-clear { display: block; }

/* Chrome draws its own cross on a search input, which would sit next to ours. */
.pp-search input[type="search"]::-webkit-search-cancel-button { display: none; }

.pp-skeleton {
  background: linear-gradient(90deg, var(--pp-border) 25%, var(--pp-bg) 37%, var(--pp-border) 63%);
  background-size: 400% 100%;
  animation: pp-shimmer 1.3s ease infinite;
  border-radius: 6px;
}
@keyframes pp-shimmer { 0% { background-position: 100% 50%; } 100% { background-position: 0 50%; } }

.pp-empty { text-align: center; padding: 46px 18px; }
.pp-empty-icon {
  width: 52px; height: 52px; border-radius: 50%;
  background: var(--pp-bg); color: var(--pp-muted);
  display: grid; place-items: center; margin: 0 auto 14px;
}

.pp-toasts {
  position: fixed; right: 18px; bottom: 18px; z-index: 1080;
  display: flex; flex-direction: column; gap: 10px; max-width: 360px;
}
.pp-toast {
  background: var(--pp-surface);
  border: 1px solid var(--pp-border);
  border-left: 4px solid var(--pp-muted);
  border-radius: var(--pp-radius-sm);
  box-shadow: var(--pp-shadow);
  padding: 12px 14px;
  display: flex; align-items: flex-start; gap: 10px;
  font-size: 14px;
}
.pp-toast-success { border-left-color: var(--pp-success); }
.pp-toast-error { border-left-color: var(--pp-danger); }
.pp-toast-warning { border-left-color: var(--pp-warning); }
.pp-toast-info { border-left-color: var(--pp-info); }
.pp-toast button { border: 0; background: transparent; color: var(--pp-muted); cursor: pointer; line-height: 1; }

.pp-field-error { color: var(--pp-danger); font-size: 13px; margin-top: 5px; }
.form-control.pp-invalid, .form-select.pp-invalid { border-color: var(--pp-danger); }

.pp-banner {
  border-radius: var(--pp-radius-sm);
  padding: 12px 14px;
  font-size: 14px;
  border: 1px solid transparent;
}
.pp-banner-warning { background: var(--pp-warning-soft); color: var(--pp-warning); border-color: var(--pp-warning); }
.pp-banner-danger { background: var(--pp-danger-soft); color: var(--pp-danger); border-color: var(--pp-danger); }
.pp-banner-info { background: var(--pp-info-soft); color: var(--pp-info); border-color: var(--pp-info); }

.form-control, .form-select {
  border-radius: var(--pp-radius-sm);
  border-color: var(--pp-border);
  background: var(--pp-surface);
  color: var(--pp-text);
  min-height: 44px;
}
.form-control:focus, .form-select:focus {
  border-color: var(--pp-primary);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--pp-primary) 28%, transparent);
  background: var(--pp-surface);
  color: var(--pp-text);
}
.form-label { font-size: 14px; font-weight: 600; margin-bottom: 5px; }
.form-text { color: var(--pp-muted); font-size: 13px; }

.form-check-input:checked { background-color: var(--pp-primary); border-color: var(--pp-primary); }
.form-check-input:focus { box-shadow: 0 0 0 3px color-mix(in srgb, var(--pp-primary) 28%, transparent); }

:focus-visible { outline: 3px solid color-mix(in srgb, var(--pp-primary) 60%, transparent); outline-offset: 2px; }

.pp-table { width: 100%; border-collapse: separate; border-spacing: 0; font-size: 14px; }
.pp-table th {
  text-align: left; font-size: 12.5px; text-transform: uppercase;
  letter-spacing: .03em; color: var(--pp-muted); font-weight: 600;
  padding: 10px 14px; border-bottom: 1px solid var(--pp-border);
}
.pp-table td { padding: 13px 14px; border-bottom: 1px solid var(--pp-border); vertical-align: middle; }
.pp-table tr:last-child td { border-bottom: 0; }

.pp-avatar {
  width: 34px; height: 34px; border-radius: 50%;
  object-fit: cover; background: var(--pp-primary); color: var(--pp-on-primary);
  display: inline-grid; place-items: center; font-size: 13px; font-weight: 700;
}
.pp-avatar-lg { width: 84px; height: 84px; font-size: 26px; }

.pp-thumb {
  width: 100%; aspect-ratio: 16/9; object-fit: cover;
  border-radius: var(--pp-radius-sm); background: var(--pp-bg); display: block;
}

.pp-pick-card {
  border: 2px solid transparent; border-radius: var(--pp-radius-sm);
  padding: 6px; cursor: pointer; background: transparent; width: 100%; text-align: left;
}
.pp-pick-card:hover { border-color: var(--pp-border); }
.pp-pick-card.selected { border-color: var(--pp-primary); }

.pp-bottom-nav { display: none; }

.modal-content { background: var(--pp-surface); color: var(--pp-text); border-radius: var(--pp-radius); }

@media (max-width: 767.98px) {
  .pp-sidebar { display: none; }
  .pp-content { padding: 16px 14px 96px; }
  .pp-topbar { padding: 0 14px; justify-content: space-between; }
  .pp-toasts { right: 12px; left: 12px; bottom: 80px; max-width: none; }

  .pp-bottom-nav {
    display: flex;
    position: fixed; bottom: 0; left: 0; right: 0; z-index: 40;
    background: var(--pp-surface);
    border-top: 1px solid var(--pp-border);
    padding: 6px 4px calc(6px + env(safe-area-inset-bottom));
  }
  .pp-bottom-nav a, .pp-bottom-nav button {
    flex: 1; display: flex; flex-direction: column; align-items: center; gap: 3px;
    padding: 7px 2px; font-size: 11px; color: var(--pp-muted);
    text-decoration: none; border: 0; background: transparent; min-height: 52px;
  }
  .pp-bottom-nav a.active { color: var(--pp-primary); font-weight: 600; }
  .pp-bottom-nav a.active svg { stroke: var(--pp-primary); }

  .pp-table thead { display: none; }
  .pp-table, .pp-table tbody, .pp-table tr, .pp-table td { display: block; width: 100%; }
  .pp-table tr {
    background: var(--pp-surface);
    border: 1px solid var(--pp-border);
    border-radius: var(--pp-radius);
    margin-bottom: 12px;
    padding: 6px 2px;
  }
  .pp-table td { border-bottom: 0; padding: 8px 14px; }
  .pp-table td[data-label]::before {
    content: attr(data-label);
    display: block; font-size: 11.5px; text-transform: uppercase;
    letter-spacing: .03em; color: var(--pp-muted); margin-bottom: 3px;
  }
  .pp-sticky-action {
    position: sticky; bottom: 64px;
    background: var(--pp-surface); border-top: 1px solid var(--pp-border);
    padding: 12px 14px; margin: 18px -14px 0;
  }
  .pp-sticky-action .btn { width: 100%; }
}

.pp-stat {
  background: var(--pp-surface);
  border: 1px solid var(--pp-border);
  border-radius: var(--pp-radius);
  box-shadow: var(--pp-shadow);
  padding: 16px 18px;
  height: 100%;
}
.pp-stat-value { font-size: 28px; font-weight: 600; line-height: 1.15; margin-top: 2px; }

.pp-bars {
  display: flex;
  align-items: flex-end;
  gap: 3px;
  height: 120px;
}
.pp-bar {
  flex: 1 1 0;
  height: 100%;
  display: flex;
  align-items: flex-end;
  min-width: 4px;
}
.pp-bar span {
  display: block;
  width: 100%;
  min-height: 2px;
  border-radius: 3px 3px 0 0;
  background: var(--pp-primary);
}

.pp-chip-danger { background: var(--pp-danger-soft); color: var(--pp-danger); }
.pp-chip-row { display: flex; flex-wrap: wrap; gap: 8px; }
.pp-chip-row .pp-chip { text-decoration: none; border: 1px solid transparent; }
.pp-chip-row .pp-chip:hover { border-color: var(--pp-border); }
.pp-chip-active {
  background: var(--pp-primary);
  color: var(--pp-on-primary);
  border-color: var(--pp-primary);
  font-weight: 600;
}

.pp-avatar-sm { width: 30px; height: 30px; font-size: 12px; }

.btn-pp-ghost {
  background: transparent;
  color: var(--pp-muted);
  border: 1px solid var(--pp-border);
  border-radius: var(--pp-radius-sm);
  font-weight: 500;
}
.btn-pp-ghost:hover { background: var(--pp-bg); color: var(--pp-text); }

.pp-modal { border: 1px solid var(--pp-border); box-shadow: var(--pp-shadow); }
.pp-modal .modal-header, .pp-modal .modal-footer { border-color: var(--pp-border); }

@media (max-width: 767.98px) {
  .pp-bars { height: 90px; }
  .pp-stat-value { font-size: 23px; }
}

img, svg, video { max-width: 100%; height: auto; }

.pp-table-scroll { overflow-x: auto; -webkit-overflow-scrolling: touch; }

.pp-table td, .pp-table th { overflow-wrap: anywhere; }

/* A table squeezed into a narrow window crushes its first column, which is the
   one carrying the name. Below this width the wrapper scrolls instead, and the
   name keeps its room. Under 768px the rows become cards and none of this
   applies. */
@media (min-width: 768px) {
  .pp-table-scroll > .pp-table { min-width: 720px; }
  .pp-table-scroll > .pp-table th:first-child,
  .pp-table-scroll > .pp-table td:first-child { min-width: 180px; }
}
.pp-meta, .pp-page-title, .pp-section-title { overflow-wrap: anywhere; }
.pp-filter-chip { max-width: 100%; overflow-wrap: anywhere; }

@media (max-width: 767.98px) {
  html, body { overflow-x: hidden; }
  .pp-content { min-width: 0; }
  .pp-card { min-width: 0; }
  .pp-bars { gap: 2px; }
}

/* The chart. Its plot is stretched to whatever width is available, so nothing
   that must stay legible is drawn inside it: the scale and the dates are HTML
   sitting alongside, and only lines and bars go in the SVG. */
.pp-chart-wrap {
  display: flex;
  gap: 10px;
  align-items: stretch;
}

.pp-chart-scale {
  position: relative;
  flex: 0 0 auto;
  width: 34px;
  height: 120px;
  margin-bottom: 20px;
}
.pp-chart-tick {
  position: absolute;
  right: 0;
  transform: translateY(50%);
  font-size: 11px;
  color: var(--pp-muted);
  font-variant-numeric: tabular-nums;
}

.pp-chart-plot { position: relative; flex: 1 1 auto; min-width: 0; }

.pp-chart-plot svg {
  width: 100%;
  height: 120px;
  display: block;
  overflow: visible;
}

.pp-chart-grid {
  stroke: var(--pp-border);
  stroke-width: 1;
  vector-effect: non-scaling-stroke;
}
.pp-chart-base { stroke: var(--pp-muted); opacity: .6; }

.pp-chart-views { fill: var(--pp-primary); }
.pp-chart-clicks { fill: var(--pp-text); opacity: .5; }

/* Invisible, but it is what a pointer actually finds. */
.pp-chart-hit { fill: transparent; }
.pp-chart-hit:hover { fill: var(--pp-text); fill-opacity: .05; }

.pp-chart-days { position: relative; height: 20px; }
.pp-chart-day {
  position: absolute;
  transform: translateX(-50%);
  top: 4px;
  font-size: 11px;
  white-space: nowrap;
  color: var(--pp-muted);
}

.pp-chart-key {
  display: flex;
  flex-wrap: wrap;
  gap: 18px;
  align-items: center;
  margin-top: 10px;
  font-size: 13px;
  color: var(--pp-muted);
}
.pp-legend-strong { color: var(--pp-text); font-weight: 600; }

@media (max-width: 767.98px) {
  .pp-chart-scale { width: 28px; height: 96px; }
  .pp-chart-plot svg { height: 96px; }
  /* Three dates is all a narrow screen can hold without them touching. */
  .pp-chart-day:nth-child(even) { display: none; }
}

.pp-spark {
  display: block;
  width: 100%;
  height: 26px;
  margin-top: 8px;
  color: var(--pp-primary);
  opacity: .85;
}

.pp-spark-note { margin-top: 2px; font-size: 11.5px; }

/* The mark and the words as one object, on the sign in and sign up pages.
   The mark is display:block, which text-align cannot move, so it used to sit
   against the left edge of a box that was itself centred. Laying the two out
   in a row centres both and puts the name beside the mark where it belongs.
   It wraps on a narrow screen rather than pushing the card sideways. */
.pp-auth-brand {
  display: flex;
  align-items: center;
  justify-content: center;
  flex-wrap: wrap;
  gap: 10px;
  margin: 0 0 20px;
  font-size: 20px;
  font-weight: 600;
  line-height: 1.25;
  text-align: center;
}

.pp-auth-brand .pp-brand-mark { width: 40px; height: 40px; }

/* Out of the way until a keyboard reaches it, then fully visible. Hiding it
   with display:none would take it out of the tab order, which is the one thing
   it exists for. */
.pp-skip {
  position: absolute;
  left: 8px;
  top: -60px;
  z-index: 100;
  background: var(--pp-surface);
  color: var(--pp-text);
  border: 1px solid var(--pp-border);
  border-radius: var(--pp-radius-sm);
  padding: 10px 16px;
  font-weight: 600;
  text-decoration: none;
  transition: top .15s ease;
}
.pp-skip:focus { top: 8px; color: var(--pp-text); }

.pp-content:focus { outline: none; }

/* Somebody who has asked their machine to stop moving things has asked for a
   reason, and a dashboard is not the place to argue with it. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
    scroll-behavior: auto !important;
  }
}

.pp-sort {
  color: inherit;
  text-decoration: none;
  display: inline-flex;
  align-items: center;
  gap: 4px;
  white-space: nowrap;
}
.pp-sort:hover { color: var(--pp-accent-text); }
.pp-sort-on { color: var(--pp-accent-text); font-weight: 700; }
.pp-sort-on::after { content: "\2193"; font-size: 11px; }

.pp-target-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.pp-target-list li {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  padding: 10px 12px;
  border: 1px solid var(--pp-border);
  border-radius: var(--pp-radius-sm);
  background: var(--pp-bg);
}
.pp-target-name { font-weight: 600; overflow-wrap: anywhere; }

/* Filter chips are controls, not decoration, so they carry a real tap target. */
.pp-chip-row .pp-chip {
  min-height: 36px;
  padding: 8px 14px;
}

@media (max-width: 767.98px) {
  /* A thumb needs 44px. On a phone the links inside rows, banners and prose
     become blocks with enough room to hit without magnifying the text. */
  .pp-table td a,
  .pp-banner a,
  .pp-card-body > .row a:not(.btn),
  .pp-target-list a {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
    padding: 2px 0;
  }

  .pp-chip-row {
    gap: 10px;
  }

  .pp-chip-row .pp-chip {
    min-height: 44px;
    padding: 12px 16px;
    font-size: 14px;
  }

  .pp-sort {
    min-height: 44px;
  }
}

@media (max-width: 767.98px) {
  .pp-meta a,
  .pp-topbar .pp-brand,
  .pp-topbar .dropdown > button {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
  }

  .pp-topbar .dropdown > button {
    padding: 0 2px;
  }
}

.pp-sub-title {
  font-size: 15px;
  font-weight: 600;
  margin: 0 0 6px;
}

/* The card payment block, set apart from marking it paid by hand. */
.pp-pay {
  border: 1px solid var(--pp-border);
  border-radius: var(--pp-radius-sm);
  background: var(--pp-bg);
  padding: 14px;
}

.pp-pay input[readonly] {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 13px;
}

/* Settings tabs. A row that scrolls sideways on a phone rather than wrapping
   into a block of buttons that pushes the form off the screen. */
.pp-tabs {
  display: flex;
  gap: 2px;
  padding: 6px 6px 0;
  border-bottom: 1px solid var(--pp-border);
  overflow-x: auto;
  scrollbar-width: none;
}
.pp-tabs::-webkit-scrollbar { display: none; }

.pp-tab {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  white-space: nowrap;
  border: 0;
  background: transparent;
  color: var(--pp-muted);
  font-size: 14.5px;
  font-weight: 600;
  padding: 12px 16px;
  min-height: 48px;
  border-radius: var(--pp-radius-sm) var(--pp-radius-sm) 0 0;
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;
  cursor: pointer;
}
.pp-tab:hover { background: var(--pp-bg); color: var(--pp-text); }
.pp-tab-on {
  color: var(--pp-text);
  border-bottom-color: var(--pp-primary);
  background: var(--pp-surface);
}

/* Show and hide a password. The button sits inside the field's own box, and
   the field is given room on the right so typing never runs underneath it. */
.pp-password { position: relative; display: block; }
.pp-password .form-control { padding-right: 48px; }

/* The wrapper takes the place the input used to hold. Several password fields
   sit beside a Save button in a flex row, and a wrapper that did not grow the
   way the input did would leave the field stranded at its own width. */
.d-flex > .pp-password { flex: 1 1 auto; min-width: 0; }

.pp-password-toggle {
  position: absolute;
  right: 6px;
  top: 50%;
  transform: translateY(-50%);
  display: flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  border: 0;
  background: transparent;
  color: var(--pp-muted);
  border-radius: var(--pp-radius-sm);
  cursor: pointer;
  padding: 0;
}
.pp-password-toggle:hover { color: var(--pp-text); background: var(--pp-bg); }
.pp-password-toggle:focus-visible {
  outline: 2px solid var(--pp-primary);
  outline-offset: 1px;
}

/* The price, shown while the budget is being decided rather than discovered
   afterwards. It is the one number an advertiser cares about most. */
.pp-quote {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  align-items: center;
  justify-content: space-between;
  padding: 14px 18px;
  border: 1px solid var(--pp-border);
  border-left: 3px solid var(--pp-primary);
  border-radius: var(--pp-radius-sm);
  background: var(--pp-bg);
}
.pp-quote-label {
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: .4px;
  color: var(--pp-muted);
}
.pp-quote-sum { font-size: 14px; margin-top: 2px; }
.pp-quote-total {
  font-size: 26px;
  font-weight: 600;
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}
.pp-quote-currency { font-size: 14px; color: var(--pp-muted); margin-left: 4px; }

/* What the system made of the advertisement, shown above its results. A wrong
   list of subjects explains a wrong list of videos, and that cannot be worked
   out from the videos on their own. */
.pp-understood {
  border: 1px solid var(--pp-border);
  border-left: 3px solid var(--pp-primary);
  border-radius: var(--pp-radius-sm);
  background: var(--pp-bg);
  padding: 14px 16px;
  margin-bottom: 16px;
}
.pp-understood-head {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  justify-content: space-between;
  gap: 10px;
}
.pp-understood-title {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}

/* Label and value on one line, for the short pairs on the review page. The
   chip lists below outgrew this, which is what the grid underneath is for. */
.pp-understood-row {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  align-items: baseline;
  margin-top: 8px;
}
.pp-understood-label {
  flex: 0 0 92px;
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: .5px;
  color: var(--pp-muted);
}

/* A grid so every label starts in the same column however many chips follow
   it. Flexed pairs could not do this: a short list stayed beside its label and
   a long one wrapped underneath, so no two rows agreed. */
.pp-understood-grid {
  display: grid;
  grid-template-columns: 92px minmax(0, 1fr);
  align-items: baseline;
  gap: 10px 14px;
  margin: 12px 0 0;
}
.pp-understood-grid dt {
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: .5px;
  color: var(--pp-muted);
  padding-top: 3px;
}
.pp-understood-grid dd {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin: 0;
  min-width: 0;
}

@media (max-width: 575.98px) {
  .pp-understood-grid {
    grid-template-columns: minmax(0, 1fr);
    gap: 4px;
  }
  .pp-understood-grid dd {
    margin-bottom: 6px;
  }
}

/* The video a match is about, shown rather than only named. */
.pp-match-video {
  display: flex;
  align-items: center;
  gap: 10px;
  min-width: 0;
}
.pp-match-thumb {
  flex: 0 0 auto;
  width: 72px;
  height: 41px;
  border-radius: 4px;
  object-fit: cover;
  background: var(--pp-border);
  display: block;
}
.pp-match-thumb-empty {
  background: linear-gradient(135deg, var(--pp-border), var(--pp-bg));
}
.pp-match-title {
  font-weight: 600;
  min-width: 0;
}

/* The advertisement currently on a campaign, shown while it is being edited.
   A name on its own says nothing about whether the right file was picked. */
.pp-chosen {
  display: flex;
  flex-wrap: wrap;
  gap: 18px;
  align-items: flex-start;
  margin-bottom: 8px;
}

.pp-chosen-stage {
  position: relative;
  flex: 0 0 auto;
  width: 320px;
  max-width: 100%;
  aspect-ratio: 16 / 9;
  border-radius: var(--pp-radius-sm);
  overflow: hidden;
  background: #101316;
  border: 1px solid var(--pp-border);
}
.pp-chosen-stage-image { width: 260px; aspect-ratio: auto; min-height: 120px; }

.pp-chosen-media { display: block; width: 100%; height: 100%; border: 0; object-fit: contain; }
.pp-chosen-stage-image .pp-chosen-media { height: auto; max-height: 260px; }

/* Sits behind the picture, so it shows through only when there is none. */
.pp-chosen-placeholder {
  position: absolute;
  inset: 0;
  z-index: -1;
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: 12px;
  color: #9aa3ab;
  font-size: 13px;
}

.pp-chosen-facts { flex: 1 1 240px; min-width: 0; }
.pp-chosen-title { font-weight: 600; margin-bottom: 8px; word-break: break-word; }

@media (max-width: 575.98px) {
  .pp-chosen-stage { width: 100%; }
}

/* Uploading belongs where somebody is already looking for a video and finding
   it is not there, rather than as a second button beside the first. */
.pp-picker-upload {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  align-items: center;
  justify-content: space-between;
  padding: 14px 16px;
  margin-bottom: 16px;
  border: 1px dashed var(--pp-border);
  border-radius: var(--pp-radius-sm);
  background: var(--pp-bg);
}
.pp-picker-upload-title { font-weight: 600; margin-bottom: 2px; }

/* The row that ends a form. Ruled off from the fields above it so the buttons
   read as the end of the job rather than as one more thing to fill in. */
.pp-form-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px;
  padding: 16px 20px;
  border-top: 1px solid var(--pp-border);
  background: var(--pp-bg);
  border-radius: 0 0 var(--pp-radius) var(--pp-radius);
}
.pp-form-actions .btn { min-width: 110px; }

/* Sits with the buttons on a wide screen and drops under them on a narrow one,
   rather than being flung to the far edge away from what it describes. */
.pp-form-note {
  color: var(--pp-muted);
  font-size: 13px;
  margin-left: 6px;
}
@media (max-width: 767.98px) {
  .pp-form-actions { padding: 14px; }
  .pp-form-actions .btn { flex: 1 1 140px; }
  .pp-form-note { flex: 1 0 100%; margin-left: 0; }
}

/* The number on a step. It says this strip is a route with an order to it,
   not a set of drawers to open in any sequence. */
.pp-step-no {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 20px;
  height: 20px;
  border-radius: 50%;
  border: 1.5px solid var(--pp-border);
  font-size: 11.5px;
  font-weight: 700;
  flex: 0 0 20px;
}
.pp-tab-on .pp-step-no {
  border-color: var(--pp-primary);
  background: var(--pp-primary);
  color: #fff;
}

/* Whether that section has been filled in. Hollow means not yet. */
.pp-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  border: 1.5px solid var(--pp-border);
  flex: 0 0 8px;
}
.pp-dot-on {
  background: var(--pp-success);
  border-color: var(--pp-success);
}

.pp-tab-panel { padding-top: 20px; }

/* ---------------------------------------------------------------------------
   The landing page.

   Prefixed pp-l- and used on one page, which is why it sits in a block of its
   own rather than mixed into the dashboard rules above. It reads the same
   variables, so it follows the light and dark themes without a second palette.
   --------------------------------------------------------------------------- */

.pp-l-wrap { width: 100%; max-width: 1180px; margin: 0 auto; padding: 0 22px; }

.pp-l-bar {
  position: sticky; top: 0; z-index: 50;
  background: var(--pp-surface);
  border-bottom: 1px solid var(--pp-border);
}
.pp-l-bar-inner { display: flex; align-items: center; gap: 22px; min-height: 68px; }

.pp-l-brand {
  display: inline-flex; align-items: center; gap: 10px;
  font-weight: 700; font-size: 18px; color: var(--pp-text); text-decoration: none;
  margin-right: auto;
}
.pp-l-brand .pp-brand-mark { width: 30px; height: 30px; }
.pp-l-brand-small { font-size: 16px; margin-right: 0; }

.pp-l-bar-actions { display: flex; gap: 10px; align-items: center; }

/* The hero is a conversation between the words and the player beside them, so
   it is a two column grid rather than text over a photograph. */
.pp-l-hero {
  padding: 72px 0 78px;
  position: relative; isolation: isolate; overflow: hidden;
}
.pp-l-hero::before {
  content: ""; position: absolute; z-index: -1;
  top: -180px; right: -140px; width: 720px; height: 720px;
  background: radial-gradient(circle, color-mix(in srgb, var(--pp-primary) 22%, transparent) 0%, transparent 68%);
  pointer-events: none;
}
.pp-l-hero-grid {
  display: grid; grid-template-columns: 1.02fr 1fr; gap: 56px; align-items: center;
}

.pp-l-eyebrow {
  text-transform: uppercase; letter-spacing: .12em; font-size: 12px; font-weight: 700;
  color: var(--pp-accent-text); margin: 0 0 14px;
}

.pp-l-title {
  font-size: clamp(31px, 4vw, 47px); line-height: 1.1; font-weight: 700;
  color: var(--pp-text); margin: 0 0 18px;
}
.pp-l-lead {
  font-size: clamp(15.5px, 1.3vw, 17.5px); line-height: 1.62;
  color: var(--pp-muted); max-width: 54ch; margin: 0 0 28px;
}

.pp-l-cta { display: flex; flex-wrap: wrap; gap: 12px; }
.pp-l-cta-centre { justify-content: center; }

.pp-l-assurances { list-style: none; padding: 0; margin: 28px 0 0; }
.pp-l-assurances li {
  color: var(--pp-text); font-size: 14.5px; margin-bottom: 9px;
  display: flex; align-items: center; gap: 10px;
}
.pp-l-assurances li::before {
  content: ""; width: 7px; height: 7px; border-radius: 50%;
  background: var(--pp-primary); flex: 0 0 auto;
}

/* The player. A frame, a picture inside it, and the advertisement furniture on
   top, because what is being sold is the thing that sits over the video. */
.pp-l-stage { position: relative; }

.pp-l-player {
  position: relative; aspect-ratio: 16 / 9; overflow: hidden;
  border-radius: var(--pp-radius); background: #0b0e11;
  border: 1px solid var(--pp-border); box-shadow: var(--pp-shadow);
}
.pp-l-reel, .pp-l-reel .carousel-inner, .pp-l-reel .carousel-item {
  position: absolute; inset: 0; height: 100%;
}
.pp-l-reel .carousel-item img { width: 100%; height: 100%; object-fit: cover; display: block; }

.pp-l-reel-caption {
  position: absolute; left: 18px; bottom: 74px; right: 18px;
  display: flex; flex-direction: column; gap: 3px;
  text-shadow: 0 1px 12px rgba(0, 0, 0, .8);
}
.pp-l-reel-channel { color: rgba(255, 255, 255, .78); font-size: 12.5px; font-weight: 600; }
.pp-l-reel-title { color: #fff; font-size: 16px; font-weight: 600; }

.pp-l-ad-chip {
  position: absolute; top: 16px; left: 16px;
  display: inline-flex; align-items: center; gap: 8px;
  background: rgba(8, 12, 15, .74); color: #fff;
  font-size: 12.5px; font-weight: 600;
  padding: 7px 13px; border-radius: 999px;
  backdrop-filter: blur(4px);
}
.pp-l-ad-dot { width: 7px; height: 7px; border-radius: 50%; background: var(--pp-primary); }

.pp-l-player-bar {
  position: absolute; left: 0; right: 0; bottom: 0;
  padding: 26px 18px 16px;
  background: linear-gradient(to top, rgba(8, 12, 15, .92), transparent);
}
.pp-l-player-line {
  height: 3px; background: rgba(255, 255, 255, .3); border-radius: 99px; overflow: hidden;
}
.pp-l-player-line span { display: block; width: 38%; height: 100%; background: var(--pp-primary); }
.pp-l-player-note {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  margin-top: 11px; color: rgba(255, 255, 255, .82); font-size: 12.5px;
}
.pp-l-player-btn {
  background: var(--pp-primary); color: var(--pp-on-primary);
  font-weight: 600; padding: 6px 13px; border-radius: var(--pp-radius-sm);
}

.pp-l-dots { display: flex; justify-content: center; gap: 8px; margin-top: 16px; }
.pp-l-dots button {
  width: 26px; height: 4px; border: 0; padding: 0; border-radius: 99px;
  background: var(--pp-border); cursor: pointer;
}
.pp-l-dots button.active { background: var(--pp-primary); width: 40px; }

.pp-l-trust { border-top: 1px solid var(--pp-border); background: var(--pp-surface); }
.pp-l-trust-inner {
  display: flex; align-items: center; justify-content: space-between;
  flex-wrap: wrap; gap: 16px 30px; padding-top: 22px; padding-bottom: 22px;
}
.pp-l-trust-line { margin: 0; font-size: 14.5px; color: var(--pp-muted); }
.pp-l-trust-line strong { color: var(--pp-text); }
.pp-l-pills { list-style: none; display: flex; flex-wrap: wrap; gap: 8px; padding: 0; margin: 0; }
.pp-l-pills li {
  font-size: 12.5px; font-weight: 600; color: var(--pp-muted);
  border: 1px solid var(--pp-border); border-radius: 999px; padding: 5px 13px;
}

.pp-l-band { background: var(--pp-text); color: var(--pp-surface); }
.pp-l-figures {
  display: grid; grid-template-columns: repeat(4, 1fr); gap: 22px;
  padding-top: 32px; padding-bottom: 32px; text-align: center;
}
.pp-l-figures strong { display: block; font-size: clamp(23px, 2.8vw, 32px); font-weight: 700; }
.pp-l-figures span { font-size: 13px; opacity: .72; }

.pp-l-section { padding: 74px 0; }
.pp-l-head { max-width: 62ch; margin: 0 0 26px; }
.pp-l-h2 {
  font-size: clamp(24px, 3vw, 33px); line-height: 1.18; font-weight: 700;
  margin: 0 0 12px; color: var(--pp-text);
}
.pp-l-h3 { font-size: 20px; font-weight: 600; margin: 0 0 10px; color: var(--pp-text); }
.pp-l-sub { font-size: 16px; line-height: 1.6; color: var(--pp-muted); margin: 0; }

/* Three sections' worth of reading behind three tabs, using the same component
   the dashboard uses so it is already familiar once somebody signs up. */
.pp-l-panel { overflow: hidden; }
.pp-l-panel-body { padding: 32px; }

.pp-l-steps {
  list-style: none; padding: 0; margin: 0;
  display: grid; grid-template-columns: repeat(4, 1fr); gap: 24px;
}
.pp-l-step-number {
  display: inline-flex; align-items: center; justify-content: center;
  width: 36px; height: 36px; border-radius: 50%;
  background: var(--pp-primary); color: var(--pp-on-primary);
  font-weight: 700; font-size: 15px; margin-bottom: 13px;
}
.pp-l-steps h3 { font-size: 16.5px; font-weight: 600; margin: 0 0 7px; color: var(--pp-text); }
.pp-l-steps p { font-size: 14.5px; line-height: 1.56; color: var(--pp-muted); margin: 0; }

.pp-l-reasons { display: grid; grid-template-columns: repeat(3, 1fr); gap: 26px 30px; }
.pp-l-reasons h3 { font-size: 16.5px; font-weight: 600; margin: 0 0 7px; color: var(--pp-text); }
.pp-l-reasons p { font-size: 14.5px; line-height: 1.56; color: var(--pp-muted); margin: 0; }

.pp-l-split { display: grid; grid-template-columns: 1fr 1fr; gap: 44px; align-items: center; }
.pp-l-split-image img {
  width: 100%; border-radius: var(--pp-radius);
  border: 1px solid var(--pp-border); display: block;
}
.pp-l-ticks { list-style: none; padding: 0; margin: 18px 0 24px; }
.pp-l-ticks li {
  position: relative; padding-left: 26px; margin-bottom: 10px;
  font-size: 15px; color: var(--pp-text);
}
.pp-l-ticks li::before {
  content: ""; position: absolute; left: 0; top: 6px;
  width: 13px; height: 7px; border-left: 2px solid var(--pp-primary);
  border-bottom: 2px solid var(--pp-primary); transform: rotate(-45deg);
}

.pp-l-final {
  padding: 76px 0; text-align: center;
  background: var(--pp-surface); border-top: 1px solid var(--pp-border);
}
.pp-l-final .pp-l-h2 { margin-bottom: 12px; }
.pp-l-final .pp-l-sub { max-width: 50ch; margin: 0 auto 28px; }

.pp-l-footer { border-top: 1px solid var(--pp-border); padding: 24px 0; }
.pp-l-footer-inner {
  display: flex; align-items: center; justify-content: space-between;
  flex-wrap: wrap; gap: 14px;
}
.pp-l-footer-links { display: flex; gap: 20px; }
.pp-l-footer-links a { color: var(--pp-muted); text-decoration: none; font-size: 14px; }
.pp-l-footer-links a:hover { color: var(--pp-text); }

@media (max-width: 991.98px) {
  .pp-l-hero { padding: 44px 0 52px; }
  .pp-l-hero-grid { grid-template-columns: 1fr; gap: 38px; }
  .pp-l-reasons { grid-template-columns: repeat(2, 1fr); }
  .pp-l-steps { grid-template-columns: repeat(2, 1fr); gap: 28px; }
  .pp-l-split { grid-template-columns: 1fr; gap: 30px; }
  .pp-l-figures { grid-template-columns: repeat(2, 1fr); gap: 24px; }
}

@media (max-width: 575.98px) {
  .pp-l-reasons, .pp-l-steps, .pp-l-figures { grid-template-columns: 1fr; }
  .pp-l-section, .pp-l-final { padding: 52px 0; }
  .pp-l-panel-body { padding: 22px 18px; }
  .pp-l-cta .btn { width: 100%; }
  .pp-l-reel-caption { bottom: 68px; }
  .pp-l-reel-title { font-size: 14.5px; }

  /* Two buttons and a wordmark do not fit across a phone, and the name was
     breaking in half to make room. Signing in is a link in the footer and a
     button at the end of the page, so the bar keeps the one that matters. */
  .pp-l-bar-actions .btn-pp-secondary { display: none; }
  .pp-l-brand { font-size: 16.5px; }
  .pp-l-brand span { white-space: nowrap; }
}
