fix(lotus): in-call mobile UI fixes (EC audit wave-2)
CI / Build embedded bundle (push) Successful in 44s
CI / Publish to Gitea npm registry (push) Has been skipped

3-agent survey of the in-call UI at phone width + 2-agent review of the
staged diff. All changes are mobile-gated CSS (mobile-first @media on
Compound tokens), so desktop rendering is provably unchanged.

- CallFooter: wrap the control row and tighten gap/padding at <=500px so
  the buttons (incl. the destructive hangup) can never be clipped by the
  grid's overflow-x:hidden. A loudspeaker button was added to the bar
  without a shed rule, pushing 6-7 lg buttons past the viewport at
  320-500px.
- OneOnOnePortraitLayout: give the 1:1 self-view the same safe-area-aware
  inset as SpotlightExpandedLayout so it clears the home indicator /
  floating footer (was a bare 16px inset). Phone-only layout.
- GridTile: enlarge the always-visible camera-flip control to a 44px touch
  target on coarse pointers (was ~28px).
- ReactionToggleButton: enlarge reaction-picker emoji buttons to 44px at
  <=420px (were ~32px); five still fit a 360px drawer row.
- Tabs: scroll the horizontal tab row on the inline axis (overflow-x) so
  the Settings tabs don't clip in a phone drawer.
- SpotlightLandscapeLayout: shrink the 180px filmstrip rail to 132px on
  short landscape phones (max-height:400px) so the spotlight isn't a sliver.

Gates: tsc 0, prettier clean, affected vitest pass. No TS changed.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Lotus CI
2026-07-19 01:08:43 -04:00
co-authored by Claude Opus 4.8
parent 0ffe247929
commit e36aef8aa3
6 changed files with 55 additions and 4 deletions
+4 -2
View File
@@ -12,8 +12,10 @@
@media (max-width: 420px) {
.reactionPopupMenu {
--reaction-button-padding: 8px;
--reaction-button-fontsize: 16px;
/* 20px glyph + 2×12px padding = a 44px square touch target. Five buttons
still fit a ~360px drawer row; previously these were ~32px. */
--reaction-button-padding: 12px;
--reaction-button-fontsize: 20px;
--reaction-button-gap: 6px;
}
}
+14
View File
@@ -102,6 +102,20 @@ Once we exceed 500 we hide everything except the buttons.
@media (max-width: 500px) {
.footer {
grid-template-areas: "buttons buttons buttons";
/* Reclaim horizontal budget so the control row fits on phones. */
padding-left: calc(env(safe-area-inset-left) + var(--cpd-space-3x));
padding-right: calc(env(safe-area-inset-right) + var(--cpd-space-3x));
}
.buttons {
/* Fill the row and wrap instead of overflowing: on the narrowest phones the
control set (mic/video/loudspeaker/hangup) exceeds the viewport, and the
parent's overflow-x: hidden would otherwise clip the outer buttons —
including the destructive hangup. Wrapping keeps every control reachable. */
justify-self: stretch;
flex-wrap: wrap;
justify-content: center;
gap: var(--cpd-space-2x);
}
.settingsOnlyShowNarrow {
+8 -1
View File
@@ -16,7 +16,14 @@ Please see LICENSE in the repository root for full details.
.pip {
position: absolute;
inset: var(--cpd-space-4x);
/* Keep the self-view within the safe area (home indicator) and the inline
content insets, and clear of the floating footer — matching the
reference-correct SpotlightExpandedLayout. A bare 16px inset let the
bottom-right self-tile sit under the controls / device chrome on phones. */
inset: calc(env(safe-area-inset-top) + var(--cpd-space-4x))
var(--content-inset-right)
calc(env(safe-area-inset-bottom) + var(--cpd-space-4x))
var(--content-inset-left);
}
.pip[data-size="sm"] {
@@ -43,3 +43,17 @@ unconditionally select the container so we can use cq units */
inline-size: 180px;
block-size: 135px;
}
/* On a landscape phone the fixed 180px filmstrip rail squeezes the spotlight to
a sliver; shrink the rail (keeping the 4:3 tile ratio) to give the spotlight
room. Desktop landscape (height > 400px) is unaffected. */
@media (max-height: 400px) {
.layer {
--grid-slot-width: 132px;
}
.grid > .slot {
inline-size: 132px;
block-size: 99px;
}
}
+7 -1
View File
@@ -12,7 +12,12 @@ Please see LICENSE in the repository root for full details.
}
.tabList {
overflow-y: auto;
/* The tab row is horizontal, so scroll along the inline axis when the tabs
exceed the width (e.g. the Settings modal as a phone drawer). The prior
overflow-y:auto expressed the wrong axis; make the horizontal intent
explicit and hide the scrollbar. */
overflow-x: auto;
overflow-y: hidden;
max-width: 100%;
/*no scrollbars*/
@@ -24,4 +29,5 @@ Please see LICENSE in the repository root for full details.
/*no scrollbars*/
background: transparent; /* Chrome/Safari/Webkit */
width: 0px;
height: 0px;
}
+8
View File
@@ -98,6 +98,14 @@ borders don't support gradients */
color: var(--cpd-color-icon-primary);
}
/* The camera-flip control is always visible and primarily used on phones;
its inherited 4px padding yields a ~28px box, below the touch minimum. */
@media (hover: none), (pointer: coarse) {
.tile .switchCamera {
padding: var(--cpd-space-3x);
}
}
@media (hover) {
.tile .switchCamera:hover {
background: var(--cpd-color-bg-subtle-secondary);