/* ==========================================================================
   PhilanthropyTube — the whole visual identity.
   ==========================================================================

   Spec section 34: credible, modern, clean, social, transparent, optimistic —
   and explicitly NOT like an old nonprofit website. The reference points are a
   social video platform, Kickstarter's project clarity, and a financial
   transparency dashboard.

   Three decisions follow from that:

   1. THE CONTENT IS THE DESIGN. Warm off-white ground, the logo's navy ink, and
      the brand red held back for actions and progress. Photographs and video
      from the field carry the colour; the chrome does not compete with them. A
      charity site that decorates is a charity site that looks like it spent the
      money on decoration.

   2. MONEY IS SET IN TABULAR FIGURES. Every currency figure uses
      font-variant-numeric: tabular-nums, so digits align in a column and
      $2,140 under $320 reads as an accounting record rather than as ad copy.

   3. MOBILE FIRST, AND THE LEDGER TOO. Section 38 is explicit that financial
      tables must stay usable on a phone. They are built as rows that become
      stacked cards under 640px, not as a table with a horizontal scrollbar.
*/

/* --------------------------------------------------------------------------
   Tokens
   -------------------------------------------------------------------------- */

/* Every colour below is sampled from the logo (assets/logo-full.png) or chosen
   against it on a measured contrast ratio. The logo is a red→orange heart with
   a deep-navy wordmark, so the ground is warm off-white and the ink is the
   wordmark's own navy.

   THE ONE CONFLICT, AND HOW IT IS SETTLED. The brand is red. Red is also the
   universal colour of "error", and the logo's orange is the universal colour of
   "warning" — so a naive palette makes a Donate button and a failed payment
   look like the same thing on a page about money.

     · Saturated red/orange are reserved for BRAND: primary actions and the
       funding progress bar. They never mark state.
     · Money that is confirmed, paid or completed is TEAL — cool, complementary
       to the warm brand, and unmistakably not-brand.
     · Errors are a much darker maroon than the brand crimson, never the bright
       brand red.
     · Every badge also carries a text label, so colour is never the only
       carrier of meaning. */

:root {
  /* Ground and ink. Warm off-white, because a neutral grey under a warm logo
     reads as slightly dirty. */
  --pt-bg: #faf8f6;
  --pt-surface: #ffffff;
  --pt-surface-2: #fdfbf9;
  --pt-ink: #202838;         /* the wordmark's navy — 13.8:1 on the ground */
  --pt-ink-2: #55606f;
  --pt-ink-3: #837f86;
  --pt-line: #e9e5e1;
  --pt-line-2: #d8d2cd;

  /* BRAND. Two reds, and the difference matters:
     --pt-brand is the logo's bright red (#f04840). It is only 3.7:1 against
     white, so it may tint and it may sit in a gradient, but white text must
     NEVER be placed on it.
     --pt-accent is the crimson from the heart's shadow (#c01838) at 6.1:1 —
     that is the one that carries white text. */
  --pt-brand: #ee4038;
  --pt-brand-orange: #f8a828;
  --pt-accent: #c01838;
  --pt-accent-hover: #a20f2e;
  --pt-accent-soft: #fdeceb;
  --pt-accent-line: #f5cdc8;

  /* The heart's own gradient, for progress bars and brand moments. */
  --pt-brand-gradient: linear-gradient(90deg, #d8253c 0%, #ee4038 45%, #f8a828 100%);

  /* Status. */
  --pt-verified: #1063a8;
  --pt-verified-soft: #e7f1fa;
  --pt-warn: #8a5a00;        /* brown-amber: darker than the brand orange */
  --pt-warn-soft: #fdf3e0;
  --pt-done: #0f6b5c;        /* teal: "this money is confirmed", never brand */
  --pt-done-soft: #e4f2ef;
  --pt-danger: #7d1420;      /* clearly darker than --pt-accent */
  --pt-danger-soft: #fbe9e9;
  --pt-muted-soft: #f1eeeb;

  --pt-radius: 14px;
  --pt-radius-sm: 9px;
  --pt-radius-pill: 999px;

  --pt-shadow: 0 1px 2px rgba(20, 24, 26, .04), 0 8px 24px rgba(20, 24, 26, .06);
  --pt-shadow-lift: 0 2px 4px rgba(20, 24, 26, .05), 0 16px 40px rgba(20, 24, 26, .10);

  --pt-max: 1180px;
  --pt-gap: 20px;

  --pt-sans: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
             "Helvetica Neue", Arial, sans-serif;
}

/* --------------------------------------------------------------------------
   Reset and base
   -------------------------------------------------------------------------- */

*, *::before, *::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  background: var(--pt-bg);
  color: var(--pt-ink);
  font-family: var(--pt-sans);
  font-size: 16px;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
}

img, video { max-width: 100%; display: block; }

/* The `hidden` attribute must actually hide things.
   The browser default is `[hidden] { display: none }` at zero specificity, so
   ANY class that sets `display` beats it — and this stylesheet has several
   (.pt-btn is inline-flex, .pt-form and .pt-donate-panel are grid). Without
   this rule a `hidden` Load-more button still rendered, and the admin ledger's
   collapsed forms would sit open on page load. One rule, rather than remembering
   to write `.pt-thing[hidden]` for every component that sets a display. */
[hidden] { display: none !important; }

a { color: inherit; }

h1, h2, h3, h4 {
  margin: 0;
  line-height: 1.15;
  letter-spacing: -0.021em;
  font-weight: 660;
}

h1 { font-size: clamp(2rem, 5.2vw, 3.25rem); }
h2 { font-size: clamp(1.35rem, 3vw, 1.95rem); }
h3 { font-size: 1.12rem; }

p { margin: 0 0 1em; }
p:last-child { margin-bottom: 0; }

button { font: inherit; color: inherit; }

/* Every focusable thing gets a visible ring. Non-negotiable: a donation form
   that cannot be completed by keyboard is a donation form that excludes people. */
:focus-visible {
  outline: 2px solid var(--pt-accent);
  outline-offset: 2px;
  border-radius: 4px;
}

.pt-sr {
  position: absolute; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* --------------------------------------------------------------------------
   Layout
   -------------------------------------------------------------------------- */

.pt-wrap {
  width: 100%;
  max-width: var(--pt-max);
  margin: 0 auto;
  padding: 0 20px;
}

.pt-section { padding: 44px 0; }
.pt-section--tight { padding: 28px 0; }

.pt-section-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
  margin-bottom: 20px;
}

.pt-section-head p {
  margin: 6px 0 0;
  color: var(--pt-ink-2);
  max-width: 62ch;
}

.pt-eyebrow {
  font-size: .75rem;
  font-weight: 660;
  letter-spacing: .085em;
  text-transform: uppercase;
  color: var(--pt-ink-3);
  margin-bottom: 8px;
}

.pt-grid { display: grid; gap: var(--pt-gap); }
.pt-grid--3 { grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); }
.pt-grid--2 { grid-template-columns: repeat(auto-fill, minmax(380px, 1fr)); }
.pt-grid--4 { grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); }

/* --------------------------------------------------------------------------
   Header
   -------------------------------------------------------------------------- */

.pt-header {
  position: sticky;
  top: 0;
  z-index: 50;
  background: rgba(250, 248, 246, .9);
  backdrop-filter: saturate(1.6) blur(12px);
  border-bottom: 1px solid var(--pt-line);
}

.pt-header-inner {
  display: flex;
  align-items: center;
  gap: 18px;
  height: 62px;
}

.pt-logo {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  text-decoration: none;
  font-weight: 700;
  letter-spacing: -0.03em;
  font-size: 1.06rem;
  white-space: nowrap;
}

.pt-logo-mark {
  /* Height-driven, width auto: the heart is slightly wider than it is tall and
     forcing it square would squash it. */
  height: 30px;
  width: auto;
  flex: none;
  display: block;
}

.pt-nav {
  display: flex;
  align-items: center;
  gap: 2px;
  margin-left: 6px;
  flex: 1;
  min-width: 0;
}

.pt-nav a {
  text-decoration: none;
  color: var(--pt-ink-2);
  font-size: .93rem;
  font-weight: 520;
  padding: 7px 11px;
  border-radius: var(--pt-radius-sm);
  white-space: nowrap;
}

.pt-nav a:hover { background: var(--pt-muted-soft); color: var(--pt-ink); }
.pt-nav a[aria-current="page"] { color: var(--pt-ink); font-weight: 620; background: var(--pt-muted-soft); }

.pt-header-actions { display: flex; align-items: center; gap: 10px; margin-left: auto; }

.pt-avatar {
  width: 32px; height: 32px;
  border-radius: 50%;
  background: var(--pt-muted-soft);
  object-fit: cover;
  display: grid;
  place-items: center;
  font-size: .8rem;
  font-weight: 660;
  color: var(--pt-ink-2);
  border: 1px solid var(--pt-line);
  text-decoration: none;
  flex: none;
}

/* The nav collapses to a horizontally scrollable strip below the logo rather
   than into a hamburger. Five destinations fit; hiding them behind a menu would
   bury "Live Impact", which is the reason to come back to the site. */
@media (max-width: 860px) {
  .pt-header-inner { height: auto; flex-wrap: wrap; padding: 10px 0 0; row-gap: 4px; }
  .pt-header-actions { margin-left: auto; }
  .pt-nav {
    order: 3;
    /* `flex: none` is load-bearing. The base rule sets `flex: 1`, which is
       shorthand for `flex-basis: 0%` — and flex-basis beats `width` on the main
       axis, so the nav stayed on the logo's row and scrolled inside whatever
       space was left instead of wrapping onto its own line. */
    flex: none;
    width: 100%;
    margin: 0 -20px;
    padding: 4px 20px 8px;
    overflow-x: auto;
    scrollbar-width: none;
  }
  .pt-nav::-webkit-scrollbar { display: none; }
}

/* --------------------------------------------------------------------------
   Buttons
   -------------------------------------------------------------------------- */

.pt-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 7px;
  padding: 10px 17px;
  border-radius: var(--pt-radius-pill);
  border: 1px solid transparent;
  background: var(--pt-muted-soft);
  color: var(--pt-ink);
  font-size: .92rem;
  font-weight: 600;
  text-decoration: none;
  cursor: pointer;
  transition: background .14s ease, border-color .14s ease, transform .06s ease;
  white-space: nowrap;
}

.pt-btn:active { transform: translateY(1px); }
.pt-btn:disabled { opacity: .5; cursor: not-allowed; }

.pt-btn--primary { background: var(--pt-accent); color: #fff; }
.pt-btn--primary:hover:not(:disabled) { background: var(--pt-accent-hover); }

.pt-btn--ghost { background: transparent; border-color: var(--pt-line-2); }
.pt-btn--ghost:hover:not(:disabled) { background: var(--pt-surface); border-color: var(--pt-ink-3); }

.pt-btn--lg { padding: 13px 24px; font-size: 1rem; }
.pt-btn--sm { padding: 7px 13px; font-size: .85rem; }
.pt-btn--block { display: flex; width: 100%; }
.pt-btn--danger { background: var(--pt-danger-soft); color: var(--pt-danger); }

.pt-btn-row { display: flex; flex-wrap: wrap; gap: 10px; }

/* --------------------------------------------------------------------------
   Badges
   -------------------------------------------------------------------------- */

.pt-badge {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 3px 9px;
  border-radius: var(--pt-radius-pill);
  font-size: .74rem;
  font-weight: 640;
  letter-spacing: .015em;
  background: var(--pt-muted-soft);
  color: var(--pt-ink-2);
  white-space: nowrap;
}

.pt-badge--verified { background: var(--pt-verified-soft); color: var(--pt-verified); }
.pt-badge--impact { background: var(--pt-accent-soft); color: var(--pt-accent); }
.pt-badge--warn { background: var(--pt-warn-soft); color: var(--pt-warn); }
.pt-badge--done { background: var(--pt-done-soft); color: var(--pt-done); }
.pt-badge--draft { background: #f0eef7; color: #5a4a86; }

.pt-badge-row { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; }

/* --------------------------------------------------------------------------
   Cards
   -------------------------------------------------------------------------- */

.pt-card {
  background: var(--pt-surface);
  border: 1px solid var(--pt-line);
  border-radius: var(--pt-radius);
  overflow: hidden;
  display: flex;
  flex-direction: column;
  transition: box-shadow .16s ease, border-color .16s ease;
}

.pt-card:hover { box-shadow: var(--pt-shadow); border-color: var(--pt-line-2); }

.pt-card-media {
  position: relative;
  aspect-ratio: 16 / 9;
  background: var(--pt-muted-soft);
  overflow: hidden;
}

.pt-card-media img,
.pt-card-media video { width: 100%; height: 100%; object-fit: cover; }

.pt-card-media--empty {
  display: grid;
  place-items: center;
  color: var(--pt-ink-3);
  font-size: .8rem;
}

.pt-card-body { padding: 15px 16px 16px; display: flex; flex-direction: column; gap: 9px; flex: 1; }

.pt-card-title {
  font-size: 1.03rem;
  font-weight: 640;
  line-height: 1.3;
  letter-spacing: -0.012em;
}

.pt-card-title a { text-decoration: none; }
.pt-card-title a:hover { color: var(--pt-accent); }

.pt-card-meta {
  font-size: .84rem;
  color: var(--pt-ink-3);
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 5px;
}

.pt-card-meta .pt-dot { color: var(--pt-line-2); }

.pt-card-text { font-size: .92rem; color: var(--pt-ink-2); }

.pt-card-foot {
  margin-top: auto;
  padding-top: 12px;
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
}

/* --------------------------------------------------------------------------
   Organization identity line
   -------------------------------------------------------------------------- */

.pt-org-line {
  display: flex;
  align-items: center;
  gap: 9px;
  min-width: 0;
}

.pt-org-logo {
  width: 34px; height: 34px;
  border-radius: 9px;
  object-fit: cover;
  background: var(--pt-muted-soft);
  border: 1px solid var(--pt-line);
  flex: none;
  display: grid;
  place-items: center;
  font-weight: 700;
  font-size: .85rem;
  color: var(--pt-ink-2);
}

.pt-org-logo--lg { width: 68px; height: 68px; border-radius: 16px; font-size: 1.5rem; }

.pt-org-name {
  font-weight: 620;
  font-size: .93rem;
  display: flex;
  align-items: center;
  gap: 6px;
  min-width: 0;
}

.pt-org-name a { text-decoration: none; }
.pt-org-name a:hover { color: var(--pt-accent); }

/* --------------------------------------------------------------------------
   Progress
   -------------------------------------------------------------------------- */

.pt-progress {
  height: 7px;
  border-radius: var(--pt-radius-pill);
  background: var(--pt-muted-soft);
  overflow: hidden;
}

.pt-progress-fill {
  height: 100%;
  border-radius: inherit;
  /* Fixed-width gradient so a bar at 12% shows the RED end rather than a
     squeezed copy of the whole ramp — the colour then genuinely tracks
     progress across cards instead of every bar looking identical. */
  background: var(--pt-brand-gradient);
  background-size: 640px 100%;
  background-repeat: no-repeat;
  transition: width .5s cubic-bezier(.2, .8, .3, 1);
}

.pt-funding {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
  font-size: .88rem;
  margin-bottom: 7px;
  font-variant-numeric: tabular-nums;
}

.pt-funding-raised { font-weight: 680; }
.pt-funding-goal { color: var(--pt-ink-3); }

/* A program has no goal, so it gets a plain total and no bar — never a bar
   sitting at 0% or 100%, both of which would say something untrue. */
.pt-funding--nogoal .pt-funding-goal { display: none; }

/* --------------------------------------------------------------------------
   Feed — the card format of spec section 35
   -------------------------------------------------------------------------- */

.pt-feed { display: grid; gap: 22px; max-width: 680px; }
.pt-feed--wide { max-width: none; grid-template-columns: repeat(auto-fill, minmax(340px, 1fr)); }

.pt-post {
  background: var(--pt-surface);
  border: 1px solid var(--pt-line);
  border-radius: var(--pt-radius);
  overflow: hidden;
}

.pt-post-head {
  display: flex;
  align-items: center;
  gap: 11px;
  padding: 14px 16px;
}

.pt-post-head-text { min-width: 0; flex: 1; }

.pt-post-sub {
  font-size: .8rem;
  color: var(--pt-ink-3);
  display: flex;
  flex-wrap: wrap;
  gap: 5px;
  align-items: center;
}

.pt-post-media {
  position: relative;
  background: #0c0e0f;
  aspect-ratio: 16 / 9;
}

.pt-post-media img,
.pt-post-media video { width: 100%; height: 100%; object-fit: cover; }

/* A vertical field video from a phone is the common case, so portrait media is
   contained rather than cropped — cover would cut the top and bottom off the
   thing the update is about. */
.pt-post-media--portrait { aspect-ratio: 4 / 5; }
.pt-post-media--portrait img,
.pt-post-media--portrait video { object-fit: contain; }

.pt-post-body { padding: 14px 16px; display: grid; gap: 11px; }
.pt-post-caption { font-size: .96rem; }

.pt-post-project {
  border: 1px solid var(--pt-line);
  border-radius: var(--pt-radius-sm);
  padding: 11px 13px;
  background: var(--pt-surface-2);
  display: grid;
  gap: 8px;
}

.pt-post-project-name {
  font-size: .88rem;
  font-weight: 620;
  text-decoration: none;
}

.pt-post-project-name:hover { color: var(--pt-accent); }

.pt-post-actions {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
  padding: 0 16px 15px;
}

/* --------------------------------------------------------------------------
   Hero
   -------------------------------------------------------------------------- */

.pt-hero { padding: 52px 0 40px; }

.pt-hero-grid {
  display: grid;
  gap: 34px;
  grid-template-columns: 1fr;
  align-items: center;
}

@media (min-width: 940px) {
  .pt-hero-grid { grid-template-columns: 1.02fr .98fr; gap: 46px; }
}

.pt-hero h1 { margin-bottom: 16px; }

.pt-hero-sub {
  font-size: clamp(1.02rem, 1.9vw, 1.19rem);
  color: var(--pt-ink-2);
  max-width: 54ch;
  margin-bottom: 24px;
}

.pt-hero-media {
  border-radius: 18px;
  overflow: hidden;
  background: #0c0e0f;
  aspect-ratio: 4 / 3;
  box-shadow: var(--pt-shadow-lift);
  position: relative;
}

.pt-hero-media img,
.pt-hero-media video { width: 100%; height: 100%; object-fit: cover; }

.pt-hero-media-caption {
  position: absolute;
  left: 0; right: 0; bottom: 0;
  padding: 34px 18px 15px;
  background: linear-gradient(to top, rgba(8, 10, 11, .82), transparent);
  color: #fff;
  font-size: .87rem;
}

.pt-hero-stats {
  display: flex;
  flex-wrap: wrap;
  gap: 26px;
  margin-top: 30px;
  padding-top: 24px;
  border-top: 1px solid var(--pt-line);
}

.pt-stat-value {
  font-size: 1.55rem;
  font-weight: 690;
  letter-spacing: -0.028em;
  font-variant-numeric: tabular-nums;
}

.pt-stat-label { font-size: .8rem; color: var(--pt-ink-3); }

/* --------------------------------------------------------------------------
   Stat tiles
   -------------------------------------------------------------------------- */

.pt-tiles { display: grid; gap: 13px; grid-template-columns: repeat(auto-fit, minmax(165px, 1fr)); }

.pt-tile {
  background: var(--pt-surface);
  border: 1px solid var(--pt-line);
  border-radius: var(--pt-radius);
  padding: 15px 16px;
}

.pt-tile-label {
  font-size: .77rem;
  color: var(--pt-ink-3);
  font-weight: 560;
  margin-bottom: 5px;
}

.pt-tile-value {
  font-size: 1.42rem;
  font-weight: 690;
  letter-spacing: -0.025em;
  font-variant-numeric: tabular-nums;
}

.pt-tile-note { font-size: .78rem; color: var(--pt-ink-3); margin-top: 3px; }
.pt-tile--accent { background: var(--pt-accent-soft); border-color: var(--pt-accent-line); }

/* --------------------------------------------------------------------------
   How it works
   -------------------------------------------------------------------------- */

.pt-steps { counter-reset: ptstep; display: grid; gap: 14px; }

@media (min-width: 760px) {
  .pt-steps { grid-template-columns: repeat(3, 1fr); }
}

.pt-step {
  background: var(--pt-surface);
  border: 1px solid var(--pt-line);
  border-radius: var(--pt-radius);
  padding: 18px;
}

.pt-step::before {
  counter-increment: ptstep;
  content: counter(ptstep);
  display: grid;
  place-items: center;
  width: 27px; height: 27px;
  border-radius: 50%;
  background: var(--pt-accent-soft);
  color: var(--pt-accent);
  font-size: .82rem;
  font-weight: 700;
  margin-bottom: 11px;
}

.pt-step h3 { font-size: .99rem; margin-bottom: 5px; }
.pt-step p { font-size: .89rem; color: var(--pt-ink-2); }

/* --------------------------------------------------------------------------
   Tabs
   -------------------------------------------------------------------------- */

.pt-tabs {
  display: flex;
  gap: 3px;
  border-bottom: 1px solid var(--pt-line);
  margin-bottom: 26px;
  overflow-x: auto;
  scrollbar-width: none;
}

.pt-tabs::-webkit-scrollbar { display: none; }

.pt-tab {
  appearance: none;
  background: none;
  border: none;
  border-bottom: 2px solid transparent;
  padding: 11px 15px;
  font-size: .94rem;
  font-weight: 570;
  color: var(--pt-ink-3);
  cursor: pointer;
  white-space: nowrap;
  margin-bottom: -1px;
}

.pt-tab:hover { color: var(--pt-ink); }

.pt-tab[aria-selected="true"] {
  color: var(--pt-ink);
  border-bottom-color: var(--pt-accent);
  font-weight: 640;
}

/* --------------------------------------------------------------------------
   Filters
   -------------------------------------------------------------------------- */

.pt-filters {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
  margin-bottom: 22px;
  align-items: center;
}

.pt-chip {
  appearance: none;
  border: 1px solid var(--pt-line-2);
  background: var(--pt-surface);
  border-radius: var(--pt-radius-pill);
  padding: 6px 13px;
  font-size: .85rem;
  font-weight: 560;
  color: var(--pt-ink-2);
  cursor: pointer;
  white-space: nowrap;
}

.pt-chip:hover { border-color: var(--pt-ink-3); }

.pt-chip[aria-pressed="true"] {
  background: var(--pt-ink);
  border-color: var(--pt-ink);
  color: #fff;
}

/* --------------------------------------------------------------------------
   Financial ledger — section 38 says this must stay usable on a phone
   -------------------------------------------------------------------------- */

.pt-ledger { display: grid; gap: 1px; background: var(--pt-line); border: 1px solid var(--pt-line); border-radius: var(--pt-radius); overflow: hidden; }

.pt-ledger-row {
  display: grid;
  grid-template-columns: 108px 1fr 128px 108px;
  gap: 14px;
  align-items: center;
  padding: 13px 16px;
  background: var(--pt-surface);
  font-size: .91rem;
}

.pt-ledger-row--head {
  background: var(--pt-surface-2);
  font-size: .76rem;
  font-weight: 640;
  letter-spacing: .05em;
  text-transform: uppercase;
  color: var(--pt-ink-3);
}

.pt-ledger-date { color: var(--pt-ink-2); font-variant-numeric: tabular-nums; }
.pt-ledger-title { font-weight: 570; }
.pt-ledger-desc { font-size: .84rem; color: var(--pt-ink-3); margin-top: 2px; }
.pt-ledger-amount { font-weight: 660; text-align: right; font-variant-numeric: tabular-nums; }
.pt-ledger-status { text-align: right; }

.pt-ledger-links { display: flex; gap: 10px; flex-wrap: wrap; margin-top: 6px; font-size: .82rem; }
.pt-ledger-links a { color: var(--pt-accent); font-weight: 560; }

/* Stacked cards, NOT a horizontal scroll. A donor checking where the money went
   on a phone should not have to swipe sideways to see the amount. */
@media (max-width: 640px) {
  .pt-ledger-row {
    grid-template-columns: 1fr auto;
    gap: 4px 12px;
    padding: 14px 15px;
  }
  .pt-ledger-row--head { display: none; }
  .pt-ledger-date { grid-column: 1 / -1; font-size: .78rem; order: -1; }
  .pt-ledger-title { grid-column: 1; }
  .pt-ledger-amount { grid-column: 2; grid-row: 2; }
  .pt-ledger-status { grid-column: 1 / -1; text-align: left; margin-top: 5px; }
}

/* --------------------------------------------------------------------------
   Milestones
   -------------------------------------------------------------------------- */

.pt-milestones { display: grid; gap: 0; }

.pt-milestone {
  display: grid;
  grid-template-columns: 26px 1fr;
  gap: 14px;
  padding-bottom: 22px;
  position: relative;
}

.pt-milestone:not(:last-child)::before {
  content: "";
  position: absolute;
  left: 12px;
  top: 26px;
  bottom: 0;
  width: 1.5px;
  background: var(--pt-line);
}

.pt-milestone-dot {
  width: 25px; height: 25px;
  border-radius: 50%;
  border: 1.5px solid var(--pt-line-2);
  background: var(--pt-surface);
  display: grid;
  place-items: center;
  font-size: .7rem;
  color: var(--pt-ink-3);
  z-index: 1;
}

.pt-milestone--completed .pt-milestone-dot {
  background: var(--pt-done);
  border-color: var(--pt-done);
  color: #fff;
}

.pt-milestone--in_progress .pt-milestone-dot {
  border-color: var(--pt-brand);
  color: var(--pt-accent);
}

.pt-milestone-title { font-weight: 620; font-size: .99rem; }
.pt-milestone-meta { font-size: .82rem; color: var(--pt-ink-3); margin-top: 2px; }
.pt-milestone-desc { font-size: .9rem; color: var(--pt-ink-2); margin-top: 6px; }

/* --------------------------------------------------------------------------
   Project hero
   -------------------------------------------------------------------------- */

.pt-project-hero { display: grid; gap: 26px; padding: 30px 0 34px; }

@media (min-width: 940px) {
  .pt-project-hero { grid-template-columns: 1.35fr .65fr; gap: 38px; align-items: start; }
}

.pt-project-media {
  border-radius: var(--pt-radius);
  overflow: hidden;
  background: #0c0e0f;
  aspect-ratio: 16 / 9;
}

.pt-project-media img,
.pt-project-media video { width: 100%; height: 100%; object-fit: cover; }

/* The donate panel follows the reader down a long project page on desktop, so
   the call to action is never more than a glance away — section 38. */
.pt-donate-panel {
  background: var(--pt-surface);
  border: 1px solid var(--pt-line);
  border-radius: var(--pt-radius);
  padding: 20px;
  display: grid;
  gap: 15px;
}

@media (min-width: 940px) {
  .pt-donate-panel { position: sticky; top: 78px; }
}

.pt-donate-amounts {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 8px;
}

.pt-amount {
  appearance: none;
  border: 1.5px solid var(--pt-line-2);
  background: var(--pt-surface);
  border-radius: var(--pt-radius-sm);
  padding: 11px 4px;
  font-size: .97rem;
  font-weight: 640;
  cursor: pointer;
  font-variant-numeric: tabular-nums;
}

.pt-amount:hover { border-color: var(--pt-ink-3); }

.pt-amount[aria-pressed="true"] {
  border-color: var(--pt-accent);
  background: var(--pt-accent-soft);
  color: var(--pt-accent);
}

.pt-field { display: grid; gap: 5px; }

.pt-label { font-size: .82rem; font-weight: 600; color: var(--pt-ink-2); }

.pt-input,
.pt-select,
.pt-textarea {
  width: 100%;
  padding: 10px 12px;
  border: 1px solid var(--pt-line-2);
  border-radius: var(--pt-radius-sm);
  background: var(--pt-surface);
  font: inherit;
  font-size: .94rem;
  color: var(--pt-ink);
}

.pt-input:focus,
.pt-select:focus,
.pt-textarea:focus {
  outline: none;
  border-color: var(--pt-accent);
  box-shadow: 0 0 0 3px var(--pt-accent-soft);
}

.pt-textarea { min-height: 100px; resize: vertical; line-height: 1.5; }

.pt-check { display: flex; align-items: flex-start; gap: 9px; font-size: .88rem; color: var(--pt-ink-2); }
.pt-check input { margin-top: 3px; flex: none; }

.pt-help { font-size: .8rem; color: var(--pt-ink-3); }

/* --------------------------------------------------------------------------
   Notices
   -------------------------------------------------------------------------- */

.pt-note {
  border-radius: var(--pt-radius-sm);
  padding: 12px 14px;
  font-size: .88rem;
  border: 1px solid var(--pt-line);
  background: var(--pt-surface-2);
  color: var(--pt-ink-2);
}

/* Errors lean on a heavy left rule as well as colour, because on a red-branded
   page hue alone no longer distinguishes "failed" from "primary action". */
.pt-note--error {
  background: var(--pt-danger-soft);
  border-color: #eec4c4;
  border-left: 4px solid var(--pt-danger);
  color: var(--pt-danger);
}
.pt-note--ok { background: var(--pt-done-soft); border-color: #bfded8; color: var(--pt-done); }
.pt-note--warn { background: var(--pt-warn-soft); border-color: #eddcb8; color: var(--pt-warn); }
.pt-note[hidden] { display: none; }

.pt-empty {
  text-align: center;
  padding: 52px 20px;
  color: var(--pt-ink-3);
  border: 1px dashed var(--pt-line-2);
  border-radius: var(--pt-radius);
  background: var(--pt-surface-2);
}

.pt-empty h3 { color: var(--pt-ink-2); margin-bottom: 6px; font-size: 1rem; }
.pt-empty p { font-size: .9rem; margin: 0; }

/* Skeletons. A charitable-giving page that pops numbers in with no warning
   looks like the numbers changed; a placeholder that is obviously a placeholder
   does not. */
.pt-skeleton {
  background: linear-gradient(90deg, var(--pt-muted-soft) 25%, #f6f6f3 37%, var(--pt-muted-soft) 63%);
  background-size: 400% 100%;
  animation: pt-shimmer 1.3s ease-in-out infinite;
  border-radius: var(--pt-radius-sm);
}

@keyframes pt-shimmer {
  0% { background-position: 100% 50%; }
  100% { background-position: 0 50%; }
}

@media (prefers-reduced-motion: reduce) {
  .pt-skeleton { animation: none; }
  .pt-progress-fill { transition: none; }
}

/* --------------------------------------------------------------------------
   Prose
   -------------------------------------------------------------------------- */

.pt-prose { max-width: 68ch; }
.pt-prose p { margin-bottom: .95em; color: var(--pt-ink-2); }
.pt-prose h3 { margin: 1.6em 0 .5em; font-size: 1.05rem; color: var(--pt-ink); }
.pt-prose h3:first-child { margin-top: 0; }

/* --------------------------------------------------------------------------
   Footer
   -------------------------------------------------------------------------- */

.pt-footer {
  margin-top: 56px;
  border-top: 1px solid var(--pt-line);
  padding: 34px 0 44px;
  font-size: .87rem;
  color: var(--pt-ink-3);
}

.pt-footer-grid { display: flex; flex-wrap: wrap; gap: 26px; justify-content: space-between; }
.pt-footer a { color: var(--pt-ink-2); text-decoration: none; }
.pt-footer a:hover { color: var(--pt-accent); }
.pt-footer-links { display: flex; flex-wrap: wrap; gap: 16px; }

.pt-footer-legal { margin-top: 20px; max-width: 76ch; font-size: .8rem; line-height: 1.6; }

/* --------------------------------------------------------------------------
   Admin
   -------------------------------------------------------------------------- */

.pt-admin { display: grid; grid-template-columns: 1fr; gap: 24px; padding: 24px 0 60px; }

@media (min-width: 900px) {
  .pt-admin { grid-template-columns: 218px 1fr; gap: 32px; align-items: start; }
}

.pt-admin-side { display: grid; gap: 18px; }

@media (min-width: 900px) {
  .pt-admin-side { position: sticky; top: 78px; }
}

.pt-admin-nav { display: grid; gap: 1px; }

.pt-admin-nav a {
  padding: 8px 11px;
  border-radius: var(--pt-radius-sm);
  text-decoration: none;
  font-size: .91rem;
  color: var(--pt-ink-2);
  font-weight: 540;
}

.pt-admin-nav a:hover { background: var(--pt-muted-soft); color: var(--pt-ink); }
.pt-admin-nav a[aria-current="page"] { background: var(--pt-ink); color: #fff; font-weight: 600; }

/* The organization switcher — spec section 19. Deliberately the most prominent
   thing in the admin sidebar: everything below it is filtered by what it says,
   and an admin who forgets which organization they are posting as will publish
   Congo & Beyond's video on Refuge Ministries' channel. */
.pt-org-switch {
  background: var(--pt-surface);
  border: 1px solid var(--pt-line-2);
  border-radius: var(--pt-radius);
  padding: 12px 13px;
  display: grid;
  gap: 7px;
}

.pt-org-switch-label {
  font-size: .71rem;
  text-transform: uppercase;
  letter-spacing: .085em;
  font-weight: 660;
  color: var(--pt-ink-3);
}

.pt-admin-main { min-width: 0; display: grid; gap: 24px; }

.pt-panel {
  background: var(--pt-surface);
  border: 1px solid var(--pt-line);
  border-radius: var(--pt-radius);
  padding: 20px;
}

.pt-panel-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
  flex-wrap: wrap;
  margin-bottom: 16px;
}

.pt-panel-head h2 { font-size: 1.12rem; }

.pt-form { display: grid; gap: 15px; }
.pt-form-row { display: grid; gap: 15px; }

@media (min-width: 700px) {
  .pt-form-row--2 { grid-template-columns: 1fr 1fr; }
  .pt-form-row--3 { grid-template-columns: 1fr 1fr 1fr; }
}

.pt-list { display: grid; gap: 9px; }

.pt-list-item {
  display: flex;
  align-items: center;
  gap: 13px;
  padding: 12px 14px;
  border: 1px solid var(--pt-line);
  border-radius: var(--pt-radius-sm);
  background: var(--pt-surface);
  flex-wrap: wrap;
}

.pt-list-item-main { flex: 1; min-width: 190px; }
.pt-list-item-title { font-weight: 600; font-size: .95rem; }
.pt-list-item-sub { font-size: .82rem; color: var(--pt-ink-3); margin-top: 2px; }
.pt-list-item-actions { display: flex; gap: 7px; flex-wrap: wrap; }

/* --------------------------------------------------------------------------
   Utilities
   -------------------------------------------------------------------------- */

.pt-muted { color: var(--pt-ink-3); }
.pt-nowrap { white-space: nowrap; }
.pt-num { font-variant-numeric: tabular-nums; }
.pt-hidden { display: none !important; }
.pt-mt { margin-top: 16px; }
.pt-mb { margin-bottom: 16px; }
.pt-center { text-align: center; }
