style: product page polish — content-card layering, comment form fix

Wrap the product page's Description, File info, and Comments sections in
a new .content-card pattern: white surface, --border-light, --elevation-1
shadow, --radius-lg, --space-5 padding. Replaces the loose <br/><br/>
separators each section used to rely on with proper visual chunks layered
above the page surface (material-style).

Comment form fixes:
- Add input[type=email] to the global input style block (was unstyled,
  picking up browser default narrow width — the inline style="width:100%"
  on .comment-form-field's <input> got swamped by browser default).
- Replace ad-hoc <div>/<br/> markup with .comment-form-field rows; inputs
  and textarea fill width via box-sizing:border-box; submit button is
  justify-self:start instead of stretching across the form.
- Individual comments now sit on a --surface-dim soft inset card with
  --color-navy left accent on .comment-reply; .comment-header is a
  baseline-aligned 3-col grid (name / date / title).

Back-to-shop link is now a small secondary anchor (.mps-button-small),
left-aligned, instead of a full-width button.

Styleguide gains three subsections: Content card (under #wells), Comment
form, and a sample rendered comment with reply (under #comments).

Tests: targeted product/comment/styleguide slice — 51 passed.
This commit is contained in:
russell@unturf.com 2026-05-15 08:27:34 -04:00
parent 6e44027354
commit 3e4e663498
No known key found for this signature in database
4 changed files with 226 additions and 44 deletions

View file

@ -211,6 +211,7 @@ section {
input[type="text"],
input[type="tel"],
input[type="email"],
input[type="password"],
input[type="number"],
input[type="date"] {
@ -2064,6 +2065,127 @@ section.checkout-page .well {
color: white;
}
/* Content card — material-style elevated panel for product page sections
(description, file info, comments). Subtle elevation-1 shadow + light
border gives clear layering against the page surface; generous padding
replaces the loose <br/><br/> separators these sections used to rely
on. Grid only — no flex. */
.content-card {
background-color: var(--surface-base, #FFFFFF);
border-radius: var(--radius-lg, 12px);
border: 1px solid var(--border-light, #eeeeee);
box-shadow: var(--elevation-1);
padding: var(--space-5, 20px);
margin-bottom: var(--space-4, 16px);
display: grid;
gap: var(--space-3, 12px);
}
.content-card-header {
margin: 0;
font-size: var(--text-sm, 0.875rem);
font-weight: 700;
letter-spacing: 0.04em;
text-transform: uppercase;
color: var(--text-muted, #777);
}
.content-card-body { margin: 0; }
.content-card-meta {
margin: 0;
color: var(--text-muted, #777);
font-size: var(--text-sm, 0.875rem);
}
[data-theme="dark"] .content-card {
background-color: var(--surface-container, #161b22);
border-color: var(--border-default, #30363d);
}
/* Comment form polish — applied inside .content-card so it inherits the
panel chrome. Stacked label / control / hint with proper spacing,
inputs and textarea fill the width consistently. Grid only. */
.comment-form {
display: grid;
gap: var(--space-3, 12px);
}
.comment-form h4 {
margin: 0;
font-size: var(--text-md, 1.125rem);
font-weight: 600;
}
.comment-form form {
display: grid;
gap: var(--space-3, 12px);
}
.comment-form-field {
display: grid;
gap: var(--space-1, 4px);
}
.comment-form label {
margin: 0;
font-weight: 600;
}
.comment-form input[type="text"],
.comment-form input[type="email"],
.comment-form textarea {
width: 100%;
box-sizing: border-box;
padding: var(--space-2, 8px) var(--space-3, 12px);
}
.comment-form textarea {
min-height: 6rem;
resize: vertical;
}
.comment-form .mps-comment-form-button {
justify-self: start;
padding: var(--space-2, 8px) var(--space-4, 16px);
}
/* Comments list polish — each comment is a soft inset surface within
the parent .content-card so the depth reads clearly. Replies inherit
the same chrome with a left accent. */
.comments-section { display: grid; gap: var(--space-4, 16px); }
.comments-section h3 { margin: 0; }
#comments-list { display: grid; gap: var(--space-3, 12px); }
.comments-section .comment {
background-color: var(--surface-dim, #f9f9fa);
border-radius: var(--radius-md, 8px);
padding: var(--space-3, 12px) var(--space-4, 16px);
/* The inline `style="margin-left: Npx"` on .comment in the snippet
gives nested replies a stair-step indent; keep that working but
drop the legacy 20px bottom-margin (we use grid gap above). */
margin-bottom: 0 !important;
}
.comments-section .comment-reply {
border-left: 3px solid var(--color-navy, #5871ad);
}
.comments-section .comment-header {
display: grid;
grid-template-columns: auto auto 1fr;
gap: var(--space-2, 8px);
align-items: baseline;
margin-bottom: var(--space-2, 8px);
}
.comments-section .comment-date {
color: var(--text-muted, #777);
font-size: var(--text-sm, 0.875rem);
}
.comments-section .comment-title {
font-weight: 600;
}
.comments-section .comment-content {
margin-bottom: var(--space-2, 8px);
}
/* Back-to-shop link on the product page: small secondary link below the
comments card, left-aligned, not stretched to the full row. */
.product-back-link {
margin-top: var(--space-3, 12px);
justify-self: start;
}
[data-theme="dark"] .one-column.well.well-green,
[data-theme="dark"] .action-columns.well.well-green {
background-color: var(--dark-button-bg, #2d3748);

View file

@ -136,50 +136,45 @@
<div class="cinema-content-stack">
<div class="product-description">
<br/>
<br/>
<b>Description</b>
<section>{{ product.description_html | safe }}</section>
<br/>
<br/>
<article class="content-card">
<h3 class="content-card-header">Description</h3>
<div class="content-card-body">{{ product.description_html | safe }}</div>
{% if request.shop.show_dates %}
<p class="content-card-meta product-meta-dates">
Created {{ product.human_created_timestamp }}{% if product.human_created_timestamp != product.human_updated_timestamp %} · Updated {{ product.human_updated_timestamp }}{% endif %}{% if product.human_view_count %} · <span class="product-view-count">{{ product.human_view_count }}</span>{% endif %}
</p>
{% endif %}
</article>
{% if product.is_bundle %}
{% if product.products_in_this_bundle %}
<b>Bundle Contents</b>
<ul>
{% for p in product.products_in_this_bundle %}
<li>
{{p.title}}
</li>
{% endfor %}
</ul>
<article class="content-card">
<h3 class="content-card-header">Bundle Contents</h3>
<ul class="content-card-body">
{% for p in product.products_in_this_bundle %}
<li>{{p.title}}</li>
{% endfor %}
</ul>
</article>
{% endif %}
{% elif product.has_product_file %}
<b>File Type</b>
<br/>
{{ product.get_content_type("product") }} {{ product_size }}
<br/>
Please make sure you have an application to open this file type.
<article class="content-card">
<h3 class="content-card-header">File</h3>
<p class="content-card-body">{{ product.get_content_type("product") }} &middot; {{ product_size }}</p>
<p class="content-card-meta">Make sure you have an application to open this file type.</p>
</article>
{% endif %}
{% if request.shop.show_dates %}
<div class="product-meta-dates">
Created {{ product.human_created_timestamp }}{% if product.human_created_timestamp != product.human_updated_timestamp %} · Updated {{ product.human_updated_timestamp }}{% endif %}{% if product.human_view_count %} · <span class="product-view-count">{{ product.human_view_count }}</span>{% endif %}
</div>
{% endif %}
</div>
<div class="product-comments">
<br/>
<br/>
<!-- Comments Section -->
{% include 'snippets/comments.j2' %}
<article class="content-card">
{% include 'snippets/comments.j2' %}
</article>
<br/>
<a href="/" class="product-edit-button mps-button">Back to shop</a>
<a href="/" class="mps-button-small product-back-link">&larr; Back to shop</a>
</div>
</div>

View file

@ -85,13 +85,11 @@
<input type="hidden" name="product_id" value="{{ product.id if product else '' }}" />
<input type="hidden" name="parent_id" value="" />
<div>
<label for="comment-data">Comment:</label>
<textarea name="data" id="comment-data" rows="4" style="width: 100%;" required></textarea>
<div class="comment-form-field">
<label for="comment-data">Comment</label>
<textarea name="data" id="comment-data" rows="4" required></textarea>
</div>
<br/>
<div>
<input type="submit" value="Send Comment" class="mps-comment-form-button" />
</div>
@ -107,16 +105,17 @@
<input type="hidden" name="product_id" value="{{ product.id if product else '' }}" />
<input type="hidden" name="parent_id" value="" />
<div>
<label for="comment-data">Comment:</label>
<textarea name="data" id="comment-data" rows="4" style="width: 100%;" required></textarea>
<div class="comment-form-field">
<label for="comment-data">Comment</label>
<textarea name="data" id="comment-data" rows="4" required></textarea>
</div>
<div>
<label for="comment-email">Email:</label>
<input type="email" name="email" id="comment-email" style="width: 100%;" required />
<div class="comment-form-field">
<label for="comment-email">Email</label>
<input type="email" name="email" id="comment-email" required />
</div>
{# Honeypot for spam bots. #}
<input
name="email2"
type="email"
@ -124,10 +123,9 @@
value=""
tabindex="-1"
autocomplete="off"
class="hidden-form"
/>
<br/>
<div>
<input type="submit" value="Send Comment" class="mps-comment-form-button" />
</div>

View file

@ -730,6 +730,20 @@ Grid only — no flex.</div>
Coupon container with dotted border. border: 3px dotted #bbb, border-radius: 4px, padding: 20px.
</div>
</div>
<div class="sg-subsection">
<div class="sg-label">Content card (elevated panel, layered above page)</div>
<article class="content-card" style="max-width: 520px;">
<h3 class="content-card-header">Description</h3>
<p class="content-card-body">Reusable elevated card. Layered above the page surface with <code>--elevation-1</code> and <code>--radius-lg</code>. Used on the product page for description, file info, and the comments panel — each section reads as its own chunk instead of floating in raw text with <code>&lt;br/&gt;</code> separators.</p>
<p class="content-card-meta">Stacked tokens-only: <code>--surface-base</code> background, <code>--border-light</code> border, <code>--elevation-1</code> shadow, <code>--space-5</code> padding.</p>
</article>
<div class="sg-code">.content-card — surface-base, border-light, elevation-1, radius-lg
.content-card-header — small uppercase label, var(--text-muted)
.content-card-body — content (paragraphs / lists / forms)
.content-card-meta — small muted meta line (dates, hints)
Dark mode: surface-container + border-default override (auto).</div>
</div>
</div>
@ -908,6 +922,59 @@ Checkout page:
.delete-link — red text, red border on hover
.moderate-link — same as reply
Dark mode: uses theme background images on hover</div>
<div class="sg-subsection">
<div class="sg-label">Comment form (inside .content-card)</div>
<article class="content-card" style="max-width: 520px;">
<div class="comment-form">
<h4>Leave a Comment</h4>
<form onsubmit="return false;">
<div class="comment-form-field">
<label for="sg-comment-data">Comment</label>
<textarea id="sg-comment-data" rows="4"></textarea>
</div>
<div class="comment-form-field">
<label for="sg-comment-email">Email</label>
<input type="email" id="sg-comment-email" />
</div>
<div>
<input type="submit" value="Send Comment" class="mps-comment-form-button" />
</div>
</form>
</div>
</article>
<div class="sg-code">.comment-form — grid, gap var(--space-3)
.comment-form-field — label + control stacked, gap var(--space-1)
inputs / textarea — width:100%, box-sizing:border-box
.mps-comment-form-button — justify-self:start (doesn't span full width)
Hosted inside a .content-card so the panel chrome handles padding/elevation.</div>
</div>
<div class="sg-subsection">
<div class="sg-label">Sample rendered comment (depth 0 + reply)</div>
<section class="comments-section" style="max-width: 520px;">
<div id="comments-list">
<div class="comment">
<div class="comment-header">
<strong>jane-doe</strong>
<span class="comment-date">2 days ago</span>
</div>
<div class="comment-content"><p>Great product, fast download. Will recommend.</p></div>
</div>
<div class="comment comment-reply" style="margin-left: 20px;">
<div class="comment-header">
<strong>shop-owner</strong>
<span class="comment-date">1 day ago</span>
</div>
<div class="comment-content"><p>Thanks for the review, jane-doe!</p></div>
</div>
</div>
</section>
<div class="sg-code">.comments-section .comment — soft surface-dim card, radius-md
.comments-section .comment-reply — left accent in --color-navy
.comment-header — grid auto auto 1fr, baseline-aligned
The snippet sets inline margin-left for depth-N replies (depth * 20px).</div>
</div>
</div>