/* /content/fundraise/ — the playbook as a working checklist.
 *
 * Every bullet in the document becomes a checkbox, a floating dock keeps the
 * count, and the page takes on each phase's accent colour as you scroll —
 * the same idea as the "How We Work" rail on /clients/, applied to a document
 * instead of a card stack.
 *
 * Progressive enhancement: fundraise-track.js injects the checkbox controls and
 * the .ft-on flag on <html>. Without scripting the page stays exactly the
 * document it was, so nothing here may hide content behind the .ft-on flag.
 */

/* A custom property only animates if it is registered, so the accent crossfade
   below is dead without this. */
@property --ft-accent {
  syntax: '<color>';
  inherits: true;
  initial-value: #35D0EE;
}

/* ---------- phase accents ----------
   Indigo is too dark to read as an accent on this background, so phase 3 uses
   the lit variant, matching the LIT map in clients/process-scroller.js. */
.fundraise-page {
  --ft-accent: var(--fundraise-cyan);
  --ft-accent-ink: var(--fundraise-dark);
}
.fundraise-page[data-ft-phase="1"] { --ft-accent: #35D0EE; }
.fundraise-page[data-ft-phase="2"] { --ft-accent: #F45FC0; }
.fundraise-page[data-ft-phase="3"] { --ft-accent: #8878FF; }
.fundraise-page[data-ft-phase="4"] { --ft-accent: #FFB627; }
.fundraise-page[data-ft-phase="5"] { --ft-accent: #3EE08F; }

/* The accent crossfade is the visible signal that you have moved between
   phases, so it is slower than a hover transition and eased to a stop. */
.fundraise-page {
  transition: --ft-accent .7s ease;
}

/* ---------- sticky mobile phase bar ----------
   Mirrors the compact /clients/ progress bar. It lives inside the document so
   it naturally releases before the contact CTA and footer arrive. */
.ft-sectionbar { display: none; }
.ft-sectionbar[hidden] { display: none !important; }

/* ---------- scroll-driven scene ----------
   A single fixed layer behind everything. Tinting one element avoids
   repainting the document on every phase change. */
.ft-scene {
  position: fixed;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  /* Solid first, so a browser without color-mix still paints the page ground
     rather than dropping the whole declaration and showing nothing. */
  background: var(--fundraise-dark);
  background:
    radial-gradient(120% 90% at 82% -10%, color-mix(in srgb, var(--ft-accent) 26%, transparent), transparent 62%),
    radial-gradient(90% 70% at -10% 105%, color-mix(in srgb, var(--ft-accent) 16%, transparent), transparent 58%);
  transition: background .8s ease, opacity .5s ease;
}
.ft-scene::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, transparent 55%, rgba(10,16,24,.75));
}
/* The header is deliberately absent here. It is already `position: fixed` with
   z-index 1000 in site-header.css, so it clears .ft-scene (z-index 0) without
   help — and forcing `position: relative` on it un-fixed the site header on this
   page alone. Worse, .site-header's backdrop-filter makes it a containing block
   for fixed descendants, so the mobile nav drawer was then positioned against
   the header box instead of the viewport and came out 16px narrow. */
.fundraise-page main,
.fundraise-page .site-contact-cta,
.fundraise-page .site-footer { position: relative; z-index: 1; }

/* The hero owns its own gradient; let the scene read through it so the accent
   is visible from the first scroll rather than appearing abruptly. */
.fundraise-page .fundraise-hero { background: linear-gradient(145deg, rgba(7,16,29,.92), rgba(13,27,46,.86) 68%, rgba(8,17,30,.92)); }

/* ---------- ambient floaties ----------
   Unified float standard (see /brandkit/#float): 4px, 8s, paused on hover and
   keyboard focus. */
/* Deliberately NOT clipped: the shapes live in the page gutters beside the
   760px reading column. Clipping them here is what turned them into stray arcs
   pinned to the text edge. */
.ft-floaties {
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
}
/* Below this width the reading column fills the viewport, so there is no gutter
   to float in. Rather than dropping the flourish entirely on phones, the shapes
   move behind the prose and drop to a texture-level opacity — content already
   sits at z-index 1 above them. */
@media (max-width: 1180px) {
  .ft-floaty { opacity: .13 !important; }
  .ft-floaty--ring { left: auto !important; right: -18px !important; }
  .ft-floaty--square { right: auto !important; left: -14px !important; }
  .ft-floaty--bar { left: auto !important; right: -20px !important; }
  .ft-floaty--dot { right: 8% !important; }
}
.ft-floaty {
  --float-distance: 4px;
  --float-duration: 8s;
  filter: drop-shadow(0 0 14px color-mix(in srgb, var(--ft-accent) 40%, transparent));
  position: absolute;
  display: block;
  animation: unifiedFloat var(--float-duration) ease-in-out infinite;
  animation-delay: var(--ft-delay, 0s);
  opacity: .62;
}
@keyframes unifiedFloat {
  0%, 100% { transform: translateY(0); }
  50% { transform: translateY(calc(var(--float-distance) * -1)); }
}
.ft-floaty--ring {
  width: var(--ft-size, 64px);
  height: var(--ft-size, 64px);
  border: 3px solid var(--ft-accent);
  border-radius: 50%;
}
.ft-floaty--square {
  width: var(--ft-size, 46px);
  height: var(--ft-size, 46px);
  background: var(--ft-accent);
  box-shadow: 6px 6px 0 var(--fundraise-indigo);
  opacity: .34;
}
.ft-floaty--bar {
  width: var(--ft-size, 84px);
  height: 8px;
  background: var(--ft-accent);
  opacity: .4;
}
.ft-floaty--dot {
  width: var(--ft-size, 14px);
  height: var(--ft-size, 14px);
  border-radius: 50%;
  background: var(--fundraise-gold);
}
.playbook-phase { position: relative; }
/* Must exclude the floaty layer, which needs to stay absolutely positioned. */
.playbook-phase > *:not(.ft-floaties) { position: relative; z-index: 1; }

/* ---------- checkboxes ----------
   Every bullet gets one. Parent bullets that own sub-bullets act as group
   toggles and show an indeterminate dash until their children are all done. */
.ft-on .task-list,
.ft-on .subtasks { list-style: none; }
.ft-on .task-list { padding-left: 0; }
.ft-on .subtasks { padding-left: .35rem; }

.ft-on .ft-item {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  gap: 0 12px;
  align-items: start;
}
.ft-on .ft-item > .ft-content { min-width: 0; }

.ft-box {
  flex: 0 0 auto;
  width: 21px;
  height: 21px;
  margin: 0;
  padding: 0;
  position: relative;
  display: grid;
  place-items: center;
  appearance: none;
  cursor: pointer;
  background: rgba(255,255,255,.04);
  border: 2px solid rgba(255,255,255,.34);
  transition: background .18s ease, border-color .18s ease, box-shadow .18s ease;
}
.ft-box--sub { width: 17px; height: 17px; margin-top: 4px; }
.ft-box:hover { border-color: var(--ft-accent); }
.ft-box:focus-visible { outline: 2px solid var(--ft-accent); outline-offset: 3px; }
.ft-box::after {
  content: "";
  width: 10px;
  height: 6px;
  border-left: 3px solid var(--ft-accent-ink);
  border-bottom: 3px solid var(--ft-accent-ink);
  transform: rotate(-45deg) scale(.4);
  opacity: 0;
  transition: opacity .16s ease, transform .16s cubic-bezier(.2,.9,.3,1.4);
}
.ft-box--sub::after { width: 8px; height: 5px; border-width: 2px; }
.ft-box:checked {
  background: var(--ft-accent);
  border-color: var(--ft-accent);
  box-shadow: 3px 3px 0 var(--fundraise-indigo);
}
.ft-box:checked::after { opacity: 1; transform: rotate(-45deg) scale(1); }
.ft-box:indeterminate { background: transparent; border-color: var(--ft-accent); }
.ft-box:indeterminate::after {
  width: 9px;
  height: 0;
  border-left: 0;
  border-bottom: 3px solid var(--ft-accent);
  transform: none;
  opacity: 1;
}

/* Parent rows are summaries, not bulk-toggle checkboxes. Their circle fills as
   child checklist items are completed and only shows a check at 100%. */
.ft-group-progress {
  position: relative;
  width: 23px;
  height: 23px;
  display: grid;
  place-items: center;
  flex: 0 0 auto;
  color: var(--ft-accent);
}
.ft-group-progress svg { width: 100%; height: 100%; transform: rotate(-90deg); }
.ft-group-progress circle { fill: none; stroke-width: 2.5; }
.ft-group-progress__track { stroke: rgba(255,255,255,.2); }
.ft-group-progress__value { stroke: currentColor; stroke-linecap: round; transition: stroke-dashoffset .35s cubic-bezier(.2,.8,.2,1), stroke .5s ease; }
.ft-group-progress__check { position: absolute; inset: 0; display: grid; place-items: center; color: var(--ft-accent-ink); font: 900 12px/1 Inter,sans-serif; opacity: 0; transform: scale(.6); transition: opacity .18s ease, transform .18s ease; }
.ft-group-progress.is-complete { border-radius: 50%; background: var(--ft-accent); }
.ft-group-progress.is-complete svg { opacity: 0; }
.ft-group-progress.is-complete .ft-group-progress__check { opacity: 1; transform: scale(1); }
.ft-on .ft-item--group > .ft-content { cursor: default; }

/* Completed bullets recede but stay readable — this is a working document, not
   a to-do app, and the text still has to be re-readable after ticking. */
.ft-on .ft-item.is-done > .ft-content { color: var(--fundraise-muted); }
.ft-on .ft-item.is-done > .ft-content .task-title,
.ft-on .ft-item.is-done > .ft-content strong { color: rgba(255,255,255,.62); }
.ft-content { transition: color .2s ease; }
.ft-on .ft-item > .ft-content { cursor: pointer; }
.ft-on .ft-item > .ft-content a { cursor: pointer; }

/* Reading cards carry no checkbox since #107, so they need no checkbox column
   and no gutter compensation for one. The rules that paid for it are gone. */

/* ---------- phase completion cue ---------- */
.ft-on .phase-header h2::before { background: var(--ft-accent); box-shadow: 5px 0 0 var(--fundraise-magenta); transition: background .5s ease; }
.ft-phase-meter {
  display: flex;
  align-items: center;
  gap: 12px;
  margin: -14px 0 30px;
  font: 800 11px/1 Inter, sans-serif;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--fundraise-muted);
}
.ft-phase-meter__track { flex: 1 1 auto; max-width: 260px; height: 4px; background: rgba(255,255,255,.12); }
.ft-phase-meter__fill { display: block; height: 100%; width: 0; background: var(--ft-accent); transition: width .45s cubic-bezier(.2,.8,.2,1); }
.ft-phase-meter.is-complete { color: var(--ft-accent); }

/* The checkbox column costs the prose ~30px of measure. On phones that is
   enough to strand a last word, so the gutter tightens rather than the text
   being bound with &nbsp; everywhere (see scripts/check-orphan-words.js). */
@media (max-width: 760px) {
  .ft-on .ft-item { gap: 0 9px; }
  .ft-on .subtasks { padding-left: 0; }
  .ft-box { width: 19px; height: 19px; }
  .ft-box--sub { width: 16px; height: 16px; }
  .ft-group-progress { width: 21px; height: 21px; }
}

/* The card title is a <span>, so site-typography.css's `li { text-wrap: pretty }`
   never reaches it and its last word strands. Balancing the lines clears the
   orphan without an &nbsp; pair, which at 320px overflowed the card by 12px. */
.resource-title { text-wrap: balance; }


/* ---------- floating dock ---------- */
.ft-dock {
  position: fixed;
  right: 26px;
  bottom: 26px;
  z-index: 40;
  display: flex;
  align-items: center;
  gap: 18px;
  padding: 14px 20px 14px 16px;
  color: #fff;
  background: rgba(10,16,24,.93);
  border: 1px solid var(--fundraise-line);
  box-shadow: 8px 8px 0 var(--ft-accent);
  backdrop-filter: blur(8px);
  transition: transform .4s cubic-bezier(.2,.8,.2,1), opacity .3s ease, box-shadow .6s ease;
}
.ft-dock[hidden] { display: none; }
/* Tucked away once the footer is in view, so it never covers the contact CTA. */
.ft-dock.is-tucked { transform: translateY(140%); opacity: 0; pointer-events: none; }

.ft-dock__ring { position: relative; flex: 0 0 auto; width: 52px; height: 52px; }
.ft-dock__ring svg { width: 100%; height: 100%; transform: rotate(-90deg); }
.ft-dock__ring circle { fill: none; stroke-width: 5; }
.ft-dock__track { stroke: rgba(255,255,255,.16); }
.ft-dock__value { stroke: var(--ft-accent); stroke-linecap: butt; transition: stroke-dashoffset .5s cubic-bezier(.2,.8,.2,1), stroke .6s ease; }
.ft-dock__pct {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  font: 800 13px/1 Inter, sans-serif;
}

.ft-dock__meta { display: flex; flex-direction: column; gap: 4px; }
.ft-dock__count { font: 800 15px/1 Inter, sans-serif; }
.ft-dock__count b { color: var(--ft-accent); font-size: 19px; }
.ft-dock__label { font: 700 9px/1 Inter, sans-serif; letter-spacing: .16em; text-transform: uppercase; color: var(--fundraise-muted); }

.ft-dock__pips { display: flex; gap: 5px; margin: 0; padding: 0; list-style: none; }
.ft-dock__pip {
  width: 26px;
  height: 26px;
  display: grid;
  place-items: center;
  padding: 0;
  color: rgba(255,255,255,.55);
  background: rgba(255,255,255,.07);
  border: 1px solid transparent;
  font: 800 10px/1 Inter, sans-serif;
  cursor: pointer;
  transition: color .2s ease, background .2s ease, border-color .2s ease;
}
.ft-dock__pip:hover { color: #fff; background: rgba(255,255,255,.16); }
.ft-dock__pip:focus-visible { outline: 2px solid var(--ft-accent); outline-offset: 2px; }
.ft-dock__pip.is-current { color: var(--ft-accent-ink); background: var(--ft-accent); }
.ft-dock__pip.is-complete::after { content: "✓"; }
.ft-dock__pip.is-complete { color: var(--fundraise-green); border-color: var(--fundraise-green); }
.ft-dock__pip.is-complete.is-current { color: var(--ft-accent-ink); }
.ft-dock__pip span { pointer-events: none; }
.ft-dock__pip.is-complete span { display: none; }

.ft-dock__reset {
  padding: 7px 10px;
  color: var(--fundraise-muted);
  background: none;
  border: 1px solid var(--fundraise-line);
  font: 800 9px/1 Inter, sans-serif;
  letter-spacing: .12em;
  text-transform: uppercase;
  cursor: pointer;
  transition: color .2s ease, border-color .2s ease;
}
.ft-dock__reset:hover { color: #fff; border-color: var(--ft-accent); }
.ft-dock__reset:focus-visible { outline: 2px solid var(--ft-accent); outline-offset: 2px; }

.ft-dock__done { display: none; color: var(--fundraise-green); font: 800 11px/1 Inter, sans-serif; letter-spacing: .12em; text-transform: uppercase; }
.ft-dock.is-complete .ft-dock__done { display: block; }

@media (max-width: 860px) {
  .ft-dock { display: none !important; }
  .ft-on .document-layout { padding-bottom: 88px; }
}

@media (max-width: 900px) {
  .ft-sectionbar {
    position: sticky;
    top: 76px;
    z-index: 8;
    display: flex;
    flex-direction: column;
    gap: 9px;
    margin: 0 -8px 30px;
    padding: 12px 14px 13px;
    color: #fff;
    background: rgba(10,16,24,.95);
    border-top: 1px solid rgba(255,255,255,.14);
    border-bottom: 1px solid rgba(255,255,255,.14);
    backdrop-filter: blur(16px);
    box-shadow: 0 5px 18px rgba(0,0,0,.22);
  }
  .ft-sectionbar__head { display: flex; align-items: baseline; gap: 10px; min-width: 0; }
  .ft-sectionbar__num { flex: 0 0 auto; color: var(--ft-accent); font: 400 30px/1 'Bakbak One',sans-serif; transition: color .5s ease; }
  .ft-sectionbar__title { min-width: 0; overflow: hidden; color: #fff; font: 800 12px/1.2 Inter,sans-serif; letter-spacing: .025em; text-overflow: ellipsis; text-transform: uppercase; white-space: nowrap; }
  .ft-sectionbar__segments { display: flex; gap: 5px; }
  .ft-sectionbar__segments button { flex: 1 1 0; height: 4px; min-width: 0; padding: 0; appearance: none; cursor: pointer; background: rgba(255,255,255,.18); border: 0; transition: background .3s ease, transform .3s ease, opacity .3s ease; }
  .ft-sectionbar__segments button.is-past { background: var(--ft-segment); opacity: .62; }
  .ft-sectionbar__segments button.is-current { background: var(--ft-segment); opacity: 1; transform: scaleY(1.5); }
  .ft-sectionbar__segments button:focus-visible { outline: 2px solid var(--ft-segment); outline-offset: 3px; }
  .playbook-phase { scroll-margin-top: 158px; }
}

/* Ambient motion is decorative; a reader who asks for less should get less.
   (The rest of this site neutralises its reduced-motion blocks with an
   impossible min-width, per #48 — that decision was about the homepage hero
   canvas, so it is not carried into this page's new ambient motion.) */
@media (prefers-reduced-motion: reduce) {
  .ft-floaty { animation: none !important; }
  .ft-scene,
  .ft-dock,
  .ft-dock__value,
  .ft-phase-meter__fill,
  .ft-group-progress__value,
  .ft-group-progress__check,
  .ft-box,
  .ft-box::after { transition: none !important; }
}
.ft-floaty:is(:hover, :focus-visible) { animation-play-state: paused; }

@media print {
  .ft-dock, .ft-scene, .ft-floaties { display: none !important; }
  .ft-box { appearance: none; width: 14px; height: 14px; border: 1.5px solid #444; background: #fff; }
  .ft-box:checked { background: #fff; }
  .ft-box:checked::after { border-color: #111; opacity: 1; }
  .ft-phase-meter { display: none; }
  .ft-on .ft-item.is-done > .ft-content { color: #333; }
}
