/* draft-surface.css — extracted from draft.html 2026-07-30 so the SAME surface can be
 * mounted inside the slide-out sheet on grant pages.
 *
 * ⚠ Tokens are scoped to `.ds-scope`, NOT `:root`. This file now loads on ~690 grant
 * pages that define their own --forest/--sienna/--cream; a :root block here would
 * silently restyle every one of them. Put `.ds-scope` on whatever element wraps the
 * surface (draft.html puts it on <body>; the sheet puts it on the panel).
 * The `*`, `html` and `body` rules deliberately stayed inline on draft.html. */
/* Design tokens defined LOCALLY — this page must survive without homepage-v7.css.
   Palette + type per .impeccable.md (warm editorial, light mode only). */
.ds-scope{
  --paper:#FFFDF9; --cream:#FAF7F2; --cream-dk:#F1EBE1;
  --ink:#1C1917; --ink-60:#5C5550; --ink-40:#8B837C;
  --forest:#2D6A4F; --forest-dk:#1B4332; --forest-lt:#D8F3DC;
  --sienna:#C4532B; --sienna-dk:#A3401F;
  --gold:#B8860B; --gold-lt:#FEF3C7;
  --line:rgba(28,25,23,.12); --line-soft:rgba(28,25,23,.07);
  --serif:'Fraunces',Georgia,serif; --sans:'DM Sans',system-ui,sans-serif; --mono:'IBM Plex Mono',monospace;
}



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

/* ⚠ THE EXTRACTION BUG (2026-07-30). draft.html styled this content through
   `body{font-family:var(--sans);line-height:1.6;color:var(--ink)}`, which stayed inline on
   that page when the tokens moved here. On a grant page nothing then set a font at all:
   <body> there resolves `var(--sans)` against a token it does not define, so the
   declaration is invalid at computed-value time and the whole sheet fell back to TIMES
   beside a site running DM Sans. Whatever carries `.ds-scope` must carry the typography
   too — the tokens and the rule that consumes them cannot live on different surfaces. */
.ds-scope{font-family:var(--sans);line-height:1.6;color:var(--ink);-webkit-font-smoothing:antialiased}
.ds-scope h1,.ds-scope h2,.ds-scope h3{color:var(--ink)}

.ds{max-width:1080px;margin:0 auto;padding:clamp(26px,5vw,60px) clamp(16px,4vw,40px) 80px}
.ds-head{border-bottom:1px solid var(--line);padding-bottom:20px;margin-bottom:clamp(20px,3vw,32px)}
.ds-kicker{font-family:var(--mono);font-size:11px;letter-spacing:.12em;text-transform:uppercase;color:var(--forest);margin:0 0 10px}
.ds-title{font-family:var(--serif);font-weight:600;font-size:clamp(25px,3.6vw,40px);line-height:1.1;letter-spacing:-.02em;margin:0;max-width:22ch}

.ds-grid{display:grid;grid-template-columns:1fr;gap:clamp(20px,3vw,34px)}
@media(min-width:900px){.ds-grid{grid-template-columns:minmax(0,1fr) 320px;align-items:start}}
.ds-main{min-width:0}

/* progress — denominator is the APPLICATION, never the free section */
.ds-prog{margin-bottom:18px}
.ds-prog-top{display:flex;justify-content:space-between;align-items:baseline;gap:12px;margin-bottom:8px;flex-wrap:wrap}
.ds-prog-label{font-size:14.5px;font-weight:500}
.ds-prog-count{font-family:var(--mono);font-size:11.5px;color:var(--ink-40);letter-spacing:.04em}
.ds-meter{height:5px;border-radius:3px;background:var(--cream-dk);overflow:hidden}
.ds-meter i{display:block;height:100%;background:var(--forest);border-radius:3px;transition:width .32s cubic-bezier(.22,1,.36,1)}

.ds-doc{background:var(--paper);border:1px solid var(--line);border-radius:14px;padding:clamp(20px,3vw,32px)}
.ds-sec-title{font-family:var(--serif);font-size:clamp(18px,2.2vw,22px);font-weight:600;letter-spacing:-.012em;margin:0 0 14px}
.ds-prose p{margin:0 0 14px;font-size:16px;line-height:1.75;color:#2E2A26}
.ds-prose p:last-child{margin-bottom:0}

/* tokens — the trust claim made visible.
   ⚠ These are drawn as EMPTY FIELDS, not as tinted words. Tinted words are indistinguishable
   from emphasis when you are scanning a paragraph, and real model output on 2026-07-30 read as
   "...for vulnerable children your target." — grammatically broken prose rather than a gap to
   fill. A dashed field with a pencil is the one convention no reader has to be taught.
   `display:inline` + box-decoration-break:clone so a long label wraps across lines like text
   instead of forcing its own box wider than the column (an inline-flex chip cannot wrap and
   overflows at 320px). */
.ds-tok{display:inline;font:inherit;cursor:pointer;padding:1px 7px;border-radius:6px;
  line-height:inherit;text-align:left;
  -webkit-box-decoration-break:clone;box-decoration-break:clone;
  transition:background .16s ease,border-color .16s ease}
.ds-tok-ico{display:inline-block;width:11px;height:11px;margin-right:5px;vertical-align:-1px;opacity:.85}
.ds-tok-ico svg{width:100%;height:100%;display:block}
.ds-tok-lab{font-style:italic}
.ds-tok--fill{background:rgba(196,83,43,.07);color:var(--sienna-dk);border:1.5px dashed rgba(196,83,43,.55)}
.ds-tok--fill:hover{background:rgba(196,83,43,.15);border-color:var(--sienna)}
.ds-tok--confirm{background:rgba(184,134,11,.09);color:#7A5A08;border:1.5px dashed rgba(184,134,11,.55)}
.ds-tok--confirm:hover{background:var(--gold-lt);border-color:var(--gold)}
.ds-tok:focus-visible{outline:2px solid var(--forest);outline-offset:2px}
/* A FILLED blank keeps a field treatment, in a different grammar from an empty one: SOLID
   hairline (dashed means "not answered"), tinted forest (this is settled, not outstanding), no
   pencil icon, upright text. It says "your answer, placed here, not yet written in" — which is
   the truth until the weave runs, and it is the only thing standing between a founder's phrase
   and a model's sentence colliding into broken English. Still a button: an answer they can see
   is an answer they must be able to change. */
.ds-tok--filled{display:inline;background:rgba(45,106,79,.08);color:var(--ink);
  border:1px solid rgba(45,106,79,.3);padding:1px 6px;border-radius:6px}
.ds-tok--filled:hover{background:rgba(45,106,79,.15);border-color:rgba(45,106,79,.6)}
.ds-tok-val{font-style:normal}

.ds-trust{margin:16px 0 0;font-size:14px;color:var(--ink-60);background:rgba(45,106,79,.06);
  border-left:3px solid var(--forest);border-radius:0 9px 9px 0;padding:13px 16px}
.ds-trust b{color:var(--forest-dk);font-weight:500}

/* masthead */
.ds-mast{display:flex;align-items:center;justify-content:space-between;gap:16px;
  max-width:1080px;margin:0 auto;padding:16px clamp(16px,4vw,40px) 0}
.ds-mast-brand{display:inline-flex;align-items:center;gap:8px;color:var(--forest-dk);
  text-decoration:none;font-family:var(--serif);font-weight:600;font-size:17px;letter-spacing:-.01em}
.ds-mast-brand:hover{color:var(--sienna-dk)}
.ds-mast-mark{width:20px;height:20px;flex:0 0 auto}
.ds-mast-mark svg{width:100%;height:100%;display:block}
.ds-mast-back{color:var(--ink-60);text-decoration:none;font-size:13.5px;
  padding:8px 4px;border-radius:6px}
.ds-mast-back:hover{color:var(--forest-dk);text-decoration:underline;text-underline-offset:3px}

/* the section map — one place that answers "how much is left" */
.ds-map{background:var(--paper);border:1px solid var(--line-soft);border-radius:13px;
  padding:16px 18px;margin-bottom:14px}
.ds-map-h{font-family:var(--mono);font-size:10.5px;letter-spacing:.1em;text-transform:uppercase;
  color:var(--ink-40);margin:0 0 12px;font-weight:500}
.ds-map-list{list-style:none;margin:0;padding:0}
.ds-map-row{display:flex;gap:11px;align-items:flex-start;padding:9px 0;border-top:1px solid var(--line-soft)}
.ds-map-row:first-child{border-top:0;padding-top:0}
.ds-map-ico{width:15px;height:15px;color:var(--ink-40);flex:0 0 auto;margin-top:3px}
.ds-map-ico svg{width:100%;height:100%;display:block}
.ds-map-row--now .ds-map-ico{color:var(--forest)}
.ds-map-t{margin:0;font-size:14.5px;font-weight:500;line-height:1.35}
.ds-map-row--now .ds-map-t{color:var(--forest-dk)}
.ds-map-s{margin:2px 0 0;font-size:12.5px;color:var(--ink-60);line-height:1.45}
.ds-map-row--now .ds-map-s{color:var(--forest);font-weight:500}

/* the ask rail */
.ds-rail{position:relative}
@media(min-width:900px){.ds-rail{position:sticky;top:24px}}
.ds-ask{background:var(--paper);border:1px solid rgba(196,83,43,.3);border-radius:13px;padding:20px}
.ds-ask--premium{border-color:rgba(45,106,79,.4);background:linear-gradient(180deg,rgba(216,243,220,.4),var(--paper) 55%)}
.ds-ask--quiet{border-color:var(--line-soft);background:transparent}
.ds-ask-k{font-family:var(--mono);font-size:10.5px;letter-spacing:.1em;text-transform:uppercase;color:var(--forest);margin:0 0 9px}
.ds-ask-h{font-family:var(--serif);font-size:20px;font-weight:600;letter-spacing:-.014em;margin:0 0 8px;line-height:1.22}
.ds-ask-p{font-size:14px;color:var(--ink-60);margin:0 0 15px}

/* ⚠ `text-decoration:none` belongs on the CLASS, not on an inline style on whichever <a>
   happened to exist when it was written. The premium-member CTA is an <a class="ds-btn"> and
   shipped underlined, because the one anchor that already used this class carried the fix
   inline. Any future anchor button would have inherited the same defect. */
.ds-btn{display:block;width:100%;background:var(--sienna);color:#fff;font-family:var(--sans);font-weight:500;
  font-size:15px;padding:12px 18px;border-radius:9px;border:0;cursor:pointer;text-align:center;
  text-decoration:none;transition:background .16s ease}
.ds-btn:hover,.ds-btn:focus,.ds-btn:visited,.ds-btn:active{background:var(--sienna-dk);color:#fff;text-decoration:none}
.ds-btn:focus-visible{outline:2px solid var(--forest);outline-offset:2px}
.ds-btn--sm{width:auto;font-size:13.5px;padding:9px 15px}
/* ⚠ COLOUR SEMANTICS, set 2026-07-30. Sienna means MONEY OR ACCOUNT (Sign Up Free, Get
   Premium, Finish all 4). Forest means the FREE DRAFTING ACTION. Before this, "Write my
   opening" was forest on the grant page and sienna one screen later — the same action, two
   colours across a single handoff — while on this page the free action and the $39/mo ask
   were both sienna, so the page's only colour signal distinguished nothing. */
.ds-btn--draft{background:var(--forest)}
.ds-btn--draft:hover,.ds-btn--draft:focus,.ds-btn--draft:active{background:var(--forest-dk)}
.ds-link{background:none;border:0;color:var(--forest-dk);font-family:var(--sans);font-size:14px;
  cursor:pointer;text-decoration:underline;text-underline-offset:3px;padding:6px 0}
.ds-link--sm{font-size:13px}
.ds-micro{font-size:12.5px;color:var(--ink-40);margin:10px 0 0}

/* ask state */
.ds-askbox{background:var(--paper);border:1px solid var(--line);border-radius:14px;
  padding:clamp(22px,3.5vw,38px);max-width:560px}
.ds-ask-title{font-family:var(--serif);font-size:clamp(21px,2.8vw,28px);font-weight:600;letter-spacing:-.018em;margin:0 0 8px;line-height:1.18}
.ds-ask-sub{font-size:15px;color:var(--ink-60);margin:0 0 20px}
.ds-form{display:flex;flex-direction:column;gap:10px}
@media(min-width:560px){.ds-form{flex-direction:row}.ds-form .ds-btn{width:auto;flex:0 0 auto}}
.ds-input{flex:1 1 auto;min-width:0;font-family:var(--sans);font-size:15.5px;padding:12px 14px;
  border:1px solid var(--line);border-radius:9px;background:var(--cream);color:var(--ink)}
.ds-input:focus{outline:2px solid var(--forest);outline-offset:1px;background:var(--paper)}
/* The description route is a FIRST-CLASS route (half of real users have no website), so it
   gets a field sized for a sentence or two. ⚠ `.ds-form` turns into a row at 560px, which
   would stand a 3-row textarea beside a button; the description form stays stacked. */
.ds-input--area{width:100%;resize:vertical;line-height:1.55;min-height:88px}
.ds-form--stack{flex-direction:column}
@media(min-width:560px){.ds-form--stack{flex-direction:column}
  .ds-form--stack .ds-btn{width:auto;align-self:flex-start}}

/* the two-way door — the other route, on screen, at the same time */
.ds-alt{margin:18px 0 0;padding-top:16px;border-top:1px solid var(--line-soft)}
.ds-alt-lab{margin:0 0 8px;font-size:13.5px;color:var(--ink-60)}
.ds-alt-btn{display:inline-block;font-family:var(--sans);font-size:14.5px;font-weight:500;
  color:var(--forest-dk);background:var(--cream);border:1px solid rgba(45,106,79,.35);
  border-radius:9px;padding:11px 16px;min-height:44px;cursor:pointer;text-align:left;
  max-width:100%;transition:background .16s ease,border-color .16s ease}
.ds-alt-btn:hover{background:var(--forest-lt);border-color:rgba(45,106,79,.6)}
.ds-alt-btn:focus-visible{outline:2px solid var(--forest);outline-offset:2px}

/* provenance — what this draft is being written from, and one click to change it */
.ds-prov{display:flex;align-items:center;gap:10px;flex-wrap:wrap;margin:0 0 14px;
  font-size:13px;color:var(--ink-60)}
.ds-prov-t{min-width:0;overflow-wrap:anywhere}
.ds-prov-edit{display:inline-flex;align-items:center;gap:5px;font-family:var(--sans);font-size:13px;
  color:var(--forest-dk);background:none;border:0;padding:6px 4px;min-height:32px;cursor:pointer;
  text-decoration:underline;text-underline-offset:3px}
.ds-prov-edit:hover{color:var(--sienna-dk)}
.ds-prov-edit:focus-visible{outline:2px solid var(--forest);outline-offset:2px;border-radius:6px}
.ds-prov-ico{width:12px;height:12px;flex:0 0 auto}
.ds-prov-ico svg{width:100%;height:100%;display:block}

/* the website OFFER — never a gate, and it keeps what you typed across a re-render.
   ⚠ It now lives INSIDE `.ds-prov`, beside Edit, because it is a statement about the source.
   ⚠ And its border is SOLID: dashed is the grammar of an unfilled blank on this surface, and
   wearing it made an optional enrichment read as something missing from the draft. */
.ds-offerwrap{min-width:0}
.ds-offerwrap--open{flex:1 1 100%;margin-top:4px}
.ds-offer-btn{display:inline-flex;align-items:center;gap:7px;font-family:var(--sans);font-size:13px;
  color:var(--forest-dk);background:transparent;border:1px solid rgba(45,106,79,.32);border-radius:8px;
  padding:6px 11px;min-height:32px;cursor:pointer;text-align:left;max-width:100%}
.ds-offer-btn:hover{background:var(--forest-lt);border-color:rgba(45,106,79,.65)}
.ds-offer-btn:focus-visible{outline:2px solid var(--forest);outline-offset:2px}
.ds-offer-ico{width:13px;height:13px;flex:0 0 auto}
.ds-offer-ico svg{width:100%;height:100%;display:block}
.ds-offer-form{display:flex;gap:10px;flex-direction:column}
@media(min-width:560px){.ds-offer-form{flex-direction:row;align-items:center}
  .ds-offer-form .ds-btn{width:auto;flex:0 0 auto}}
.ds-input--sm{font-size:14.5px;padding:10px 12px}
.ds-offer-lab{margin:0 0 9px;font-size:13px;color:var(--ink-60)}

/* loading — the wait is ~20s median, so it has to be worth looking at */
.ds-loadbox{max-width:560px;background:var(--paper);border:1px solid var(--line);
  border-radius:14px;padding:clamp(20px,3vw,28px)}
.ds-load-why{margin:16px 0 0;padding-top:15px;border-top:1px solid var(--line-soft);
  font-size:13.5px;line-height:1.6;color:var(--ink-60)}
.ds-load-why b{color:var(--forest-dk);font-weight:500}
.ds--load .ds-load{display:flex;align-items:center;gap:10px;font-size:15.5px;color:var(--ink);margin:0}
.ds-dot{width:8px;height:8px;border-radius:50%;background:var(--sienna);animation:dspulse 1.5s ease-out infinite}
@keyframes dspulse{0%{opacity:1;transform:scale(1)}70%{opacity:.2;transform:scale(1.6)}100%{opacity:1;transform:scale(1)}}

/* editor popover */
/* ⚠ `position:fixed`, not absolute, and above the sheet. Absolute + window.scrollY is
   document-relative, but the sheet scroll-locks <body> to position:fixed, so the editor
   landed far off its blank; and z-index 9999 sat UNDER the sheet panel (10001), so it was
   invisible even when correctly placed. Clicking a blank did nothing at all — the single
   most important interaction on the surface, dead, while every component test passed. */
.ds-pop{position:fixed;z-index:10050;background:var(--paper);border:1px solid var(--line);
  border-radius:12px;padding:15px 16px;box-shadow:0 12px 34px -14px rgba(28,25,23,.35);width:min(320px,calc(100vw - 24px))}
.ds-pop-q{font-family:var(--serif);font-size:16px;font-weight:600;margin:0 0 6px;line-height:1.3}
.ds-pop-h{font-size:12.5px;color:var(--ink-40);margin:0 0 12px}
.ds-pop-in{width:100%;font-family:var(--sans);font-size:15px;padding:10px 12px;border:1px solid var(--line);
  border-radius:8px;background:var(--cream);margin-bottom:11px}
.ds-pop-in:focus{outline:2px solid var(--forest);outline-offset:1px}
.ds-pop-row{display:flex;gap:12px;align-items:center}
.ds-chips{display:flex;gap:8px;flex-wrap:wrap}
.ds-chip{font-family:var(--sans);font-size:13.5px;padding:8px 14px;border-radius:8px;cursor:pointer;
  border:1px solid var(--line);background:var(--cream);color:var(--ink)}
.ds-chip:hover{background:var(--forest-lt);border-color:rgba(45,106,79,.4)}
.ds-chip:focus-visible{outline:2px solid var(--forest);outline-offset:2px}

@media (prefers-reduced-motion: reduce){
  *{animation-duration:.01ms !important;animation-iteration-count:1 !important;transition-duration:.01ms !important}
  html{scroll-behavior:auto}
}

/* Export affordance + provenance + the locks' unlock path (2026-07-30, founder lens and
   blind review). */
.ds-doc-act{display:flex;align-items:center;gap:12px;flex-wrap:wrap;margin:14px 0 0}
/* ⚠ The promoted Copy button is a real touch target, not a small one. `.ds-btn--sm` computes to
   35px, which the 9-width stress test flags on every phone size — and this is the payoff
   control at the surface's highest-investment moment, on the 38% of traffic that is mobile. */
.ds-doc-act .ds-btn{min-height:44px;display:inline-flex;align-items:center;justify-content:center}
.ds-doc-act-note{font-size:12.5px;color:var(--forest);min-height:1em}
.ds-doc-act-note:empty{display:none}
.ds-trust-src{display:block;margin-top:5px;color:var(--ink-40);font-size:12.5px}

/* THE LADDER (2026-07-30). Two asks can now stand in the rail at once — the free door and,
   below it, the paid one. They need a real gap: adjacent offer blocks read as a paywall, and
   the free ask is not an offer at all, so it must not look like the first half of one. */
.ds-ask + .ds-ask{margin-top:18px}

/* The program's intake status, disclosed once, quietly, under the title. Not an alert: it does
   not stop anything, and a founder may well want the draft ready for the next intake. */
.ds-statusnote{margin:0 0 clamp(16px,2.4vw,24px);font-size:13.5px;line-height:1.55;
  color:var(--ink-60);border-left:3px solid rgba(184,134,11,.55);
  background:rgba(184,134,11,.06);border-radius:0 8px 8px 0;padding:10px 14px;max-width:62ch}

/* The handover, when prose typed into the website field becomes the description. An
   explanation, not an error: forest, not red, and their sentence is still in the field. */
.ds-ask-hand{margin:-8px 0 18px;font-size:13.5px;line-height:1.55;color:var(--forest-dk);
  background:rgba(45,106,79,.07);border-radius:8px;padding:9px 12px}

/* the weave — "my answers make the draft better" (spec §W4, 2026-07-30).
   Deliberately the same visual language as the two-way door and the website offer: a bordered
   forest affordance on cream, 44px minimum, never a sienna button. It is a FREE action on the
   draft the visitor already has, and colour on this surface means money-or-account. */
.ds-weave{margin:0 0 16px}
.ds-weave-btn{display:inline-flex;align-items:center;gap:8px;font-family:var(--sans);font-size:14.5px;
  font-weight:500;color:var(--forest-dk);background:var(--cream);border:1px solid rgba(45,106,79,.35);
  border-radius:9px;padding:11px 16px;min-height:44px;cursor:pointer;text-align:left;max-width:100%;
  transition:background .16s ease,border-color .16s ease}
.ds-weave-btn:hover{background:var(--forest-lt);border-color:rgba(45,106,79,.6)}
.ds-weave-btn:focus-visible{outline:2px solid var(--forest);outline-offset:2px}
.ds-weave-ico{width:13px;height:13px;flex:0 0 auto}
.ds-weave-ico svg{width:100%;height:100%;display:block}
.ds-weave-sub{margin:8px 0 0;font-size:12.5px;line-height:1.5;color:var(--ink-60);max-width:56ch}
.ds-weave-note{margin:8px 0 0;font-size:13px;line-height:1.5;color:var(--forest);max-width:56ch}
.ds-weave-note:empty{display:none}
/* the working state: a line, not a spinner over the page — the draft must stay readable */
.ds-weave--busy{display:flex;align-items:center;gap:10px;font-size:13.5px;color:var(--ink-60);
  background:var(--cream);border:1px solid var(--line-soft);border-radius:9px;padding:11px 14px}
.ds-weave--busy .ds-dot{flex:0 0 auto}
/* ⚠ Both halves are needed. `pointer-events` is the visible half (the cursor stops offering an
   edit); the JS guard in wire() is the real one, because a stylesheet that fails to load must
   not be able to re-enable an interaction whose result we would have to throw away. */
.ds-doc--weaving{opacity:.72;transition:opacity .2s ease}
.ds-doc--weaving .ds-tok{pointer-events:none}
