feat: cinema only activates for landscape media (aspect > 1)
Portrait and square media stay in the normal watch layout even when the Cinema toggle is on — tall phone videos no longer get stretched into a skinny column on a wide screen. Only wider-than-square media triggers the layout adjustment that makes wide/ultrawide content fill the horizontal viewport. Two-class gate: .cinema-mode — user intent (from the toggle) .cinema-wide — runtime state (current media aspect > 1) CSS layout rules now require BOTH classes. When cinema is on but media is portrait, .cinema-mode is on and .cinema-wide is off, and the selectors don't match — normal watch layout applies. Aspect detection reads video.videoWidth/videoHeight or img.naturalWidth/naturalHeight. Unknown dimensions (metadata not yet loaded) defaults to not wide; a loadedmetadata / img.load listener re-invokes applyCinemaMode once real dimensions are known. Taskbar relocation also gated on cinema-wide — portrait doesn't steal the hamburger + Edit from their normal home.
This commit is contained in:
parent
aa72430323
commit
92a305072e
2 changed files with 56 additions and 19 deletions
|
|
@ -1727,7 +1727,7 @@ textarea.markup-editor-textarea {
|
|||
stack everything in a single column so cinema doesn't collapse
|
||||
into natural block flow (which caused the "wasted whitespace"
|
||||
state between 800px and 960px when nothing owned the layout). */
|
||||
section.two-column.cinema-mode {
|
||||
section.two-column.cinema-mode.cinema-wide {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr;
|
||||
grid-template-areas:
|
||||
|
|
@ -1741,11 +1741,11 @@ section.two-column.cinema-mode {
|
|||
align-items: start;
|
||||
}
|
||||
|
||||
section.two-column.cinema-mode .watch-left {
|
||||
section.two-column.cinema-mode.cinema-wide .watch-left {
|
||||
display: contents;
|
||||
}
|
||||
|
||||
section.two-column.cinema-mode .cinema-content-stack {
|
||||
section.two-column.cinema-mode.cinema-wide .cinema-content-stack {
|
||||
display: grid;
|
||||
grid-area: content;
|
||||
grid-template-rows: auto auto;
|
||||
|
|
@ -1754,10 +1754,10 @@ section.two-column.cinema-mode .cinema-content-stack {
|
|||
min-width: 0;
|
||||
}
|
||||
|
||||
section.two-column.cinema-mode .product-images { grid-area: images; }
|
||||
section.two-column.cinema-mode section.product-right { grid-area: purchase; align-self: start; }
|
||||
section.two-column.cinema-mode.cinema-wide .product-images { grid-area: images; }
|
||||
section.two-column.cinema-mode.cinema-wide section.product-right { grid-area: purchase; align-self: start; }
|
||||
|
||||
section.two-column.cinema-mode .watch-video-container {
|
||||
section.two-column.cinema-mode.cinema-wide .watch-video-container {
|
||||
max-height: 92vh;
|
||||
}
|
||||
|
||||
|
|
@ -1765,9 +1765,9 @@ section.two-column.cinema-mode .watch-video-container {
|
|||
of the CLAUDE.md media-sizing rule — cinema wants edge-to-edge
|
||||
even if viewport aspect ratio forces a little letterbox.
|
||||
object-fit:contain keeps aspect ratio safe. */
|
||||
section.two-column.cinema-mode .product-main,
|
||||
section.two-column.cinema-mode .watch-video-container > video,
|
||||
section.two-column.cinema-mode .watch-audio-container > .product-main {
|
||||
section.two-column.cinema-mode.cinema-wide .product-main,
|
||||
section.two-column.cinema-mode.cinema-wide .watch-video-container > video,
|
||||
section.two-column.cinema-mode.cinema-wide .watch-audio-container > .product-main {
|
||||
width: 100%;
|
||||
height: auto;
|
||||
max-width: 100%;
|
||||
|
|
@ -1781,7 +1781,7 @@ section.two-column.cinema-mode .watch-audio-container > .product-main {
|
|||
/* Cinema: the main media is already showing at full viewport width,
|
||||
so the wrapping "click to open in new window" link is redundant
|
||||
and just steals the click from scrolling and other interactions. */
|
||||
section.two-column.cinema-mode .product-images > a[target="_blank"] {
|
||||
section.two-column.cinema-mode.cinema-wide .product-images > a[target="_blank"] {
|
||||
pointer-events: none;
|
||||
cursor: default;
|
||||
}
|
||||
|
|
@ -1789,13 +1789,13 @@ section.two-column.cinema-mode .product-images > a[target="_blank"] {
|
|||
/* Cinema: task bar (hamburger + Edit) relocates into .product-right
|
||||
above the well via JS. Stack its children vertically and make it
|
||||
feel like part of the sidebar rather than a floating chrome strip. */
|
||||
section.two-column.cinema-mode section.product-right section.windows-95-task-bar {
|
||||
section.two-column.cinema-mode.cinema-wide section.product-right section.windows-95-task-bar {
|
||||
grid-template-columns: 1fr;
|
||||
padding: 0;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
section.two-column.cinema-mode section.product-right section.windows-95-start-button,
|
||||
section.two-column.cinema-mode section.product-right section.call-to-action {
|
||||
section.two-column.cinema-mode.cinema-wide section.product-right section.windows-95-start-button,
|
||||
section.two-column.cinema-mode.cinema-wide section.product-right section.call-to-action {
|
||||
padding-left: 0;
|
||||
padding-right: 0;
|
||||
}
|
||||
|
|
@ -1885,7 +1885,7 @@ section.two-column.cinema-mode section.product-right section.call-to-action {
|
|||
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 {
|
||||
section.two-column.cinema-mode.cinema-wide {
|
||||
grid-template-columns: 2fr 1fr;
|
||||
grid-template-areas:
|
||||
"images images"
|
||||
|
|
|
|||
|
|
@ -200,15 +200,51 @@
|
|||
}
|
||||
})();
|
||||
|
||||
// Cinema activates only for landscape media (aspect > 1). Portrait
|
||||
// and square content stays in the normal watch layout so tall phone
|
||||
// videos don't get forced into a full-viewport wide treatment that
|
||||
// leaves the page as a skinny column in a sea of black.
|
||||
function isMediaWide() {
|
||||
var video = document.querySelector('#watch-video');
|
||||
if (video && video.videoWidth && video.videoHeight) {
|
||||
return video.videoWidth / video.videoHeight > 1;
|
||||
}
|
||||
var img = document.querySelector('.product-images .product-main');
|
||||
if (!img) img = document.querySelector('.product-images img');
|
||||
if (img && img.naturalWidth && img.naturalHeight) {
|
||||
return img.naturalWidth / img.naturalHeight > 1;
|
||||
}
|
||||
return false; // unknown — don't activate cinema layout yet
|
||||
}
|
||||
|
||||
function bindCinemaAspectHandlers() {
|
||||
var video = document.querySelector('#watch-video');
|
||||
if (video && !video._cinemaAspectBound) {
|
||||
video._cinemaAspectBound = true;
|
||||
video.addEventListener('loadedmetadata', applyCinemaMode);
|
||||
}
|
||||
var img = document.querySelector('.product-images .product-main');
|
||||
if (!img) img = document.querySelector('.product-images img');
|
||||
if (img && img.tagName === 'IMG' && !img._cinemaAspectBound) {
|
||||
img._cinemaAspectBound = true;
|
||||
img.addEventListener('load', applyCinemaMode);
|
||||
}
|
||||
}
|
||||
|
||||
function applyCinemaMode() {
|
||||
var section = document.querySelector('section.two-column');
|
||||
if (!section) return;
|
||||
|
||||
bindCinemaAspectHandlers();
|
||||
|
||||
var taskbar = document.querySelector('section.windows-95-task-bar');
|
||||
var productRight = document.querySelector('section.product-right');
|
||||
var wide = cinemaMode && isMediaWide();
|
||||
|
||||
if (cinemaMode) {
|
||||
section.classList.add('cinema-mode');
|
||||
// Move taskbar (hamburger + Edit) into the sidebar above the well.
|
||||
section.classList.toggle('cinema-mode', cinemaMode);
|
||||
section.classList.toggle('cinema-wide', wide);
|
||||
|
||||
if (wide) {
|
||||
if (taskbar && productRight) {
|
||||
var well = productRight.querySelector('.well');
|
||||
if (well && taskbar.parentElement !== productRight) {
|
||||
|
|
@ -216,8 +252,6 @@
|
|||
}
|
||||
}
|
||||
} else {
|
||||
section.classList.remove('cinema-mode');
|
||||
// Put taskbar back where it came from.
|
||||
if (taskbar && _taskbarOriginalParent && taskbar.parentElement !== _taskbarOriginalParent) {
|
||||
_taskbarOriginalParent.insertBefore(taskbar, _taskbarOriginalNextSibling);
|
||||
}
|
||||
|
|
@ -1001,6 +1035,9 @@
|
|||
if (window.sandboxReapply) {
|
||||
window.sandboxReapply();
|
||||
}
|
||||
|
||||
// New media element — re-detect aspect and update cinema classes
|
||||
applyCinemaMode();
|
||||
}
|
||||
|
||||
function updateRelated(related, commentsEnabled, commentCount) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue