MR-039 · v6Catalog product · edit — facts beside the tab moduleProductSetupSource formula
goes to another screengoes to another state of this screenfaded = not mocked yetEverything else — filters, sorts, tabs, modals — works, it just stays on this screen. The URL always names the state you are on, so any view can be copied and shared.
Catalog/Catalog Products/CP-0102 Memopryl Brain SupportUpdated 2026-08-27, created 2026-06-30 by DJ
Anything about this product worth the next person knowing — a supplier conversation, a packaging change, why a measurement is what it is. Product-level, so a note stays put when the version toggle moves.
Dana Whitfield2026-08-21 11:38
eBay listing L-202 is holding on copy approval because the v2 panel names Alpha-GPC and the marketing blurb still reads like v1. Rewrite is with Marc.
Paul2026-06-30 09:05
Legacy import from the old sheet. The 1-pack eBay listing predates the catalog product, which is why L-198 carries no batch and no approved price.
MR-039 (v6) · fixtures CP-0102 · base art from mockups/sample-images/memopryl-base-images/ and memorpyl-marketplace/
A free-only product is checked for shipping (MR-398)
Change Sold on its own to No and the setup chip and drawer re-check: only the front image, weight and size can block, and the product reads Ready to use as a free item (RI-801).
Sold on its own (MR-394)
Gift eligible is replaced by Sold on its own. No is for a gift bag or a sample: never listed for sale, always offered free with a listing. Which product goes free is each listing’s choice (RI-786, RI-787).
Instructions, and Markdown for Ingredients (MR-393)
Instructions sit under the label panel, in the same module. Like the panel they are a copy of the formula’s taken when the version was made, so v1 says matches SF-0007 and v2 matches SF-0072; an edit says edited and offers Reset to formula. A product with no formula types its own — a real product starts from its label’s directions (RI-783). An Ingredients panel has Table / Markdown (RI-782).
Memopryl opens complete (MR-389)
With no #setup= in the link, the record opens on what its own page shows. Memopryl has its front image (approved, main), a 4.8 oz weight on SF-0007 and three channel listings, so its chip reads Setup complete and Create listings is on. Until now it opened on 2 things block listing — front image and weight — beside the image and the weight the page was showing, and OPEN-ITEMS carried that as two product screens, one product. Paul, 2026-09-14, asked which story is true: the page’s (RI-769).
The rule is the front image, the one gap the four drawn products differ on: Avinol PM and Zero Air, whose fronts are still missing, open on 1 thing blocks listing; the real products, whose fronts are in, open complete. The Setup harness still puts the drawer in any of its five states, including state 1 on Memopryl — that is a rewind for review, and the drawer’s fixture means it that way (missing is what was outstanding in state 1). The drawer does not yet watch this page: remove the front image here and the chip will not notice.
The scope model
Version-scoping is per field, not per tab, and one mark carries it: v1 plus a heavy left rule means the field belongs to the version selected in the brand strip. No mark means product-level — one value for every version.
The shared label is gone (MR-345). It used to mark the product-level fields too, and on this screen that is the normal case: the Identity tab said shared on the tab, on the group heading and on fields inside it, and Notes and Channel listings each wore a product-level chip. Paul, 2026-09-12: “Wouldn't everything be shared by default? If it's not shared, it'll have the V sticker.” A mark that is on almost everything carries no information; the version sticker has its own hue and rule, so its absence reads clearly on its own. The SF-0007 ▸ tag stays — it answers a different question, who owns this fact, not which version is it.
Colour is now spent on version identity, and this is a deliberate reversal. The rule used to be “no colour for scope, keeping colour for status only”. But a sticker that reads v1 in one hue and v2 in another can be traced back to the toggle at a glance, which a uniform black chip could not. The hues are drawn from outside the semantic set — never green, amber or red — so they cannot be mistaken for status, and the status chip stays where it was, inside the toggle button. Each version’s hue is the same on its sticker and on its button, so the pressed button and the stickers it governs read as one object.
A tab now carries two axes, not one. The old rule was “a tab is never mixed”, meaning one scope per tab. That still holds for scope — everything on Specs is version-scoped. What is new is ownership: Physical & packaging and Source formula are shown here but owned by the source formula, so they render read-only with an SF-0007 ▸ mark and are edited in the formula’s own drawer. Filling a blank from here is not allowed either — one owner, one place. Switching version flashes the Specs tab’s groups.
Benefits and gift eligibility sit on Identity because both are product-level. Benefits come from a managed list rather than free text, so the listing builder’s angle picker does not fill with near-duplicates; gift eligibility exists only because a freebie is named in marketing copy and imagery — otherwise it is just another product riding in a combo.
Benefits stopped being a word cloud (MR‑331). Every value in the system used to be drawn as a pill you toggled. That is readable at six and unreadable at sixty, and the list is administered — it grows without any screen being edited, so the six was never a ceiling. It is now chips for what is on the product, and a search for adding one, which is the same interaction at six and at six hundred. The control is _tagfield.js, shared with the create wizard and the setup gate, and it owns the vocabulary too: the pill row had been pasted into three screens and had already drifted — this screen offered six benefits, the create wizard offered seven, and one of that seven (Skin & Hair) was never a benefit at all but a Sold for value. A list held in one place cannot do that.
Benefits are not inherited from the source formula, and that was asked for and turned down (RI‑616). The tempting version is real: four products share SF‑0007, they share its ingredients, so they would plausibly share what it does — and the screen already reads Physical & packaging and Current batch from the formula under exactly that argument. It loses because those are facts about the thing; a benefit is a claim made about a label, and two products on one formula are sold on different claims on purpose. Inheritance would also need a per-product memory of every removal, or a benefit deleted here would come back on the formula's next edit. The formula has no Benefits field and gains none.
Tags moved to the rail, beside Categories. Two chip controls stacked in one form read as one crowded field, and these two are opposites: Benefits is closed, curated and feeds real machinery downstream; Tags is the open place for what nothing else asks. The rail is where loose classification already lives. What tags are for was the genuinely open question, and the old fixture answered it by accident: nootropic, focus, memory, capsules — four words that other fields already hold (Benefits, Form, and at the time Sold for). A field whose contents duplicate its neighbours has no job. What is actually left over is operational: bestseller, subscription, seasonal, heat-sensitive, no-amazon — how a product is traded, handled and positioned.
Sold for is removed (MR-345). It was a single value — Nootropic, Sleep aid — added for one reader: research, which looked each ingredient up for that one purpose and cached the finding under it (RI-594, RI-595). Its twelve values turned out to restate the Benefits list almost one for one (Memory support / Memory & Focus, Sleep aid / Sleep, Joint support / Joints), and three fields describing one product's purpose — Categories, Sold for, Benefits — confused the person filling them in. Research now reads every benefit on the product instead, each ingredient against each benefit, and which benefit a listing leads on is chosen per listing in the angle picker, where it always was. Starring one benefit as the lead was offered and not taken: a stored lead would be a second answer to a question the listing already asks. So pick every benefit that applies — that is now what research reads, and the Benefits tooltip says so.
The tooltips were cut to what the control is. Each one had grown into a definition-by-contrast — Categories is what the product IS, Sold for what it is BOUGHT FOR… — which is rationale, and rationale lives here. A tooltip answers what goes in this box in a sentence or two. Categories gained one, since it had none.
Tags are curated, and a product screen may still add one. They are a managed vocabulary like the other three — Settings holds the order, the usage counts and the delete guard — but typing a name the list does not have offers to add it, because a catch-all that can only be chosen from is not a catch-all. Adding is the only write the picker does: renaming and removing stay in Settings, which is MR‑328/MR‑329's lesson pointed the other way — a screen reads a vocabulary, only the admin governs it. Two things keep the list from filling with near-duplicates: the search folds punctuation and case, so typing Heat Sensitivefindsheat-sensitive rather than offering to create a twin of it; and an add says out loud that it was global and what value was stored, because a write that reaches every product should not look like filling in a field.
The pickers do not say how many products share a value (MR‑332). They did for one round. A count is showing the work, and on the Settings tab it is load-bearing — 4 products is what makes a delete safe to reason about, and it is what the delete guard reads. On a picker it is a number beside every row answering a question nobody has while choosing one, and because the search matches a row's tag as well as its name, carrying it also made 4 a search term. The rows are names. Show the act does not mean show every number you happen to be holding — which is worth keeping as the correction rather than quietly tidying away.
Layout
Top section is the brand and the version toggle, right-aligned — a second deliberate reversal of “the brand and nothing else”. The toggle governs the whole module (both Specs and Base images are version-scoped), so the module’s own header is where it belongs, and the strip now reads as one statement of context: Memopryl · editing v1. The tab row was the alternative and lost: it already carries three tabs and their scope chips, it wraps, and a toggle dropping to its own line reads as broken.
Supplement facts is always visible and sits beside the tab module, each taking half the container, so both stack to roughly equal height and channel listings ride higher.
The sticky page header keeps only what acts on the whole product — save, create listings, attention.
Field grids fill the container width; an individual field stays around 230–300px, so nothing stretches.
Notes sits full-width directly under supplement facts, above channel listings.
Channel listings sit full-width at the bottom, one tab per sales channel.
Notes
The same shared block that source-formula.html carries, lifted markup-and-CSS intact rather than re-drawn: a container with data-notes and an optional data-author holding [data-newnote], [data-addnote], [data-notelist] and an optional [data-ncount]. Every lookup is scoped to that container, so the two screens cannot collide and neither needs initialising.
It is product-level on purpose. A note is about these goods — a supplier conversation, a packaging change — and reading it should not depend on which version the toggle happens to be showing. The formula's log answers the same question one level up; this one does not repeat it.
The nav collapses to its icons
A toggle in the brand row drops the rail from 284px to 58px. Labels are hidden rather than removed, so the section order, the current-page rule and the not mocked yet stubs are all still there when it opens again — and the work column gains the width, which is what the collapse is for: the identity grid goes from two fields across to three.
While collapsed each link carries its label as a native title, set by the toggle and removed on expand. A CSS tooltip was the first attempt and it does not survive: .sb has overflow:hidden and its scroller has overflow-y:auto, which clips anything reaching past the 58px rail, and there is no honest way to have overflow visible on one axis only.
Open: the collapsed state is not remembered — no reload survives it, because this screen has no URL state to hang it on. Worth settling before this is copied to the other promoted mockups.
Supplement facts editor
Table and Markdown are two views of the same data. The markdown dialect reads Serving Size:, Servings Per Container: and Other Ingredients: as their own lines; a row prefixed with - nests under the blend above it, which is what the real MemoPryl label needs. Paste a whole panel, hit Save facts, and the table repopulates.
Current batch (MR-072)
The newest received batch on the source formula — COA, expiry, batch number, received date — sits on the Specs tab as a read-only group beside Physical & packaging, under the same rule and wearing the same SF-0007 ▸ owner tag. It is the stock, not the label, so all four products on SF-0007 show the identical batch.
The COA opens here, in a lightbox with Download (MR-345). It used to link back to the source formula, on the argument that a second viewer in a second file would drift from the first. Paul, 2026-09-12: “Why force the user to go to the source formula and then pull it up?” Both halves are honoured: the viewer moved into _doc-viewer.js, which the source formula now loads too, so there is one viewer and no walk. Moving it also fixed the formula screen's copy, which had quietly lost its page styling and whose Download had no file behind it. The document is still replaced on the formula — the group's SF-0007 ▸ tag is the way there.
QB FP SKU — editable, as a relink (MR-346)
One QuickBooks SKU per catalog product, and a different count is a different product (Paul, 2026-09-12). This closes the old open item on where the SKU lives. It is why v2 on this screen is now a 60-count formula swap rather than a 90-count: two counts under one SKU would put two different bottles in one QuickBooks stock line, so neither count nor cost per unit could be read.
Editing it is a relink, never a rename. The box searches QuickBooks Inventory items (RI-362) by code or description. An item already linked to another product is listed and refused, because an FP SKU belongs to exactly one product. Choosing an unlinked item asks first, and the confirm says what does not move: the old SKU keeps its stock, and the ShipStation bundles that ship it keep shipping it until each is remapped. Renaming the code inside QuickBooks is deliberately not offered anywhere on this screen — every channel SKU and bundle knows the item by that code, so a rename would break them with no error.
Fixture:FP-0262Memopryl Brain Support 60 Capsules, qty 0 and unlinked, is the item a relink exists for — the duplicate someone created in QuickBooks. It is illustrative and recorded as such in SAMPLE-DATA.md.
Sourcing — labeled by us, or arrives finished (MR-348, MR-350)
Some products never have a raw stage, and some never have a formula. Paul, 2026-09-12: a reseller’s product, a cream that comes “in acrylic jars that are silk-screened, and those acrylic jars come packed into a branded box”, and a branded vacuum jar — “You can't really rebrand that.” So every product carries Sourcing, set when it is created: Labeled by us (our label on a formula we hold; a source formula is required and a raw SKU may exist) or Arrives finished (already labeled or branded; never a raw SKU, stock received straight into the FP SKU, and never a source formula). It is read-only here because the two values have different records behind them (RI-670).
A formula link was optional for one round and is now gone (RI-669). Avinol PM was drawn linked to SF‑0012 with its facts read-only, and Paul’s first question was how anyone would edit them: for goods that arrive labeled, the carton, lot, COA and panel all belong to that receipt, so a link shared almost nothing and linking later would overwrite the product’s facts — “a whole bunch of complexity for a pretty rare edge case.”
Four products show the four shapes, each opened from its row on the catalog list (or the harness): Memopryl is labeled by us, as before. Avinol PM is the supplement that arrives finished: Supplement Facts typed here, and an incoming v2 — the manufacturer changed from Vox to Vitalabs — to walk Make active. Complexion MD is the topical: an ingredient list, a received batch still waiting on its COA, and research by Category. Zero Air is the hard good: a Product details panel, purchase orders with the QuickBooks columns only, and research by Guidance.
Brand_Kind stays a separate axis — Complexion MD is our own brand and Zero Air is resold, and both arrive finished.
Fixtures: Complexion MD and Zero Air’s weights, sizes, ingredients, specs, lots, POs, FP SKUs and quantities are illustrative — Paul named the products, not the numbers. Avinol PM is the existing SAMPLE-DATA.md CP‑0044 with its existing v2 (Vitalabs “Nighttime Formula”, 3.0 oz, cutover 2026-09-15); its PO-4460 is illustrative. None of the three has images, notes or listings yet.
Who owns what on a product that arrives finished (MR-352)
Only Sourcing locks (RI-673). The PO number, date received, status and quantities are QuickBooks’; everything else a formula would have held — L × W × H, weight, container, the panel, and each batch’s number, expiry and COA — stays editable, because this product is the only place it can be edited. The hazard of an edit is what it reaches, so the screen says that at the edit rather than locking the field.
A weight or size change asks first and names its reach (RI-676). Change a weight on the Specs tab and a confirm lists the packaging rows that were Tested and go back to Estimated, and the ShipStation write: one write, to the product’s own ShipStation record, which every bundle takes its weight from. The bundles are named, not written. On a version that is not active, nothing goes to ShipStation until cutover.
Versions stay, and going active is a button (RI-674, RI-678). A correction edits the version in place; a real change from the manufacturer is + New version, which copies every fact. Make v2 active replaces the old status dropdown and its confirm says what the dropdown never did: the warehouse ships v2 from that moment, ShipStation’s weight changes now, and old stock still in the bin ships at the new weight until it is gone. The line under Physical & packaging always says which weight ShipStation carries. This is on every product, Memopryl included.
The label panel is a toggle a person picks (RI-679): Supplement Facts, Ingredients or Product details — the source formula’s own control, not Form’s derivation. Paul had decided that on 2026-09-09 (RI-547) and the MR-348 round drew these products deriving it from Form anyway. Switching away from typed lines asks first. The panel decides whether the label image role is offered.
Batches & POs sits under the split, not on the Specs tab (RI-684, RI-688), because receipts belong to the product’s one FP SKU and do not change with the version toggle. It is _batch-grid.js, the same grid the source formula mounts. Rows arrive with QuickBooks receipts; a missing COA reads No COA yet and never blocks listing.
Setup states are on the product now (MR-385, RI-757). Paul, 2026-09-14: the source formula shows every state of its RW SKU mint and the catalog product showed none, although a product mints two records at once — its QuickBooks item and its ShipStation component. The five states are the setup drawer’s own (catalog-product-setup.html): things need you, QuickBooks needs you, creating the records, ShipStation needs you (new in the same round) and complete. The Setup harness segment picks one (#setup=). The header and rail chip say the state, a run bar under the header shows both systems side by side while something is running or stopped, and + Create listings waits until setup is complete. Every one of those controls opens the Setup & gaps drawer here, on this product (MR-386, RI-760) — until that round they sent you to catalog-product-setup.html. The drawer is _setup-drawer.js, the same one the setup screen and the create form mount, and its checklist reads this screen live: untick every Active mark or every Research by input and the chip’s count and the drawer’s rows change with it. A fix closes the drawer and switches to the tab that owns the fact; a weight a source formula owns opens the formula. The rail chip used to read 3 attention, a count that agreed with nothing else; it now names the state.
The rail’s big image has arrows (MR-384, RI-755). Paul, 2026-09-14: scroll through all the images “without clicking on it and seeing the full screen.” Previous and next overlay the image and a counter says 3 / 6; the picture still opens the lightbox, at whichever image is showing. It starts on the main image, and the main badge shows only while the main one is in view — the arrows move a view, not the main mark, which stays on the Base images tab. A missing image is stepped through too, drawn as its empty slot, because an absent image is the one thing a reviewer most needs to find.
Research by (RI-682) is on the Identity tab for every product, and since MR-381 it is four checkboxes, any combination: Active ingredients, Benefits, Category and Guidance (RI-750). It was one choice here while the create form had already become a set (RI-733); Paul, 2026-09-14: “you can toggle between them, but you can’t select which ones will be utilized.” The ticked set is read in two places — Generate description on this screen, and the listing builders’ prompts — so it is one set, not one per consumer. A hard good cannot tick Active ingredients. Memopryl opens with Active ingredients and Benefits ticked, to show two read together.
Benefits as an input reads the chips in the Benefits field above it, and repaints when they change. Active ingredients already read each marked row against each benefit; Benefits on its own is research on what each benefit can claim, shared with every product that carries it — which is what a product with no panel, or a panel nobody has marked, can still stand on.
Generate description (RI-751) sits on the Description’s own header, not in the editor’s toolbar: the toolbar formats text, and this replaces it. It opens a small panel that names every input it will read, with what each holds (Active ingredients (Bacopa, Lion’s Mane …) + Benefits (Memory, Focus, Energy)), and says it replaces the description when there is one. The result lands in the same editor as ordinary text with a dated line under it saying what it was generated from. Nothing ticked disables the button, and its tooltip says why. The generated copy is a fixture assembled from the product’s own name, benefits and marked rows.
Active ingredients are a marked subset (MR-364, RI-719). Every row on the panel has an Active checkbox, and research reads only the ticked rows — melatonin and valerian on a sleep aid, not the vitamins beside them. Research by says 4 of 5 marked and links to the panel; with none ticked it says research is blocked, because running on every row instead would hand the writer findings on ingredients nobody sells the product on. v1’s Vitamin B6 is unmarked on purpose so the count has something to leave out. In the Markdown view a marked name is bold, so a label pasted from a manufacturer marks nothing (RI-721).
Thumbnails (MR-345)
The rail has five fixed slots: three images, a fourth wearing +N for the rest, and a dashed + to add. The count sits on an image rather than in an empty box — the pattern Facebook, Airbnb and Google Shopping use — so four pictures show in the width that three and a label would take. +N opens the Base images tab.
Base images keeps two rows of cards and then one line of thumbnails that fits the width, up to seven slots, the last a dashed +N when more remain; pressing it lays every card out, with Show fewer to put the strip back. The line used to scroll sideways, which hid how many there were, and it never appeared at all on this tab: the two rows are read off the grid's resolved columns, which a hidden tab does not have. The tab now lays itself out again when opened. With this fixture's six images the strip holds three and needs no +N; the rail shows +2. Three of the images are borrowed from the marketplace set to make the overflow visible.
Open — needs Paul
② No front-of-bottle image.memopryl-.webp is a byte-identical duplicate of the ingredients side, so the base set has ingredients and instructions only. Delete the duplicate and drop the front in as memopryl-front.webp — this screen picks it up with no code change.
③ A tag that encodes a rule wants to be a field.no-amazon is in the fixture on purpose and it is the one that will break the model first: it is not a label, it is an instruction to a channel, and the moment anything downstream reads it the catch-all has become a schema nobody designed. The question is not whether to remove it — it is what the trigger is for promoting a tag to a real field, and who watches for it. Nothing is blocked today; nothing reads tags at all.
①② aside — batch inheritance (MR-072).Newest received wins is wrong the week after a delivery: this product's 340 finished units may have been bottled from an older raw batch than PO-4392. Fixing it means the finished product knowing which raw batch it came from, which is a QuickBooks question rather than a UI one. Recorded, not built — see OPEN-ITEMS.md B2.