fix: cinema — description+comments in one grid cell, no row stretch

Previously purchase (ring sidebar) spanned grid rows 2 and 3. When
Up Next was tall and description was short, grid distributed the
spanning column's height across both rows — description sat at top
of a stretched row 2 with hundreds of pixels of empty space before
comments.

New structure: wrap description + comments in .cinema-content-stack.
Outside cinema mode the wrapper is display:contents (transparent,
zero effect). In cinema mode it becomes a single grid cell containing
description + comments as an internal stack. Main grid is now just
two rows: images (full width) then content | purchase.

Row 2 height = max(content column, purchase column). If purchase is
taller, content stack still starts at top, and description + comments
stay glued together at the top of the column — comments is reachable
without scrolling past a dead zone.
This commit is contained in:
russell@unturf.com 2026-04-22 15:18:17 -04:00
parent eb9dcf6df4
commit 1386fc660c
3 changed files with 30 additions and 9 deletions

View file

@ -1713,6 +1713,15 @@ textarea.markup-editor-textarea {
}
}
/* cinema-content-stack is a template wrapper around description +
comments. Default display:contents makes it transparent so every
layout outside cinema mode sees children as direct grid items.
Cinema mode turns it into a single grid cell (rules below) so the
purchase column can't stretch description's row. */
.cinema-content-stack {
display: contents;
}
/* Cinema mode base applies at every viewport size. Desktop
(>=960px) enhances it to the 2-column layout. Narrow viewports
stack everything in a single column so cinema doesn't collapse
@ -1723,8 +1732,7 @@ section.two-column.cinema-mode {
grid-template-columns: 1fr;
grid-template-areas:
"images"
"description"
"comments"
"content"
"purchase";
gap: 16px;
max-width: 100%;
@ -1737,10 +1745,17 @@ section.two-column.cinema-mode .watch-left {
display: contents;
}
section.two-column.cinema-mode .cinema-content-stack {
display: grid;
grid-area: content;
grid-template-rows: auto auto;
gap: 16px;
align-content: start;
min-width: 0;
}
section.two-column.cinema-mode .product-images { grid-area: images; }
section.two-column.cinema-mode .product-description { grid-area: description; }
section.two-column.cinema-mode .product-comments { grid-area: comments; }
section.two-column.cinema-mode section.product-right { grid-area: purchase; }
section.two-column.cinema-mode section.product-right { grid-area: purchase; align-self: start; }
section.two-column.cinema-mode .watch-video-container {
max-height: 92vh;
@ -1844,13 +1859,15 @@ section.two-column.cinema-mode .watch-audio-container > .product-main {
/* Desktop cinema enhancement description + comments beside ring.
The base cinema rules live outside any media query so narrow
viewports also get a sensible single-column stack. */
viewports also get a sensible single-column stack. content area
contains description + comments as an internal stack, so row 2
is sized by whichever column is taller and no spanning tricks
stretch description's row when the Up Next list is long. */
section.two-column.cinema-mode {
grid-template-columns: 2fr 1fr;
grid-template-areas:
"images images"
"description purchase"
"comments purchase";
"images images"
"content purchase";
gap: 24px;
padding-left: 20px;
padding-right: 20px;

View file

@ -117,6 +117,7 @@
<h1>{{ product.title }}<br/><span class="subtitle-text">uploaded to <a href="{{ product.shop.absolute_about_url(request) }}" rel="nofollow" class="shop-theme-link-color">{{ product.shop.name }}</a></span></h1>
</div>
<div class="cinema-content-stack">
<div class="product-description">
<br/>
@ -158,6 +159,7 @@
<!-- Comments Section -->
{% include 'snippets/comments.j2' %}
</div>
</div>
{% if request.shop.watch_mode_enabled %}</div>{% endif %}

View file

@ -134,6 +134,7 @@
{% endfor %}
</div>
<div class="cinema-content-stack">
<div class="product-description">
<br/>
<br/>
@ -180,6 +181,7 @@
<br/>
<a href="/" class="product-edit-button mps-button">Back to shop</a>
</div>
</div>
{% if request.shop.watch_mode_enabled %}</div>{% endif %}