bd35b3ff296d
adaptive layout: layout-compact/medium/expanded body class on resize, breakpoints for two-pane + landscape + narrow split
- time
- 2026-05-01 04:08 UTC · 5 months ago
- machine
- koh2
- parent
- a145a1c8e968
↓ peach-browser-bd35b3ff.tar.gzatlas at this save
files changed2 files
src/popup/App.tsx+14 −0src/popup/styles/popup.css+71 −0src/popup/App.tsx+14 −0
@@ -367,6 +367,19 @@367367 document.documentElement.classList.add("peach-mobile-root");368368 void applyMobileStatusBar(theme());369369 370+ // Window Size Class detection — compact/medium/expanded matches Android's371+ // breakpoints. Drives two-pane layout on Z Fold inner display + tablets.372+ const updateLayoutClass = () => {373+ const w = window.innerWidth;374+ const cls = document.body.classList;375+ cls.remove("layout-compact", "layout-medium", "layout-expanded");376+ if (w >= 840) cls.add("layout-expanded");377+ else if (w >= 600) cls.add("layout-medium");378+ else cls.add("layout-compact");379+ };380+ updateLayoutClass();381+ window.addEventListener("resize", updateLayoutClass);382+370383 const keyboardShow = await Keyboard.addListener("keyboardWillShow", (info) => {371384 document.body.style.paddingBottom = `${info.keyboardHeight}px`;372385 });@@ -401,6 +414,7 @@401414 void keyboardShow.remove();402415 void keyboardHide.remove();403416 void backButton.remove();417+ window.removeEventListener("resize", updateLayoutClass);404418 document.removeEventListener("touchstart", handleTouchStart);405419 document.removeEventListener("touchend", handleTouchEnd);406420 document.body.style.paddingBottom = "0";src/popup/styles/popup.css+71 −0
@@ -7033,3 +7033,74 @@70337033 margin: 0;70347034 padding: 2px 0 0;70357035 }7036+7037+/* ── Adaptive layout — Window Size Classes ───────────────────────────7038+ Compact (< 600dp) — phone, foldable cover, narrow split-screen7039+ Medium (600–839) — Z Fold inner display, small tablet7040+ Expanded (840+) — tablet, DeX window, desktop7041+ Body class is set from App.tsx onMount + window resize. */7042+7043+/* Compact stays edge-to-edge (existing behavior). */7044+7045+body.peach-mobile.layout-medium .popup-root,7046+body.peach-mobile.layout-expanded .popup-root {7047+ max-width: 840px;7048+ margin: 0 auto;7049+}7050+7051+body.peach-mobile.layout-medium .peach-shell[data-surface="extension"],7052+body.peach-mobile.layout-expanded .peach-shell[data-surface="extension"] {7053+ max-width: 840px;7054+ margin: 0 auto;7055+}7056+7057+/* Two-pane: vault list on the left, entry detail on the right.7058+ Activates on medium+ when both are present. App-side wires the7059+ .peach-vault-twopane wrapper class on these widths. */7060+body.peach-mobile.layout-medium .peach-vault-twopane,7061+body.peach-mobile.layout-expanded .peach-vault-twopane {7062+ display: grid;7063+ grid-template-columns: 320px minmax(0, 1fr);7064+ gap: 0;7065+ height: 100%;7066+}7067+7068+body.peach-mobile.layout-medium .peach-vault-twopane > .peach-vault-list-pane,7069+body.peach-mobile.layout-expanded .peach-vault-twopane > .peach-vault-list-pane {7070+ border-right: 1px solid var(--peach-border, var(--peach-t3));7071+ overflow-y: auto;7072+ scrollbar-width: none;7073+}7074+7075+body.peach-mobile.layout-medium .peach-vault-twopane > .peach-vault-detail-pane,7076+body.peach-mobile.layout-expanded .peach-vault-twopane > .peach-vault-detail-pane {7077+ overflow-y: auto;7078+ scrollbar-width: none;7079+}7080+7081+/* Tabletop posture — pad content away from the hinge crease. */7082+body.peach-mobile[data-posture="tabletop"] .peach-vault-twopane,7083+body.peach-mobile[data-posture="tabletop"] .peach-stage,7084+body.peach-mobile[data-posture="tabletop"] .peach-overlay-view {7085+ padding-bottom: var(--peach-hinge-height, 0px);7086+}7087+7088+/* Landscape phone — short viewport, reduce vertical padding so content fits. */7089+@media (orientation: landscape) and (max-height: 500px) {7090+ body.peach-mobile .popup-root {7091+ padding-top: env(safe-area-inset-top);7092+ }7093+ body.peach-mobile .peach-shell[data-surface="extension"] {7094+ grid-template-rows: auto minmax(0, 1fr);7095+ }7096+}7097+7098+/* Narrow split-screen (down to 280dp) — keep content readable. */7099+@media (max-width: 320px) {7100+ body.peach-mobile .peach-chrome,7101+ body.peach-mobile .peach-stage,7102+ body.peach-mobile .peach-overlay-view {7103+ padding-left: 8px;7104+ padding-right: 8px;7105+ }7106+}