//! The public project page, described. //! //! `/p/{slug}`: the cover, who made it, what is in it, and every way to follow, //! read, subscribe to or support it. It replaces `templates/pages/project.html` //! and `ProjectTemplate`, and it is the last of the three pages that wrote //! `` by hand. //! //! # Why the route stays an axum handler //! //! [`super::project_blog`]'s reason, at the page it is largest for. The handler //! resolves a slug, runs the project-level paywall gate, loads items, tiers, //! git repos, sections, gallery frames and follow state, and records a page //! view unless the caller is a crawler. `super::Viewer` carries no session and //! none of that wants a described route. What is described is the document. //! //! # Four behaviours the vocabulary took over //! //! - **The section tabs.** `.section-tab` buttons over `.section-panel` divs, //! switched by `static/page-project.js`. A [`RegionKind::TabGroup`] whose //! children carry a [`Slot::label`] is that, and `quasi-webview` writes the //! strip and the program that moves it. The script is gone. //! - **The gallery.** An Askama macro over the shipped widget. The described //! half of the same widget is [`super::widgets::carousel::region`], so the //! gallery here and the three templates still calling the macro cannot be two //! different carousels. Its frames are ordinary pictures, so a host that has //! never heard of a carousel still draws every one of them. //! - **The tip offer's disclosure**, which is [`super::tip`]'s. //! - **The share link**, which is [`quasi_router::Act::copies`]. //! //! # Three that did not survive, and why //! //! **The grid/list toggle.** Two `.view-btn`s over two copies of the same //! items, with the choice kept in `localStorage` by //! `static/page-project-2.js`. The list copy carried strictly less than the //! grid copy -- a title, a type and a price against a cover, tags, a //! description, a date and a sales count -- so what the toggle offered was one //! full view and one lossy one. There is no member for how densely a list is //! drawn and there should not be: that is the renderer's, which is the whole //! premise. One described list, drawn once. //! //! **`.follow-btn.is-selected`**, for [`super::follow`]'s reason. //! //! **The promo code's `
`.** One optional input behind a summary, per //! tier. Said as a field with the placeholder the template wrote, because a //! [`Reveal`](quasi_router::Reveal) names its control by name and every tier //! card on the page would have named the same one. //! //! # What is still markup, and who owes it //! //! **The section bodies.** [`Node::rich`] carries markdown and quasi renders //! it, and a project section's markdown has been through //! [`crate::markdown::render_creator_markdown`] first: media paths rewritten //! against the CDN under the creator's own id, off-platform media hosts //! stripped, and `` of a video file turned into a `