/* MusicDen app styles.
   Layout, structure, spacing and type scale come from relayout (rl-*). This file holds only what
   relayout doesn't own: colour tokens, surfaces, the nav's fixed height, scrolling regions, and
   the look of a few custom controls. */

/* ── Theme tokens ──────────────────────────────────────────────────────────────
   Neutrals are the portal's (codesense/portal/ui/assets/css/portal.css), which were measured
   for contrast there: text 16:1 · muted 7:1 · subtle 4.6:1 against --bg in both themes.

   --brand is the mark's crimson, #dc143c. Measured: white on it 5.0, it on the light page 4.7,
   on the dark page 3.5 (fine for fills, rings and icons; not for small text, which is what
   --brand-text is for in dark). */
:root {
    color-scheme: light;
    --bg: #f5f8fb;
    --bg-elev: #ffffff;
    --bg-sunken: #f2f4f8;
    --chrome: var(--bg-elev);
    --border: #cdd1d7;
    --text: #141619;
    --text-muted: #4e5258;
    --text-subtle: #6a6e74;

    /* The mark's own colour, crimson, the same in both themes: the fill in assets/favicon.svg. It is also the UI accent. */
    --logo: #dc143c;
    --brand: var(--logo);
    --brand-on: oklch(1 0 0);
    --brand-text: var(--brand);

    /* How a folder slides in and out (ui.md › Dive and back animation). */
    --nav-duration: 250ms;
    --nav-ease: cubic-bezier(0.2, 0, 0, 1);

    --notice-bg: oklch(0.96 0.04 85);
    --notice-border: oklch(0.82 0.1 85);
    --danger-bg: oklch(0.96 0.03 27);
    --danger-border: oklch(0.8 0.1 27);
    --ok: oklch(0.65 0.15 150);
    --danger-text: oklch(0.5 0.17 27);

}

[data-theme="dark"] {
    color-scheme: dark;
    --bg: #171a1f;
    --bg-elev: #23262b;
    --bg-sunken: #2a2e33;
    /* The nav sinks below the page in dark, as in the portal: it is the frame, not a panel. */
    --chrome: #0b0d12;
    --border: #2f3339;
    --text: #eceff3;
    --text-muted: #989da4;
    --text-subtle: #797d83;

    /* A lighter crimson for text: 6.4:1 on --bg, 7.1:1 on --chrome, 5.0:1 on --bg-sunken. */
    --brand-text: #ff6b81;

    --notice-bg: oklch(0.3 0.04 85);
    --notice-border: oklch(0.45 0.08 85);
    --danger-bg: oklch(0.3 0.05 27);
    --danger-border: oklch(0.45 0.1 27);
    --ok: oklch(0.72 0.15 150);
    --danger-text: oklch(0.75 0.13 27);
}

/* Web Awesome follows the same brand. Its components read these semantic brand tokens (not a
   single "primary"), and its theme declares them inside @layer wa-theme, so these unlayered
   values win whatever order the stylesheets load in. */
:root, .wa-light, .wa-dark {
    --wa-color-brand-fill-loud: var(--brand);
    --wa-color-brand-border-loud: var(--brand);
    --wa-color-brand-on-loud: var(--brand-on);
    --wa-color-brand-fill-quiet: color-mix(in oklab, var(--brand) 10%, var(--bg-elev));
    --wa-color-brand-fill-normal: color-mix(in oklab, var(--brand) 18%, var(--bg-elev));
    --wa-color-brand-border-quiet: color-mix(in oklab, var(--brand) 25%, var(--bg-elev));
    --wa-color-brand-border-normal: color-mix(in oklab, var(--brand) 40%, var(--bg-elev));
    --wa-color-brand-on-quiet: var(--brand-text);
    --wa-color-brand-on-normal: var(--brand-text);
    --wa-color-focus: var(--brand);
    --wa-color-surface-raised: var(--bg-elev);
}

/* ── Base ── */
html, body { margin: 0; padding: 0; background: var(--bg); color: var(--text); }
body { font-family: var(--rl-font-sans, system-ui, sans-serif); font-size: 16px; line-height: 1.5; -webkit-font-smoothing: antialiased; }
h1, h2, h3, p { margin: 0; }
a { color: inherit; text-decoration: none; }
code { font-family: var(--rl-font-mono, ui-monospace, monospace); font-size: 0.9em; }

ms-app { display: block; }

.ms-text-muted { color: var(--text-muted); }

/* ── Shell ──
   The tab bar is a rail beside the content (regular) or a bar below it (compact); the content
   column takes the rest, and <main> scrolls on its own. */
.ms-shell { height: 100dvh; }
.ms-content { min-width: 0; }
.ms-main { overflow-y: auto; overscroll-behavior: contain; }
/* Every page: the full width of the window on a phone, no wider than relayout's xl and centred on a desktop. */
.ms-page { max-width: var(--rl-width-xl); margin-inline: auto; height: 100%; }

/* ── Tab bar ── */
ms-tab-bar { display: contents; }
.ms-rail {
    width: 80px;
    flex-shrink: 0;
    background: var(--chrome);
    border-right: 1px solid var(--border);
}
.ms-rail .ms-tab { width: 100%; }
.ms-rail-mark {
    color: var(--logo);
    font-size: 2rem;
    line-height: 0;
    padding: 0.5rem;
    border-radius: 8px;
}
.ms-rail-mark:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; }
.ms-tabbar {
    background: var(--chrome);
    border-top: 1px solid var(--border);
}

.ms-tab {
    color: var(--text-muted);
    padding: 0.5rem 0.25rem;
    transition: color .15s;
}
.ms-tab:hover { color: var(--text); }
.ms-tab:focus-visible { outline: 2px solid var(--brand); outline-offset: -2px; border-radius: 8px; }
.ms-tab--selected, .ms-tab--selected:hover { color: var(--brand-text); }
.ms-tab--selected .ms-tab-label { font-weight: 600; }
/* The pill behind the selected tab's icon. */
.ms-tab-icon {
    position: relative;
    font-size: 1.5rem;
    line-height: 0;
    transition: background .15s;
}
.ms-tab--selected .ms-tab-icon { background: color-mix(in oklab, var(--brand) 18%, transparent); }
/* A pulsing dot on the Player tab while a track plays, so playback shows from every tab. */
.ms-tab-live {
    position: absolute; top: 2px; right: 8px;
    width: 7px; height: 7px;
    border-radius: 50%;
    background: var(--brand-text);
    animation: ms-pulse 1.2s ease-in-out infinite;
}
@media (prefers-reduced-motion: reduce) { .ms-tab-live { animation: none; } }

/* padding: 0 matters: Web Awesome's native styles give every <button> 0 16px of padding, which
   left 2px of content in a 34px square and shrank the icon to a dot. */
.ms-icon-btn {
    width: max(34px, var(--ms-touch)); height: max(34px, var(--ms-touch));
    display: grid; place-items: center;
    padding: 0;
    border: none; background: none; cursor: pointer;
    border-radius: 7px; color: var(--text-muted);
    transition: color .15s, background .15s;
}
.ms-icon-btn:hover { color: var(--text); background: var(--bg-sunken); }
.ms-icon-btn:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; }

/* A green "connected" dot. */
.ms-status-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--ok); }

/* ── Notices ── */
.ms-notice {
    background: var(--notice-bg);
    border: 1px solid var(--notice-border);
}
.ms-notice--danger {
    background: var(--danger-bg);
    border-color: var(--danger-border);
}

/* ── Settings ── */
.ms-section-title { letter-spacing: 0.06em; }
.ms-card {
    background: var(--bg-elev);
    border: 1px solid var(--border);
}

/* ── Page-level spinner (restoring, OAuth callback) ── */
.ms-page-spinner { font-size: 2rem; }

/* ── Library ──
   The page fills <main> exactly: the header stays put and the rows scroll under it. */
ms-library-page, ms-recent-page { display: block; height: 100%; }
.ms-library, .ms-recent { height: 100%; }
ms-scan-status { display: block; }
ms-scan-status:empty { display: none; }
.ms-library-alert { margin: 0 var(--rl-space-m, 0.5rem) var(--rl-space-m, 0.5rem); }

.ms-library-header, .ms-page-header { border-bottom: 1px solid var(--border); }
.ms-library-title { min-width: 0; margin: 0; }
.ms-library-back { min-width: 0; }
.ms-back-btn {
    min-width: 0; max-width: 100%;
    min-height: max(34px, var(--ms-touch));
    padding: 0 0.5rem 0 0.25rem; margin-left: -0.25rem;
    border: none; background: none; cursor: pointer;
    border-radius: 7px;
    color: var(--brand-text); font: inherit;
    transition: background .15s;
}
.ms-back-btn:hover { background: var(--bg-sunken); }
.ms-back-btn:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; }
.ms-back-btn svg { font-size: 1.25rem; }

.ms-search { width: 20rem; max-width: 100%; }
ms-app[data-layout='compact'] .ms-search { width: 100%; }
.ms-search-scope { margin: 0; }

/* Opaque, so that while two lists slide past each other (see Folder navigation) neither shows through the other. */
ms-folder-view, ms-recent-list { display: block; min-height: 0; background: var(--bg); }
.ms-folder-view, .ms-recent-list { height: 100%; }
.ms-recent-list { position: relative; }

/* The list is windowed (folder-view.ts): the spacer is as tall as all the rows, and the window of
   rows that exist is moved to where they belong in it. The row height (--ms-row-h) is set from
   there too, so the CSS and the arithmetic can't disagree. */
.ms-row-scroller { overflow-y: auto; overscroll-behavior: contain; }
.ms-row-spacer { position: relative; }
.ms-row-window { position: absolute; top: 0; left: 0; right: 0; }

.ms-row {
    height: var(--ms-row-h);
    width: 100%;
    box-sizing: border-box;
    border-bottom: 1px solid color-mix(in oklab, var(--border) 45%, transparent);
    cursor: pointer;
}
.ms-row:hover { background: var(--bg-sunken); }
.ms-row--current { background: color-mix(in oklab, var(--brand) 12%, transparent); }
.ms-row--current .ms-row-main { color: var(--brand-text); font-weight: 600; }
.ms-row:has(.ms-row-main:focus-visible) { outline: 2px solid var(--brand); outline-offset: -2px; }

/* The title is the row's keyboard control; a click anywhere on the row does the same (see folder-view.ts). */
/* display and width matter: Web Awesome styles native buttons as centred flex boxes, which centred every title. */
.ms-row-main {
    display: block; width: 100%; min-width: 0; min-height: 0; height: auto;
    padding: 0; border: none; background: none;
    color: inherit; font: inherit; line-height: inherit; text-align: left; text-decoration: none;
    cursor: pointer;
}
.ms-row-main:focus-visible { outline: none; }

.ms-row-lead { width: 3.75rem; flex-shrink: 0; }
.ms-rows--compact .ms-row-lead { width: 1.5rem; }
.ms-row-icon { line-height: 0; flex-shrink: 0; font-size: 1.25rem; }
.ms-row-icon--play { color: var(--text-subtle); }
.ms-row-number { width: 1.5rem; text-align: right; font-variant-numeric: tabular-nums; }
.ms-row-meta { flex-shrink: 0; }
.ms-row-time { width: 3.5rem; flex-shrink: 0; text-align: right; font-variant-numeric: tabular-nums; }
.ms-row-when { width: 6rem; flex-shrink: 0; text-align: right; font-variant-numeric: tabular-nums; }

/* Recent: "Latest" floats over the bottom of the list while it is scrolled up. */
.ms-latest-btn {
    position: absolute; left: 50%; bottom: 0.75rem; transform: translateX(-50%);
    min-height: max(34px, var(--ms-touch)); padding: 0 0.9rem 0 0.7rem;
    border: none; border-radius: 999px; cursor: pointer;
    background: var(--brand); color: var(--brand-on);
    font: inherit; font-weight: 600;
    box-shadow: 0 2px 10px rgb(0 0 0 / 0.25);
}
.ms-latest-btn:hover { filter: brightness(1.08); }
.ms-latest-btn:focus-visible { outline: 2px solid var(--brand); outline-offset: 3px; }
.ms-latest-btn svg { font-size: 1.1rem; }
/* ⋯ is shown from the start, but there is no menu behind it yet. */
.ms-row-more { flex-shrink: 0; cursor: default; opacity: 0.45; font-size: 1.25rem; }
.ms-row-more:hover { background: none; color: var(--text-muted); }
.ms-now-icon { line-height: 0; flex-shrink: 0; }
/* A gentle pulse on the note while the track is actually playing (not paused or loading). */
.ms-now-icon--playing { animation: ms-pulse 1.2s ease-in-out infinite; }
@keyframes ms-pulse { 50% { opacity: 0.35; } }
@media (prefers-reduced-motion: reduce) { .ms-now-icon--playing { animation: none; } }

.ms-empty-list { margin: 0; padding-left: 1.25rem; }

/* A favorite in a list. It sits left of the time, which has a fixed width, so the hearts line up. */
.ms-row-fav { line-height: 0; flex-shrink: 0; font-size: 1rem; color: var(--brand-text); }

/* A heading in a list: the album that the files after it belong to. */
.ms-row--heading { cursor: default; background: var(--bg-sunken); }
.ms-row--heading:hover { background: var(--bg-sunken); }
.ms-row-heading { font-weight: 600; min-width: 0; }

/* ── Cover tile ──
   A placeholder until real art is read: an outlined tile with a note in the accent, on no fill.
   Sized by --cover-size from whatever contains it. */
ms-cover-tile { display: block; flex-shrink: 0; width: var(--cover-size, 44px); height: var(--cover-size, 44px); }
.ms-cover-tile {
    box-sizing: border-box;
    width: 100%; height: 100%;
    border-radius: 10%;
    border: 2px solid color-mix(in oklab, var(--brand) 55%, transparent);
    background: transparent;
    font-size: calc(var(--cover-size, 44px) * 0.45);
    line-height: 0;
    color: var(--brand-text);
}

/* ── Play button ── */
ms-play-button { display: block; flex-shrink: 0; }
.ms-play-btn {
    width: max(40px, var(--ms-touch)); height: max(40px, var(--ms-touch));
    display: grid; place-items: center;
    padding: 0;
    border: none; border-radius: 50%;
    background: var(--brand); color: var(--brand-on);
    font-size: 1.5rem;
    cursor: pointer;
    transition: transform .1s;
}
.ms-play-btn:hover { transform: scale(1.06); }
.ms-play-btn:focus-visible { outline: 2px solid var(--brand); outline-offset: 3px; }
.ms-play-btn wa-spinner { font-size: 1.1rem; --track-color: color-mix(in oklab, var(--brand-on) 30%, transparent); --indicator-color: var(--brand-on); }
ms-play-button[large] .ms-play-btn { width: 56px; height: 56px; font-size: 2rem; }
ms-play-button[large] .ms-play-btn wa-spinner { font-size: 1.6rem; }

/* ── Now-playing bar (every tab but Player) ── */
ms-now-playing-bar { display: block; flex-shrink: 0; }
.ms-bar {
    --cover-size: 44px;
    position: relative;
    height: 64px;
    background: var(--chrome);
    border-top: 1px solid var(--border);
    cursor: pointer;
}
.ms-bar-inner { height: 100%; }
/* How far the track has got, along the bar's top edge. It can't be dragged: seeking is on the Player. */
.ms-bar-progress { position: absolute; top: -1px; left: 0; height: 2px; width: var(--progress, 0%); background: var(--brand); }
.ms-bar-text { min-width: 0; line-height: 1.3; }
.ms-bar-open {
    display: block; width: 100%; min-width: 0; min-height: 0; height: auto;
    padding: 0; border: none; background: none;
    color: inherit; font: inherit; font-weight: 600; line-height: inherit; text-align: left;
    cursor: pointer;
}
.ms-bar-open:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; border-radius: 4px; }
.ms-bar-error { color: var(--danger-text); }

/* ── Now playing (the Player tab) ── */
.ms-now { --cover-size: 120px; }
.ms-now--compact { --cover-size: 72px; }
.ms-now-text { min-width: 0; }
/* A long title wraps, rather than being cut off where it matters most. */
.ms-now-title { margin: 0; overflow-wrap: anywhere; line-height: 1.25; }
.ms-now-folder {
    align-self: flex-start; max-width: 100%; min-width: 0; min-height: 0; height: auto;
    padding: 0; border: none; background: none;
    color: var(--text-muted); font: inherit; text-align: left;
    cursor: pointer;
}
.ms-now-folder { min-height: var(--ms-touch); }
.ms-now-folder:hover { color: var(--text); }
.ms-now-folder:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; border-radius: 4px; }
.ms-now-folder svg { font-size: 1.1rem; }
.ms-skip-btn { width: 44px; height: 44px; font-size: 1.75rem; color: var(--text); }
.ms-skip-btn:disabled { opacity: 0.35; cursor: default; }
.ms-skip-btn:disabled:hover { background: none; }

/* ♡ beside the title. */
.ms-fav-btn { flex-shrink: 0; font-size: 1.4rem; }
.ms-fav-btn--on { color: var(--brand-text); }

/* The Player fills <main>: Now playing keeps the height it needs, and the Sense tabs take the rest
   (at least 18rem; on a short window the page scrolls instead) and scroll inside it. */
ms-player-page { display: block; height: 100%; }
.ms-player { height: 100%; box-sizing: border-box; }
.ms-player .ms-sense-host { min-height: 18rem; }
ms-sense-tabs { display: block; min-height: 0; }
.ms-sense { height: 100%; }
.ms-sense-strip { flex-shrink: 0; overflow-x: auto; scrollbar-width: none; border-bottom: 1px solid var(--border); }
.ms-sense-strip::-webkit-scrollbar { display: none; }
/* Like the other native buttons here, reset what Web Awesome's button styles give them. */
.ms-sense-tab {
    display: block; flex: 0 0 auto; max-width: 14rem; min-width: 0; height: auto; min-height: max(40px, var(--ms-touch));
    padding: 0 0.9rem; margin: 0;
    border: none; border-bottom: 2px solid transparent; border-radius: 0; background: none;
    color: var(--text-muted); font: inherit; cursor: pointer;
}
.ms-sense-tab:hover { color: var(--text); }
.ms-sense-tab--selected { color: var(--brand-text); border-bottom-color: var(--brand); font-weight: 600; }
.ms-sense-tab:focus-visible { outline: 2px solid var(--brand); outline-offset: -2px; }
/* Lists inside the panel scroll themselves; the panel only clips. */
.ms-sense-panel { min-height: 0; overflow: hidden; }
.ms-sense-empty { max-width: 28rem; text-align: center; }
.ms-chips { flex-shrink: 0; }
.ms-chip {
    display: block; max-width: 14rem; min-width: 0; height: auto; min-height: max(32px, var(--ms-touch));
    padding: 0 0.8rem; margin: 0;
    border: 1px solid var(--border); border-radius: 999px; background: none;
    color: var(--text); font: inherit; cursor: pointer;
}
.ms-chip:hover { background: var(--bg-sunken); }
.ms-chip--on { background: color-mix(in oklab, var(--brand) 18%, transparent); border-color: var(--brand); color: var(--brand-text); font-weight: 600; }
.ms-chip:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; }

.ms-player-time { width: 3.25rem; flex-shrink: 0; font-variant-numeric: tabular-nums; }
.ms-player-time:first-child { text-align: right; }
.ms-progress, .ms-volume { min-width: 0; --thumb-width: 14px; --thumb-height: 14px; --track-size: 4px; }
.ms-volume { width: 6.5rem; }
.ms-player-volume { flex-shrink: 0; }
.ms-player-volume .ms-icon-btn { font-size: 1.25rem; }
/* The sliders are labelled for screen readers; there is no room for visible labels. */
.ms-progress::part(label), .ms-volume::part(label) {
    position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap;
}

/* ── Folder navigation ──
   Diving into a folder slides the list in from the right while the old one drifts left and dims;
   going back does the reverse. app-shell wraps the change in a view transition and sets
   <html data-nav="dive|back"> while it runs. Only the list pane moves: the tab bar and the
   now-playing bar are named so they are captured on their own and stay put, and the rest of the
   page (the header's title and back button) cross-fades.

   Opening the Player (data-nav="player") is a different animation: the page cross-fades while the
   now-playing bar's cover grows into the Player's (or shrinks back when leaving it).

   The names exist only during a transition, so nothing else is affected by them. */
html[data-nav='dive'] ms-folder-view,
html[data-nav='back'] ms-folder-view { view-transition-name: ms-list; }
html[data-nav] .ms-rail,
html[data-nav] .ms-tabbar { view-transition-name: ms-tabs; }
/* While the Player opens or closes the bar comes or goes, so it cross-fades with the page instead. */
html[data-nav='dive'] ms-now-playing-bar,
html[data-nav='back'] ms-now-playing-bar { view-transition-name: ms-player; }
/* One cover on screen at a time (the bar's, or the Player's), so the name is never doubled. */
html[data-nav='player'] .ms-cover { view-transition-name: ms-cover; }

/* The page stays live under the animation, so a tap during it reaches the real new list and starts the next navigation. */
::view-transition { pointer-events: none; }

::view-transition-group(root),
::view-transition-group(ms-cover) {
    animation-duration: var(--nav-duration);
    animation-timing-function: var(--nav-ease);
}

/* These three don't move or resize, so the group's own animation has nothing to do, and the list's
   sliding images are clipped to the pane rather than drawn over the rail and header. */
::view-transition-group(ms-list),
::view-transition-group(ms-tabs),
::view-transition-group(ms-player) { animation: none; }
::view-transition-group(ms-list) { overflow: clip; }

/* Show only the new tab bar and player bar: the old ones are identical. */
::view-transition-old(ms-tabs),
::view-transition-old(ms-player) { display: none; }
::view-transition-new(ms-tabs),
::view-transition-new(ms-player) { animation: none; }

/* Plus-lighter, the default, adds overlapping layers together, which would light up the strip where
   the sliding lists overlap. */
html[data-nav]::view-transition-old(ms-list),
html[data-nav]::view-transition-new(ms-list) {
    mix-blend-mode: normal;
    animation-duration: var(--nav-duration);
    animation-timing-function: var(--nav-ease);
    animation-fill-mode: both;
}
html[data-nav='dive']::view-transition-old(ms-list) { animation-name: ms-nav-recede; }
html[data-nav='dive']::view-transition-new(ms-list) { animation-name: ms-nav-from-right; }
/* Going back, the list you leave slides off the top of the one you return to. */
html[data-nav='back']::view-transition-old(ms-list) { animation-name: ms-nav-to-right; z-index: 1; }
html[data-nav='back']::view-transition-new(ms-list) { animation-name: ms-nav-return; }

@keyframes ms-nav-recede { to { transform: translateX(-30%); opacity: 0.4; } }
@keyframes ms-nav-return { from { transform: translateX(-30%); opacity: 0.4; } }
@keyframes ms-nav-from-right { from { transform: translateX(100%); } }
@keyframes ms-nav-to-right { to { transform: translateX(100%); } }
@keyframes ms-nav-fade-in { from { opacity: 0; } }
@keyframes ms-nav-fade-out { to { opacity: 0; } }

/* No sliding for people who ask for less motion: a quick cross-fade instead. */
@media (prefers-reduced-motion: reduce) {
    ::view-transition-group(root) { animation-duration: 100ms; }
    /* The cover stays where it ends up and fades, rather than travelling. */
    ::view-transition-group(ms-cover) { animation: none; }
    ::view-transition-old(ms-cover),
    ::view-transition-new(ms-cover) { animation-duration: 100ms; }
    html[data-nav]::view-transition-old(ms-list),
    html[data-nav]::view-transition-new(ms-list) {
        mix-blend-mode: plus-lighter;
        animation-duration: 100ms;
        animation-timing-function: linear;
    }
    html[data-nav]::view-transition-old(ms-list) { animation-name: ms-nav-fade-out; }
    html[data-nav]::view-transition-new(ms-list) { animation-name: ms-nav-fade-in; }
}

/* ── Installed app and touch (ui.md › PWA and touch) ── */
/* A pull-down at the top of a list must not reload the page in the installed app: that would stop the music. */
html, body { overscroll-behavior: none; }
/* No 300 ms wait for a second tap, and no grey flash on tap. */
a, button, [role='tab'], [role='radio'], .ms-row { touch-action: manipulation; -webkit-tap-highlight-color: transparent; }

/* Notches and home indicators. The bars pad into the space the system reserves; the page behind
   them keeps its colour. Zero where there is no inset, which is everywhere but a notched phone
   or an iPad. */
.ms-rail { width: calc(80px + env(safe-area-inset-left, 0px)); padding-left: env(safe-area-inset-left, 0px); }
.ms-tabbar { padding-bottom: env(safe-area-inset-bottom, 0px); }
.ms-content { padding-right: env(safe-area-inset-right, 0px); }
ms-app[data-layout='regular'] .ms-content { padding-bottom: env(safe-area-inset-bottom, 0px); }
ms-app[data-layout='compact'] .ms-shell { padding-left: env(safe-area-inset-left, 0px); }

/* Fingers need 44 px; a pointer doesn't, so a mouse on a wide window keeps the denser controls.
   --ms-touch is the floor for the size of anything tappable: 44 px on the phone layout and on any
   touch screen (an iPad in the wide layout too), nothing otherwise. The controls above read it. */
ms-app { --ms-touch: 0px; }
ms-app[data-layout='compact'] { --ms-touch: 44px; }
@media (pointer: coarse) { ms-app { --ms-touch: 44px; } }
/* Web Awesome's buttons, fields and radios are 43 px tall; this lifts them to the floor and leaves larger sizes alone. */
ms-app { --wa-form-control-height: max(var(--ms-touch), round(calc(2 * 0.75em + 1em * 1.2), 1px)); }
/* The seek and volume sliders draw a 4 px track. Padding on the slider part makes the strip you can
   press 44 px tall, and the negative margin gives the layout back, so nothing around it moves. */
.ms-progress::part(slider), .ms-volume::part(slider) { padding-block: 20px; margin-block: -16px; }
