@import url('https://fonts.googleapis.com/css2?family=Outfit:wght@600;700&display=swap');   /* titles (the InControl look) */
/*  PWA template - shared app styles (dev.admin/pwa).
    EVERY rule here is scoped under html.app (or only fires inside a view
    transition, which desktop never starts), so desktop pages are untouched.
    Per-site colors come in through --pwa-accent / --pwa-bg set by pwa_head().  */

/* ---------------------------------------------------------------- tokens */
html.app {
	--pwa-top: env(safe-area-inset-top, 0px);
	--pwa-bottom: env(safe-area-inset-bottom, 0px);
	--pwa-bar-h: 44px;
	--pwa-tab-h: 50px;
	--pwa-gutter: 16px;                            /* page side margin, like iOS */
	--pwa-ease: cubic-bezier(.2, .8, .2, 1);
	--pwa-spring: cubic-bezier(.32, .72, 0, 1);   /* iOS sheet curve */
	--pwa-font: -apple-system, BlinkMacSystemFont, "SF Pro Text", system-ui, sans-serif;
	--pwa-font-display: -apple-system, BlinkMacSystemFont, "SF Pro Display", system-ui, sans-serif;

	--pwa-bg: var(--pwa-site-bg, #000);
	--pwa-surface: #1c1c1e;
	--pwa-surface-2: #2c2c2e;
	--pwa-text: #fff;
	--pwa-text-2: rgba(235, 235, 245, .6);
	--pwa-sep: rgba(84, 84, 88, .65);
	--pwa-chrome: rgba(22, 22, 24, .78);
	--pwa-fill: rgba(120, 120, 128, .24);
	--pwa-danger: #ff453a;
}
html.app[data-pwa-theme="light"] {
	--pwa-bg: var(--pwa-site-bg, #f2f2f7);
	--pwa-surface: #fff;
	--pwa-surface-2: #f2f2f7;
	--pwa-text: #000;
	--pwa-text-2: rgba(60, 60, 67, .6);
	--pwa-sep: rgba(60, 60, 67, .29);
	--pwa-chrome: rgba(249, 249, 249, .82);
	--pwa-fill: rgba(120, 120, 128, .12);
	--pwa-danger: #ff3b30;
}
@media (prefers-color-scheme: light) {
	html.app[data-pwa-theme="auto"] {
		--pwa-bg: var(--pwa-site-bg, #f2f2f7);
		--pwa-surface: #fff;
		--pwa-surface-2: #f2f2f7;
		--pwa-text: #000;
		--pwa-text-2: rgba(60, 60, 67, .6);
		--pwa-sep: rgba(60, 60, 67, .29);
		--pwa-chrome: rgba(249, 249, 249, .82);
		--pwa-fill: rgba(120, 120, 128, .12);
		--pwa-danger: #ff3b30;
	}
}

/* ------------------------------------------------------------- base feel */
/* Template chrome sizes include its safe-area padding - never rely on the site's box-sizing */
html.app :is(.pwa-bar, .pwa-tabs, .pwa-sheet, .pwa-actions, .pwa-toast, .pwa-ptr, .pwa-scrim, .pwa-large-title),
html.app :is(.pwa-bar, .pwa-tabs, .pwa-sheet, .pwa-actions, .pwa-toast) * { box-sizing: border-box; }
html.app.pwa-modal-sheets dialog.kui.modal { box-sizing: border-box; }
html.app {
	-webkit-text-size-adjust: 100%;
	-webkit-tap-highlight-color: transparent;
	background: var(--pwa-bg);
	overflow-x: clip;   /* with body's below: html's goes to the window, so body clips its own content (a page sliding in) */
}
html.app body {
	min-height: 100dvh;
	background: var(--pwa-bg);
	padding-top: calc(var(--pwa-bar-h) + var(--pwa-top));
	padding-bottom: calc(var(--pwa-tab-h) + var(--pwa-bottom));
	padding-left: env(safe-area-inset-left, 0px);
	padding-right: env(safe-area-inset-right, 0px);
	-webkit-touch-callout: none;
	overscroll-behavior-y: none;
	overflow-x: clip;   /* a page sliding in (ajax_nav) or out never makes the page wider: no sideways scroll or scrollbar */
}
html.app-standalone body { -webkit-user-select: none; user-select: none; }
/* iOS starts an installed app with its page 62pt short (the status bar's height) until the first drag: fixed things - the
   tab bar - sit on that short bottom, and under it shows only the page's own colour. That colour is the tab bar's, so the
   strip reads as more tab bar, not a black band. (Nothing a page does makes iOS measure again - tested in the simulator.) */
html.app-standalone { background-color: color-mix(in srgb, rgb(22 22 24) 78%, var(--pwa-bg)); }
/* The fix for it (WebKit bug 301108, iOS 26+, black-translucent status bar): iOS keeps the short height only while the page
   is shorter than the screen, so the page is made the screen's height - the short height plus the status bar's, never more
   than the full screen (lvh) - and the tab bar lands on the real bottom from the start. (frappe-ui's fix, PR 1284.) */
html.app-standalone { min-height: min(100lvh, calc(100% + env(safe-area-inset-top, 0px))); }
html.app-standalone :is(input, textarea, [contenteditable], .selectable, p, td) { -webkit-user-select: text; user-select: text; }
html.app :is(a, button, [role="button"], .func, .pwa-tab) { touch-action: manipulation; }
/* iOS zooms into inputs under 16px - keep forms from jumping. */
html.app :is(input, select, textarea) { font-size: max(16px, 1em); }
html.app body.no-tabs { padding-bottom: var(--pwa-bottom); }
html.app body.no-bar { padding-top: var(--pwa-top); }
/* A page shorter than the screen doesn't scroll: body's screen height takes in its own padding (the bars' room), and the
   template's main doesn't add a second screen height on top of it */
html.app body { box-sizing: border-box; }
html.app body > main { min-height: 0; }

/* Element-level control (usable on any site, any page):
   .m-hide / .d-only  hidden in the app      .m-only  shown only in the app */
.m-only { display: none !important; }
html.app .m-only { display: revert !important; }
html.app :is(.m-hide, .d-only) { display: none !important; }

/* ---------------------------------------------------------------- top bar */
html.app .pwa-bar {
	position: fixed; z-index: 900; top: 0; left: 0; right: 0;
	height: calc(var(--pwa-bar-h) + var(--pwa-top));
	padding: var(--pwa-top) max(8px, env(safe-area-inset-right)) 0 max(8px, env(safe-area-inset-left));
	display: grid; grid-template-columns: 1fr auto 1fr; align-items: center;
	background: var(--pwa-chrome);
	-webkit-backdrop-filter: saturate(180%) blur(20px); backdrop-filter: saturate(180%) blur(20px);
	border-bottom: .5px solid transparent;
	transition: border-color .2s;
	font-family: var(--pwa-font); color: var(--pwa-text);
	view-transition-name: pwa-bar;
}
/* bar off (config bar: false): only the Back chevron, floating over the page - no bar colour, line or title */
html.app .pwa-bar.pwa-bar-float { background: none; -webkit-backdrop-filter: none; backdrop-filter: none; border-bottom-color: transparent !important; pointer-events: none; }
html.app .pwa-bar.pwa-bar-float > * { pointer-events: auto; }
html.app body.pwa-back-float main .page_title { padding-left: 34px; }	/* clear of the chevron, on its line */
html.app body.pwa-back-float .pwa-bar-float { transform: translateY(12px); }	/* the chevron level with the title (main pads 20px) */
html.app .pwa-bar.scrolled, html.app body:not(.pwa-has-large) .pwa-bar { border-bottom-color: var(--pwa-sep); }
html.app .pwa-bar-title {
	grid-column: 2; max-width: 60vw; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
	font: 600 18px/1.2 "Outfit", var(--pwa-font-display); letter-spacing: .03em; text-align: center;
	transition: opacity .2s;
}
html.app body.pwa-has-large .pwa-bar:not(.scrolled) .pwa-bar-title { opacity: 0; }
html.app .pwa-bar-left, html.app .pwa-bar-right { display: flex; align-items: center; gap: 4px; min-width: 0; }
html.app .pwa-bar-left { grid-column: 1; }
html.app .pwa-bar-right { grid-column: 3; justify-content: flex-end; }
html.app .pwa-bar :is(.pwa-back, .pwa-action, [data-m-action]) {
	display: inline-flex; align-items: center; gap: 2px;
	min-height: 44px; min-width: 44px; padding: 0 6px;
	color: var(--pwa-accent); font-size: 17px; background: none; border: 0; text-decoration: none;
}
/* Back: InControl's round see-through button with the chevron in it */
html.app .pwa-bar .pwa-back {
	box-sizing: border-box; width: 40px; height: 40px; min-width: 40px; min-height: 40px; padding: 0; margin-left: 2px;
	justify-content: center; border-radius: 50%; color: var(--pwa-text);
	background: rgba(8,6,16,.2); border: 1px solid rgba(255,255,255,.08);
	-webkit-backdrop-filter: blur(10px); backdrop-filter: blur(10px); -webkit-tap-highlight-color: transparent;
	transition: background .2s, transform .15s;
}
html.app .pwa-back svg { width: 22px; height: 22px; margin-left: -2px; stroke-width: 2.4; }
html.app .pwa-bar .pwa-back:active { transform: scale(.92); }
html.app[data-pwa-theme="light"] .pwa-bar .pwa-back { background: rgba(0,0,0,.06); border-color: rgba(0,0,0,.06); }   /* light apps: a faint grey disc */
/* Site buttons moved into the bar (data-m-action) lose their desktop button look and
   become iOS bar buttons: accent-colored, icon only when they have an icon */
html.app .pwa-bar [data-m-action] {
	width: auto !important; height: 44px; margin: 0 !important;
	background: none !important; border: 0 !important; box-shadow: none !important;
}
html.app .pwa-bar [data-m-action]:has(> i, > .kft) { font-size: 0; }
html.app .pwa-bar [data-m-action] > :is(i, .kft) { font-size: 22px; color: var(--pwa-accent); }
html.app .pwa-bar [data-m-action] > :is(i, .kft)::before { color: var(--pwa-accent) !important; }
html.app .pwa-bar :is(.pwa-back, .pwa-action, [data-m-action]):active { opacity: .35; }

/* The shared site wrapper: full width with an even iOS gutter, whatever width the
   desktop CSS gives it (home.css sets 90%, admin.css 96%) */
html.app #page_wrap {
	width: auto !important; max-width: none !important;
	margin: 0 !important;
	padding-left: var(--pwa-gutter) !important; padding-right: var(--pwa-gutter) !important;
	box-sizing: border-box;
}

/* The admin back-to-top button sits over the tab bar - in the app, tapping the current
   tab scrolls to the top instead (iOS behavior). @layer pwa beats layered !important. */
@layer pwa { html.app #scrollUp { display: none !important; } }

/* Admin pages pin their action buttons (.top-right) to the screen corner - right where
   the app's top bar is. In the app they sit as a normal row at the top of the page. */
html.app .top-right {
	position: static !important; inset: auto !important;
	display: flex; flex-wrap: wrap; justify-content: flex-end; align-items: center; gap: 8px;
	margin: 0 0 12px !important;
}

/* Large title - collapses into the bar on scroll. Lines up with the page gutter. */
html.app .pwa-large-title {
	margin: 4px 0 8px; padding: 0;
	font: 700 36px/1.15 "Outfit", var(--pwa-font-display); letter-spacing: .04em;   /* InControl's titles: Outfit, a drop shadow and an accent glow */
	color: var(--pwa-text); -webkit-font-smoothing: antialiased; text-align: center;
	text-shadow: 0 4px 14px rgba(0,0,0,.35);
	text-shadow: 0 4px 14px rgba(0,0,0,.35), 0 0 30px color-mix(in srgb, var(--pwa-accent) 55%, transparent);
}
@media (min-width: 700px) { html.app .pwa-large-title { font-size: 44px; } }

/* --------------------------------------------------------------- tab bar */
html.app .pwa-tabs {
	position: fixed; z-index: 900; left: 0; right: 0; bottom: 0;
	height: calc(var(--pwa-tab-h) + var(--pwa-bottom));
	padding: 0 env(safe-area-inset-right) var(--pwa-bottom) env(safe-area-inset-left);
	display: flex;
	background: var(--pwa-chrome);
	-webkit-backdrop-filter: saturate(180%) blur(20px); backdrop-filter: saturate(180%) blur(20px);
	border-top: .5px solid var(--pwa-sep);
	font-family: var(--pwa-font);
	view-transition-name: pwa-tabs;
	transition: transform .25s var(--pwa-ease);
}
/* The tab bar slides away under the keyboard and under any open sheet/modal, like iOS */
html.app.pwa-keyboard .pwa-tabs, html.app body:has(dialog.kui.modal.open, dialog[open]:modal) .pwa-tabs { transform: translateY(110%); }
html.app .pwa-tab {
	flex: 1; position: relative;
	display: flex; flex-direction: column; align-items: center; justify-content: flex-start;
	padding-top: 6px; gap: 2px;
	color: var(--pwa-text-2); text-decoration: none;
	font-size: 10px; font-weight: 500; letter-spacing: .1px;
	background: none; border: 0;
}
html.app .pwa-tab svg { width: 26px; height: 26px; transition: transform .15s var(--pwa-ease); }
html.app .pwa-tab:active svg { transform: scale(.86); }
html.app .pwa-tab.active { color: var(--pwa-accent); }
html.app .pwa-badge {
	position: absolute; top: 2px; left: calc(50% + 6px);
	min-width: 18px; height: 18px; padding: 0 5px; border-radius: 9px;
	background: var(--pwa-danger); color: #fff;
	font-size: 12px; font-weight: 600; line-height: 18px; text-align: center;
}
html.app .pwa-badge:empty { display: none; }

/* ----------------------------------------------------- sheets & dialogs */
html.app .pwa-scrim {
	position: fixed; inset: 0; z-index: 1000;
	background: rgba(0, 0, 0, .4);
	opacity: 0; transition: opacity .3s;
}
html.app .pwa-scrim.show { opacity: 1; }
html.app .pwa-sheet {
	position: fixed; z-index: 1001; left: 0; right: 0; bottom: 0;
	max-height: calc(100dvh - var(--pwa-top) - 12px);
	display: flex; flex-direction: column;
	background: var(--pwa-surface); color: var(--pwa-text);
	border-radius: 14px 14px 0 0;
	padding-bottom: var(--pwa-bottom);
	font-family: var(--pwa-font);
	transform: translateY(100%);
	transition: transform .45s var(--pwa-spring);
	box-shadow: 0 -2px 30px rgba(0, 0, 0, .25);
}
html.app .pwa-sheet.show { transform: translateY(0); }
html.app .pwa-sheet.dragging { transition: none; }
html.app .pwa-grab { flex: none; height: 22px; display: flex; justify-content: center; align-items: center; touch-action: none; cursor: grab; }
html.app .pwa-grab::before { content: ""; width: 36px; height: 5px; border-radius: 3px; background: var(--pwa-fill); }
html.app .pwa-sheet-head { flex: none; padding: 0 16px 10px; font-size: 17px; font-weight: 600; text-align: center; touch-action: none; }
html.app .pwa-sheet-body { overflow-y: auto; overscroll-behavior: contain; -webkit-overflow-scrolling: touch; padding: 0 16px 16px; }

/* Existing site modals (dialog.kui.modal) become bottom sheets */
html.app.pwa-modal-sheets dialog.kui.modal {
	position: fixed !important; inset: auto 0 0 0 !important;
	margin: 0 !important; width: 100% !important; max-width: 100% !important; min-width: 0 !important;
	max-height: calc(100dvh - var(--pwa-top) - 12px) !important;
	transform: translateY(100%);
	border-radius: 14px 14px 0 0 !important;
	padding-bottom: var(--pwa-bottom) !important;
	transition: transform .45s var(--pwa-spring), opacity .2s !important;
	overflow-y: auto; overscroll-behavior: contain;
}
html.app.pwa-modal-sheets dialog.kui.modal.open { transform: translateY(0); }
html.app.pwa-modal-sheets dialog.kui.modal.dragging { transition: none !important; }
html.app.pwa-modal-sheets dialog.kui.modal::backdrop { background: rgba(0, 0, 0, .4); }
html.app.pwa-modal-sheets dialog.kui.modal > .pwa-grab { position: sticky; top: 0; z-index: 2; }
html.app body:has(dialog.open) { padding-right: env(safe-area-inset-right, 0px); }

/* Grouped list (iOS Settings style) - use anywhere in app pages */
html.app .pwa-list { margin: 0 0 20px; padding: 0; list-style: none; background: var(--pwa-surface-2); border-radius: 10px; overflow: hidden; }
html.app .pwa-sheet .pwa-list { background: var(--pwa-surface-2); }
html.app .pwa-list > li > :is(a, button), html.app .pwa-list > li.row {
	display: flex; align-items: center; gap: 12px; width: 100%;
	min-height: 44px; padding: 10px 16px;
	color: var(--pwa-text); text-decoration: none; text-align: left;
	font: 400 17px var(--pwa-font); background: none; border: 0;
	position: relative;
}
html.app .pwa-list > li + li > :is(a, button)::before, html.app .pwa-list > li.row + li.row::before {
	content: ""; position: absolute; top: 0; left: 16px; right: 0; border-top: .5px solid var(--pwa-sep);
}
html.app .pwa-list > li > :is(a, button):active { background: var(--pwa-fill); }
html.app .pwa-list svg { width: 22px; height: 22px; color: var(--pwa-accent); flex: none; }
html.app .pwa-list .chev { margin-left: auto; width: 14px; height: 14px; color: var(--pwa-text-2); }
html.app .pwa-list .danger, html.app .pwa-list .danger svg { color: var(--pwa-danger); }

/* Action sheet */
html.app .pwa-actions { position: fixed; z-index: 1001; left: 8px; right: 8px; bottom: calc(8px + var(--pwa-bottom)); transform: translateY(120%); transition: transform .4s var(--pwa-spring); font-family: var(--pwa-font); }
html.app .pwa-actions.show { transform: none; }
html.app .pwa-actions .grp { background: var(--pwa-chrome); -webkit-backdrop-filter: blur(20px); backdrop-filter: blur(20px); border-radius: 14px; overflow: hidden; margin-top: 8px; }
html.app .pwa-actions .ttl { padding: 14px 16px; font-size: 13px; color: var(--pwa-text-2); text-align: center; border-bottom: .5px solid var(--pwa-sep); }
html.app .pwa-actions button { display: block; width: 100%; height: 57px; border: 0; background: none; color: var(--pwa-accent); font: 400 20px var(--pwa-font); }
html.app .pwa-actions button + button { border-top: .5px solid var(--pwa-sep); }
html.app .pwa-actions button.danger { color: var(--pwa-danger); }
html.app .pwa-actions button.cancel { font-weight: 600; background: var(--pwa-surface); }
html.app .pwa-actions button:active { background: var(--pwa-fill); }

/* ------------------------------------------------------- toast & banners */
html.app .pwa-toast {
	position: fixed; z-index: 1100; left: 50%; top: calc(var(--pwa-top) + 8px);
	display: flex; align-items: center; gap: 12px;
	/* One line, always: left:50% left it only half the screen to size itself in, so "A new version is ready  Reload"
	   wrapped on a phone. As wide as its text, at most the screen less 16px a side; longer text ends in "…" */
	width: max-content; max-width: calc(100vw - 32px); padding: 12px 18px; border-radius: 22px; white-space: nowrap;
	background: var(--pwa-surface-2); color: var(--pwa-text);
	box-shadow: 0 8px 30px rgba(0, 0, 0, .3);
	font: 500 15px var(--pwa-font);
	transform: translate(-50%, -150%); transition: transform .45s var(--pwa-spring);
}
html.app .pwa-toast.show { transform: translate(-50%, 0); }
html.app .pwa-toast > span { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
html.app .pwa-toast button { flex: none; border: 0; background: none; color: var(--pwa-accent); font: 600 15px var(--pwa-font); padding: 0; white-space: nowrap; }

/* Layout debug (?debug=1): outline every box, wrap long toasts */
html.app.pwa-debug #page_wrap * { outline: 1px dashed rgba(255, 80, 80, .35); }
html.app.pwa-debug .pwa-toast { max-width: calc(100vw - 16px); font: 500 12px/1.4 ui-monospace, Menlo, monospace; word-break: break-all; white-space: normal; }
html.app.pwa-debug .pwa-toast > span { overflow: visible; }

/* ---------------------------------------------------- pull to refresh */
html.app .pwa-ptr {
	position: fixed; z-index: 899; left: 50%; top: calc(var(--pwa-bar-h) + var(--pwa-top) + 6px);
	width: 30px; height: 30px; margin-left: -15px;
	color: var(--pwa-text-2); opacity: 0; pointer-events: none;
}
html.app .pwa-ptr svg { width: 30px; height: 30px; }
html.app .pwa-ptr.spin svg { animation: pwa-spin .8s linear infinite; }
@keyframes pwa-spin { to { transform: rotate(360deg); } }

/* ----------------------------------------------------- swipe back */
html.app .pwa-swiping main, html.app .pwa-swiping #page_wrap:not(main #page_wrap) { box-shadow: -12px 0 24px rgba(0, 0, 0, .25); }

/* --------------------------------------------- page transitions (native push/pop) */
::view-transition-group(pwa-bar), ::view-transition-group(pwa-tabs) { animation: none; z-index: 10; }
::view-transition-old(pwa-tabs), ::view-transition-new(pwa-tabs) { animation: none; }
::view-transition-old(pwa-bar) { animation: .2s ease both pwa-fade-out; }
::view-transition-new(pwa-bar) { animation: .25s ease both pwa-fade-in; }

html:active-view-transition-type(forward)::view-transition-old(root) { animation: .4s var(--pwa-spring, ease) both pwa-push-out; }
html:active-view-transition-type(forward)::view-transition-new(root) { animation: .4s var(--pwa-spring, ease) both pwa-push-in; }
html:active-view-transition-type(back)::view-transition-old(root) { animation: .38s var(--pwa-spring, ease) both pwa-pop-out; z-index: 2; }
html:active-view-transition-type(back)::view-transition-new(root) { animation: .38s var(--pwa-spring, ease) both pwa-pop-in; }
/* After a finished swipe the old page is already off screen */
html:active-view-transition-type(back-swiped)::view-transition-old(root) { animation: none; opacity: 0; }
html:active-view-transition-type(back-swiped)::view-transition-new(root) { animation: .25s var(--pwa-ease, ease) both pwa-pop-in; }
/* Tab switch: the old page stays fully there while the new one fades in over it. Fading both at once left them
   half see-through over nothing for a moment - a dark flash, and a black strip at the bottom until the new page's
   tab bar (built by pwa.js, deferred) was in. The new page is live, so its tab bar fades in as soon as it exists. */
/* Tab to the right / left of the current one (pwa.js): the pages slide sideways, the tab bar stays put */
html:active-view-transition-type(tab-right)::view-transition-old(root) { animation: .34s var(--pwa-spring, ease) both pwa-slide-out-left; }
html:active-view-transition-type(tab-right)::view-transition-new(root) { animation: .34s var(--pwa-spring, ease) both pwa-slide-in-right; }
html:active-view-transition-type(tab-left)::view-transition-old(root)  { animation: .34s var(--pwa-spring, ease) both pwa-slide-out-right; }
html:active-view-transition-type(tab-left)::view-transition-new(root)  { animation: .34s var(--pwa-spring, ease) both pwa-slide-in-left; }
html:active-view-transition-type(tab)::view-transition-old(root) { animation: none; mix-blend-mode: normal; }
html:active-view-transition-type(tab)::view-transition-new(root) { animation: .2s ease both pwa-fade-in; mix-blend-mode: normal; }   /* normal: the browser's plus-lighter would brighten the pair */

/* The app template's per-type choices (boot.js: fx-<choice>, the same whichever way you go) */
html:active-view-transition-type(fx-slide-right)::view-transition-old(root) { animation: .34s var(--pwa-spring, ease) both pwa-slide-out-left; }
html:active-view-transition-type(fx-slide-right)::view-transition-new(root) { animation: .34s var(--pwa-spring, ease) both pwa-slide-in-right; }
html:active-view-transition-type(fx-slide-left)::view-transition-old(root)  { animation: .34s var(--pwa-spring, ease) both pwa-slide-out-right; }
html:active-view-transition-type(fx-slide-left)::view-transition-new(root)  { animation: .34s var(--pwa-spring, ease) both pwa-slide-in-left; }
html:active-view-transition-type(fx-slide-up)::view-transition-old(root)    { animation: .36s var(--pwa-spring, ease) both pwa-sink-out; }
html:active-view-transition-type(fx-slide-up)::view-transition-new(root)    { animation: .36s var(--pwa-spring, ease) both pwa-rise-in; }
html:active-view-transition-type(fx-fade)::view-transition-old(root)        { animation: .2s ease both pwa-fade-out; mix-blend-mode: normal; }
html:active-view-transition-type(fx-fade)::view-transition-new(root)        { animation: .25s ease both pwa-fade-in; mix-blend-mode: normal; }
html:active-view-transition-type(fx-zoom)::view-transition-old(root)        { animation: .22s ease both pwa-zoom-out; mix-blend-mode: normal; }
html:active-view-transition-type(fx-zoom)::view-transition-new(root)        { animation: .3s var(--pwa-spring, ease) both pwa-zoom-in; mix-blend-mode: normal; }

@keyframes pwa-push-in  { from { transform: translateX(100%); } }
@keyframes pwa-push-out { to   { transform: translateX(-30%); filter: brightness(.8); } }
@keyframes pwa-pop-in   { from { transform: translateX(-30%); filter: brightness(.8); } }
@keyframes pwa-pop-out  { to   { transform: translateX(100%); } }
@keyframes pwa-fade-in  { from { opacity: 0; } }
@keyframes pwa-slide-in-right  { from { transform: translateX(100%); } }
@keyframes pwa-slide-out-left  { to   { transform: translateX(-100%); } }
@keyframes pwa-slide-in-left   { from { transform: translateX(-100%); } }
@keyframes pwa-slide-out-right { to   { transform: translateX(100%); } }
@keyframes pwa-fade-out { to   { opacity: 0; } }
@keyframes pwa-rise-in  { from { transform: translateY(100%); } }
@keyframes pwa-sink-out { to   { transform: translateY(-12%); filter: brightness(.8); } }
@keyframes pwa-zoom-in  { from { opacity: 0; transform: scale(1.04); } }
@keyframes pwa-zoom-out { to   { opacity: 0; transform: scale(.97); } }

@media (prefers-reduced-motion: reduce) {
	::view-transition-old(root), ::view-transition-new(root) { animation-duration: .01s !important; }
	html.app :is(.pwa-sheet, .pwa-toast, .pwa-actions) { transition-duration: .01s; }
}

/* The keyboard up (pwa.js keyboardWatch): a sheet sits on top of it, filling the space above, so a field and what it
   lists (a search and its results) stay in view instead of under the keyboard */
html.app.pwa-modal-sheets.pwa-keyboard dialog.kui.modal { bottom: var(--pwa-kb, 0px) !important; max-height: calc(var(--pwa-vh, 100dvh) - 12px) !important; }
html.app.pwa-keyboard .pwa-sheet { bottom: var(--pwa-kb, 0px); max-height: calc(var(--pwa-vh, 100dvh) - 12px); }

/* --------------------------------------------- tablets / desktop (mode 'always') */
/* The same app, sized for a wide screen: tabs grouped in the middle instead of stretched
   edge to edge, sheets and dialogs as centred panels, mouse hover on bar buttons and tabs. */
@media (min-width: 768px) {
	html.app .pwa-tabs { justify-content: center; }
	html.app .pwa-tab { flex: 0 1 120px; }
	html.app .pwa-bar-title { max-width: 50vw; }
	html.app :is(.pwa-sheet, .pwa-actions) { left: 50%; right: auto; width: min(560px, calc(100vw - 32px)); margin-left: calc(min(560px, calc(100vw - 32px)) / -2); }
	html.app .pwa-actions { width: min(420px, calc(100vw - 32px)); margin-left: calc(min(420px, calc(100vw - 32px)) / -2); }
	html.app.pwa-modal-sheets dialog.kui.modal { inset: auto 0 0 0 !important; width: min(600px, 100%) !important; margin: 0 auto !important; }
}
@media (hover: hover) {
	html.app .pwa-tab:hover:not(.active) { color: var(--pwa-text); }
	html.app .pwa-bar :is(.pwa-back, .pwa-action, [data-m-action]):hover { opacity: .7; }
	html.app .pwa-list > li > :is(a, button):hover { background: var(--pwa-fill); }
}

/* --------------------------------------------- landscape / bigger phones */
@media (orientation: landscape) and (max-height: 500px) {
	html.app { --pwa-tab-h: 32px; --pwa-bar-h: 32px; }
	html.app .pwa-tab { flex-direction: row; justify-content: center; align-items: center; padding: 0; gap: 6px; font-size: 13px; }
	html.app .pwa-tab svg { width: 22px; height: 22px; }
	html.app .pwa-large-title { display: none; }
}

/* -------------------------------------------------- ajax pages (ajax_nav) */
/* A page that takes a moment: a spinner in the middle (pwa.js adds .pwa-loading after 400ms) */
html.app.pwa-loading::after {
	content: ""; position: fixed; z-index: 950; left: 50%; top: 50%; width: 28px; height: 28px; margin: -14px 0 0 -14px;
	border-radius: 50%; border: 2.5px solid rgba(255, 255, 255, .2); border-top-color: var(--pwa-accent, #fff);
	animation: pwa-spin .7s linear infinite; pointer-events: none;
}
