style(settings): pair Save and Close into one tray in the phone sheet header

Below 860px Save moves into the header (a bottom action bar would cost 60px
of a phone sheet), which left the two ways OUT of the sheet sitting side by
side in mismatched shapes: a fat accent pill next to a bare 1.5rem glyph
with no box at all. They are the same decision (save-and-close vs
discard-and-close), hit in the same corner with the same thumb, so they now
share a recessed tray and matching pill geometry and read as one cluster.

- 36px on both, so the tray comes out at 44px including its 3px padding and
  1px border — the same height as the phone header it sits in.
- `.modal-close` gets a real box (36x36, radius 9) only inside the tray; its
  bare-glyph form is still right in a plain modal header.
- Tray colors come from skin tokens (--border/--bg-input). A hardcoded black
  alpha would render as a grey slab on the four light skins, the same trap
  the layout preview frame hit.
- `:has(.set-head-save)` keeps the tray off the sheets that carry a lone x:
  Session Options and Add Case save from inside their own forms.
- The shared focus ring offsets OUTWARD, which inside the tray would draw on
  top of the tray border, so it is inset to ring the button instead.

DOM order stays close-then-save so the focus trap still lands on Close;
row-reverse paints Save to its left.

Verified at 390x844: tray 44px tall, Save 36px, Close 36x36, both radius 9
inside a 12-radius tray. PostCSS-parsed (prettier does not catch an unclosed
CSS block, and styles.css is prettier-ignored by design).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Codeman maintainer
2026-08-11 19:34:21 +02:00
parent aa28ef048c
commit e20aa1d4d8
2 changed files with 83 additions and 4 deletions
+28 -1
View File
@@ -3157,9 +3157,36 @@ html:is([data-skin="paper-gray"], [data-skin="solarized-light"], [data-skin="cat
border-radius: 10px;
}
/* Save moves into the header; the bottom action bar would cost 60px */
/* Save + Close are the two ways out of the sheet (save-and-close vs
discard-and-close), hit in the same corner with the same thumb, so here —
and only here, since Save is header-only below 860px — they share a
recessed tray and matching pill geometry instead of reading as a fat
accent pill parked beside a stray × glyph. Tray colors come from skin
tokens, never a hardcoded black alpha, or the light skins get a grey slab.
`:has()` keeps the tray off the two sheets that carry a lone × (Session
Options and Add Case save from inside their own forms). */
:is(#appSettingsModal, #sessionOptionsModal, #createCaseModal) .set-head-actions:has(.set-head-save) {
padding: 3px;
border: 1px solid var(--border);
border-radius: 12px;
background: var(--bg-input);
}
/* Save moves into the header; the bottom action bar would cost 60px. Both
buttons grow to a thumb-sized target and keep identical heights so the
pair reads as one cluster — 36 + the tray's 3px padding and 1px border on
each side is a 44px block, the same height as the phone header. */
:is(#appSettingsModal, #sessionOptionsModal, #createCaseModal) .set-head-save {
display: inline-flex;
height: 36px;
padding: 0 16px;
font-size: 0.86rem;
}
:is(#appSettingsModal, #sessionOptionsModal, #createCaseModal) .set-head-actions .modal-close {
width: 36px;
height: 36px;
font-size: 1.35rem;
}
:is(#appSettingsModal, #sessionOptionsModal, #createCaseModal) .set-foot {
+55 -3
View File
@@ -14759,11 +14759,14 @@ html[data-skin="daylight-blue"] .welcome-btn-tunnel.active:hover {
flex-shrink: 0;
}
/* DOM order stays close-then-save so the focus trap lands on Close;
row-reverse paints Save to the left of it. Below 860px, where Save joins the
header, the two become ONE control cluster inside a tray (mobile.css). */
:is(#appSettingsModal, #sessionOptionsModal, #createCaseModal) .set-head-actions {
display: flex;
flex-direction: row-reverse;
align-items: center;
gap: 6px;
gap: 3px;
margin-left: auto;
}
@@ -14771,16 +14774,65 @@ html[data-skin="daylight-blue"] .welcome-btn-tunnel.active:hover {
instead; on desktop the footer owns Save, so this stays hidden. */
:is(#appSettingsModal, #sessionOptionsModal, #createCaseModal) .set-head-save {
display: none;
align-items: center;
justify-content: center;
height: 30px;
font: inherit;
font-size: 0.82rem;
font-weight: 620;
letter-spacing: -0.01em;
padding: 8px 15px;
padding: 0 14px;
border: 0;
border-radius: 10px;
border-radius: 9px;
cursor: pointer;
background: linear-gradient(180deg, var(--accent-grad-a), var(--accent-grad-b));
color: var(--accent-ink);
transition:
filter 0.15s ease,
transform 0.1s ease;
}
:is(#appSettingsModal, #sessionOptionsModal, #createCaseModal) .set-head-save:hover {
filter: brightness(1.08);
}
:is(#appSettingsModal, #sessionOptionsModal, #createCaseModal) .set-head-save:active {
transform: scale(0.97);
}
/* `.modal-close` ships as a bare 1.5rem glyph with no box — fine in a plain
modal header, but inside the tray it needs the same footprint as Save. */
:is(#appSettingsModal, #sessionOptionsModal, #createCaseModal) .set-head-actions .modal-close {
display: inline-flex;
align-items: center;
justify-content: center;
width: 30px;
height: 30px;
padding: 0;
border-radius: 9px;
font-size: 1.2rem;
color: var(--text-dim);
background: transparent;
transition:
background 0.15s ease,
color 0.15s ease,
transform 0.1s ease;
}
:is(#appSettingsModal, #sessionOptionsModal, #createCaseModal) .set-head-actions .modal-close:hover {
background: var(--bg-hover);
color: var(--text);
}
:is(#appSettingsModal, #sessionOptionsModal, #createCaseModal) .set-head-actions .modal-close:active {
transform: scale(0.94);
}
/* The shared rule offsets the ring OUTWARD, which inside the tray draws it on
top of the tray border. Inset it so the focused button is ringed, not the
cluster. */
:is(#appSettingsModal, #sessionOptionsModal, #createCaseModal) .set-head-actions .modal-close:focus-visible {
outline-offset: -2px;
}
:is(#appSettingsModal, #sessionOptionsModal, #createCaseModal) .set-body {