This page tracks substantive changes to the site: new pages, rewrites, layout work, sourcing passes, editorial cleanups. Newest entries at the top. The same content lives in CHANGELOG.md at the repo root, which is the source this page is generated from.
2026-07-05
Cat’s Claw page rewritten around corynoxine B
- Cat’s Claw rewritten end-to-end. The earlier version had corynoxine B bolted onto a structure built before it, with two separate botanical-cover passages and a trailing synthetic-chemistry section that read as scattered. New structure leads with what’s actually in the products, makes corynoxine B the spine of the explanation (pharmacology, then why it works as an unscheduled cover ingredient), folds the two botanical-cover passages into one “cover story” section, and ends with clinical risks and a quit/withdrawal wayfinder. Dropped a weak kratomscience.com citation. Same verified facts as the prior pass; clearer sequence.
- The earlier same-day edit (superseded by the rewrite above) first added corynoxine B, the mu-opioid-active oxindole alkaloid being corynoxine B, the mu-opioid-active oxindole alkaloid being reported in the newer “Cat’s Claw” product lines. New section explains why it works as a regulatory-evasion ingredient: it’s a real kratom/Uncaria alkaloid, it’s opioid-active (mu partial agonist, Ki ≈ 118 nM, per the 2026 Frontiers receptor study already cited on the page), and it is not named in any of the July 2026 DEA scheduling notices, so a corynoxine-B product can sit under the 7-OH threshold and still deliver opioid effects. Cross-linked to The Federal 7-OH Ban.
- Corrected the “real cat’s claw isn’t psychoactive” framing: the same Frontiers study found mitraphylline and rhynchophylline (the marketing-cover alkaloids) inactive at opioid receptors but corynoxine B active, so the page now draws that distinction instead of implying the whole alkaloid class is inert. Reconciled the clinical-implications and “if you’re already taking one” sections (corynoxine B is natural, not synthetic) and added a wayfinder to the quit/withdrawal pages.
2026-07-04
Leaf-alongside-Suboxone correction
- Fixed a factual error on Paths Off 7-OH: the “Moving between rungs” list claimed leaf alongside Suboxone is “uncommon and unnecessary; bupe already covers the receptors.” Bupe covers the mu side only; the community commonly recommends a small amount of leaf when minor-alkaloid withdrawal (adrenergic and serotonergic) breaks through. Rewritten to say that, with a link to the minor-alkaloids page.
- Same list, next line: the naltrexone warning linked
/other-tools/low-dose-naltrexone, a path that soft-404s to the homepage shell (the naltrexone pages live underpost-acute/). Re-pointed to Naltrexone and added_redirectsbridges for the two old naltrexone paths so stale inbound links land on the right pages.
2026-07-03
Federal scheduling action: new page + site-wide banner
- New page: The Federal 7-OH Ban
(
/compounds/7-oh-ban) covering DEA’s July 1, 2026 notices of intent to temporarily schedule 7-OH above a 0.05% / 1 mg threshold (Docket DEA-1570) and to place mitragynine pseudoindoxyl, MGM-15, and MGM-16 fully in Schedule I (Docket DEA-1644). Leads with the date question readers actually have (nothing banned yet; Federal Register publication July 6; earliest effective date August 5, 2026, per the 30-day requirement in 21 U.S.C. § 811(h)), then the threshold mechanics, the HHS OASH public-comment window (Docket HHS-OASH-2026-0232, due July 31), what Schedule I means in practice, and a planning section routing to the site’s documented paths off. All dates and quotes verified against the Federal Register full texts and the DEA/HHS press releases. - New site-wide banner (SchedulingBanner.tsx,
mounted in
BaseLayout.astro): one-line announcement linking to the new page on every page. Dismissible, persisted in localStorage under a dated key so a future re-announcement can reset it; hides itself on the ban page. - Editorial pass on the ban page after review: broke up the run of same-shape “The X” section headers and cut performative-emphasis phrasing (“Read the 1 mg line again…”, “Practical translation:”, “Here is the clock”) in favor of direct statements.
- Stale federal-status text updated on the 7-OH, kratom leaf, MGM-15, MGM-16, and pseudo pages (“DEA has not acted as of mid-2026” and similar), each now pointing at the ban page. Compounds category blurb mentions the scheduling action.
2026-06-20
Veterinary gabapentin on the helper-meds page
- Added a Veterinary gabapentin (no prescription needed) subsection to Helper Medications: vet gabapentin is the same molecule in the same manufacturer packaging and standard strengths, a no-prescription route the community uses. Framed with the existing dosing/taper cautions, the opioid+benzo+alcohol respiratory warning, a “legality varies by state” note, and a pointer back to telehealth as the simpler path. Two verified vendor callouts: Dog & Cat Stuff and Pet Pharm Canada (both confirmed live, in manufacturer packaging, purchasable).
2026-06-19
Brand & style guide
- New page:
/brand— a live, theme-aware brand showcase: the Lift Cup logo and its color mapping, the semantic color tokens, all 8 variants in light and dark, the Fraunces + IBM Plex Sans type system and scale, component specimens (buttons, callouts, cards, inputs, focus rings), shape/surface rules, voice, and links to the downloadable assets. Standalone page onBaseLayout(wide, full container), built from the realLogo,Callout, andbuttonVariantsso the specimens stay truthful. For anyone building an app or companion tool on the brand. - In-page theme switcher. A sticky theme bar (8 color swatches +
light/dark/system toggle) and a clickable variant catalog let you
recolor the whole page from the page itself, not just the header. Both
share the header picker’s storage keys and apply logic and stay in sync
via a
MutationObserver; the on-dark logo preview recolors to the active variant’s dark palette. NewBrandThemeControlisland;Logogained alink={false}option so the on-page specimens aren’t homepage links. - New doc:
docs/brand/style-guide.md— the written companion (exact HSL/hex tokens, font specs, logo usage), GitHub-linkable, cross-referencing the existing logo SVGs and favicons. - AI agent context for downstream builds. A copy-pasteable block on
/brand(anddocs/brand/agent-context.md) that someone can drop into their own project’sAGENTS.md/CLAUDE.mdso an AI agent matches the brand. It links the rendered guide, the repo tokens/logo, and tells the agent to scrape with Playwright if it can’t fetch directly. The page reads the file at build so the two never drift.
2026-06-16
Recovery coaching resource (You Are Accountable)
- New page: Recovery Coaching
in resources (
sort: 3). Explains what peer recovery coaching is, what it costs, and how to weigh a paid service, with You Are Accountable as the first listed entry. Follows the telehealth-comparison model: neutral, every claim cited and dated, the company’s own stats labeled as unaudited claims, and a “questions to ask before you sign up” checklist. - Holds the no-ads line. The page opens with a disclosure that no money changes hands and that a service appears only because community members can use it, keeping the welcome page’s no-sponsorship promise intact. Free community options (Discord, r/quitting7oh, mutual aid, meetings) are named first, with paid coaching framed as an optional add-on. Scholarships are mentioned softly: limited slots, ask the company directly.
- Resources category blurb updated to name recovery coaching.
2026-06-09
Typography refresh: IBM Plex Sans + Fraunces
- Body font is now IBM Plex Sans (variable, self-hosted via
Fontsource), replacing Inter. Slightly warmer, better x-height, and
holds up in dense tables; the Inter-specific
cvfeature settings went with it. - Content headings are now Fraunces, the display serif that was already shipped but only used in the logo. Applies to article prose headings (H1–H4), page titles, and the sitemap section headings at weight 600. Small UI headings (sidebar labels, calculator panels, crisis dialog) stay on the sans.
- Picked from a ten-font contact sheet (
docs/font-contact-sheet.html) rendered on the site’s own light/dark palettes.
Desktop navigation upgrades
- Scroll-spy in the right-rail TOC. The “On this page” rail now
highlights the section currently in view (left border + foreground
text on the active link,
aria-current="location"for screen readers). Tracking uses a rAF-throttled scroll listener against the same 5rem header offset the heading anchors use, with a bottom-of-page case so the last section activates even when its heading can’t reach the reading line. - Anchor bar for wide pages. Pages with
wide: truehide the right-rail TOC and previously offered no in-page navigation. They now get a horizontal H2 anchor bar under the title (TocWide.astro, static markup, no hydration). Currently applies topharmacology/chemical-structures. - Taper calculators go wide. The four taper calculator pages (7-OH, Suboxone, kratom leaf, SR-17 cross-taper) now use the wide layout: the calculator gets the full container width and the right-rail TOC is dropped — there’s little prose on those pages for it to navigate.
- Click-to-copy heading anchors. The hover
#on H2–H4 now copies the section URL to the clipboard (with a “Copied” bubble and a polite screen-reader announcement) instead of jump-navigating. The hash still updates viareplaceState, modified clicks keep normal anchor behavior, and browsers without clipboard access fall back to plain navigation. Vanilla delegated listener inDocLayout.astro— no per-heading hydration. - Copy the page link from the breadcrumb. The current-page crumb is now a link with a copy icon; clicking it copies the page URL. Same “Copied” feedback and screen-reader announcement as the heading anchors.
Source-anchored audit fixes across the site
Acting on docs/source-audit-2026-06-09.md. Four-pass sweep.
- Propagation chain. Replaced PMID 15165526 (mis-cited as “Yang
et al. 2005” — actually Ulfberg’s editorial on Karl-Axel Ekbom) with
Garcia-Borreguero et al., IRLSSG/EURLSSG, Sleep Med 2016
in
CLAUDE.mdand the five content pages that propagated it:helper-meds.md,start-here/7-oh-withdrawal-help.md,post-acute/impending-doom-anxiety.md,quit-7-oh-with-kratom-leaf.md,mat-suboxone/why-suboxone-isnt-working.md. - Pseudoindoxyl Kᵢ corrected.
compounds/mitragynine-pseudoindoxyl.mdhad MP Kᵢ = 0.087 nM and mitragynine Kᵢ = 7.24 nM from a Wikipedia propagation. Replaced with Varadi 2016’s measured value (MP Kᵢ ≈ 0.8 nM) and Obeng 2020’s mitragynine Kᵢ (≈ 160–240 nM). pharmacology/morphine-vs-kratom.mdKᵢ table re-anchored. Removed the fabricated “Kruegel 2019 (hMOR, ~7 nM)” mitragynine citation. Kruegel 2019 reports EC₅₀ 339 nM functional, not Kᵢ. Now cites Obeng 2020 (hMOR Kᵢ ≈ 161 nM) for mitragynine and Obeng 2020 + Matsumoto 2004 for 7-OH. Buprenorphine corrected from “~1 nM, similar to morphine” to “~0.2 nM, tighter than morphine”. MGM-15 dual-receptor causal language reworked with Matsumoto 2014 Kᵢ values. MGM-16 240× framing clarified as “240× oral, ~71× sc”.- Citation mis-attributions fixed.
suboxone-bernese-method.md: Hess → Menard & Jhawar 2022, Vu → Alexander & Woford 2025, Sandhu → Wong et al. 2021 (NCT04234191).sublocade-brixadi.md: Kazim → Hayes & Mills 2025 (re-described as withdrawal characterization, which is what the paper actually documents).post-acute/7-oh-recovery-timeline.mdanddopamine-recovery.md: Volkow → Cosgrove on PMC3760378.start-here/cravings-and-relapse-thoughts.md: Smith → Henningfield on PMC10311168. - Frontiers citation removed where the paper doesn’t contain the
cited claim. Pseudo-binds-tighter-than-bupe now cites Varadi 2016
(with measured Kᵢ values) on
sows-cows-induction-guide.mdx,suboxone-for-7oh.md, andwhy-suboxone-isnt-working.md. MGM-15 dual mu/delta now cites Matsumoto 2014. - Numeric fixes. Sublocade list price $1,500–1,900 → $2,100–2,200
(2024–2026 list per drugs.com / GoodRx). Ohio scheduling date
Dec 16 → Dec 12, 2025 on
compounds/kratom-leaf.md. Mitragynine α-adrenergic strength “moderate” → “weak (micromolar)” per Obeng 2020 onkratom-leaf.md,kratom-minor-alkaloids.md,7-oh.md. Leaf 7-OH math fixed (0.04% of 1 g ≈ 0.4 mg, not 0.5–4 mg). CLAUDE.md line count: 700 → 1,000. HIMS: Motivation → Motivational. EVALI 2,800 hospitalizations softened to “around 2,800” per CDC final tallies. Suboxone receptor-occupancy table reconciled to De Aquino values used elsewhere on the site (2 mg = 41%, 16 mg = 80%, 32 mg = 84%, vs the prior overstated row). NIDA chronic-disease comparison: dropped diabetes (NIDA’s published comparison only includes hypertension and asthma). - Half-life claims qualified. “7-OH plasma half-life ~100 minutes”
on five pages (
compounds/7-oh.md,sows-cows-induction-guide.mdx,suboxone-for-7oh.md,suboxone-rapid-taper.md,7-oh-taper-calculator.mdx) re-labeled as community-observed effect duration with a note that no direct human PK is published (Tanna 2024 reports the 7-OH metabolite at 4–9 hr). The compound page has the long explanation; other pages link to it. MGM-15 “~15 hour half-life” on three pages (sows-cows-induction-guide.mdx,suboxone-for-7oh.md,suboxone-bernese-method.md) re-labeled as “community-reported effective duration roughly 9–15 hours per dose (no published human PK)”. The MGM-15 compound page already had the caveat; sibling pages now match. - Smaller items. Kruegel-2019 “prodrug” attribution on
kratom-leaf.mdrephrased (Kruegel doesn’t use the term). Mitragynine human half-life onquit-7-oh-with-kratom-leaf.mdcorrected from “24+ hours” to “roughly 7 to 39 hours” per Huestis 2024. Zamboni 2019 over-claim onendocrine-recovery.mdcorrected (no significant methadone vs buprenorphine difference per published abstract). SAMHSA helpline URL bumped past 301 redirect (samhsa.gov/find-help/national-helpline→…/helplines/national-helpline) across five content pages. Bicycle Health BBB profile link removed (URL 404s; rating data kept). - Reddit-side date corrections on
about/the-community.mdx: subreddit creation August 2024 → July 2024 (Playwright-verified Jul 16, 2024). The May-2026 stepdown framing split into two events: February 2026 Discord step-back (post1reegp9is about Discord policy from Feb 25, 2026), May 2026 subreddit step-down (post1t0u0jofrom May 1, 2026).
The audit had one false positive: it claimed quit-7-oh-with-mitragynine.md
had swapped Kᵢ values for 7-OH (78 nM) and mitragynine (709 nM). The
cited paper (PMC7923387, Obeng 2021 JPET) actually reports those exact
values; the page is correct. Skipped.
Calculator callouts on the path master pages
- Every taper calculator now has a prominent callout on its corresponding path master page, placed right above the first H2 so a reader arriving on the master from search or a referral doesn’t have to know the calculator exists to find it.
- Added on:
/for-you/tapering-7oh→ 7-OH Taper Calculator/mat-suboxone/suboxone-for-7oh→ Suboxone Taper Calculator/mat-suboxone/suboxone-rapid-taper→ Suboxone Taper Calculator (framed as “doesn’t see a taper plan that fits your situation? — build a custom one”)/other-tools/sr-17→ SR-17 Cross-Taper Calculator/other-tools/quit-7-oh-with-kratom-leaf→ Kratom Leaf Taper Calculator
- Same callout pattern across all five: blockquote with a chart emoji, an intent-matching CTA (“Want a day-by-day schedule…”), one-sentence description of what the calculator builds, and a single link out. Rapid-taper page uses the “doesn’t fit your situation” framing rather than the default “want a schedule” framing, since readers landing on rapid-taper already know they want a schedule and need a way to deviate from the templates.
Full DHM/MIT-A cascade: merge into MGM-15 page, stub the old, sweep the references
/compounds/mgm15rewritten as the canonical page for the compound that’s sold under all three labels (MGM-15, MIT-A, DHM). Folded in the unique content from the old/compounds/mit-a-dhmpage: the chemistry of how MGM-15 is made (NaBH₄ reduction of 7-OH) and why “reducing mitragynine” wouldn’t give a clean product; the GC-MS reversion problem that lets vendors publish “non-detect 7-OH” COAs on products containing MGM-15; the regulatory landscape (Florida’s 400 ppm 7-OH gap, Ohio explicitly scheduling dihydro-7-hydroxy mitragynine, Louisiana scheduling both mitragynine and 7-OH); dose patterns (10 mg MGM-15 ≈ 30–40 mg 7-OH); the “harder to come off than 7-OH” community pattern; and a practical “for the reader being sold one of these products” section./compounds/mit-a-dhmconverted to a stub that explains the labels point at MGM-15, names the chemistry confusion the original page perpetuated, and pushes readers to/compounds/mgm15for everything.- Cascade across 27 content files. Replaced
[MIT-A](/compounds/mit-a-dhm)and similar patterns where MIT-A was being treated as a distinct compound: dropped from compound lists (MGM-15 covers it), converted standalone links to bare market-label text where the framing was already “products sold as MIT-A”, and pointed any remaining/compounds/mit-a-dhmlink at/compounds/mgm15. Manual cleanup of redundant bullets that said “MIT-A/DHM: also long-acting. Similar timeline to MGM-15” (which now reads as a compound being similar to itself). Files touched: most ofmat-suboxone/*,start-here/*,compounds/*,for-loved-ones/*,other-tools/*,post-acute/*, and the calculator pages. - Removed the dihydro-mitragynine structure from
/pharmacology/chemical-structures. The structure was an illustration of a compound that doesn’t appear in characterized commercial products — diagramming it in the synthetic-derivatives row was misleading. - Affinity is not activity — new dedicated section on
/pharmacology/morphine-vs-kratomplaced right before the binding-affinity ranking table. Reframes affinity, activity (full / partial agonist / antagonist, ceiling effects), and exposure as three independent things that combine to drive what a compound does in practice — so a reader sees what the Kᵢ numbers tell them and what they don’t (buprenorphine and morphine have similar µ-affinities but very different ceilings). Replaced the briefer caveat below the table with a pointer to this section.
Pharmacology page reflects DHM/MIT-A relabeling
- Updated
/pharmacology/morphine-vs-kratomafter the community converged on the fact that products sold as “DHM” or “MIT-A” have been characterized as MGM-15, not as a distinct dihydro-mitragynine compound. The chemistry of saturating the side-chain C=C bond on mitragynine is real, but that compound doesn’t appear in characterized commercial products — so listing it on a page about what’s actually circulating was misleading. - Removed the “Dihydro-mitragynine (DHM / MIT-A)” row from all three tables on the page (compounds compared, structural modifications, µ-opioid affinity ranking). The MGM-15 row now mentions that the same molecule is sold as MIT-A and (mislabeled) DHM. Added a dedicated “A note on DHM and MIT-A” subsection so readers searching for either name land on the clarification.
- Count updated everywhere: “seven compounds” → “six,” “six related to mitragynine” → “five.” Pattern intro reworked since the table now has only one reduction example. “Where to read next” replaces the standalone MIT-A/DHM link with a pointer to MGM-15 carrying the parenthetical “(which covers what’s sold as MIT-A and DHM).”
- Downstream pages still need the same pass —
/compounds/mit-a-dhm,/compounds/mgm15,/pharmacology/chemical-structures, and the ~25 other content files that reference DHM or MIT-A as a distinct compound. Tracking the cascade as a follow-up; this commit is the pharmacology-page anchor.
Virtual SMART Recovery meeting finder at /virtual-smart-meetings-now
- New shareable landing page at
/virtual-smart-meetings-now: a third-party viewer over the public SMART Recovery online meeting list, sorted into the reader’s local timezone. Same four-pane structure as the NA page — Live now, Starting soon, Later today, Tomorrow — and the same filter pattern: program chips (4-Point Recovery dominates with 383; Family & Friends 58; Successful Life Skills 4), audience chips (Adults Welcome 410; LGBTQIA+ 9; Women 7; Military, Veterans & First Responders 7; Teens, Young Adults, BIPOC), language chips, and a free-text search across facilitator- host city + host state. Copy button per card.
- Pathminder behavior, surfaced honestly. SMART routes every meeting join through their own gateway (Pathminder / Pathcheck) which only redirects to the actual Zoom/Meet room during the meeting’s active join window. For live or starting-soon meetings the Join Online button on each card links directly to the Pathminder URL — one click, gateway handles the room. For meetings later today or tomorrow, the link instead goes to the meeting’s page on meetings.smartrecovery.org since the gateway wouldn’t open a room outside the window. A note above the panes explains this so readers aren’t surprised.
- Framing and trademark respect. The page leads with a callout that quitting7oh.org is not affiliated with SMART Recovery, attributes meeting data to © SMART Recovery, and routes update reports back to SMART’s own meeting search.
- Data pipeline. A new build script at
scripts/build-smart-meetings.mjsscrapes the SMART listing UI with multi-city union coverage (Houston, LA, NYC, Kansas City at 1000-mi radius each) because a single-city search misses meetings hosted outside its radius. Across the four cities: 886 raw row appearances, 462 unique meeting IDs after dedup, 445 verified online meetings after per-meeting detail-page validation (drops 17 that had no Pathminder URL — most were in-person meetings that slipped through the meetingType=1 filter). - Triple-check that meetings are actually online. The pipeline
filters by SMART’s own
meetingType=1URL parameter, additionally validates that each listing row carries the<i class="fas fa-video">icon + “Online” text, and finally requires a Pathminder URL on the detail page. Any row that fails all three is dropped. - Audience-aware split. SMART’s audience field can encode
multiple tags like “BIPOC, Young Adults (18-30)” or include a
tag that contains its own comma (
Military, Veterans & First Responders). The parser does longest-match against the known set from SMART’s own form dropdown so the tag with the literal comma stays intact. - Daily refresh. A new cron at
.github/workflows/refresh-smart-meetings.ymlruns every morning at 09:30 UTC (just after the NA refresh). Daily not weekly because SMART’s listing exposes each meeting’s next occurrence as a specific UTC timestamp, not a recurring template — weekly would leave “next meeting at 7 PM today” stamps stale for days. - Homepage hook updated. The
NextMeetingcard now points readers at both the NA finder and the SMART finder when no kratom-specific meeting is in session, instead of just NA. No specific meeting is named — the finders are the destinations. - Added to the human-facing
/sitemapunder “Standalone tools”. - Filter-chip counts reflect what’s actually visible. Initial build showed the build-time dataset count on each chip (e.g. LGBTIA+ “9”), which was misleading: most meetings aren’t in the ~36-hour viewer window of the four panes, so clicking the chip could yield only 2 visible meetings out of the 9 advertised. Chip counts now reflect the visible set (live + soon + today + tomorrow), so the number on the chip matches what you see when you click it. Tags with no current visible meetings are hidden unless already active (so they don’t disappear under your cursor).
Virtual NA meeting finder at /virtual-na-meetings-now
-
New shareable landing page at
/virtual-na-meetings-now: a third-party viewer over the public Narcotics Anonymous® virtual meeting list, US English-language only, sorted into the reader’s local timezone. The page leads with the always-on 24/7 room as a featured card, then four panes: Live now (started in the last hour), Starting soon (next 60 minutes), Later today, and Tomorrow. Each card has a one-click Zoom join with the passcode pre-filled where the host published it (~80% of Zoom rows); the others display the raw passcode for typing. -
Filter bar across the top: meeting-type chips (Newcomer, Discussion, Speaker, JFT/Basic Text/Step/Literature Studies, Meditation, Topic, Men, Women, LGBTQ+, Young People, Hybrid), an Open/Closed radio, and a free-text search box that matches against group name, city, and state.
-
Framing and trademark respect. The page leads with a callout that quitting7oh.org is not affiliated with Narcotics Anonymous World Services or any NA group. NA® and Narcotics Anonymous® carry the registered-mark symbol on first prominent use. Meeting data is attributed to © Narcotics Anonymous World Services, Inc. The open vs closed distinction is expanded into a two-card definition list with NA’s own wording (“for addicts only”) — readers can see upfront whether a meeting is for them or whether they’re welcome as a curious newcomer or family member. Meeting-update reports are routed back to na.org’s own “Submit Update” form rather than being collected on our end.
-
Data pipeline. A new build script
scripts/build-na-meetings.mjspulls the full week of meetings from na.org’sadmin-ajaxendpoint (the same one their/meetingsearch/virtual-meeting-search/page uses), filters to US + English (4,104 of 7,043 raw rows), normalizes into a render-ready shape, and writessrc/data/na-meetings.generated.json. The Astro page imports the JSON at build time so the page is fully static — no runtime data fetch, no Pages Functions. -
Freshness. A new weekly cron at
.github/workflows/refresh-na-meetings.ymlruns the fetcher every Sunday 09:00 UTC, content-hashes the result (ignoring thefetched_attimestamp so it’s not a no-op commit), commits if changed, and pushes tomain. Cloudflare auto-deploys from the push. One bot commit per week at most. -
Authorization. NAWS senior leadership approved republication with a link back to na.org and a clear unaffiliated disclaimer.
-
Supporting infrastructure. Extracted a generic
src/lib/tz.tswithwallClockToUTC,todayInTimezone,addDays, andnextOccurrencehelpers that work against any IANA timezone (the existingsrc/data/meetings.tswas ET-only). The NA dataset spans dozens of timezones, every meeting carries its own. Pre-existing kratom-meeting code untouched — the new lib is additive. -
Added to the human-facing
/sitemapunder “Standalone tools”. -
Homepage hook. The homepage
<NextMeeting>card now surfaces the NA finder when the next kratom-specific meeting isn’t in session (statusfuture, i.e. more than 15 minutes away). A small inline callout above the card body says “The kratom-specific meeting below starts later. There’s a virtual NA meeting happening every hour — find one live.” with a link to/virtual-na-meetings-now. No specific NA meeting is named on the homepage — the finder is the destination, and the reader picks. When a kratom meeting is starting soon, live, or just started, the callout doesn’t appear. -
Intro container. The intro / disclaimer / open-vs-closed section now spans the full page width rather than the prior
max-w-3xlreading column, so the disclaimer aligns visually with the featured card and filter bar beneath it. -
Blank-URL recovery. ~23% of the US English rows came back from na.org with the
linkfield empty and the actual connection info packed into thepasswordfield as free text — patterns like “Zoom ID: 669 913 3088 Password: LL130” and “+1 605.313-4221 Access Code: 3074093”. The build script now parses these out: 807 Zoom meetings (with embedded passcode where present) and 93 NA phone meetings (tel: URLs + access codes) were recovered. Total unjoinable rows dropped from 910 to 11. The remaining 11 are na.org data-entry quirks (“Skype Meeting” labeled rows with Zoom URLs in other fields) — they render with a “Connection details unavailable, check na.org” inline note instead of a broken Join button. -
Phone meetings as a first-class platform. Surfaced as 93 rows with platform=“Phone”, a
tel:link, a Phone icon (not the external-link arrow), a formatted phone number in the room field, and an “Access code” label instead of “Passcode” — NA has run phone meetings for decades and this is legitimate recovery infrastructure. -
Platform filter. A new chip row in the filter bar lists every detected platform with its count. Zoom (3,788), Phone Call (93), and Google Meet (11) are visible by default; the rest sit behind a “Show all” toggle, matching the meeting-type chip pattern (Online meeting 39, GoToMeeting 4, Microsoft Teams 3, Discord 3, FreeConferenceCall 2, Facebook 2, Jitsi 1). The semantics are OR — selecting multiple chips shows meetings on any of them — because a meeting is on one platform, so AND would be empty. Detection upgraded in
scripts/build-na-meetings.mjs: GoToMeeting, FreeConferenceCall, Microsoft Teams Live, Discord, Jitsi all now recognized; previously they fell into the “Online meeting” catch-all. The phone-dial-in platform is labeled “Phone Call” everywhere — chip, card body, copy snippet — for unambiguous reading. -
Copy meeting details. Every meeting card and the 24/7 featured card now have a Copy button that puts a plaintext snippet on the clipboard:
NA Meeting: In Spirit Discussion · Open Wednesdays at 7:00 PM (your local time) Zoom · Room 669 913 3088 · Passcode LL130 https://us02web.zoom.us/j/6699133088?pwd=LL130Day-of-week framing rather than specific date since meetings recur weekly. Falls back to a textarea +
execCommand('copy')in environments without the async clipboard API. -
Simplified open/closed callout. Replaced the two-card definition list (added one iteration ago) with a single-paragraph inline explanation. The cards were taking up disproportionate vertical space at the top of the page; one tight sentence with bolded labels carries the same information.
SOWS partial-score early exit
- The SOWS calculator’s partial-score message now short-circuits when the running sum has already crossed the at-home induction floor (17) or threshold (21). Each SOWS item is 0–4 (never subtracts), so a partial sum past the floor means the final score will also be past it; the remaining items can only raise it. Before, any partial state read “Score so far: X. Y items left,” which implied the reader should keep scoring when the right message was “no need to finish.”
- Partial sum ≥ 21 → “Past the threshold — no need to keep scoring.”
- Partial sum 17–20 → “Probably in the induction window.”
- Partial sum < 17 → unchanged “Score so far: X. Y items left.”
- Result-panel border tone tracks the ready flag (primary tint when ready), so the visual cue matches the copy.
Standalone tools on the human-facing /sitemap
- The
/sitemappage only iterated the docs content collection, so top-level pages insrc/pages/(notably the new/next-kratom-support-meetinglanding) weren’t visible to readers scanning by eye. The XML sitemap at/sitemap-index.xmlalready caught them via@astrojs/sitemap. - Adds a curated “Standalone tools” section after the categories that lists hand-picked top-level pages worth surfacing. Total- pages counter in the header updated to include them.
Rolling meetings page at /next-kratom-support-meeting
- New shareable landing page that opens with a featured “Next up” card (Kratom Anonymous or There Is A Way Out, whichever is the next live or upcoming meeting) and then a 3-day rolling grid of compact cards grouped by day. Each card has a local-time stamp, live countdown, fellowship + format, platform (Zoom / Google Meet), and is itself a click-target to the join URL.
- Featured card swaps its badge depending on status: “Next up” while the meeting is still future, then “Starting soon” → “Live now” as the clock turns over. Updates on a 30-second tick.
- New
findUpcomingMeetings()helper insrc/data/meetings.tsenumerates recurring meeting occurrences within an N-day window; reuses the existing ET→local-time DST math. - Page uses BaseLayout directly (no sidebar, no DocLayout) to match the homepage’s stripped framing — the intent is a clean, share- able link target.
Taper calculator follow-ups
- SR preload defaults to 3 days instead of 1. The 1-day textbook preload is calibrated for pure short-acting 7-OH; most readers coming through the calculator are on synthetics or stacks where the longer runway works better. Calculator page prose updated to match — points back to the SR-17 page for the 1-day textbook version and to push higher (4–5) for harder cases.
- No more “0 mg × 1” jump-off row. When the SR jump-off is set to 0, the generator now skips the zero-dose final row and lets the last natural taper day be the end before Stop. When jump-off is non-zero (default 25 mg), it still renders its own labelled Jump-off row with the final-dose note.
- SR taper doses-per-day eases down proportionally. Previously held at preload doses/day (3) until jump-off, producing fractional per-dose math (33 mg, 25 mg, 17 mg). Now drops 3 → 2 → 1 as the total falls so per-dose mg stays in a sensible 25–50 mg range.
- Misleading “spaced every 6–8 hours” footnote dropped from the SR table. The hour-spacing is a preload convention; during the taper the schedule reduces frequency over time.
- New “Copy schedule” button on every calculator. Plain-text taper plan + day-by-day, no AI scaffolding — drops straight into a journal, Notes app, email, or message. Lives next to the existing “Copy AI prompt” and “Save as PDF” buttons; each tracks its own “Copied” confirmation.
- Sort order fixed: the Taper Calculators landing page now precedes the four sub-calculators in the resources section (landing = sort 4, sub-pages = sort 5–8). Previously the landing and the 7-OH calculator both held sort 4 and collided.
Taper calculators: split into four substance-specific pages
The single mega-calculator at /resources/taper-calculator got too
busy once the SR-17 cross-taper was added — it’s structurally a
two-substance protocol with four sequential phases, not a single-
substance percentage taper like the rest. Split into four focused
calculators plus a landing page:
/resources/7-oh-taper-calculator— 7-OH, MGM-15 / MIT-A / DHM, and pseudoindoxyl in one calculator with a substance picker (they share the percentage-taper math; defaults differ per compound)./resources/suboxone-taper-calculator— buprenorphine taper with the published 5/7/10/14/21-day rapid-taper schedules built in and percentage-math fallback for non-standard start doses./resources/kratom-leaf-taper-calculator— kratom leaf in grams, defaulting to a 1 g/day jump-off rather than zero./resources/sr-17-taper-calculator— the SR-17 cross-taper with all four configurable phases (preload, 7-OH cross-taper, hold, SR taper-down), plus the optional allergy-test day. New standaloneSr17CrossTaper.tsxcomponent; was inline inTaperCalculator.tsx./resources/taper-calculator— landing page, links to the four sub-pages with a short description of each path. Existing URL is preserved so external links still work.
Other changes that came with the split:
TaperCalculatoraccepts asubstancesprop (filters the dropdown; hides it entirely when only one is passed) and astorageSuffixso each instance has its own localStorage key and can’t overwrite the others.- All calculator instances now save inputs to localStorage and reload on next visit. A “Reset form” link at the top clears saved state and restores defaults.
- “Source compound” framing in the SR-17 calculator replaced with “7-OH (or your kratom synthetic)” throughout — table column, config-panel labels, print PDF, AI prompt. The protocol math applies to MGM-15 / MIT-A / pseudo too; the helper text calls out that synthetics may need a longer preload.
Legacy Discord channel callout
quit-7-oh-with-kratom-leaf.md“If leaf isn’t working” section pointed readers at#kratom-leaf, a leftover from when content routed to specific Discord channels by name. Replaced with the standard pattern: post in the Discord or subreddit to talk through options.
2026-06-08
SOWS calculator on the SOWS/COWS induction-guide page
- New interactive SOWS calculator at the top of
mat-suboxone/sows-cows-induction-guide. 16 items, each scored 0–4 by tapping a button. The page sums the total, names the severity bucket, and prints a light-language induction-readiness hint (“Probably too early”, “Getting close, but probably not yet”, “Probably in the induction window”, “Past the threshold — no need to wait longer”, “Severe range”) so a reader inducting solo at home can see where they are without doing the arithmetic. - Log line appears once all 16 items are scored: a single pastable string with the score, severity bucket, and current date/time, plus a “Copy to clipboard” button. Re-scoring later updates the timestamp so users can log each observation as the trajectory climbs.
- Collapsed by default with a callout-style trigger header (“SOWS calculator — Drop down to take your score”, calculator icon, primary-tinted background, primary-colored chevron) so the surrounding prose stays scannable and the calculator reads as the primary action when you want it.
- Per-button labels (None / A little / Moderate / A lot / Extreme) sit underneath each number column. Variable-width labels would have made the buttons look uneven if placed inside them; the under-button layout keeps the buttons uniform and the labels always-visible without scroll-back to the top legend.
- Page renamed from
.mdto.mdxto host the React island. The existing hand-score item list is kept below for offline / printed use; that section’s heading is now “Self-scoring SOWS (by hand)”.
Peptides page title + two body-prose framing leaks
other-tools/peptides-for-withdrawal.mdtitle renamed from “Peptides for Opioid Withdrawal” to “Peptides for 7-OH and Kratom-Synthetic Withdrawal”. Title affects the<title>tag, the SERP heading, the breadcrumb, and the sidebar — the previous framing was the wrong scope for this site.about/this-site.mdlead paragraph: “for getting off 7-OH, kratom synthetics, and the opioid dependence they produce” → “for getting off 7-OH, MGM-15, and other kratom-derived synthetics”. Site self-description, same reframe as SITE.description.for-loved-ones/rehabilitation-centers.md: “For 7-OH and opioid dependence, detox handles…” → “For 7-OH and kratom-synthetic dependence, detox handles…”. Page is in the for-loved-ones section of this community; the scope hand-off should match.
The rest of the opioid framing in body content stays as-is — most of it is correct technical claims (bupe is an opioid, kratom- synthetic withdrawal is biochemically opioid withdrawal) or deliberate borrowing from OUD literature. Detailed audit in docs/page-descriptions-audit.md Part 3.
Per-page descriptions: SEO + 7-OH/MGM-15/kratom-synthetic framing
- 48 content pages got tightened meta descriptions per the audit in docs/page-descriptions-audit.md Part 2. Target: 120-160 chars to fit Google’s SERP truncation (many of the originals ran 180-260 and were getting cut off in every result), with the search-query nouns front-loaded.
- “Opioid withdrawal” / “opioid dependence” framing replaced with “7-OH and kratom-synthetic withdrawal” / “kratom-derived synthetics” on pages where the page is about our scope, not generic OUD. Compound names (MGM-15, MIT-A, DHM, LDN, ULDN, CRAFT, NARR, COWS, SOWS, Bernese) added to descriptions where they’re the actual search query for that page.
- One typo fix:
compounds/7-oh.mddescriptiontapereable→taperable. - A handful of the proposed descriptions came in slightly over the 160-char target (160-190) where the SEO surface justified the extra terms; flagged in the audit doc for a follow-up tighten if needed.
last_updatedbumped on every touched file.
Site-wide scope reframe: 7-OH / MGM-15 / kratom-derived synthetics
SITE.descriptionrewritten. The site-wide meta description (used in every<meta name="description">, everyog:description, and every embed) previously trailed “…and related opioid dependence”, which framed the site as if it also covered general OUD (heroin, fentanyl, prescription opioids). It doesn’t. The new description names MGM-15 explicitly, says “kratom-derived synthetics” instead of “kratom synthetics” (clearer about the semi-synthetic nature), and lists what the site actually delivers: taper plans, MAT options, helper meds, PAWS guides. Front-loads the search-query nouns so the SERP snippet does triage work.og:image:alt/twitter:image:altupdated inBaseLayout.astroto match the new scope (“…recovery information for 7-OH, MGM-15, and kratom-derived synthetics”). The previous “Community recovery information.” was too generic to do any SEO or accessibility work.- Recommendation source: docs/page-descriptions-audit.md Part 1.
Helper Medications rewrite: quick-reference table, cluster ordering, slop pass
- Above-the-fold restructure: page now opens with a single-table “Quick reference” — symptom cluster → medication → typical dose — covering clonidine, gabapentin, baclofen, trazodone, ondansetron, loperamide, PEG/docusate, NSAIDs/acetaminophen, and bupropion. A reader can take that table to a prescriber without reading the rest of the page.
- Deep-dive sections reordered into clusters: autonomic (clonidine) → GABA/wired (gabapentin, baclofen + muscle relaxants) → sleep (trazodone, doxepin, mirtazapine, hydroxyzine, melatonin) → GI (anti-nausea, loperamide, constipation) → OTC body aches → post- acute (bupropion, SSRIs/SNRIs, buspirone) → the benzo conversation.
- Clonidine section expanded to name real alternatives in the sympathetic family: lofexidine (existing), guanfacine (longer- acting alpha-2A agonist), and propranolol (beta-blocker, narrower but overlapping coverage). The page previously left clonidine as if it were the only option.
- Verbiage pass per the stop-slop ruleset: dropped “(the workhorse)” from clonidine’s heading, the “Why prescribers like it / Why prescribers say no / Why they work / When they do get prescribed” Wh-headers (replaced with flat prose or “Trade-offs”), the “Bottom line” performance-signposting header, “deserves its own callout” (mirtazapine), “worth asking” (mirtazapine), “real tools, not extras” (“X is real” tic), “is a real adjunct” (magnesium), “rare but real” (baclofen seizure caveat), “the realistic alternatives” (benzos antithesis ladder), and “The catch:” (bupropion).
- Discord channel references removed (#helper-meds was named twice). Project rule routes Discord traffic to the server in general, not to named channels.
- Diphenhydramine warning relocated from a bottom-of-page bullet into the sleep section, where it belongs alongside hydroxyzine’s RLS caveat. Double-period typo fixed. Duplicate Tizanidine bullet at the bottom removed.
- Frontmatter
descriptioncomma-splice fixed;last_updatedbumped.
OG / Twitter card image with the brand lockup
- New
public/og-image.png(1200×630) carries the Lift Cup mark andquitting7oh.orgwordmark in Fraunces 700, set against the stone- light brand background, with a short tagline below. The wordmark is rendered as genuine Fraunces — vendored Fraunces and Inter TTFs underscripts/og-fonts/give the rasterizer real glyph data, so embeds don’t fall back to Georgia. - BaseLayout
<head>addsog:image, theog:image:width/height/ type/altquartet,twitter:image, and bumpstwitter:cardfromsummarytosummary_large_image. Replaces the earlier “intentionally no og:image” choice now that the brand is in place. - New
scripts/build-og-image.mjs(npm run build:og) rebuilds the image from inline SVG using@resvg/resvg-js. Re-run when the brand design changes.
Brand: Lift Cup logo + per-theme favicon system
- New
<Logo>component atsrc/components/Logo.astrorenders the Lift Cup mark plus thequitting7oh.orgwordmark as an inline SVG so the strokes inherit theme variables. Cup useshsl(var(--foreground)), arrow useshsl(var(--primary)), the7useshsl(var(--primary)), the.orgsuffix useshsl(var(--muted-foreground)). One component covers all 16 theme + light/dark states; no logo hex anywhere. - Header dot replaced with the lockup. The previous header brand was a 2.5px primary-colored dot followed by plain text; it’s gone. The footer’s brand column header was plain text too; it now uses the same Logo at a smaller size for visual consistency.
- Footer converted from React to Astro as part of the swap. The
component had no interactivity, so dropping
client:idlealso skips a hydration pass. - Fraunces (variable) added via
@fontsource-variable/frauncesfor the wordmark, alongside Inter. Self-hosted, no Google Fonts. New--font-displaytoken inglobal.css. - Favicons reorganized under
public/favicons/<theme>/with one folder per theme (accent-teal,zinc,slate,stone,neutral,rose,blue,green). Each carriesfavicon.svg,favicon.ico,apple-touch-icon.png,icon-192.png,icon-512.png,icon-maskable-512.png, andsite.webmanifest. The old single-colorpublic/favicon.svgwas removed. - BaseLayout head now references the default-theme (
stone) versions of the SVG favicon, ICO, apple-touch-icon, manifest, and atheme-colormeta starting at stone-light’s primary (#604020). The old hardcoded#0d9488is gone. - theme-sync.js runs after the inline ThemeScript and repoints the
SVG favicon and
theme-colormeta wheneverdata-themeor the.darkclass changes. Fixed the script’s default fallback tostone(wasaccent-teal), since the project’s default omits thedata-themeattribute entirely. - Reference assets moved out of
public/intodocs/brand/:THEME-ICONS-README.md,theme-coverage.html, and the standalone logo SVGs. Nothing on the live site renders those; they’re for design reference and shouldn’t ship as public URLs.
2026-06-07
Taper Calculator: 7-OH stays ≥ 2×/day, tooltip refinements
- 7-OH keeps at least 2 daily doses throughout the taper. 7-OH’s
short half-life (community-reported ~3–5 hours) means dropping
to once-daily mid-taper creates long inter-dose withdrawal
valleys. The calculator now floors doses-per-day at 2 for 7-OH
whenever the reader started at 2 or more times daily. Other
substances unchanged (configurable per substance via
SubstanceConfig’s
minDosesPerDay). - Absolute-zero stop day renders as “Stop. Taper complete.” Picking jump-off = 0 appends a final 0-dose day. The previous render showed it as “0 mg × 1/day = 0 mg/day” — and with the new 7-OH 2× floor, it also fired a misleading “Drop dosing to 1×/day starting Day N” callout. Replaced with a single green “Stop. Taper complete.” row. Same fix applied to the printable PDF (green-tinted stop row) and the AI prompt (“Day N: stop (taper complete)”).
- Per-dose hint uses hover on desktop, tap on mobile. The
earlier swap to Popover for mobile support lost the desktop
hover affordance — clicks felt wrong for a quick hint. Now
detects
(hover: hover) and (pointer: fine)and renders shadcn Tooltip on hover-capable devices, shadcn Popover on touch. Same ❓ icon and body content in both modes. - Tablet tooltip shows actual mg, not just count. Closest- quarter rounding was misleading: for a 94.5 mg target on a 50 mg tablet, “2 tablets” implies 100 mg, not 94.5. When the dose doesn’t snap cleanly to a quarter, the tooltip now shows both adjacent quarter-tablet options with the mg each delivers — e.g. “1¾ tablets = 87.5 mg or 2 tablets = 100 mg (50 mg per tablet)”. Reader picks whether to under- or over-shoot. Fractional counts ≤ 1 read singular (“¼ tablet”), > 1 plural.
- Schedule table grows vertically instead of capping at
max-h-80with internal scroll. A 30-day or 90-day taper now expands in line with page scroll instead of trapping the reader in a nested scroll context.
2026-06-06
Taper Calculator bug fixes: schedule length, mobile tooltips, fraction reduction
- N-day taper now has exactly N rows. The “1 month” preset was
producing 32-day schedules, “2 months” 62, “3 months” 92 — an
off-by-one caused by the iterative percentage loop pushing one
extra row when floating-point rounding put the final dose
slightly above the jump-off. Replaced the iterative loop with the
closed-form
start · ratio^(k/(N−1))so the count is exact. Convention matches the bupe established schedules: day 1 is the starting dose, day N is the jump-off, N − 1 cuts in between. Custom-mode percentage display and the reverse percentage-→days calculation use the same (N − 1) convention. - Per-dose tooltips work on mobile. The bupe strip-equivalents
and tablet-count hovers were built on shadcn
Tooltip(Radix UI), which is hover/focus-only and doesn’t fire on touch. Swapped both for shadcnPopover— opens on tap (mobile) or click (desktop), closes on outside tap. Same content, same trigger affordance (the ❓ icon next to each per-dose value). - Bupe strip fractions are reduced. 4/16 reads as 1/4, 6/16 as 3/8, 8/16 as 1/2. 16/16 reads as “a full N mg strip”; clean multiples read as “N strips of M mg”; mixed values read as “1 1/2 strips of 4 mg” for cases like 6 mg on a 4 mg strip.
Taper Calculator: per-dose × times-per-day model, days everywhere, duration-driven custom mode
Reworked the taper calculator after first-round feedback:
-
Dose input split into per-dose × times-per-day, with a live “Total daily” display. Schedule output now shows per-dose, times-per-day, and total daily on each row. As the total descends, the calculator drops doses-per-day proportionally (
ceil(N0 × T / T0)) so per-dose stays in a tolerable range instead of grinding down to fractions of a tablet. -
Step unit is now days for every substance. The previous weekly math produced 30-week schedules for 20 mg/day dependencies, which doesn’t match how anyone in this community actually tapers. If a reader wants a multi-week taper, they enter the duration in days (14, 21, 60, etc.).
-
Duration presets of 5, 10, 14, and 21 days, plus a Custom duration option. The values line up with the columns on the Suboxone Rapid Taper page so the bupe established schedules fire when the start dose matches. For other substances or non-matching bupe doses, the per-day percentage is derived from the duration:
pct = 1 − (jumpOff / totalStart)^(1/days). The preset labels show only the day count (no “easier” or “harder” wording) so the calculator doesn’t editorialize on which duration is right. -
Custom mode now has bidirectional duration ↔ percentage inputs. Editing days updates the displayed %; editing the % updates the duration. The duration is the source of truth for the math.
-
Per-dose values round to the nearest 0.25 throughout the practical range so no day asks for a hard-to-measure dose like 13.847 mg or 0.996 mg. Sub-0.25 doses (the bupe volumetric tail 0.1 / 0.05 / 0.02 mg) preserve precision via the finer
roundDoseladder. Total daily is recomputed from the rounded per-dose × N so the numbers actually multiply out — and uses the same 0.25 grid as per-dose, so 11.75 × 3 reads as 35.25 instead of being rounded to 35.3 by the 0.1-grid branch. -
Copy AI prompt button copies a self-contained ChatGPT / Claude prompt to the clipboard. The prompt embeds the reader’s plan (substance, doses, schedule, total medication) and asks the LLM to help personalize it by asking the reader about their context (history, polysubstance use, support, etc.). Explicit caveats included: community-derived, not clinical, flag anything dangerous.
-
Save as PDF opens a self-contained printable view in a popup window — separate from the site’s layout chrome (header, sidebar, footer, theme picker, crisis button) — and auto- triggers the print dialog. The popup carries its own minimal styles tuned for paper (system font, light grey accents, page- break-avoiding rows, half-inch margins). Reader picks “Save as PDF” as the destination. The popup closes itself after the print dialog is dismissed. If popups are blocked, the calculator falls back to printing the current page with its
print:hiddenTailwind classes — not as clean but still works. -
Bupe per-dose tooltip: each bupe per-dose value in the schedule table shows a small ❓ icon next to the dose. Hovering (or tapping on mobile) opens a tooltip listing which /16-strip pieces the dose equals across all three commercial Suboxone strip sizes (8 / 4 / 2 mg). Math validates: a 1/16 piece is 0.5 mg from an 8 mg strip, 0.25 mg from a 4 mg strip, 0.125 mg from a 2 mg strip. Doses that don’t snap to clean /16ths get a “volumetric dosing recommended” hint instead. The ❓ icon is hidden in print.
-
Dose-count transitions are called out loudly in the schedule table. When the calculator drops doses-per-day (e.g. 4×/day → 3×/day), an amber-bordered banner row above the transition reads ”↓ Drop dosing to N×/day starting Day X” and the times-per-day cell on that row is bold.
-
Page intro stripped. The calculator is the first thing on
/resources/taper-calculatornow; the explanatory prose moved below it. The in-form substance notes already cover the substance-specific framing the intro was repeating. -
Default substance is 7-OH, not bupe. The audience landing on quitting7oh.org is overwhelmingly there for 7-OH; bupe is a later-funnel concern. Dropdown order matches: 7-OH first, then bupe.
-
Duration presets are now substance-aware. Bupe keeps the 5 / 10 / 14 / 21 day presets that line up with the published Suboxone Rapid Taper columns. Everything else (7-OH, MGM-15 / MIT-A / DHM, pseudo, leaf, SR-17 custom) starts at 21 days and stretches into months: 21 days · 1 month · 2 months · 3 months. Backend math still operates in days (
pct = 1 − (jumpOff / totalStart)^(1/days)); the labels read in months for the longer presets because that’s how readers think about a taper that runs that long. -
Jump-off can be 0. Setting the jump-off to 0 was previously rejected because multiplicative % math can’t reach zero in finite steps and the schedule came out empty. Fixed by running the percentage curve to a substance-aware floor (0.02 mg for bupe — the smallest documented volumetric tail value; 2% of the starting total or 0.5 units, whichever is larger, for other substances) and then appending a single 0-dose day as the explicit “taper-all-the-way-off” step. The chart and table both extend cleanly to zero.
-
SR-17 has its own duration presets. The community-validated SR-17 course range is 5 to 14 days, much shorter than the 21-day-to-three-month range that fits 7-OH, MGM-15, pseudo, and leaf. SR-17 now shows 5 days · 10 days · 14 days · Custom. The earlier auto-emitted “100 → 75 → 50 → 25 → jump” community pattern is gone; SR-17 now runs the same percentage math as the rest, scaled to the reader’s chosen duration.
-
Tablet / capsule size input for non-bupe substances. The field starts blank; the reader optionally fills in the size of each tablet, capsule, or dose unit they actually have. A placeholder shows the typical value (7-OH 15 mg, MGM-15 / MIT-A 10 mg, pseudo 5 mg, kratom capsule 0.5 g, SR-17 25 mg) without pre-filling. When a size is set, each per-dose value in the schedule table shows a ❓ icon; hovering reveals the equivalent in tablets / capsules rounded to the nearest quarter (e.g.
1¼ tablets (15 mg per tablet)). Mirrors the bupe strip-equivalents tooltip already on bupe rows. The form’s caveat names that real tablets vary in content between products and batches. Capsules and powder open and can be poured out, so quarter precision applies to both. -
7-OH (concentrated)→7-OHin the substance dropdown. The (concentrated) parenthetical was redundant on a site whose entire audience is here for the concentrated synthetic; it just added visual noise to the most-picked option. -
Substance-aware default duration. 7-OH, MGM-15 / MIT-A, pseudo, and leaf now default to 1 month (30 days) instead of 2 months. Bupe still defaults to 14 days (the most-used Suboxone Rapid Taper column); SR-17 defaults to 10 days (middle of its 5–14 day range). Switching substances resets duration to the new substance’s default, matching how per-dose, times-per-day, jump-off, and tablet size already reset.
New page: Taper Calculator
New page at /resources/taper-calculator
with a unified taper calculator covering buprenorphine, 7-OH,
MGM-15 / MIT-A / DHM products, mitragynine pseudoindoxyl,
kratom leaf, and SR-17. Reader enters the current daily dose,
the jump-off dose they want to land on, and a taper speed; the
calculator emits a schedule chart (Recharts via shadcn), a
day-by-day or week-by-week table, total medication required,
and a substance-specific note linking to the relevant
compound / protocol pages.
Math model:
- Four difficulty levels on one axis — Easier (5%/week), Clinician recommended (10%/week, CDC default), Harder (20%/week), Super Hard Mode (50% per step) — plus a “Custom” option where the reader enters their own percentage.
- For buprenorphine, the calculator pulls from the established short-taper schedules on Suboxone Rapid Taper when the starting dose matches a published row (2, 4, 6, or 8 mg) and the chosen speed maps to a published length. For non-matching combinations, it falls back to percentage math. Setting a jump-off below 0.25 mg extends the tail with the page’s published volumetric sub-0.25 mg doses (0.1 → 0.05 → 0.02 mg).
- For SR-17, picking a named speed emits the community 4-day descending pattern (100 → 75 → 50 → 25 → jump) scaled to the reader’s actual maintenance dose. Custom percentage available for non-standard courses.
- For everything else, weekly percentage math at the chosen speed.
Form follows site theme tokens — works in all 8 color variants
and both light and dark mode. shadcn chart, select, label,
and card components added on first use; recharts brought in
as a dependency.
/resources/ category blurb updated to mention the calculator
alongside the existing entries.
Community page: custom Discord widget replaces the iframe
Swapped the iframe-based Discord embed on
The Community for a custom widget
(DiscordCard.tsx) that pulls
the same live data (server name, online count, member avatars,
status dots) directly from discord.com/api/guilds/{id}/widget.json
and renders it as a styled card using the site’s theme tokens
(bg-card, text-foreground, text-primary, border-border).
Followups:
- Theme variants now match. The site has 8 color variants on top
of light/dark/system; the iframe only honored
theme=dark|light, so on every non-default variant the embed felt like a foreign object dropped on the page. The custom card inherits whichever variant the reader picked. - No Discord JS / iframe sandbox. One JSON fetch on idle; renders nothing while loading, falls back to a small “Join the Discord →” link if Discord rate-limits or is unreachable.
- Same features: server name, live online count with a pulsing green dot, scrollable member list with avatars and status dots (online green / idle amber / dnd rose), full-width Join button. Channel list and per-member game activity dropped to keep the widget clean.
- The community page converted from
.mdto.mdxso it can import the React component. URL unchanged.
Followup: the first render of the widget leaked
prose-recovery typography styles (margins on img, bullets and
padding on ul/li) into the component, blowing up the spacing
and pushing status dots out of position. Fixed by adding
not-prose to the component’s outermost div plus explicit m-0
/ list-none / block overrides on the avatar and list
elements.
Default theme variant: zinc → stone
Switched the default theme variant from zinc (the cool grey
monochrome) to stone (the warm neutral). The site now opens in
stone for any visitor without a theme-variant localStorage
entry. Existing readers who explicitly picked a variant are
unaffected.
What changed:
- The bare
:root { … }and.dark { … }blocks now share their declarations with[data-theme='stone']. Zinc moved to a scoped[data-theme='zinc']-only block. ThemeScript.astroandThemePicker.tsxdefaults swapped from'zinc'to'stone'. The “no localStorage entry = the default” convention is preserved (picking stone removes the storage key; picking anything else writes it).- The zinc-only prose-link tint from the previous entry still fires when the reader explicitly picks zinc.
Zinc theme: prose links now distinguishable from body text
The zinc theme variant is monochrome by design: --foreground is
240 10% 8% and --primary is 240 8% 18%, both desaturated
and only a hair apart in lightness. Prose links inherit
text-decoration-color: var(--primary) and so were rendering
the same shade as body text — essentially invisible as links.
Added a zinc-only override that gives prose anchors (excluding
the # heading anchors) a muted-blue tint
(hsl(220 55% 38%) light, hsl(220 70% 72%) dark). The rest of
the zinc palette (buttons, sidebar primary, anything else using
--primary) is unchanged — the zinc aesthetic stays monochrome
where it should.
Discord live presence: homepage online-count badge + community page widget embed
The Discord card on the homepage now shows a live “N online”
badge next to the “Discord” label, with a small pulsing green
dot. Implemented as a small React island
(src/components/DiscordOnlineCount.tsx) hydrated client:idle,
fetching discord.com/api/guilds/{id}/widget.json from the
client. Renders nothing on fetch failure (rate limit, offline,
widget disabled) so the static card never shows an error. The
“you’re not alone, N people are here right now” signal at the
moment of need was the rationale.
The full Discord widget iframe is now embedded on
The Community under the Discord section,
so visitors can see the server membership preview, the live
online count, and the “Join Server” button without leaving the
page. 350×500 iframe with max-width: 100% so it shrinks on
narrow screens, loading="lazy" so it doesn’t block initial
paint, and the same sandbox attributes Discord recommends.
2026-06-05
Rapid taper: total-bupe-required per schedule + every schedule lands at 0.25 mg
Each of the five taper-schedule tables on Suboxone Rapid Taper (2 mg, 4 mg, 6 mg, 8 mg, and the bottom-of-the-taper tail) now has a “Total bupe” row so the reader can see at a glance how much medication the taper calls for. Math verified independently for every schedule.
Same pass surfaced an inconsistency: the prose said “all schedules end at 0.25 mg” but five schedules ended at 0.5 mg. Fixed:
- 6 mg / 5-day: day 5 changed 0.5 → 0.25 (total 13.25 mg)
- 6 mg / 7-day: day 7 changed 0.5 → 0.25 (total 22.25 mg)
- 8 mg / 5-day: day 5 changed 0.5 → 0.25 (total 17.75 mg)
- 8 mg / 7-day: day 7 changed 0.5 → 0.25 (total 29.25 mg)
- 8 mg / 10-day: previously a mislabeled 8-day schedule ending at 0.5 mg. Rebuilt to actually run 10 days, top-loaded like the 14-day: 8, 8, 6, 5, 4, 3, 2, 1, 0.5, 0.25 (total 37.75 mg).
The final-day 1 → 0.25 step on the squeezed 5- and 7-day schedules is steep; the bottom-of-the-taper tail (0.1 → 0.05 → 0.02) is the soft-landing tool for readers who find it sharp.
Suboxone page title shortened so the sidebar highlight fits
“Suboxone (Buprenorphine/Naloxone)” was wrapping to two lines in the sidebar; the active-page highlight didn’t fit the second line cleanly. Shortened the title to “Suboxone” so it sits on one line like its siblings. Added “Suboxone is the brand name for buprenorphine/naloxone” inline in the opening sentence so new readers still get the disambiguation.
2026-06-04
MIT-A / DHM page rewrite + MGM-15 chemistry corrections
The MIT-A / DHM compound page (currently at
/compounds/mit-a-dihydromitragynine) was wrong on the underlying
chemistry. It framed “DHM” as 1,2-dihydromitragynine (a reduction
of mitragynine itself) and as a distinct compound from
MGM-15. The forensic-chemistry literature
(CFSRE monograph, UNODC substance detail, Matsumoto 2014) is
consistent: DHM is the same compound as MGM-15 —
dihydro-7-hydroxymitragynine, a reduction product of 7-OH, not of
mitragynine. The page has been rewritten end-to-end to correct
this and to document what’s actually in products sold under those
labels.
Eight beats: TL;DR with the correction up front, community reports (effect comparisons, dose patterns, withdrawal severity, inter-product and batch variability, COA references, geographic concentration), the chemistry (selective NaBH₄ reduction of 7-OH gives MGM-15; selective reduction of mitragynine doesn’t give a clean product), how standard GC-MS testing thermally reverts MGM-15 to mitragynine and misses it, the regulatory landscape (Florida 400-ppm 7-OH threshold; Louisiana; Ohio explicitly naming dihydro-7-hydroxy mitragynine in December 2025), marketing patterns, open questions and limits, and what this means for a reader being sold one of these products.
Sourcing combined Playwright-driven Reddit research (~50 substantive threads across r/quitting7oh, r/Kratom_7OH, r/Quittingfeelfree, r/quittingkratom, r/Life_After_7oh, r/7ohbuddies, r/recoverywithoutAA, and several smaller subs) for the empirical side, and peer-reviewed chemistry + the CFSRE forensic-chemistry monograph for the technical and analytical side. Community reports independently confirm the GC-MS reversion pattern, the geographic concentration in 7-OH ban states, and the “marketed as MIT but feels like 7-OH” effect-vs-label dispute that the chemistry hypothesis predicts.
Same commit also corrected four factual errors on the MGM-15 page that the chemistry-verification agent caught against Matsumoto et al. 2014:
- MGM-16 fluorine position: noted as 10-fluoro per natural-product numbering with the 9-fluoro IUPAC convention referenced (previously only 9-fluoro)
- MGM-15 receptor Ki: corrected to ~6.4 nM MOR and ~16 nM DOR (previously listed as ~28 nM and ~59 nM with no source)
- 240×-morphine potency: attributed to MGM-16 only (previously implicitly attributed to MGM-15 in places)
- 15-hour half-life claim: removed (no traceable primary source; community-reported 9–15 hour duration noted as anecdotal until human PK is published)
Also: the Why Suboxone Might Not Be Working MIT-A subsection updated to reflect that “MIT-A or DHM” products contain MGM-15 plus mitragynine, with induction guidance pointing at the MGM-15 page.
Slug rename executed: the page moved from
/compounds/mit-a-dihydromitragynine to /compounds/mit-a-dhm.
The old slug encoded the wrong chemistry into the URL (since
DHM is dihydro-7-hydroxymitragynine, not dihydromitragynine). The
new slug matches what users actually search for. 301 redirects
added for both no-trailing-slash and trailing-slash variants of
the old slug; the previous Batch 2 redirect (which pointed
/mit-a-dhm at the wrong-chemistry slug) was reversed.
Internal cross-references swept; check-redirects.sh pair
updated.
Follow-up correction: the Marketing section’s MIT-A bullet originally guessed at what “-A” stands for. Vendors actually market it as “Advanced Alkaloids” (wellness-style branding that papers over the actual composition). Corrected to name the marketing claim accurately and note that the unnamed alkaloid content includes MGM-15 in the products that have been tested.
Community routing: only our resources for calls-to-action
New CLAUDE.md rule: when telling readers where to go for community support, name only the Discord and r/quitting7oh. Other subs can be named accurately in sourcing context, but ours go first in that list. The line between routing (only ours) and sourcing (others OK, ours first) is the distinction the rule turns on.
Audit pass identified two existing violations and fixed both:
- The reach-out ladder on Thinking About Using?
listed
r/quittingkratomalongside r/quitting7oh as a routing destination. r/quittingkratom removed; routing now goes to Discord + r/quitting7oh only. - The “Community support” item on Tapering Off 7-OH
led with
r/quittingkratom, then r/quitting7oh and the Discord, in a routing voice. Rewritten to route to Discord + r/quitting7oh only.
The mitragynine page itself was rebuilt to follow the rule in both routing and sourcing contexts (Discord + r/quitting7oh as the only routing destinations; r/quitting7oh first in the two sourcing lists that name other subs).
Mitragynine page restructure: lead with the playbook; drop leaf-bridge bullet
The new page restructured so the practical “how this path works” content lands first. The “Three step-down paths” orientation section dropped (the TL;DR already routes to alternates inline). The “Bringing in a clinician” section’s closing community-routing paragraph rewritten to point only at our resources. “Closing” section removed (restating the takeaway is slop).
The “Bridge doses” section in “The path in practice” had a kratom-leaf-powder bullet that didn’t belong on a page scoped to concentrated mitragynine. Plain-leaf use lives on its own page (Quit 7-OH with Kratom Leaf); the mitragynine page now lists two on-topic categories: mitragynine-dominant extract tablets and shots, and “enhanced” kratom (leaf concentrated to ~10% mitragynine). The dose-equivalence paragraph rewritten around the extract dose ranges in the corpus, since the leaf-based equivalence was the only specific dose ratio the community articulates and it’s not this page’s substance.
New page: Quit 7-OH with Concentrated Mitragynine
New page at /other-tools/quit-7-oh-with-mitragynine covering the
mitragynine-extract step-down as a documented community path off
concentrated 7-OH. The page sits alongside Quit 7-OH with Kratom
Leaf in the “Bridges off
the synthetics” sidebar group.
Sourcing was unusual for the site: clinical literature on this specific substitution doesn’t exist, so the page is built on primary-source community research (Playwright-driven Reddit scraping across r/Quittingfeelfree, r/quittingkratom, r/Life_After_7oh, r/Kratom_7OH, r/7ohbuddies, and adjacent partial-mu-agonist recovery subs for methodology cross-check) plus peer-reviewed mitragynine and 7-OH pharmacology (Kruegel 2016, Obeng 2021, Hill 2022, Huestis 2024, Singh 2014, Berthold 2022). Eight beats: how this differs from the other taper paths, the receptor-profile logic, what community reports describe (dose ranges, stabilization, taper structure, total duration, outcomes, predictors), risks specific to this path with the contamination concern foregrounded, sourcing in categories with no brand or vendor names, comparison to the other paths, clinician handoff, and an honest closing. The page explicitly surfaces the counter-position from r/Life_After_7oh that substitution paths aren’t legitimate, alongside the r/Quittingfeelfree and r/7ohbuddies endorsements, without picking a side.
SEO-focused slug renames: tapering-with-* → quit-7-oh-with-*
The two bridge pages renamed to lead with the search behavior the audience actually types (“quit 7-oh with kratom leaf”) instead of the internal site framing (“tapering with leaf”). The bridge IS the quit strategy; the taper of the bridge is the second half.
| Old | New |
|---|---|
/other-tools/tapering-with-kratom-leaf | /other-tools/quit-7-oh-with-kratom-leaf |
The mitragynine page is brand new and ships at the new slug
directly. 301 redirects added for both no-trailing-slash and
trailing-slash variants of the leaf-taper old URL. The pre-Batch-1
/other-tools/tapering-with-leaf redirect updated to point at the
new slug directly (one hop instead of two). Titles updated to
match the new slug pattern: “Quit 7-OH with Kratom Leaf” and
“Quit 7-OH with Concentrated Mitragynine”. check-redirects.sh
pair list extended; the leaf-rename ships at 26 total verified
pairs (52 with trailing-slash variants).
SEO slug renames (Batch 2)
Fifteen more slug renames from docs/seo-suggestions.md Batch 2: the
twelve medium-risk renames in the “Recommended renames” table plus
three judgment-call renames. Same workflow as Batch 1: 301 redirects
added to public/_redirects with trailing-slash destinations,
internal-link sweep across content, components, pages, and
src/lib/categories.ts.
| Old | New |
|---|---|
/post-acute/what-is-paws | /post-acute/paws-post-acute-withdrawal |
/post-acute/kindling | /post-acute/kindling-and-relapse |
/post-acute/long-term-outlook | /post-acute/7-oh-recovery-timeline |
/post-acute/impending-doom | /post-acute/impending-doom-anxiety |
/start-here/thinking-about-using | /start-here/cravings-and-relapse-thoughts |
/compounds/pseudo | /compounds/mitragynine-pseudoindoxyl |
/compounds/mit-a-dhm | /compounds/mit-a-dihydromitragynine |
/pharmacology/minor-alkaloids | /pharmacology/kratom-minor-alkaloids |
/resources/telehealth | /resources/telehealth-for-suboxone |
/mat-suboxone/suboxone-cows | /mat-suboxone/sows-cows-induction-guide |
/mat-suboxone/suboxone-isnt-working | /mat-suboxone/why-suboxone-isnt-working |
/mat-suboxone/suboxone-risks | /mat-suboxone/long-term-suboxone-risks |
/about/community | /about/the-community |
/for-you/start-here | /for-you/welcome |
/for-loved-ones/start-here | /for-loved-ones/welcome |
The three judgment-call renames: /about/community → the-community
matches the page title; the two start-here slugs in /for-you/ and
/for-loved-ones/ were colliding conceptually with /start-here/ as
a category, and renaming both to welcome resolves that ambiguity for
crawlers while staying consistent with /start-here/welcome. The
QuickMD redirect destination updated alongside the telehealth rename
so it lands on the new URL in one hop. scripts/check-redirects.sh
extended to cover all 25 Batch 1+2 pairs.
SEO slug renames (Batch 1)
Ten slug renames from docs/seo-suggestions.md Batch 1, all low risk
and high search impact. 301 redirects added to public/_redirects
for each so existing inbound links keep working; internal-link sweep
across content, components, pages, and src/lib/categories.ts so the
site itself never hits a redirect.
| Old | New |
|---|---|
/other-tools/helper-meds-info | /other-tools/helper-meds |
/other-tools/mega-vit-c-info | /other-tools/mega-dose-vitamin-c |
/other-tools/quitkit-info | /other-tools/quit-kit |
/other-tools/sr17018-info | /other-tools/sr-17 |
/other-tools/peptides-info | /other-tools/peptides-for-withdrawal |
/mat-suboxone/suboxone-info | /mat-suboxone/suboxone-for-7oh |
/mat-suboxone/sublocade-brixadi-info | /mat-suboxone/sublocade-brixadi |
/other-tools/tapering-with-leaf | /other-tools/tapering-with-kratom-leaf |
/start-here/withdrawal-help | /start-here/7-oh-withdrawal-help |
/start-here/paths-off | /start-here/how-to-quit-7-oh |
The -info suffix that appeared on six pages was internal-doc
shorthand from the retired Discord-export pipeline; dropping it
matches what readers search for. The remaining four added missing
primary keywords (7-OH, kratom, etc.). All ten files keep their
content unchanged; only the URL slug + the internal cross-link
graph + categories.ts PINNED_PAGES / CATEGORY_GROUPS entries
moved.
Page work
- Suboxone Rapid Taper picked up a “Bottom of the taper” section
with a three-day volumetric tail extension (0.1 → 0.05 → 0.02 mg,
explicit mix instructions for each); a note that some readers go
down to around 0.018 mg/day before jumping; Sublocade/Brixadi as
the escape route if the rapid taper still isn’t working. The 8 mg
starting-dose section gained 14- and 21-day extended schedules
behind a “playing with fire” warning. The 8 mg section’s two
tables and two warnings consolidated into one combined
5/7/10/14/21-day table with a single warning covering both “this
is a lot” and the trade-off of extending. The schedule tables
(2/4/6/8 mg) are now native
<details>disclosures, default- closed, with styled Tailwind summaries; the page is no longer a wall of stacked tables. A callout-reduction pass cut the page from 7 callouts to 3: three stacked top-of-page warnings collapsed into two inline intro paragraphs; the synthetic-users warning was rewritten more accurately (the schedules aren’t uniformly wrong; induction timing and bupe coverage are what differ) and routes to/mat-suboxone/suboxone-isnt-working#if-youve-been-on-long-acting-synthetics-or-stacked-compounds. Volumetric tail and the “Only have 8 mg strips?” callout reframed to “Most prescriptions come as 8 mg strips”; same routing, less implication that 8 mg is the awkward edge case. - Custom Suboxone Dosing volumetric section rewritten end-to-end. Old version was Subutex-tablet-only with an H1 mid-page plus duplicate H2 headers. New version covers films and tablets explicitly with a validated math table (five dilution ratios from 2 mg / 8 mL through 8 mg / 160 mL), specific materials (oral syringe with 0.1 mL marks, glass mixing vessel, distilled water, optional USP propylene glycol at 3:1 water:PG), buprenorphine HCl solubility sourced to US Pharmacist, glass-vs-plastic storage stability sourced to PMC5517336, the TripSit volumetric calculator linked, and a bioavailability caveat surfacing the dissenting r/suboxone thread. Math table later reordered with 8 mg rows on top and a 400 mL / 0.02 mg/mL row added to match the 8 mg three-day tail.
- Homepage Discord card given a full emerald-green emphasis treatment (border-2, fill, hover, all the parts of the amber crisis card) to read as “live, right now” at the same visual weight as the crisis card.
Infrastructure
- Public changelog page at
/about/changelog, generated from thisCHANGELOG.mdbyscripts/sync-site-changelog.mjs. The sync runs as thenpm run prebuildhook so the page rebuilds automatically on every CF Pages deploy. Idempotent: re-running with no upstream changes leaves the page’slast_updateddate alone. Sits under Site & Community at sort=6. - CHANGELOG format change. Dropped the
[Unreleased]prefix that came from the Keep-a-Changelog template. Date headers are now## YYYY-MM-DD; the site doesn’t tag releases (every push tomaindeploys) so the unreleased semantics never carried meaning.
CLAUDE.md rule additions
- Run the stop-slop pass on every prose edit, and report it. Every prose edit goes through the stop-slop ruleset before reporting done; the user-facing summary explicitly names that it ran and what it changed (or “no changes needed”). The point is visibility: a silent pass is indistinguishable from a skipped one.
2026-05-30
New pages
- NAD+ IV Therapy (
other-tools/nad-iv-therapy.md). Sourced reference: protocols, doses, methylation pairings, provider categories, and cost above the fold; honest evidence pass below (Blum 2022 pilot, the Springfield “90%” figure framed as marketing per NPR’s 2019 investigation, no RCTs in OUD/AUD, cellular-delivery question, Elysium critique with competing-product COI flagged, comparison to evidence-based alternatives). No clinic links. - Peptides for Opioid Withdrawal (
other-tools/peptides-info.md). BPC-157, Selank, Semax, DSIP/Emideltide, TB-500, plus brief notes on KPV, GHK-Cu, Thymalin, Epitalon, Cerebrolysin. Per-peptide evidence labeled: Dick 1983/1984 for DSIP (the strongest withdrawal evidence, and the bar is low), Kost 2001 for the Selank/Semax enkephalin-degradation mechanism, no human RCT for BPC-157 or TB-500. Safety section on gray-market source quality (Finnrick / Janoshik testing-lab data), injection sterility, BPC-157 angiogenic cancer-promotion concern, WADA S0 prohibition. FDA PCAC July 2026 review noted as upcoming. - Endocrine Recovery After 7-OH and Kratom
(
post-acute/endocrine-recovery.md). Symptom-recognition lead → HPG/HPA mechanism → testing → recovery dynamics → treatment → supplements → parallel men-specific and women-specific sections → PAWS connection. Women’s section built to a strict integrity discipline: every women-specific claim sourced to a women-specific study (Daniell 2008, Abs 2000, Schmittner 2005, Zamboni 2019); the Bawor 2014/2015 reconciliation (women’s testosterone not significantly affected; cycle disruption is the salient finding) explained directly; literature gaps flagged rather than papered over. The women’s-section human-reviewer step from the brief was not done; flagged for community review before treating the page as final. - Black seed oil entry on vitamins-supplements (new row in the “Physical symptoms” chart + a dedicated prose entry) with explicit thin-evidence framing: one small uncontrolled 2008 Pakistani study (Sangi et al., n=35), rodent thymoquinone data, no human RCT.
Site structure and navigation
- Homepage Live community section rebuilt as two cards mirroring the hot-list pattern. r/quitting7oh leads (searchable archive, longform stories); Discord follows. “About the community” remains as a small text link below.
- Footer Community column added to the disclaimer row (4-up on
desktop, 2x2 on tablet, stacked on mobile). Full-domain anchor
text (
reddit.com/r/quitting7oh,discord.gg/quitting7oh) for backlink SEO. - Category blurbs in
src/lib/categories.tsbrought current.other-toolsdropped the stale naltrexone reference and gained NAD+ IV and peptides.post-acuteswapped cravings/hormones placeholders for endocrine recovery and naltrexone. Homepage “Browse by topic” reads these at build time so the change propagates automatically. post-acutesort cascade to accommodateendocrine-recoveryat sort=7 in the Specific Symptoms cluster; kindling, long-term- outlook, and the four naltrexone-* pages bumped by 1.
Cross-link sweep
- Adjuncts pages reference each other coherently: vitamin C ↔ NAD+ IV ↔ peptides ↔ vitamins-supplements ↔ helper-meds. Tapering-7oh and the PAWS page route into the new adjunct pages where the symptom fit is right.
- Endocrine recovery cross-links bidirectionally with PAWS and long-term outlook.
CLAUDE.md rule additions
- Keep category blurbs in sync with content. When adding or
moving a substantive page, the parent category’s blurb in
src/lib/categories.tsis reviewed and updated in the same commit. - Keep
CHANGELOG.mdcurrent. Substantive changes get logged here; the rule documents what counts as substantive and the format conventions.
2026-05-28
Page work
- SOWS & COWS Guide rebased around SOWS as the primary at-home
scale. Slug unchanged at
/mat-suboxone/suboxone-cows; title and prose now lead with SOWS since most readers self-score through telehealth. Self-scoring and interpretation tables reordered to put SOWS first; threshold language and half-life / reminder sections made score-neutral. The mgm-15 page got the same SOWS-first framing in its COWS/SOWS callout.
2026-05-27
Page work
- Bernese Method (Micro-Induction) restructured to put the technique front-and-centre. A two-target dose schedule (4 mg/day community low-and-slow vs 8 mg/day published BC 7-day) sits immediately after the intro, with variants and pharmacology below. Strip-cut math deferred to the Custom Suboxone Dosing page rather than duplicated. “Your opioid” / “original opioid” phrasing replaced with explicit 7-OH (or MGM-15 / MIT-A / pseudo) framing in the practical sections; “full agonist” preserved only where it’s the right technical term.
- Tapering Off 7-OH front-loaded with a five-bullet “What to know before you start” summary covering the redose-discipline reality, the high-dose-easy / low-dose-grind shape, the jump-off endpoint, and the multiple endpoints. Phase table moved up alongside the bullets; the four-phase narrative descriptions stay below for readers who want depth.
Editorial passes
- Footer AI disclaimer stop-slop pass: removed both em-dashes, the “augment” corporate phrasing, the stacked adjectives, and “frankly.”
- ULDN page: BID → twice-daily cleanup.
- Sidebar pinned shortcuts picked up “Thinking about using?” for the craving-spike entry point.
2026-05-26
Site structure
- Beta banner removed from the layout. Site no longer marks itself as beta in the chrome.
- Hero search box dropped from the homepage. The header search is the canonical entry point; the hero search was redundant visual weight on a page already dense with funnel cards.
2026-05-25
A big day. The stop-slop infrastructure landed, several new pages went up, the sidebar got a substantial reorganization, and a site-wide sourcing / voice pass touched dozens of files.
Stop-slop infrastructure
- Vendored the stop-slop ruleset to
docs/stop-slop/(Hardik Pandya’s MIT-licensed skill snapshot, with project-local additions documented in the snapshot’s CHANGELOG). CLAUDE.md now points to it as the canonical anti-AI-writing-pattern source rather than duplicating ~500 lines of pattern rules inline. - Site-wide stop-slop sweep against the updated ruleset (mechanical + voice passes). Touched compounds and MAT pages most; the mgm-15 and suboxone-info pages each got their own follow-up voice pass.
New pages
- How AI Was Used (
about/how-ai-was-used.md). About-section page documenting how the site uses AI in drafting. The about category was renamed and the medical disclaimer tightened in the same pass. - Paths Off 7-OH (
start-here/paths-off.md). Consolidates the six community-discussed paths off (Suboxone, SR-17, leaf taper, helper-meds cold turkey, etc.) into one decision-support page. Replaces scattered enumeration across multiple pages. - Tapering Off 7-OH (
for-you/tapering-7oh.md). Initial creation: phase mapping (early cuts → middle range → lower-dose plateau → jump-off), variance acknowledged, multiple endpoints named. The front-load happened on 2026-05-27 (above). - Where the Site Stands (
about/where-we-stand.md). Position statement (shipped 2026-05-24; logged here for cross-reference with the about-category work).
Navigation and structure
- Naltrexone family moved from
other-tools/topost-acute/. Four pages (overview, normal-dose, LDN, ULDN) plus the existing links from PAWS and depression-and-anhedonia. The framing shift is editorial: naltrexone is post-acute support, not a way to come off opioids. - Sidebar reorganized with collapsible category groups and a reference-section separator between the recovery-focused categories (Start Here, For You, For Loved Ones, MAT/Suboxone, Adjuncts, Post-Acute) and the reference-focused ones (Compounds, Pharmacology, Resources, Site & Community).
- Sidebar pinned shortcuts and sub-groups in long categories. Pinned-shortcuts rail at the top (configurable list); sub-groups inside MAT/Suboxone, For Loved Ones, Adjuncts, Post-Acute so the long lists don’t read as one flat dump.
- Homepage layout tightened. Added Paths Off 7-OH and the For Loved Ones funnel cards. Mobile sidebar wired up. COWS rubric on suboxone-info converted to a 3-column table.
- Category emojis and 🆘 replaced with Lucide icons across the sidebar, category index, and the floating Crisis button. The Crisis button now uses LifeBuoy.
Theme and design
- Zinc as default theme variant; light-theme rework; picker tooltip added so the dropdown is discoverable.
- OG image dropped in favor of a clean text-only social card. Readers in withdrawal don’t need a banner image every time a page is shared.
Meetings widget
- Next-meeting widget added with structured-data output and a
full meetings-table component for the schedule page. Single source
of truth in
src/data/meetings.ts. A follow-up later in the day added a “Next up at TIME” line when the current meeting is live.
Content / sourcing corrections
- 7-OH binding-affinity vs antinociception-potency conflation corrected on the 7-OH compound page. Earlier copy had inflated the binding-affinity numbers using antinociception-assay potencies from animal studies, which is not what those studies measured.
- “Stop calling 7-OH and SR-17 ‘an opioid’” reframe. Both are mu-opioid-receptor agonists, but calling them straight opioids carries pharmacology baggage (full-agonist OD risk profile, legacy-opioid framing) that doesn’t fit. New framing: receptor-agonist that “walks and talks like” an opioid.
- Protocol-first rewrites of dopamine, depression-and-anhedonia, naltrexone, SR-17, and mega-dose-vitamin-C pages. Lead with the practical protocol; push the long-form pharmacology and rationale below.
- mgm-16 forensic claims tightened on the MGM-16 compound page; the speculative “If you’ve encountered MGM-16 in a product” section was stripped, the California paper reference reframed as a single unsourced mention, and “I” framing removed.
CLAUDE.md rule additions
- Don’t make multi-year claims about the synthetics. Concentrated 7-OH emerged in U.S. consumer markets around 2023; the kratom- synthetic recovery community took shape in early 2024. No reader has multi-year dependence on the synthetics specifically. Claims like “years of stacked use” should reframe as severity, not time.
- Soften MAT-fit certainty. The pages don’t get to declare which path is right for any individual reader.
2026-05-24
New pages
- The Pink Cloud (
post-acute/pink-cloud.md). Names the honeymoon-stretch phenomenon of early recovery: weeks-to-months window of unusual mood lift and energy after acute resolves, followed by settling into a more grounded baseline. Not a sign recovery is failing; documented pattern. - Where the Site Stands (
about/where-we-stand.md). Position statement on the site’s posture toward vendor capture, the kratom industry’s regulatory lobbying, AI use in drafting, monetization, data, and editorial bias. Plain language; no hedging.
Page work
- Suboxone Rapid Taper picked up the rapid-taper schedule tables (initial version, before the 2026-05-27 restructure and the 2026-06-04 collapsible / bottom-of-taper additions). Micro-induction practical sourcing added alongside; the framing is “Suboxone is one path, not the default first-attempt tool.”
- Suboxone (suboxone-info) got three practical induction-protocol notes; a high-dose-bupe-rescue note for precipitated withdrawal (with the Laxton 2025 case-report cite); the COWS/SOWS section trimmed to a reference + link to the dedicated COWS/SOWS page; cross-link to COWS in induction; the practical-tips “wait an hour after waking up” tip; SOWS PDF + SAMHSA TIP 40 references added for full sourcing.
Editorial passes
- Footer AI disclaimer evolution. Sharper second paragraph (failing-system framing, bigger-boats line, callback structure); later same day trimmed the “Don’t like that?” sidebar so the disclaimer reads tighter.
- Site-wide crisis-callout and medical-advice cleanup. Emoji prefixes stripped from callouts site-wide. An AI-slop paragraph on withdrawal-help got rewritten. Withdrawal-help opener tightened. The “On bans and regulation” section on Where the Site Stands trimmed to non-position-only content (the page’s job is the site’s posture; the wider regulation debate isn’t this site’s fight).
2026-05-23
shadcn/ui migration (experiment/shadcn branch)
Full React + shadcn/ui rebuild of all interactive components. Shipped
as 7 focused commits on experiment/shadcn rather than main; merge
to main after visual review in a browser.
- Phase 0 — foundation. Added
@astrojs/react, React 19, lucide- react, class-variance-authority, clsx, tailwind-merge, theradix-uiunified package. Createdcomponents.json(shadcn config),src/lib/utils.ts(cn helper),src/components/ui/directory. Defined HSL theme variables for 8 variants insrc/styles/global.cssvia the Tailwind v4@theme inline {}pattern. - Phase 1 — theme picker. Replaced
ThemeToggle.astro(icon-cycle button) withThemePicker.tsx: a shadcn DropdownMenu with two radio groups (Appearance: System/Light/Dark, Color: 8 variants). Both axes persist to localStorage; pre-paint script applies both before first render so no flash on either mode or variant switches. - Phase 2 — sidebar. First tried the official shadcn Sidebar
component but its
fixed inset-y-0 left-0positioning fought this site’s centered max-w-[88rem] layout. Replaced with a hybrid: shadcn Sheet for the mobile drawer (gets Radix focus trap, scroll lock, ESC, ARIA for free), plain<aside>for desktop sticky rail inside the centered container. Astro hamburger dispatches a'toggle-sidebar'window event the React sidebar listens for. - Phase 3 — search + back-to-top.
SearchBox.tsxuses shadcn Command (cmdk) inside a CommandDialog opened via the button or ⌘K; Pagefind runs the actual queries via the existing runtime-import pattern.BackToTop.tsxuses shadcn Button + ArrowUp icon, hydrates withclient:idle. - Phase 4 — Callout/Breadcrumbs/BetaBanner/Footer. Callout uses
shadcn Alert with three variants (info=Info, warning=AlertTriangle,
medical=Stethoscope). Breadcrumbs uses shadcn Breadcrumb. BetaBanner
is a custom React component with sessionStorage dismiss. Footer is a
plain React port using semantic tokens (
bg-muted,text-foreground,text-primary) so it follows theme-variant changes. - Phase 5 — TOC + TocMobile. Toc is a plain right-rail nav with
semantic tokens. TocMobile uses shadcn Collapsible (Radix) instead
of native
<details>. Fixed a missingimport * as React from "react"in the CLI-installedcollapsible.tsxthat broke SSR. - Phase 6 — cleanup. Deleted all superseded
.astroversions (Sidebar, ThemeToggle, SearchBox, BackToTop, Callout, Breadcrumbs, BetaBanner, Footer, Toc, TocMobile). Updatedsrc/pages/sitemap.astroto import the new React Breadcrumbs and dropped thesource_channel/manualrendering (those fields are gone with the Discord ingest retirement). Added a “UI components: shadcn/ui + React” section to CLAUDE.md documenting the new conventions, theme picker storage keys, semantic tokens, and the hamburger event bridge.
Bundle size: about +100 KB gzipped for the React runtime + Radix on pages with interactive islands. Acceptable trade-off for the consistent shadcn design system, accessible primitives, and the theme-picker UX.
Retired the Discord-export ingest pipeline
The site is now the sole source of truth for content. The ingest pipeline
that originally imported Discord channel exports into src/content/ has
been removed to prevent future sessions from accidentally re-ingesting and
clobbering editorial work.
- Deleted:
scripts/ingest-discord.mjs,scripts/channel-mapping.json, the entireimports/directory (raw Discord exports + the HTML source files for the pharmacology pages). - Removed
npm run ingestandnpm run ingest:dryfrompackage.json. Thelink:compoundsscript stays — it operates on current site content and isn’t tied to ingest. - Schema cleanup: dropped
source_channelandmanualfrom the content collection schema insrc/content.config.ts. Both fields only existed to serve the ingest pipeline:source_channelwas provenance from the originating Discord channel,manualtold the ingester not to overwrite an editorially-restructured page. With no ingester to talk to, they were dead weight. - Front-matter sweep: stripped
source_channel:andmanual:lines from all 46 content files. The site rebuilds cleanly with the trimmed schema. - Docs cleanup: updated
src/content/README.md front-matter table to
drop the removed fields and add a row for the
widefield that was already in use. Updated CLAUDE.md to remove the ingest references in the “Editing content” section and the build commands block.
User-facing Discord references (the homepage card, the
/resources/community page, “Join the Discord”
callouts, the discord.gg/quitting7oh invite link) are kept — these
are community-pointer content, not data sources, and they’re how
readers find live help.
Also retired: scripts/convert-pharma-html.mjs (the one-shot
HTML-to-Astro converter for the pharmacology charts). Its input folder
imports/_html-source/ was part of the deleted imports/ tree, and
the Astro components it produced (MinorAlkaloids.astro,
MorphineVsKratom.astro) are already committed and stable. The
generator-attribution comments at the top of those components have
been replaced with plain descriptions.
Third-party link sweep and new MAT-and-licensure page
- CLAUDE.md updated with a “Link every third party we name” rule. When we cite an outside organization, hotline, treatment program, tool, credential, government program, law, or book, link it on first mention (internally if we have a page, externally otherwise). See the rule for the curated list of canonical URLs for the most common references (SAMHSA, 988, DV/Childhelp hotlines, CARF, NARR, Medicaid, MHPAEA, ADA, FMLA, etc.).
- Audit and sweep across all new pages for unlinked third-party callouts: Salvation Army ARCs, CARF, Joint Commission, NARR, Oxford House, Medicaid, Vivitrol, VA, FQHCs, MHPAEA, ADA, FMLA, HIPAA, ACA, Department of Labor, Wage and Hour Division, EEOC, 988 Lifeline, DV Hotline, Childhelp, Poison Control, Open Path Collective, Inclusive Therapists/Therapy for Black Girls/Latinx Therapy, NA, AA, Heroin Anonymous, The Phoenix, In The Rooms, Al-Anon, Nar-Anon, Families Anonymous, Allies in Recovery, Beyond Addiction and Get Your Loved One Sober (book links). Each now has a link on first mention.
- Prominent FMLA-eligibility callout at the top of both FMLA pages (for-you/fmla-ada-job and for-loved-ones/fmla-workplace). The 12-month / 1,250-hour / 50-employees-within-75-miles requirements are the biggest gotcha; readers commonly plan around FMLA without realizing they don’t qualify. The warning is now the first thing they see, with a pointer to state programs as the alternative.
- New page: MAT & Your Professional License. Most jobs have no business in your medical info — but a defined set of regulated professions (CDL/DOT FMCSA, FAA pilots and ATC via the HIMS program, law enforcement, armed security and firearms permitting, healthcare licensure via state PHPs, federal security-clearance roles, heavy machinery/safety-sensitive positions, school bus and transit operators) treat MAT use as a licensure issue distinct from employer policy. Page covers each profession’s regulatory landscape, the practical “what to do before disclosing” sequence, and flags Vivitrol (extended-release naltrexone) as the non-controlled-substance option that sidesteps many regulatory issues that buprenorphine and methadone trigger. Cross-linked from suboxone-for-7oh, for-you/treatment-rehab, for-you/fmla-ada-job, for-you/start-here, and for-loved-ones/treatment-options.
- for-you/ sort order updated to slot the new MAT-job page between fmla-ada-job (3) and mutual-aid: mat-and-your-job (4), mutual-aid (5), sober-living (6).
Two new sibling sections: For You + For Loved Ones
- New top-level category
for-you(💚) — practical recovery resources for the person in recovery: Treatment & Rehab, FMLA/ADA/Job, Mutual Aid & Recovery Groups, Sober Living Homes, plus a section hub at/for-you/start-here. - New top-level category
for-loved-ones(🫂) — for family, partners, and friends of someone struggling: What to Expect, How to Talk (with a CRAFT primer), Boundaries Without Punishment, Safety (incorporating the full naloxone walkthrough), Asking Them to Leave the House, Treatment & Rehab (family POV), FMLA & Workplace Protections, Taking Care of Yourself, Support Groups for Family & Friends, plus a section hub at/for-loved-ones/start-here. - Old
/start-here/for-loved-onespage retired. Content redistributed across the new section’s pages where it fits topically; the substance explainer cross-links to/compounds/7-ohinstead of duplicating. Channel mapping entry forfor-loved-onesremoved fromscripts/channel-mapping.jsonto prevent re-ingest from clobbering the new editorial section. Inbound link instart-here/welcome.mdupdated. - Sidebar ordering — both new sections sit right after Start Here, with For You first (primary audience) and For Loved Ones second.
- Mutual aid directory in
/for-you/mutual-aidleads with Kratom Anonymous as the most directly applicable fellowship for this community, followed by Quitting Kratom Support (TIAWO), opioid-specific fellowships (NA, Heroin Anonymous), and the broader options (SMART, Refuge Recovery, Recovery Dharma, The Phoenix, In The Rooms, LifeRing, Women for Sobriety, Celebrate Recovery, AA, HAMS). Family-side directory in/for-loved-ones/support-groupscovers Nar-Anon, SMART F&F, Learn to Cope, TIAWO (welcomes family), Al-Anon, Families Anonymous, ACA, GRASP, plus a short CRAFT-learning sub-section pointing to Allies in Recovery and the Foote/Meyers books. - New
/resources/meeting-schedulespage — full Kratom Anonymous weekly schedule with day, time, format, cutt.ly shortlink, and resolved Zoom URL. Linked from both/for-you/mutual-aidand/for-loved-ones/support-groups. - MAT relationship: both treatment pages link out to existing
/mat-suboxone/*,/other-tools/low-dose-naltrexone,/other-tools/ultra-low-dose-naltrexone, and/resources/quickmd-inforather than duplicating that content. Family page also points readers to the corresponding For You page so they can see what their loved one is navigating, and vice versa. - Substance framing: new pages consistently distinguish kratom leaf (sometimes a valid taper tool) from concentrated 7-OH / MGM-15 / MIT-A / pseudo synthetics. Polysubstance warnings (alcohol, benzos, gabapentinoids) with SAMHSA + findtreatment.gov routing appear on every page where withdrawal, detox, or medical risk is discussed.
- House-style language: family pages use “person with a substance use disorder” / “your loved one” / “the person you love” rather than “addict.” Recovery-side pages meet the reader where they are without assuming readiness, abstinence, or shame. “Server” used only for Discord references; “community” / “site” for everything else.
2026-05-21
Site bootstrap & initial content
- New Astro 5 project with content collections, MDX, Tailwind v4
(via
@tailwindcss/vite), typography plugin, Pagefind search. - Three-state dark mode (
system→light→dark): toggle in the header, inline pre-paint script to prevent flash,matchMedialistener for live OS-theme changes while insystemmode. Tailwind v4@custom-variant darkpowers the class-based theming. - Self-hosted Inter via
@fontsource-variable/inter— no Google Fonts request. - Shiki dual-theme code blocks (
github-light+github-dark), swapped via the.darkclass. - External-link rehype plugin — auto-adds
target="_blank",rel="noopener noreferrer", and a CSS-driven indicator icon to off-site links. - Heading-anchor rehype plugin — appends a hover-revealed
#link to each H2/H3/H4. The visible#is rendered via a CSS::beforepseudo-element so it never enters the DOM as text (which Astro’s TOC extractor would otherwise pick up). - Site structure: 7 top-level categories — Start Here, Active
Withdrawal, Compounds, MAT / Suboxone, Other Tools, Post-Acute,
Resources. Sidebar nav auto-populates from content collection
entries; URL structure is
/<category>/<slug>. - Homepage: calm hero, prominent CTA for active-withdrawal SOS, category grid with page counts, hero search.
Ingest pipeline (Discord exports → site content)
scripts/ingest-discord.mjs— reads Discord channel exports from/imports/, parses messages, strips per-message metadata, joins them into clean markdown, writes tosrc/content/<category>/<slug>.md.scripts/channel-mapping.json— maps Discord channel slugs to site categories with optional title overrides.- Multi-channel exports supported — a single input file containing
multiple
# #channel-namesections splits into multiple output files. - CLI flags:
--dry-run,--file <path>,--in <dir>,--out <dir>,--verbose. Files prefixed with_andREADME.md/index.mdare skipped (treated as fixtures or exporter manifests). - Two-pass discovery for cross-linking: pass 1 scans every input
file’s channel header to build a
knownChannelsset; pass 2 transforms bodies and links**#channel-name**and bare#channel-namereferences only when a corresponding site page exists (or will exist after this run). - Fuzzy channel-name matching —
normChannel()strips non-alphanumerics and lowercases, so#mgm-15/#mgm15/#7oh/#7-ohall resolve to the same canonical page. - Discord syntax stripping in body transform:
*(edited)*markers (both inline and on header lines)*Reactions:* …reaction summary lines-# …Discord subtext lines:emoji:shortcodes → unicode (viaemojiMapin the config)<@123>and bare@usernamementions → anonymized
- Chronological message ordering — sorts by parsed message timestamp (oldest → newest) regardless of input direction. Different Discord exporters produce different orderings; sorting handles both.
- Code-fence-aware regex for title derivation and channel-ref
conversion (Python comments like
# fooinside code blocks no longer get mistakenly picked up as headings or channel references). - Auto-derived front matter: title (from channel override → first H1 → titleized channel name), description (first paragraph, truncated to 120 chars), last_updated (most recent message timestamp), category (from mapping), source_channel (the Discord channel name).
manual: truefront-matter flag — when set on an existingsrc/content/file, ingest skips that file even if its source channel appears in/imports/. Lets you protect editorially-restructured pages from being clobbered.- Description preservation on re-ingest —
existingDescription()reads the on-disk file’s front matter and prefers a non-empty hand-curated description over the auto-derived one. Makes it safe to hand-write descriptions even on non-manual files. - Compound auto-linker (
scripts/lib/compound-linker.mjs,scripts/link-compounds.mjs) — turns the first mention of each known compound (7-OH, MGM-15, MIT-A/DHM, pseudoindoxyl, Cat’s Claw) on each page into a link to its compound page. Self-link prevention (a compound page doesn’t link to itself). Skips code blocks, inline code, existing markdown links, headings, blockquotes. Idempotent. Integrated into the ingest pipeline AND runnable standalone vianpm run link:compounds. - Pre-commit hook at
.githooks/pre-commit— runsmarkdownlint-cli2on staged content files. Loose config in.markdownlint-cli2.jsonc.
Content (ingested + editorial)
Imported from Discord exports (20 pages, ingested via the pipeline)
| Category | Pages |
|---|---|
| start-here | what-to-expect, for-loved-ones |
| active-withdrawal | helper-meds-info, quitkit-info, vitamins-supplements |
| compounds | cats-claw, mit-a-dhm, mgm15, pseudo |
| mat-suboxone | suboxone-info, suboxone-cows, suboxone-custom-dose, suboxone-isnt-working, suboxone-rapid-taper, suboxone-risks, sublocade-brixadi-info |
| other-tools | low-dose-naltrexone, mega-vit-c-info, sr17018-info, tapering-with-leaf |
| post-acute | what-is-paws, sleep-recovery |
| resources | quickmd-info |
Hand-written editorial pages (manual: true)
welcome.md— 5.8 KB orientation page: who the site is for, what it is/isn’t, 6 contextual starting points (active withdrawal, considering MAT, post-acute, understanding compounds, loved ones, researchers), Discord + subreddit links, closing reassurance.sos-resources.md— emergency-ready SOS page: 988/911 callout, Discord/subreddit links up top, “in the next hour” action list, hour- by-hour timeline table, three paths from here (tough-it-out vs. Suboxone vs. SR-17018), explicit ER red flags, sleep/food/mindset sections, closing reading list.resources/community.md— full page on the Discord (discord.gg/quitting7oh) and subreddit (r/quitting7oh), with a “which to use when” comparison table, anonymity note, “how to help” section.
Editorial expansions to existing pages
suboxone-info.md(nowmanual: true) — added three major sections:- Why we start low — receptor occupancy: PET-imaging table showing the bupe receptor-occupancy curve flattens past 8 mg (2 mg ≈ 50–60%, 8 mg ≈ 85–90%, 16 mg ≈ 92%, 32 mg ≈ 95%); the cost of starting at 16+ mg is a much longer/harder taper for negligible additional coverage.
- About taper duration: 5–14 days is the realistic range for this community (not weeks/months). Per-dose-range table. Corrected after user feedback (“None of our tapers is ever weeks or months”).
- Long-term maintenance is a real option: explicit “no shame”; pharmacological framing (this community is short-taper-focused because 7-OH responds to short tapers, not because long-term is failure); when to consider Sublocade/Brixadi instead; pointer to r/suboxone for maintenance discussion.
suboxone-cows.md(nowmanual: true, renamed to “COWS & SOWS Guide”) — added full SOWS (Subjective Opiate Withdrawal Scale) section: 16 symptom items, 0–4 scoring, severity bands, induction threshold (SOWS ≥ 17 ≈ COWS ≥ 12), guidance on which scale to use in which context (COWS for clinician-assisted, SOWS for solo home induction).vitamins-supplements.md(nowmanual: true) — restructured: H1 + disclaimer first, Quick recommended list section with 5 scannable tables (Start with these / sleep / mood-and-PAWS / physical symptoms / avoid), then the detailed sections with dosing and citations.
Homepage callout — nuanced
The “trust the clinician” callout on the homepage was rewritten to acknowledge that for some MAT decisions (Suboxone starting doses, taper pacing) the community has lived experience worth bringing to the prescriber conversation, without abandoning the broader “clinician knows your situation” framing.
Site-wide language fixes
- “server” → “community”/“site” — 41 references across 13 imported
pages reviewed case-by-case. “Discord server” kept where explicitly
Discord; everything else mapped to “this community” (when referring
to people) or “this site” (when referring to editorial focus).
Changes made in
/imports/so they survive future re-ingestion.
Search
- Pagefind integrated. Lazy-loaded only when the user focuses a search input — visitors who never search download zero JS for it.
- Header search (
<SearchBox variant="header">) and hero search on the homepage (<SearchBox variant="hero">). Both wired to the same Pagefind client. - Dev-mode message improved — instead of “Search index not available
(was the site built with
npm run build?)”, it now reads “Search is only available on the deployed site. To test locally, runnpm run build && npm run preview.” - Index built into
dist/pagefind/as the post-Astro step ofnpm run build. Currently indexed: 27 pages, ~3,636 words.
Front matter & descriptions
- Schema in
src/content.config.ts— typed with zod:title, description, category, last_updated, source_channel, sort, draft, manual. - All 27 page descriptions tightened from auto-generated 150–160-char snippets (which were getting cut off in cards/snippets) to hand-written ~80–110-char summaries.
- Ingest auto-truncation lowered from 160 → 120 chars for future imports.
”Edit this page on GitHub” fix
- Astro 5’s glob content loader returns
doc.idwithout the file extension, so my oldeditOnGithubUrl(doc.id)produced…/start-here/welcome(404) instead of…/start-here/welcome.md. The page route now usesdoc.filePathand slices offsrc/content/to get the actual relative path with extension.
Deployment infrastructure
Two supported deploy paths, both wired up:
Option A — Cloudflare Pages (managed, free):
wrangler.tomlwithpages_build_output_dir = "dist".public/_headers— security + cache headers.public/_redirects— placeholder for permanent redirects.- Build command
npm run build, outputdist/, Node 22.
Option B — Docker + GHCR + self-hosted:
Dockerfile— multi-stage:node:22-alpinebuilds Astro + Pagefind, output copied intonginx:1.27-alpine. IncludesHEALTHCHECKfor orchestrators. Listens on :8080.docker/nginx.conf— gzip, immutable cache for/_astro/*, short cache for/pagefind/*, security headers (CSP-adjacent set, HSTS deferred to Caddy), trailing-slash routing viatry_files,/healthzendpoint, hidden version banner..dockerignore— excludesnode_modules,dist,imports, CI/docs, etc..github/workflows/docker-publish.yml— multi-arch (linux/amd64 + linux/arm64) build on every push tomain, publishes to GHCR asghcr.io/<owner>/<repo>with tagslatest,sha-<short>, semver (v*.*.*), and PR branches. Includes build attestation, provenance, and SBOM.docker-compose.yml— reference stack withsite(the nginx container),caddy(TLS + HTTP→HTTPS + www→apex), and an optionalwatchtowerthat polls GHCR every 5 min.Caddyfile— reverse-proxy config: automatic Let’s Encrypt via ACME, HTTP/3 enabled, HSTS, www→apex canonical redirect.docs/deploying.md— full server-setup walkthrough: VPS provisioning, DNS, Docker install, GHCR auth (public + private flows), starting the stack, day-to-day operations (push, rollback, pinning), logs/troubleshooting matrix, hardening, scaling notes.
Bugs fixed during the session
- Ingest’s title regex matched inside code fences (Python comment
starting with
#got picked as the page title). Now strips fenced code blocks before scanning for the first H1. - Channel reference double-replacement —
**#suboxone-info**was being wrapped twice ([[#suboxone-info](/...)](/...)). Added[to the exclusion class in the bare-reference regex so the bracketed text inside an already-formed link doesn’t re-match. - Discord message-header regex too strict — failed on headers with
trailing
*(edited)*. Now accepts an optional*(edited)*suffix. - Reverse-message-order assumption was wrong for one of the export formats — caused the H1 to end up buried mid-document. Now sorts by timestamp regardless of source order.
*Reactions:* 👍 3lines were rendering as literal text on the site. Now stripped during body transform.-#Discord subtext lines rendering as literal text. Now stripped.SKIP14literal text leaking into rendered pages from the compound-linker’s mask/restore cycle when a blockquote contained a markdown link (nested masks). Token format changed fromSKIP${n}(whitespace-delimited) to\x00SKIP${n}\x00(U+0000- delimited, can’t appear in source) and restore now loops until stable to unwind nested masks.- Compound pages were self-linking (“7-OH” on
/compounds/7-ohlinked to itself).linkCompounds()now takes aselfUrland skips that compound on its own page. - TOC entries had trailing
#because the heading-anchor rehype plugin added a text-node#child that Astro’s heading extractor picked up. The#is now rendered via CSS::beforeon the anchor element. - Bold text invisible in dark mode because the Tailwind Typography
plugin’s
--tw-prose-bolddefaults to near-black. Addeddark:prose-invertto the<article>wrapper. - Pagefind dynamic import failed at build time because
/pagefind/pagefind.jsdoesn’t exist until the post-Astro Pagefind step runs. URL is now constructed at runtime so Rollup can’t statically analyze it. src/content/README.mdwas being picked up as a content entry and failing zod validation. Glob pattern now excludes**/README.md..astro/content-assets.mjsmissing after a hard cache clean — documented the safe-clean sequence (rm -rf dist .astro node_modules/.vite && npx astro sync) in the prior conversation.
Docs
README.md— local dev, ingest workflow (Paths A + B), adding a page, adding a category, both deploy options with a decision table, what the site won’t do.src/content/README.md— 5-step “add a page” guide, full front- matter reference table (including the newmanualflag), available markdown features, callout usage in MDX, what not to do.imports/README.md— non-developer Discord-export workflow, multi-channel exports, idempotency, the_-prefix skip convention, themanual: trueflag for protecting editorial work.docs/deploying.md— full server-setup walkthrough (already listed under Deployment).
Pharmacology section (new category)
- New top-level category: Pharmacology (
🔬) — for deeper science content beyond the practical compound overviews. pharmacology/minor-alkaloids.mdx— Kratom’s Minor Alkaloids: Serotonergic & Adrenergic Activity Beyond the µ-Opioid Receptor. The 7-column chart of mitragynine vs. paynantheine, speciogynine, speciociliatine, corynantheidine, 9-hydroxycorynantheidine, and mitraphylline across µ-opioid / 5-HT / α-adrenergic receptor systems. Recovery-reader intro at the top routes anyone in acute withdrawal to the right pages elsewhere on the site.pharmacology/morphine-vs-kratom.mdx— Morphine vs. Mitragyna Alkaloids: Structure, Modification & µ-Opioid Receptor Binding. Side-by-side structural pharmacology.scripts/convert-pharma-html.mjs— one-shot converter that extracts the<style>and<body>from the source HTML, drops the Google Fonts link, and remaps the doc’s CSS variables (--paper,--card,--ink,--em, etc.) to our site palette (zinc + accent- teal) in both light and dark mode. Output is two Astro components undersrc/components/pharmacology/whose styles are auto-scoped by Astro so they don’t leak. Original layout (2000px-wide reference sheet with the 7-column grid, molecule SVGs, receptor activity cards, polypharmacology map, caution + clarification panels, source citations) preserved intact. Horizontal-scroll on narrow viewports so the chart stays legible on mobile.- Each page also includes a “Reference, not advice” callout at the
bottom, and
manual: trueso the MDX wrappers don’t get clobbered by ingest.
Pharmacology charts — wide: true layout
The two pharmacology reference charts (1200px min-width) wouldn’t fit inside the standard 832px content column. After two iterations:
First try — full-bleed calc(50% - 50vw) escape: broke out of the
prose column but pulled the chart under the left sidebar. Reverted.
Final fix — new wide: true front-matter flag:
- Added
wide: z.boolean()to the content schema. DocLayoutchecks the flag: whentrueit keeps the sidebar (so site navigation still works on pharma pages) but hides the TOC and removes themax-w-[52rem]content-column constraint.- The outer container expands from
max-w-[88rem](1408px) tomax-w-[112rem](1792px) on wide pages, giving the chart enough room next to the sidebar (~1408px of usable main width). - The chart’s own
max-width: 1600pxcaps it on huge displays;min-width: 1200pxwithoverflow-x: autoprovides horizontal scroll inside the chart wrapper on viewports narrower than 1200px. - Both pharmacology MDX pages now set
wide: true.
Header, footer, and beta banner stay at the standard max-w-[88rem]
so the chrome doesn’t sprawl. Slight asymmetry on 1792px+ displays
(content extends past chrome) but the chart fits cleanly.
Wider site layout
Bumped the layout widths across the board for a less constrained feel on modern displays (laptops 1440px+, desktops 1920px+):
| What | Was | Now |
|---|---|---|
| Outer container (header/footer/main) | 1280px | 1408px |
| Doc content column | 704px | 832px |
| Category index inner column | 768px | 832px |
| Sitemap container | 1024px | 1152px |
| Homepage hero + medical-disclaimer | 896px | 1024px |
| Homepage category grid | 3-col max | 4-col at xl |
Content prose stays in a comfortable line-length range (832px = roughly 85-95 chars per line at 16px Inter), but the page itself fills more of modern wide screens.
Site map + footer
- New
/sitemappage at src/pages/sitemap.astro — human-readable index of every page on the site, grouped by category, with title + source channel + description for each entry, and an “editorial” badge onmanual: truepages. Cross-links the search-engine sitemap at/sitemap-index.xmlfor crawlers. - Footer link bar added at the bottom of every page: Site map · Community · GitHub.
Honest ER framing on the SOS page
- The “ERs are required to stabilize you” paragraph was rewritten to
keep the legal facts (EMTALA, no legal trouble for disclosure,
on-site Suboxone induction) but acknowledge the lived reality that
not every ER and not every doctor handles withdrawal well. New
section gives readers concrete agency tools:
- Stick to medical facts and numbers (COWS score, symptoms)
- You can ask for a different provider, or escalate to the attending
- Bring someone if possible — presence changes how staff behave
- AMA discharge is allowed when you’re not in active emergency
- A bad ER doesn’t mean medical care won’t help; a telehealth Suboxone visit may be a better path
ULDN (Ultra-Low-Dose Naltrexone) — new page
other-tools/ultra-low-dose-naltrexone.mdadded (manual editorial). Companion to the existing LDN page. Covers the μg-range dose space, the dual-signaling-model mechanism, and the two community use cases: smoothing the bottom of a Suboxone taper, and reducing tolerance during longer-term bupe/Subutex maintenance.- The LDN page now ends with an explicit “Not the same as ULDN” entry
pointing readers to the new page (LDN is mg-range, after-withdrawal;
ULDN is μg-range, taken with opioids). Added in both
imports/andsrc/content/so the cross-link survives any future re-ingest. - New entry in
scripts/channel-mapping.jsonso#ultra-low-dose-naltrexonechannel references route correctly.
7-OH page filled in (was a placeholder)
The site is named after this compound, but the compounds/7-oh.md page
had been sitting as a stub. Replaced with a real, manual-editorial page
covering:
- What 7-OH actually is (alkaloid in Mitragyna speciosa, naturally trace amounts, sold concentrated/semi-synthetic at retail).
- Pharmacology: µ-receptor binding affinity (Ki ~13-17 nM, ~10× tighter than mitragynine), partial agonist with meaningful intrinsic activity, mu-dominant.
- Plasma half-life ~100 minutes — short by opioid standards.
- A side-by-side comparison table: leaf kratom vs. concentrated 7-OH. This is the single most important framing for new readers.
- Acute withdrawal timeline (table) and the SNRI-like overlay from stacked products.
- “Why 7-OH is actually tapereable” — the same short half-life and mu-dominant binding that make it easy to get hooked also make it respond well to short Suboxone tapers.
- Common retail forms (tablets, shots, pseudo, stacked products, raw powder).
- Marketing claims to be skeptical of (“non-addictive”, “all-natural”, “doesn’t cause respiratory depression”).
- Three real paths to stopping, with cross-links.
Cross-linked from welcome, what-to-expect, SOS, suboxone-info, MGM-15, LDN, and pharmacology pages via the existing compound auto-linker.
Kratom framing — leaf vs. synthetics
Site-wide audit found several “don’t use kratom” statements that wrongly grouped leaf in with concentrated 7-OH / synthetics. Distinction now made consistently:
- The compound that brought you here (7-OH, MGM-15, MIT-A/DHM, pseudo, stacked synthetics) — never redose during withdrawal or active recovery.
- Plain kratom leaf — a planned, deliberate taper tool for some people in this community (see #tapering-with-kratom-leaf); not a rescue medication and not improvised at 3 a.m.
Updated in: vitamins-supplements.md (both “Avoid” sections),
sos-resources.md (“Don’t” list), suboxone-info.md (taper bullet +
reminder callout), imports/suboxone-isnt-working.md (“don’t redose”
list), imports/suboxone-rapid-taper.md (“seek help” trigger).
Homepage — Discord + subreddit links
Added a row of community links to the homepage hero, just below the SOS CTA:
- 💬 Discord:
discord.gg/quitting7oh— real-time community - 📖 r/quitting7oh: searchable, slower, good for stories
- → About the community — links to the deeper community page
Also fixed the SOS CTA: it was pointing at the /active-withdrawal
category index; now it links straight to
/active-withdrawal/sos-resources where someone in acute distress
actually wants to land.
Site-wide beta banner
BetaBanner.astromounted at the top of every page (viaBaseLayout.astro, just below the skip-link). Amber strip, warning icon, full text: “Beta — This site is still being verified. AI tools were used to help organize and clean up content that was originally written and fact-checked by humans, but not every page has been fully reviewed yet. Use at your own risk.”- Dismissable per session via
sessionStorageso a return visitor in the same session doesn’t have to look at it, but a fresh visit always shows it — the warning matters enough that a new reader should always see it once. - Renders correctly in both light (amber-50 bg, amber-900 text) and dark (amber-950/50 bg, amber-100 text) modes.
Still in flight / next up
compounds/7-oh.mdis still a placeholder; the real Discord export for that channel hasn’t been provided.SITE.repoinsrc/lib/site.tsassumes the repo is atgithub.com/quitting7oh/quitting7oh.org— update once the canonical repo exists. (Affects “Edit on GitHub” links.)- Pharmacology pages might want a “minor alkaloids ⇄ compounds” cross-link strategy — right now they live in their own category but compound pages don’t yet link out to the deeper reference. Worth a follow-up pass to wire those connections explicitly.