The OSC 11 query opted out under tmux on the assumption it would need the
\ePtmux; passthrough wrapper. It does not, and that assumption cost the
fix precisely where it was wanted: ssh'd into a box inside tmux.
tmux answers OSC 11 from a pane itself, out of the background it queried
from the outer terminal, and it re-queries when that terminal reports a
colour scheme change -- so the value tracks the real window rather than
going stale at tmux start. Measured on tmux 3.7b, the version on both
ends: a pane's query is answered without ever reaching the outer
terminal, and after a colour scheme notification the next query returns
the new background. No tmux configuration is required.
Passthrough is the wrong tool here and stays unused: it is output-only,
so the outer terminal's reply goes to tmux rather than to the pane, and
a wrapped query returns nothing at all.
screen keeps opting out -- untested rather than known broken, and there
the caller falls back to the config files as before.
The live pty suite gains a remote-tmux scenario: config files all dark,
terminal reporting light, the whole thing inside tmux. It fails with the
opt-out restored.
Over ssh the light prompt segments came out lighter than the background
instead of darker. __tide_terminal_background_color learned the
background by reading <appearance>-theme.auto.conf, which on a remote
host belongs to *that* machine: devry pins theme-mode to dark, so
apply-theme-mode.sh writes the dark theme into all three slots there,
including light-theme.auto.conf. Asked for a light background it found
#212121, correctly refused it as contradicting the appearance, ran out of
files and left the caller on its plain-white fallback -- and a segment
derived from white sits above a #EBE8E4 background rather than below it.
Dark was unaffected because that path never recomputes the palette.
Ask the terminal instead, with an OSC 11 query: it is the one source that
describes the window this shell is actually displayed in, whichever
machine the shell runs on. The config files stay as the fallback, where
they are still right, and the static white behind them.
The query costs one 0.2s-bounded read per appearance change, restores the
terminal settings before it can fail, and steps aside under tmux and
screen, which need the query wrapped and each want it wrapped
differently.
Covered by a new live pty scenario that reproduces the ssh case exactly --
config files all dark, terminal reporting light -- which fails on the
previous ordering, plus unit tests for the reply parser and the fallback
chain.
A fixed E4E4E4 segment was 1.04:1 against Kaolin Breeze's EBE8E4 -- an
invisible pill -- and a neutral grey reads as a foreign object on a warm
or cool background anyway. Read the background kitty is showing and place
the segment a fixed contrast step below it, so it keeps the theme's tint.
Default step is 1.12:1; __tide_terminal_segment_contrast overrides it.
Moving the segment invalidates the foregrounds, which are authored at
exactly 4.5:1 against E4E4E4 with no headroom, so re-aim them at the
derived segment by the single ratio the palette's shared luminance ceiling
moved by. That scaling runs in linear light, where luminance is a weighted
sum of the channels and so scales exactly; scaling the encoded channels
drifts further the darker a color gets, which is where the floor binds.
Also fix the baseline capture: the overrides are exported, so a Fish
started from a Fish that had already applied a palette was capturing that
palette as its dark baseline and could never restore dark. Drop inherited
globals first so the baseline comes from the universal scope Tide writes.
Dark mode is unchanged.