/*
 * Everything this plugin draws, which is four things: a toast, a bar, an
 * install card and the offline page.
 *
 * Every colour is a var() with a fallback. On the DevJobsNepal theme these
 * resolve to the theme's own tokens and nothing here looks like a plugin;
 * on any other theme the fallbacks are a plain, legible grey and violet.
 * Nothing here sets a font family: whatever the page is set in is right.
 */

.djn-pwa-btn {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: .4rem;
	padding: .5rem .9rem;
	border: 1px solid var(--line, #e3e6eb);
	border-radius: var(--radius, 6px);
	background: var(--bg, #fff);
	color: var(--ink, #16181d);
	font: inherit;
	font-size: .9rem;
	line-height: 1.2;
	cursor: pointer;
}

.djn-pwa-btn:hover {
	border-color: var(--brand, #7a2ce8);
	color: var(--brand-ink, #5c1cb8);
}

/*
 * The label on a brand fill, which is white in a light scheme and is not in
 * a dark one: a dark scheme wants a fill lighter than the page, and white on
 * this theme's lit purple measures 3 to one. djn-theme carries the token; the
 * fallbacks are for any other theme, and the dark one is set below.
 */
.djn-pwa-btn--primary {
	border-color: var(--brand, #7a2ce8);
	background: var(--brand, #7a2ce8);
	color: var(--on-fill, #fff);
}

.djn-pwa-btn--primary:hover {
	background: var(--brand-ink, #5c1cb8);
	color: var(--on-fill, #fff);
}

.djn-pwa-btn[disabled] {
	opacity: .6;
	cursor: default;
}

/* --------------------------------------------------------------------------
   Toasts

   Bottom on a phone, where a thumb is, and bottom right on a desktop. Above
   the safe area so an iPhone's home indicator does not sit on top of the
   action.
   -------------------------------------------------------------------------- */

.djn-pwa-toasts {
	position: fixed;
	z-index: 60;
	left: 1rem;
	right: 1rem;
	bottom: calc(1rem + env(safe-area-inset-bottom, 0px));
	display: flex;
	flex-direction: column;
	gap: .5rem;
	pointer-events: none;
}

.djn-pwa-toast {
	display: flex;
	align-items: center;
	gap: .75rem;
	padding: .7rem .8rem .7rem 1rem;
	border-radius: var(--radius, 6px);
	background: var(--ink, #16181d);
	color: #fff;
	font-size: .9rem;
	line-height: 1.4;
	box-shadow: 0 6px 24px rgba(0, 0, 0, .28);
	pointer-events: auto;
}

.djn-pwa-toast__text {
	flex: 1 1 auto;
}

.djn-pwa-toast__action {
	flex: 0 0 auto;
	padding: .35rem .7rem;
	border: 1px solid rgba(255, 255, 255, .45);
	border-radius: var(--radius, 6px);
	background: none;
	color: #fff;
	font: inherit;
	font-size: .85rem;
	cursor: pointer;
}

.djn-pwa-toast__action:hover {
	background: rgba(255, 255, 255, .14);
}

.djn-pwa-toast__close {
	flex: 0 0 auto;
	padding: 0 .25rem;
	border: 0;
	background: none;
	color: rgba(255, 255, 255, .72);
	font: inherit;
	font-size: 1.1rem;
	line-height: 1;
	cursor: pointer;
}

.djn-pwa-toast__close:hover {
	color: #fff;
}

@media (min-width: 40rem) {
	.djn-pwa-toasts {
		left: auto;
		right: 1.25rem;
		max-width: 26rem;
	}
}

/* --------------------------------------------------------------------------
   The offline bar

   Top of the screen rather than bottom, and not dismissible. It is a
   statement of fact about why the page may be a few hours old.
   -------------------------------------------------------------------------- */

.djn-pwa-bar {
	position: sticky;
	top: 0;
	z-index: 55;
	padding: .45rem var(--gutter, 1rem);
	background: var(--warn-tint, #fdf0e3);
	color: var(--warn-ink, #92500b);
	font-size: .85rem;
	line-height: 1.4;
	text-align: center;
}

/* --------------------------------------------------------------------------
   The install card
   -------------------------------------------------------------------------- */

.djn-pwa-install {
	position: fixed;
	z-index: 58;
	left: 1rem;
	right: 1rem;
	bottom: calc(1rem + env(safe-area-inset-bottom, 0px));
	padding: 1rem 1.1rem;
	border: 1px solid var(--line, #e3e6eb);
	border-radius: var(--radius-lg, 10px);
	background: var(--bg, #fff);
	color: var(--ink, #16181d);
	box-shadow: 0 10px 34px rgba(0, 0, 0, .18);
}

.djn-pwa-install__title {
	margin: 0 0 .3rem;
	font-size: 1rem;
	font-weight: 600;
}

.djn-pwa-install__body {
	margin: 0 0 .85rem;
	color: var(--muted, #5f6673);
	font-size: .9rem;
	line-height: 1.5;
}

.djn-pwa-install__actions {
	display: flex;
	flex-wrap: wrap;
	gap: .5rem;
}

@media (min-width: 40rem) {
	.djn-pwa-install {
		left: auto;
		right: 1.25rem;
		max-width: 24rem;
	}
}

/* --------------------------------------------------------------------------
   The notification switch
   -------------------------------------------------------------------------- */

.djn-pwa-push__line {
	margin: 0 0 .5rem;
	color: var(--muted, #5f6673);
	font-size: .9rem;
	line-height: 1.5;
}

.djn-pwa-push__line:empty {
	display: none;
}

/* --------------------------------------------------------------------------
   The offline page

   Its own document, so it carries its own layout rather than relying on a
   theme's wrapper being in the cache.
   -------------------------------------------------------------------------- */

.djn-pwa-offline {
	margin: 0;
	background: var(--bg, #fff);
	color: var(--ink, #16181d);
	font-family: var(--font, system-ui, -apple-system, "Segoe UI", Roboto, Arial, sans-serif);
	line-height: 1.55;
}

.djn-pwa-offline__wrap {
	max-width: 44rem;
	margin: 0 auto;
	padding: 2.5rem 1.25rem 4rem;
}

.djn-pwa-offline__brand a {
	color: var(--muted, #5f6673);
	font-size: .85rem;
	letter-spacing: .02em;
	text-decoration: none;
	text-transform: uppercase;
}

.djn-pwa-offline__title {
	margin: .35rem 0 .6rem;
	font-size: clamp(1.6rem, 5vw, 2.1rem);
	line-height: 1.2;
}

.djn-pwa-offline__lede {
	margin: 0 0 1.5rem;
	max-width: 38rem;
	color: var(--ink-3, #474d59);
}

.djn-pwa-offline__pending {
	margin: 0 0 1.25rem;
	padding: .6rem .8rem;
	border-left: 3px solid var(--warn-ink, #92500b);
	background: var(--warn-tint, #fdf0e3);
	color: var(--warn-ink, #92500b);
	font-size: .9rem;
}

.djn-pwa-offline__list {
	margin: 0 0 1.5rem;
	padding: 0;
	list-style: none;
	border-top: 1px solid var(--line-2, #eef0f3);
}

.djn-pwa-saved {
	padding: .85rem 0;
	border-bottom: 1px solid var(--line-2, #eef0f3);
}

.djn-pwa-saved__title {
	color: var(--ink, #16181d);
	font-size: 1.02rem;
	font-weight: 600;
	text-decoration: none;
}

.djn-pwa-saved__title:hover {
	color: var(--brand-ink, #5c1cb8);
}

.djn-pwa-saved__meta {
	margin: .2rem 0 0;
	color: var(--muted, #5f6673);
	font-size: .88rem;
}

.djn-pwa-saved__flag {
	display: inline-block;
	margin-top: .35rem;
	padding: .1rem .45rem;
	border-radius: 999px;
	background: var(--brand-tint, #f2eafd);
	color: var(--brand-ink, #5c1cb8);
	font-size: .72rem;
	letter-spacing: .03em;
	text-transform: uppercase;
}

.djn-pwa-offline__empty {
	margin: 0 0 1.5rem;
	color: var(--muted, #5f6673);
}

.djn-pwa-offline__actions {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 1rem;
}

.djn-pwa-offline__link {
	color: var(--brand-ink, #5c1cb8);
	font-size: .92rem;
}

/*
 * A theme with no tokens of its own still needs to be readable in the dark,
 * and the offline page may be the only thing on screen.
 */
@media (prefers-color-scheme: dark) {
	.djn-pwa-offline {
		background: var(--bg, #14161b);
		color: var(--ink, #e8eaee);
	}

	.djn-pwa-toast {
		background: var(--ink-2, #2c3038);
	}

	.djn-pwa-install {
		background: var(--bg, #14161b);
		border-color: var(--line, #2a2e36);
		color: var(--ink, #e8eaee);
	}

	/* Under djn-theme the token is already the dark one and this changes
	   nothing. Under any other theme it is what stops the label on a light
	   brand fill from disappearing into it. */
	.djn-pwa-btn--primary,
	.djn-pwa-btn--primary:hover {
		color: var(--on-fill, #1b1030);
	}
}

/*
 * In the installed app there is no browser chrome above the page, so the
 * status bar sits on top of it.
 */
.djn-pwa-standalone body {
	padding-top: env(safe-area-inset-top, 0px);
}

/* --------------------------------------------------------------------------
   The app bar

   Shown in the installed app, and on a phone browser, and nowhere else. A
   desktop has a header with room in it and does not need a thumb rail.

   Everything below is inside one of those two media queries on purpose: on
   a laptop this file adds four rules and no layout at all.
   -------------------------------------------------------------------------- */

/*
 * How much room the bar takes, in one place.
 *
 * Five things have to agree about it: the bar itself, the gap it floats
 * above the bottom of the screen, the padding under the page, the toasts,
 * and the theme's sticky apply bar which sits on top of it. Written as a
 * number in five places, four of them are wrong within a month, and the
 * symptom is an apply button with a tab bar over the bottom two pixels
 * of it.
 *
 * The float and the side inset are shared with the header, which is the
 * same piece of glass at the other end of the screen. Two panes floating
 * by different amounts is the sort of thing nobody can name and everybody
 * can see.
 */
:root {
	--djn-pwa-tab-height: 3.5rem;
	--djn-pwa-float: .6rem;
	--djn-pwa-inset: .7rem;
	--djn-pwa-tabs: calc(var(--djn-pwa-tab-height) + var(--djn-pwa-float) + env(safe-area-inset-bottom, 0px));
}

.djn-pwa-tabs {
	display: none;
}

@media (display-mode: standalone), (max-width: 600px) {

	/*
	 * A floating pill rather than a bar welded to the bottom edge.
	 *
	 * The look is the one iOS 26 calls Liquid Glass and WhatsApp now uses:
	 * the bar lifts off the screen, rounds off completely, and lets what is
	 * behind it show through blurred rather than hiding it. What makes it
	 * read as glass is not the blur on its own, it is the three layers
	 * together: the blur, a hairline of near white around the edge where a
	 * real pane would catch the light, and a soft shadow underneath so that
	 * it is clearly above the page rather than part of it.
	 *
	 * The cost is honest and worth stating: a blurred backdrop on a fixed
	 * element is recomposited on every scroll frame, and the phones this
	 * site is read on are not fast. The radius is kept moderate for that
	 * reason, and every rule that costs anything is behind an @supports or a
	 * preference query, so a browser that cannot do it cheaply gets a solid
	 * bar that looks deliberate rather than a slow one that looks smeared.
	 */
	/*
	 * The material, written once and worn by both pieces of chrome: the tab
	 * bar at the bottom and the site header at the top. They are one object
	 * in two places as far as a reader is concerned, and a recipe copied
	 * into two rules is a recipe that drifts.
	 */
	.djn-pwa-tabs,
	.djn-pwa-has-shell .djn-header {
		border-radius: 999px;
		background: var(--bg, #fff);
		box-shadow:
			0 1px 2px rgba(16, 20, 28, .08),
			0 10px 30px rgba(16, 20, 28, .16);
	}

	/*
	 * The pane itself, where the browser can afford one.
	 *
	 * The values come from djn-theme, which defines the site's glass once
	 * and already deals with the dark scheme, so the bar cannot end up a
	 * different material from the header above it. The fallbacks are what
	 * this plugin is worth under any other theme, and they are the same
	 * numbers: eighty percent opaque, not the forty that the word glass
	 * suggests, because what sells the material is the blur and the lit edge
	 * and a thinner pane stops being readable over whatever the page
	 * scrolled underneath it.
	 */
	@supports (((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) and (background: color-mix(in srgb, currentColor 50%, transparent))) {
		.djn-pwa-tabs,
		.djn-pwa-has-shell .djn-header {
			background: var(--glass-pane, color-mix(in srgb, var(--bg, #fff) 80%, transparent));
			-webkit-backdrop-filter: var(--glass-blur, blur(18px) saturate(180%));
			backdrop-filter: var(--glass-blur, blur(18px) saturate(180%));
			box-shadow:
				var(--glass-edge, inset 0 0 0 .5px rgba(255, 255, 255, .55)),
				var(--glass-lift, 0 1px 2px rgba(16, 20, 28, .07), 0 12px 34px rgba(16, 20, 28, .18));
		}
	}

	.djn-pwa-tabs {
		position: fixed;
		z-index: 57;
		right: max(var(--djn-pwa-inset), env(safe-area-inset-right, 0px));
		bottom: calc(var(--djn-pwa-float) + env(safe-area-inset-bottom, 0px));
		left: max(var(--djn-pwa-inset), env(safe-area-inset-left, 0px));
		display: grid;
		grid-auto-columns: 1fr;
		grid-auto-flow: column;
		align-items: stretch;
		min-height: var(--djn-pwa-tab-height);
		padding: .25rem;
	}

	.djn-pwa-tab {
		display: flex;
		flex-direction: column;
		align-items: center;
		justify-content: center;
		gap: .15rem;
		/* Forty eight pixels of height before the label, which is the
		   smallest target a thumb hits reliably on a moving bus. */
		min-height: 3rem;
		padding: .35rem .2rem .3rem;
		border-radius: 999px;
		/* Darker than the usual muted grey, because this text can end up
		   over anything the page scrolled under it. */
		color: var(--ink-3, #474d59);
		font-size: .7rem;
		letter-spacing: .01em;
		text-decoration: none;
		-webkit-tap-highlight-color: transparent;
	}

	.djn-pwa-tab:hover,
	.djn-pwa-tab:focus-visible {
		color: var(--ink, #16181d);
		text-decoration: none;
	}

	/*
	 * The tab somebody is on gets a pill of its own, which is how a bar
	 * with no dividers still says where you are. Neutral rather than brand
	 * coloured: on glass a tinted pill reads as a second pane rather than
	 * as a selection, and the colour is doing its work on the icon and the
	 * label already.
	 */
	.djn-pwa-tab.is-on {
		background: color-mix(in srgb, var(--ink, #16181d) 9%, transparent);
		color: var(--brand-ink, #5c1cb8);
		font-weight: 600;
	}

	.djn-pwa-tab:active {
		background: color-mix(in srgb, var(--ink, #16181d) 13%, transparent);
	}

	/* The selected state, without a second set of icons: the same line
	   drawing, drawn a little heavier. A tinted fill inside the strokes
	   reads as muddy once there is a pane behind it. */
	.djn-pwa-tab.is-on .djn-pwa-tab__icon {
		stroke-width: 2.1;
	}

	.djn-pwa-tab__label {
		line-height: 1;
	}

	/* Room for the bar, plus the home indicator under it. */
	body.djn-pwa-has-shell {
		padding-bottom: calc(var(--djn-pwa-tabs) + .75rem);
	}

	/*
	 * The top nav, which is where this started: eight menu items in a
	 * horizontal scroller on a 5 inch screen, with the last one cut in
	 * half. The four places that matter are now at the bottom, so the top
	 * of the app is the brand and the person signed in.
	 */
	.djn-pwa-tidy-nav .djn-header .djn-nav {
		display: none;
	}

	/*
	 * The header, lifted off the top edge to match the bar at the bottom.
	 *
	 * Still sticky rather than fixed, which is the whole trick: sticky keeps
	 * its space in the flow, so the page below needs no padding invented for
	 * it and nothing has to be kept in sync. It sits in place at the top of
	 * the page, then holds at the float distance once the page moves under
	 * it.
	 *
	 * The bottom rule goes. A border is how a band that spans the window
	 * says where it ends; a pane that floats says it by floating, and a
	 * hairline across the middle of a rounded pill just looks like a mistake.
	 *
	 * The corners clip, because on a site with no footer menus the horizontal
	 * nav stays in the header, and items scrolling out of a rounded end need
	 * the rounded end to actually cut them off.
	 */
	.djn-pwa-has-shell .djn-header {
		position: sticky;
		top: calc(var(--djn-pwa-float) + env(safe-area-inset-top, 0px));
		margin: var(--djn-pwa-float) max(var(--djn-pwa-inset), env(safe-area-inset-right, 0px)) 0 max(var(--djn-pwa-inset), env(safe-area-inset-left, 0px));
		border-bottom: 0;
		overflow: hidden;
	}

	/* Three of the four tabs are links to a section of the dashboard, so the
	   place an anchor lands is not a detail here. The theme reserves room for
	   its own header; this is the floating one's, which is shorter. */
	html {
		scroll-padding-top: calc(var(--djn-pwa-float) + var(--djn-pwa-tab-height) + env(safe-area-inset-top, 0px) + .5rem);
	}

	/*
	 * Inside the pane, the gutter is the pane's, not the page's.
	 *
	 * A floating object is inset from the content it floats over, so the
	 * brand sitting a few pixels further in than the cards below it is
	 * correct rather than misaligned. The right side is tighter because what
	 * is on it is a button or an avatar, and a control inside glass nests
	 * close to the edge in the same way the lit tab does in the bar below.
	 */
	.djn-pwa-has-shell .djn-header__inner {
		gap: .75rem;
		padding-block: .4rem;
		padding-inline: .9rem .5rem;
		/* The same height as the bar at the other end of the screen, which is
		   the only reason this number is here rather than left to the
		   content. */
		min-height: var(--djn-pwa-tab-height);
	}

	/* The offline page is its own document and carries no site header, so
	   it needs the same room made for the bar. */
	.djn-pwa-offline {
		padding-bottom: calc(var(--djn-pwa-tabs) + .75rem);
	}

	/* Toasts and the install card sit above the bar rather than behind it. */
	.djn-pwa-toasts,
	.djn-pwa-install {
		bottom: calc(var(--djn-pwa-tabs) + 1rem);
	}

	/*
	 * The theme's sticky apply bar, lifted clear of this one.
	 *
	 * It was already there and already right: on a phone the apply action
	 * should be reachable at any scroll position. Putting a fixed bar along
	 * the bottom of the screen underneath it was this plugin's doing, and
	 * this is the plugin paying for it. The safe area is already accounted
	 * for by the tab bar below, so the apply bar stops adding its own.
	 */
	.djn-pwa-has-shell .djn-applybar {
		bottom: calc(var(--djn-pwa-tabs) + .3rem);
		padding-bottom: .7rem;
	}

	/*
	 * Dark glass, for a theme that does not define the site's glass itself.
	 *
	 * Under djn-theme these tokens are already the dark ones by the time
	 * this rule is read, so it sets what is set and changes nothing. Under
	 * any other theme the fallbacks are what make the bar work in the dark:
	 * a little more solid, because a blur has less to work with when
	 * everything behind it is dark, and a much fainter hairline, because
	 * light catching the edge of a pane is near white on a light background
	 * and barely there on a dark one.
	 */
	@media (prefers-color-scheme: dark) {
		@supports (((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) and (background: color-mix(in srgb, currentColor 50%, transparent))) {
			.djn-pwa-tabs,
			.djn-pwa-has-shell .djn-header {
				background: var(--glass-pane, color-mix(in srgb, var(--bg, #14161b) 84%, transparent));
				box-shadow:
					var(--glass-edge, inset 0 0 0 .5px rgba(255, 255, 255, .12)),
					var(--glass-lift, 0 1px 2px rgba(0, 0, 0, .4), 0 12px 34px rgba(0, 0, 0, .5));
			}
		}

		.djn-pwa-tab.is-on {
			background: color-mix(in srgb, #fff 14%, transparent);
		}
	}

	/*
	 * Somebody who has asked for less of this gets none of it.
	 *
	 * Transparency over text is the first thing to go for anybody who finds
	 * it hard to read, and iOS and Android both have a switch for it. The
	 * bar keeps its shape and loses its pane, which is a design rather than
	 * a degradation.
	 */
	@media (prefers-reduced-transparency: reduce), (prefers-contrast: more) {
		.djn-pwa-tabs,
		.djn-pwa-has-shell .djn-header {
			background: var(--bg, #fff);
			-webkit-backdrop-filter: none;
			backdrop-filter: none;
			box-shadow:
				inset 0 0 0 1px var(--line, #e3e6eb),
				0 6px 20px rgba(16, 20, 28, .18);
		}

		.djn-pwa-tab.is-on {
			background: var(--brand-tint, #f2eafd);
		}
	}
}

/* --------------------------------------------------------------------------
   The installed app

   Two bars stacked on a phone is the site's own header pushed down by one
   belonging to a WordPress the reader will never see. The theme switches
   the admin bar off for anybody who cannot edit; this switches it off in
   the app for everybody, because in a window with no address bar it is not
   a toolbar, it is a black stripe.
   -------------------------------------------------------------------------- */

@media (display-mode: standalone) {
	#wpadminbar {
		display: none !important;
	}

	html {
		margin-top: 0 !important;
	}

	/*
	 * The notch, paid for once.
	 *
	 * It used to be paid for twice: here, as padding inside the header, and
	 * again on the body by the rule further up this file, which left a gap
	 * above the header the height of two status bars. Now the body makes the
	 * room, which is also what the offline page needs since it has no header
	 * of its own, and the floating header adds the same inset to the offset
	 * it holds at so that it clears the notch once the page scrolls.
	 */
	body {
		padding-top: env(safe-area-inset-top, 0px);
	}

	/*
	 * The footer stays too, and is the app's "everything else" screen: the
	 * four tabs are the four things people come for, and posting a vacancy
	 * or reading how the site works is down there. Hiding it would make an
	 * app that can reach four pages.
	 */
	.djn-footer__legal {
		font-size: .75rem;
	}
}

@media print {
	.djn-pwa-tabs {
		display: none;
	}
}
