Commit graph

1102 commits

Author SHA1 Message Date
93c0facbbc
bump GIT_HASH to 5b44132 2026-05-12 20:37:13 -04:00
5b44132058
fix: offer/auction checkout — land in the new cart, not a stale empty one
offer_checkout and auction_checkout were creating a cart and hand-setting
cart.active = True, which left the user with two active carts for the
shop; /cart then resolved to the older, empty one — so "Pay $X" appeared
to do nothing. Both now use shop.create_new_cart_for_user() (deactivates
the user's other carts for that shop, activates the new one) and redirect
to /cart/{cart_id} directly, so it works regardless of which shop the
request is scoped to.

Tests: TestOfferCheckout / TestAuctionCheckout now assert there is exactly
one active cart, it carries the cart_offer/cart_auction association, it is
non-empty, and the redirect targets that cart by id. 990 passed.
2026-05-12 20:37:07 -04:00
adf6175d04
bump GIT_HASH to 87ac9d9 2026-05-12 20:10:27 -04:00
87ac9d90ca
fix: confirm prompt on terminal offer actions (accept / decline / withdraw)
These end the negotiation, so the forms now carry onsubmit="return
confirm(...)". offer.js bails when the prompt is cancelled — it checks
event.defaultPrevented before firing the AJAX request — so the JS path
respects the confirmation too, and the no-JS path gets the native dialog
before the POST+redirect.
2026-05-12 20:10:13 -04:00
c43336925c
bump GIT_HASH to 2886a42 2026-05-12 19:53:58 -04:00
2886a4255d
fix: crossfade clamps both tracks to active tab's current volume
Crossfades (user-initiated and DJ auto-transitions) faded the incoming
track up to volume 1.0 regardless of how loud the playing tab actually
was, producing a jarring jump in loudness mid-transition. Read
activeMedia.volume when a fade begins and use it as the ceiling for both
the outgoing and incoming tracks; restore that same level if a DJ
crossfade is cancelled.
2026-05-12 19:53:42 -04:00
31f8449c7d
bump GIT_HASH to 6f52af0 2026-05-12 18:40:27 -04:00
6f52af0c2c
fix: actions hub — cap at two columns, restore gap, always show Offers button
The previous .action-button-grid used auto-fit/minmax(15rem,1fr) which
produced four columns on a wide well, and .mps-button's `min-width: 100%`
+ auto margins fought grid track sizing so the gap collapsed and buttons
touched. Now: single column on narrow, exactly two equal columns at
≥720px (auto-flow keeps them balanced), explicit column/row gap, and the
grid resets .mps-button min-width/margins. The "🤝 Offers" button is now
always shown to shop owners (was gated on shop.offer_enabled) so the
offers inbox is always reachable.
2026-05-12 18:40:22 -04:00
ff6a35b887
bump GIT_HASH to e97d18b 2026-05-12 17:47:29 -04:00
e97d18bccd
MPS-21: public profile page, offer-history identity, shop offers inbox, actions hub rebuild
- Offer history & offer page show the buyer's display name (User.display_name
  = the public `name` handle; `full_name` is private) linked to a profile
  page — never the email. _serialize_offer drops buyer_email; events carry
  actor_name/actor_handle/actor_id, header carries buyer_name/buyer_handle.
- New public profile page: GET /profile/{handle} (views/user.py:user_profile,
  template profile.j2). Shows gravatar (User.gravatar_url(size) — forced
  identicon unless the user opted into Gravatar), member-since, owned/edited
  shops, and a <details> "Show email" that is server-gated: only the user
  themselves, or a shop owner/editor viewing in that shop's context
  (?shop={shop_id}) when the profile user has transacted there (an offer or
  an invoice).
- New operator offers inbox: GET /s/{shop_id}/offers (@shop_editor_required,
  shop_offers.j2) — open offers first, each row links to /o/{id} and the
  buyer's profile. Reachable from /actions/view via a new "Offers" button
  (shown when shop.offer_enabled).
- /actions/view rebuilt: one flat .action-button-grid (Grid auto-fit,
  minmax(15rem,1fr)) inside a properly-padded .action-columns well — fixes
  the off-balance two-column layout and buttons overflowing the well; no
  <br> spacers. Styleguide gains profile-card and action-button-grid
  patterns.
- offer.j2: buyer name shown (linked to profile); "Buyer:"/"Seller:" message
  lines renamed "Buyer note:"/"Seller note:" to disambiguate.

Tests: 11 new functional tests (profile render + email gating, offers inbox,
actions button, styleguide). 989 passed.
2026-05-12 17:47:24 -04:00
cb61227b2c
bump GIT_HASH to 227fc4e 2026-05-12 16:34:25 -04:00
227fc4e564
MPS-21: offer-page state notice + design-system Make-an-Offer settings form
- offer.j2 renders a state-aware notice (.offer-state-notice, .alert
  variants) above the action forms: declined / withdrawn / expired /
  accepted (+ pay-now hint for buyer) / your-turn / waiting — so the
  viewer always understands the offer state without depending on a flash
  a JS redirect would skip. _serialize_offer now exposes is_declined,
  is_withdrawn, is_expired, is_pending, is_countered, is_accepted.
- Shop-settings Make-an-Offer section restyled with the new
  .settings-form / .settings-form-grid / .settings-field /
  .settings-field-hint system (two-up grid, per-field hints, submit
  pinned right). Added a styleguide entry under #forms.
- Reworded the section blurb: auto-declined offers are NOT silent — the
  buyer is told their offer was too low; only the seller isn't pinged.
- Fixed --color-text-muted typo (→ --text-muted) on .offer-js-flash-info.

Tests: TestOfferRoutes gains 3 state-notice render tests;
TestSettingsFormStyleguide covers the styleguide + live shop-settings
markup and asserts the old wording is gone. 978 passed.
2026-05-12 16:34:21 -04:00
38b5739ce7
bump GIT_HASH to 2cad248 2026-05-12 12:04:28 -04:00
2cad2482b8
MPS-20/MPS-21: capability-driven presentation for auction & offer actions
Every bid/buy-now/watch and offer open/counter/accept/decline/withdraw
POST now works as a plain browser submit: flash + 302 redirect to the
auction/offer page. JSON is returned only when the request carries
X-Requested-With: XMLHttpRequest. Adds offer.js progressive-enhancement
layer (mirrors auction.js); pay-now CTA on accepted offers; .offer-js-flash
styling; grid layout for offer/action forms. offer_accept emails the
buyer only on the transition into ACCEPTED.

Tests: TestOfferRoutes/TestAuctionRoutes now drive the JSON path via an
AJAX helper; new TestOfferNoJsFallback/TestAuctionNoJsFallback cover the
plain-POST redirect path. 973 passed.
2026-05-12 12:04:19 -04:00
981b1316f2
bump GIT_HASH to a90979a 2026-05-12 11:13:11 -04:00
a90979a46c
MPS-23: single warm sending identity for transactional mail
All transactional mail now sends From app.email.sender (default
no-reply@origin.makepostsell.com) instead of per-shop no-reply@<domain>,
with the shop name (or email.from_name) as the display name. The origin
identity is DKIM-signed (d=makepostsell.com) and SPF-authorized and
relays via mx1's warm IP, so operator custom-domain shops stop getting
spam-foldered. format_from_header() builds the From; send_email() gained
a from_name kwarg. Reply-To / per-shop contact email still TODO.
2026-05-12 11:13:11 -04:00
0f19da5ba8
docs: add MPS-23 ticket — consolidated transactional sender identity 2026-05-12 11:07:38 -04:00
f4be4f4612
bump GIT_HASH to 9a0782e 2026-05-12 08:14:57 -04:00
9a0782e61f
verification-challenge: center on login-card, add 'try again' link to login page 2026-05-12 08:14:57 -04:00
4b96acae0c
bump GIT_HASH to f9b73bb 2026-05-11 18:14:12 -04:00
f9b73bb9de
product offer form: breathing room around bid + optional message
Per fox: "a touch more whitespace around the bid and optional message".
The expanded Make-an-offer form had the label, amount input, message
input, and submit button stacked flush against each other inside the
$42.00 well — no vertical rhythm.

New .product-offer-form CSS:
- display: grid; gap: var(--space-3, 12px)
- top margin var(--space-3) separates it from the summary button
- inputs get box-sizing: border-box, width: 100%, padding 8px 12px so
  they fill the column with comfortable internal spacing

Grid only.
2026-05-11 18:13:53 -04:00
9c00d52dfd
bump GIT_HASH to 5cad5c3 2026-05-11 17:30:11 -04:00
5cad5c3a0c
product page: 280px floor on the purchase column (two-column grid)
Per fox: the price / Add-To-Cart / Make-an-offer box gets squeezed too
narrow on mid-width viewports (960px–1200px) where the 2fr/1fr split
gives the 1fr column only ~250-300px, crushing the buttons.

section.two-column grid columns: minmax(0, 2fr) minmax(280px, 1fr)
- the images column can shrink (minmax(0, 2fr)) so the purchase
  column always gets its 280px minimum first
- once the viewport is wide enough, the columns return to the 2:1
  ratio up to the 1200px max-width

Grid only, no flex.

Tests pass (10 in target slices).
2026-05-11 17:29:55 -04:00
46dd2cb929
bump GIT_HASH to 2630b78 2026-05-11 12:55:34 -04:00
2630b78175
fix: .mps-button back to inline-block — inline-grid broke multi-child buttons
The inline-grid + place-items: center change put each child of a button
into its own grid row. Buttons that hold an icon span + label text (the
windows-95 hamburger: <span>☰</span> + "shop.unturf.com") got the icon
on one line and the label on the next.

.mps-button is now display: inline-block again — multi-child content
flows on one line as expected. The squish fix is retained without grid:
- box-sizing: border-box (normalizes <button> vs <a>)
- padding: 12px 18px (symmetric, generous horizontal — no more text
  jammed against the edge)
- line-height: 1.4 (explicit, not UA "normal")
- min-height: 44px (tap-target floor)
- appearance: none, font-family: inherit

.mps-button-primary likewise back to inline-block with box-sizing,
line-height, text-align: center.

(.edit-card-icon stays inline-grid + place-items: center — it holds a
single glyph, so grid centering is correct there. Still Grid only,
no flex anywhere.)

Tests pass (10 in target slices).
2026-05-11 12:55:14 -04:00
3af81a38e9
bump GIT_HASH to 7df421d 2026-05-11 10:44:33 -04:00
7df421dba3
fix: remove all flexbox — Grid only (CLAUDE.md transgression)
I shipped display:inline-flex / display:flex across .mps-button,
.mps-button-primary, .edit-card-icon, edit-page h3 headers,
.edit-status-bar, .edit-status-pill, .edit-save-bar,
.upload-thumbnails-header, .upload-thumbnail-item, and an inline
style on the torrent_opt_in label — all violations of the project's
Grid-only rule. fox caught it. All converted:

- .mps-button / .mps-button-primary / .edit-card-icon:
  display: inline-grid; place-items: center  (was inline-flex + center)
- edit-page h3 headers (icon + title):
  display: grid; grid-template-columns: auto 1fr; align-items: center
- .edit-status-bar: text-align: right + inline-grid pills that flow/wrap
  (was flex + flex-wrap + justify-content: flex-end)
- .edit-status-pill: display: inline-grid; grid-auto-flow: column
- .edit-save-bar: display: grid; grid-template-columns: 1fr auto
- .upload-thumbnails-header: display: grid; grid-template-columns: 1fr auto
  with a max-width: 600px media query collapsing to 1fr
- .upload-thumbnail-item: display: grid; grid-auto-rows: min-content;
  align-content: space-between  (replaces the flex margin-top: auto trick
  for pinning the upload form to the bottom of the stretched cell)
- torrent_opt_in label inline style: display:grid;grid-template-columns:auto 1fr

CLAUDE.md updated: the CSS-layout rule now spells out the Grid
equivalent for every flex pattern, clarifies which alignment
properties ARE valid in grid context, and includes a dated SHAME LOG
entry for this transgression.

Tests pass (11 in target slices).
2026-05-11 10:44:11 -04:00
cec78ccd45
bump GIT_HASH to 37e314d 2026-05-11 09:45:37 -04:00
37e314d534
cache-bust static CSS with ?v={git_hash} on every deploy
Browsers were caching /static/css/common.css indefinitely (the <link>
had no version param), so CSS fixes didn't show up until a hard
refresh. Fox kept seeing the old squished-button CSS after deploys.

- New request property request.git_hash (reified) returns the short
  git hash baked in at deploy time (views.version.GIT_HASH)
- base.j2 tokens.css and common.css links now carry ?v={{ request.git_hash }}

Each deploy bumps GIT_HASH, so the CSS URL changes, so browsers fetch
the fresh file. No more stale-CSS confusion.
2026-05-11 09:45:17 -04:00
40d25edb6d
bump GIT_HASH to 8853a5a 2026-05-11 08:19:31 -04:00
8853a5aa08
fix: .mps-button squished on <button> elements — normalize box model
Per fox: Add To Cart / Make an offer buttons looked squished (text
crammed at top, little vertical space) while .mps-button on <a>
elements (cart page) looked fine.

Root cause: <button> elements inherit UA-stylesheet line-height and
box-sizing that differ from <a>. The class set padding-top/bottom: 14px
but with the native button line-height the text didn't center properly.

Normalized .mps-button:
- appearance: none (+ -webkit-) — strip native button chrome
- box-sizing: border-box — consistent across <button>/<a>/<input>
- font-family: inherit — buttons default to a different font
- line-height: 1.4 — explicit, was relying on UA "normal"
- padding: 12px 16px (was 14px 0) — symmetric, gives horizontal
  breathing room too
- vertical-align: middle

Now <button class="mps-button">, <a class="mps-button">, and
<input type=submit class="mps-button"> all render the same.

Tests pass (9 in pricing_mode slice).
2026-05-11 08:19:18 -04:00
08ba11ab9d
bump GIT_HASH to d593062 2026-05-11 07:28:09 -04:00
d593062e6b
product page: owner sees "offers enabled" indicator instead of nothing
Per fox: "i only see add to cart not offer" — viewing their own
offer-mode (3/4) product as the shop owner showed just Add To Cart
with no sign that offers were active. The Make-an-offer form is
correctly hidden for owners (can't offer on your own product, same
as auctions), but that left owners with no feedback.

Now when product.offers_allowed and the viewer is a shop owner,
the page shows:
  ✓ Offers enabled — buyers see a "Make an offer" button here.
    You can't offer on your own product.

Buyers (non-owner, logged in) still see the expandable offer form.
Anon visitors still see "Log in to make an offer".

Updated test_make_offer_hidden_for_seller: owner now asserts no
Submit Offer button + no "Log in to make an offer" CTA, but DOES
see "Offers enabled" indicator.
2026-05-11 07:27:55 -04:00
d56c49f3ee
bump GIT_HASH to ee4bd86 2026-05-11 06:38:42 -04:00
ee4bd862ce
fix: pricing_mode never saved — handler gated on absent "submit" param
Root cause found via prod debug log: the product edit form's
onsubmit="submit.disabled = true" handler disables the submit button
before the browser collects form data, so the "submit" key is never
sent in the POST. The pricing_mode / allow_offers / auction-config
block was gated on `if "submit" in request.params:` — always False —
so it never ran. Hence no flash, no save.

The standard handlers (title, description, price, visibility) don't
have this gate; they check whether the field's value changed. The
pricing_mode block now follows the same pattern: gated on
`if "pricing_mode" in request.params:` (that radio only appears on
the product-title-and-description edit form, so other forms on the
page — uploads, inventory, bundle — don't trigger it).

- pricing_mode: read request.params["pricing_mode"], apply if valid
  and changed; immediate flush; flash; auto-create draft auction when
  switching into auction mode
- allow_offers: only processed when "allow_offers" in request.params
  (so a different form submitting won't reset the override)
- auction config block: unchanged, still inside the pricing_mode gate
- torrent_opt_in: also re-gated on "pricing_mode" in params instead of
  "submit" (was equally broken, just masked by the torrent kill switch)

Removed all the temporary debug logging (ENTER line, /opt and /tmp
file writes, journalctl warning).

Tests pass (15 in pricing_mode + auction-config slices).
2026-05-11 06:38:26 -04:00
938fda3e4a
bump GIT_HASH to a186b4d 2026-05-10 20:06:37 -04:00
a186b4d000
debug: log every product_edit view hit + use /opt path for log
The /tmp/mps-pricing-debug.log file didn't appear after fox triggered
a save attempt. Two changes to narrow down why:

1. Move the debug log to /opt/make_post_sell/pricing-debug.log (where
   uwsgi has owner write access) with /tmp as fallback. PrivateTmp or
   permissions might be blocking /tmp writes on this systemd setup.

2. Add an ENTER log line at the top of product_edit() that fires for
   every request — GET, POST, save, etc. If this line never appears,
   the view itself isn't being reached and the form is going somewhere
   else. If it appears but the pricing_mode line doesn't, the submit
   field is missing from params.
2026-05-10 20:06:24 -04:00
5c2694d7ae
bump GIT_HASH to 08b5440 2026-05-10 19:20:07 -04:00
08b5440cab
edit page: title at top + preview file as separate column + file log
Layout restructure per fox:
- "Edit Title, Description, or Visibility" rendered first at top of the
  edit grid (full width) via CSS order: 1. Useful info (title, price,
  pricing mode, visibility) is now the primary focus when landing on
  the page.
- "Upload or Replace Preview File" extracted into its own <section
  class="upload-preview well2"> sibling. It sits in the right column
  of the same row as "Upload or Replace Product File" via the natural
  2-col grid flow.
- Visual order: title-and-description → upload-product → upload-preview
  → upload-thumbnails → price-history. Implemented via CSS order
  property so HTML structure stays simple.
- Preview section only renders for digital sellable products (not bundle,
  not physical) — same guard as before but now an explicit conditional
  around the new <section>.

Debug:
- pricing_mode handler now ALSO writes to /tmp/mps-pricing-debug.log
  (world-writable) in addition to the journalctl warning. Lets us read
  POST params on prod without sudo. Will be removed when bug is fixed.

Tests still pass (9 pricing_mode tests).
2026-05-10 19:19:53 -04:00
5cc17a39a3
bump GIT_HASH to 84a2412 2026-05-10 18:34:17 -04:00
84a241221d
edit page: move status pills into call_to_action header area
Per fox: status data was "in the wrong spot" — it had been rendered at
the top of the content area as a standalone full-width row above the
edit-page grid. Moved into the call_to_action block (top-right of the
page, same area where the permanent link lives) so the at-a-glance
state sits naturally above the form rather than splitting visual flow.

- Pills (visibility / ready / price) and permanent link now render
  together in call_to_action
- .edit-status-bar restyled: no background, no border, right-justified
  flex row (matches the right-aligned page header area)
- .edit-permanent-link: right-aligned, muted, small

Tests still pass (9 in target slice).
2026-05-10 18:34:03 -04:00
9495452e98
bump GIT_HASH to dbc7453 2026-05-10 18:27:01 -04:00
dbc7453a4e
edit page: thumbnail item card layout, consistent heights, fills width
Per fox: thumbnails "not aligned properly" and "not using horizontal
space properly". Two issues:

1) Grid was at minmax(240px, 1fr) which on the full-card-width row
   often fit 3 columns instead of 4 (240 * 4 + gaps > available
   space). Lowered to minmax(200px, 1fr) so the auto-fit gives 4
   columns on a standard desktop edit card.

2) Each upload-thumbnail-item now renders as a sub-card:
   - flex-direction: column with consistent gap
   - background --surface-dim, --color-border, --radius-md
   - preview image fixed 140px height + object-fit: contain so all
     thumbnails align even when some slots are empty or have different
     aspect ratios
   - form pushed to bottom via margin-top: auto, so the upload buttons
     line up across cells regardless of how much text is above
   - p.bold-text break-word so long filenames don't blow out the cell
   - the legacy <hr/> separator between items is hidden inside the grid
     (it was a vertical-flow artifact)

The grid uses align-items: stretch so all 4 cells have equal height.

Tests still pass (9 in target slice).
2026-05-10 18:26:50 -04:00
d194fc5e18
edit page: thumbnails header flex row, grid for thumbnails below
Per fox: the thumbnails card layout was a mess — the h3, descriptor
text, and thumbnail items were all crammed into a single grid with
auto-fit columns, so thumbnail 1+2 sat on the same row as the header
and thumbnails 3+4 wrapped to row 2 leaving the left half empty.

Fix: restructure to a proper header + grid:

  <section class="upload-thumbnails well2 edit-card-full">
    <div class="upload-thumbnails-header">
      <h3>... icon + title ...</h3>
      <p class="upload-thumbnails-hint">Your cover ...</p>
    </div>
    <div class="upload-thumbnails-grid">
      <div class="upload-thumbnail-item">...</div>
      ... (4 thumbnails)
    </div>
  </section>

CSS:
- .upload-thumbnails-header: flex row, space-between, wraps on narrow
  screens; h3 grows, hint right-aligned + max-width 320px
- .upload-thumbnails-grid: auto-fit minmax(240px, 1fr) for the 4
  thumbnail slots, gap --space-4

Result: header reads cleanly across the top with the cover descriptor
on the right, and all 4 thumbnails sit in a clean grid below.

Tests still pass (9 in target slice).
2026-05-10 18:25:30 -04:00
b874b07d44
bump GIT_HASH to 64e1d8b 2026-05-10 17:45:08 -04:00
64e1d8bd3c
edit page: thumbnail + edit-details cards span both columns
Per fox: "🎨 Upload or Replace Thumbnail Files ... should be in a row
that spans two columns" — and the same for "Edit Title, Description,
or Visibility".

Both cards now get class edit-card-full, which sets grid-column: 1 / -1
so they span the entire row in the 2-column edit grid. The thumbnail
grid has up to 4 thumbnails that need room; the edit-details card
has a wide form with pricing-mode radios and description textarea.

New CSS:
  div.edit-page > section.edit-card-full { grid-column: 1 / -1; }

Styleguide updated with a live half/half/full example demonstrating
the pattern.
2026-05-10 17:44:50 -04:00
36da4e33ee
bump GIT_HASH to 705271e 2026-05-10 16:26:44 -04:00
705271ec76
edit page: Material-style cards, status bar, primary save action
Per fox: "make this look awesome", "use styleguide", "think material
design to make it stand out as to what to do".

Status bar at top of edit page — three pills surface the product's
current state in one glance:
- Visibility: Public (blue) / Unlisted (purple) / Private (gray)
- Ready to sell (green) / Missing required files (gold warning)
- Current price (gray)

The pills tell the owner immediately what's done and what isn't.

Section cards (.well2 on edit page) get Material-card treatment:
- Background, rounded corners, border, elevation-1 shadow
- Hover/focus-within bumps to elevation-3 (subtle lift)
- h3 header gets a 36px circular icon badge (.edit-card-icon),
  thin bottom border separating header from content
- Icons: 📁 product file, 📺 preview, 🎨 thumbnails, ✏️ details,
  📦 inventory, 📦 bundle

Primary save action: Save Settings button is now a filled,
prominent CTA (navy bg, white text, bold, elevation-1 shadow that
lifts to elevation-2 on hover, disabled state dims). Class
.mps-button-primary on the styleguide for reuse.

.edit-save-bar provides a sticky-bottom save container CSS for a
follow-up wrapper around the Save Settings input (not yet wired
into product_edit.j2 — same hash adds the CSS so it's available).

All wired into the styleguide:
- Status bar + 3 pill states (public ready, private incomplete, etc.)
- Section card with icon header (3 example cards)
- Primary save action button

Tokens used (with fallbacks for safety): --elevation-1/3, --radius-lg,
--radius-pill, --color-navy/navy-dark, --color-blue-tint, --space-N,
--motion-fast, --color-green-dark, --color-gold, --color-purple.

Tests still pass (10 in target slice).
2026-05-10 16:26:30 -04:00
2c63c60118
bump GIT_HASH to ea58c12 2026-05-10 16:09:38 -04:00
ea58c12fda
edit page: file-meta line + thumbnail labels + merged file stats
Per fox's feedback on shop.unturf.com edit page:

- File Type and File Size now stack on a single line with · separator
  (was 2 stacked <p> tags). Class file-meta on the wrapper, file-meta-item
  on each child. Applied to product, preview, thumbnail blocks.

- File Statistics removed as a standalone well; "Total capacity" line
  moved into the upload-product well at top, using the same file-meta
  pattern. Eliminates the half-empty 4th column in the 2-col grid.

- Thumbnail upload sections now have an <h4 class="thumbnail-label">
  showing thumbnail1 / thumbnail2 / etc. so owners can tell which slot
  is the cover (thumbnail1 shows on search pages) vs additional images.

- Description label split fix: the label, helper text, and textarea
  are now properly stacked. The section.product-title-and-description
  rule (display: grid for product page) is overridden to display: block
  on the edit page so the form flows normally.

- Helper text under the Description label uses <small class="form-help">
  with token-based styling.

- Textarea max-width 600px lifted on the edit page so it fills the
  available well width.

Styleguide entries added at /styleguide for: file-meta line, thumbnail
label, form-help.

Tests still pass (10 in target slice).
2026-05-10 16:09:29 -04:00