/*
 * phone.css — the phone shell.
 *
 * The mirror of os.css: same tokens, same glass, same icon set, below the
 * breakpoint instead of above it. Scoped to `.js` and to a narrow viewport, so
 * it costs a desktop nothing and a visitor without scripts nothing — they keep
 * the readable document in base.css.
 *
 * Only the chrome is here. What an app draws inside a screen is apps.css,
 * shared with the desktop, and it reflows on its own: the screen body declares
 * the same `eos-app` container the window body does, and at phone width the
 * container queries those views already carry do the work.
 */

@media (max-width: 767px) {

	/* ---------------------------------------------------------------------
	 * Surface
	 *
	 * The document layer becomes the content store the screens draw from,
	 * exactly as it does on the desktop.
	 * ------------------------------------------------------------------ */

	.js body {
		height: 100vh;
		height: 100dvh;
		overflow: hidden;
		overscroll-behavior: none;
	}

	.js .eos-wallpaper {
		display: block;
	}

	.js .eos-doc,
	.js .eos-pageheader,
	.js .eos-pagefooter,
	.js .eos-skip {
		display: none;
	}

	/* The notification clears the status pill rather than landing on it. */
	.js .eos-notif {
		top: calc(env(safe-area-inset-top, 0px) + 58px);
	}

	/* ---------------------------------------------------------------------
	 * The shell
	 * ------------------------------------------------------------------ */

	.js .eos-phone {
		display: block;
		position: fixed;
		inset: 0;
		z-index: 1;
	}

	/*
	 * Everything under the top screen is out of the page while it is covered:
	 * `visibility` takes it out of the tab order and the accessibility tree
	 * too, which `opacity` would not. The delay holds it visible for the
	 * length of the transition, so there is something behind the screen
	 * sliding in; uncovering has no delay, so it is there the moment the
	 * screen starts sliding out.
	 */
	.js .eos-phone__home,
	.js .eos-phone__screen {
		transition: visibility 0s linear 0s;
	}

	.js .eos-phone[data-covered="true"] .eos-phone__home,
	.js .eos-phone__screen[data-covered="true"] {
		visibility: hidden;
		transition-delay: var(--speed);
	}

	/* ---------------------------------------------------------------------
	 * Home screen
	 * ------------------------------------------------------------------ */

	.js .eos-phone__home {
		position: absolute;
		inset: 0;
		display: flex;
		flex-direction: column;
		gap: 10px;
		padding-top: calc(env(safe-area-inset-top, 0px) + 12px);
	}

	.js .eos-phone__status {
		flex: none;
		display: flex;
		align-items: center;
		justify-content: space-between;
		gap: 10px;
		height: 36px;
		margin: 0 16px;
		padding: 0 12px;
		border: 1px solid var(--edge);
		border-radius: 18px;
		background: var(--glass4);
		-webkit-backdrop-filter: blur(40px) saturate(1.8);
		backdrop-filter: blur(40px) saturate(1.8);
		box-shadow: var(--shadow-bar);
	}

	.js .eos-phone__identity {
		display: flex;
		align-items: center;
		gap: 8px;
		min-width: 0;
	}

	.js .eos-phone__mark {
		flex: none;
		width: 14px;
		height: 14px;
		border-radius: 4px;
		background: var(--accent);
	}

	.js .eos-phone__name {
		font-size: 12.5px;
		font-weight: 600;
		white-space: nowrap;
		overflow: hidden;
		text-overflow: ellipsis;
	}

	/* The menu bar's own status group, borrowed for the pill. */
	.js .eos-phone__statusitems {
		display: flex;
		align-items: center;
		flex: none;
	}

	.js .eos-phone__statusitems .eos-menubar__group {
		display: flex;
		align-items: center;
		gap: 12px;
	}

	/*
	 * The phone already has a clock, in a bar this one cannot reach — and the
	 * pill has no width to spare for the network meter.
	 */
	.js .eos-phone__statusitems .eos-clock,
	.js .eos-phone__statusitems .eos-activity {
		display: none;
	}

	.js .eos-phone__scroll {
		flex: 1;
		min-height: 0;
		overflow-y: auto;
		overscroll-behavior: contain;
		display: flex;
		flex-direction: column;
		gap: 10px;
		padding: 0 16px calc(env(safe-area-inset-bottom, 0px) + 118px);
	}

	/* ---------------------------------------------------------------------
	 * Widgets, as stacked cards
	 *
	 * The desktop rail itself, moved in: same markup, same refreshes, same
	 * count-up. Only the panel shape changes.
	 * ------------------------------------------------------------------ */

	.js .eos-phone__cards .eos-widgets {
		display: flex;
		flex-direction: column;
		gap: 10px;
		max-width: none;
		margin: 0;
		padding: 0;
		border-top: 0;
	}

	.js .eos-phone__cards .eos-widget {
		padding: 12px 14px;
		border: 1px solid var(--edge);
		border-radius: 18px;
		background: var(--glass4);
		-webkit-backdrop-filter: blur(40px) saturate(1.8);
		backdrop-filter: blur(40px) saturate(1.8);
		box-shadow: var(--shadow-bar);
	}

	.js .eos-phone__cards .eos-widget__head {
		margin-bottom: 4px;
	}

	.js .eos-phone__cards .eos-widget__source {
		font-size: 10px;
	}

	/* Rows are the tap targets, so they carry the 44px rather than the text. */
	.js .eos-phone__cards .eos-widget__post,
	.js .eos-phone__cards .eos-widget__project {
		display: flex;
		gap: 2px;
		min-height: 44px;
		padding: 8px 0;
		border-top: 1px solid var(--line4);
		text-decoration: none;
		color: inherit;
	}

	.js .eos-phone__cards .eos-widget__post {
		flex-direction: column;
		justify-content: center;
	}

	.js .eos-phone__cards .eos-widget__postrow {
		display: flex;
		align-items: baseline;
		justify-content: space-between;
		gap: 10px;
	}

	.js .eos-phone__cards .eos-widget__posttitle {
		font-size: 13px;
		font-weight: 600;
		line-height: 1.3;
	}

	.js .eos-phone__cards .eos-widget__postdate {
		flex: none;
		font-size: 10px;
	}

	.js .eos-phone__cards .eos-widget__postexcerpt,
	.js .eos-phone__cards .eos-widget__projecttitle {
		display: -webkit-box;
		-webkit-line-clamp: 1;
		-webkit-box-orient: vertical;
		overflow: hidden;
		font-size: 12px;
		line-height: 1.4;
		color: var(--ink3);
	}

	.js .eos-phone__cards .eos-widget__project {
		align-items: center;
		gap: 10px;
	}

	.js .eos-phone__cards .eos-widget__projecttext {
		display: flex;
		flex-direction: column;
		gap: 2px;
		min-width: 0;
	}

	.js .eos-phone__cards .eos-widget__projecttitle {
		font-size: 13px;
		font-weight: 600;
		color: var(--ink);
	}

	.js .eos-phone__cards .eos-widget__thumb {
		flex: none;
		width: 44px;
		height: 44px;
		border-radius: 10px;
		overflow: hidden;
	}

	.js .eos-phone__cards .eos-widget__thumb img {
		width: 100%;
		height: 100%;
		object-fit: cover;
	}

	/* At a Glance: four across, as the design draws it. */
	.js .eos-phone__cards .eos-stats {
		display: grid;
		grid-template-columns: repeat(4, 1fr);
		gap: 6px;
		margin: 0;
		padding: 0;
		list-style: none;
	}

	.js .eos-phone__cards .eos-stat {
		display: flex;
		flex-direction: column;
		align-items: center;
		gap: 4px;
		padding: 6px 0;
		border: 0;
		border-radius: 12px;
		background: var(--tile);
		text-align: center;
	}

	.js .eos-phone__cards .eos-stat__value {
		font-size: 22px;
		font-weight: 700;
		line-height: 1;
		letter-spacing: -.02em;
		color: var(--accent-text);
	}

	.js .eos-phone__cards .eos-stat__label {
		font: 500 8.5px var(--mono);
		letter-spacing: .02em;
		color: var(--muted);
	}

	.js .eos-phone__cards .eos-currently {
		display: flex;
		flex-direction: column;
		gap: 6px;
		margin: 0;
	}

	.js .eos-phone__cards .eos-currently__row {
		display: flex;
		align-items: baseline;
		gap: 10px;
		min-width: 0;
	}

	.js .eos-phone__cards .eos-currently__label {
		flex: none;
		font-size: 10px;
	}

	.js .eos-phone__cards .eos-currently__value {
		margin: 0;
		font-size: 12.5px;
		white-space: nowrap;
		overflow: hidden;
		text-overflow: ellipsis;
	}

	/* ---------------------------------------------------------------------
	 * The icon grid — all eight, whether or not they have a tab
	 * ------------------------------------------------------------------ */

	.js .eos-phone__grid {
		display: grid;
		grid-template-columns: repeat(4, 1fr);
		gap: 10px 6px;
		margin: 0;
		padding: 8px 4px 0;
		list-style: none;
	}

	.js .eos-phone__app {
		display: flex;
		flex-direction: column;
		align-items: center;
		gap: 5px;
		padding: 2px 0;
		text-decoration: none;
		color: var(--ink);
		-webkit-tap-highlight-color: transparent;
	}

	.js .eos-phone__tile {
		display: grid;
		place-items: center;
		width: 60px;
		height: 60px;
		border-radius: 17px;
		background: var(--tile-grad);
		color: var(--tile-ink);
		box-shadow:
			0 2px 6px rgba(20, 40, 50, .14),
			inset 0 0 0 1px var(--line4);
		transition: transform var(--speed) var(--ease);
	}

	.js .eos-phone__app--accent .eos-phone__tile {
		background: linear-gradient(160deg, #2d7a87, var(--accent));
		color: #fff;
		--tile-bg: #1f5f6b;
	}

	.js .eos-phone__app--dark .eos-phone__tile {
		background: linear-gradient(160deg, #243036, #121a1e);
		color: #8fd6de;
		--tile-bg: #1a2228;
	}

	.js .eos-phone__tile .eos-dock__glyph {
		width: 30px;
		height: 30px;
	}

	.js .eos-phone__app:active .eos-phone__tile {
		transform: scale(.94);
	}

	.js .eos-phone__applabel {
		font-size: 11px;
		font-weight: 500;
		text-align: center;
	}

	/* ---------------------------------------------------------------------
	 * Screens
	 *
	 * An app fills one; a record pushed from inside it fills the next. They
	 * slide in from the trailing edge and back out the same way, which is the
	 * one piece of motion the phone shell has.
	 * ------------------------------------------------------------------ */

	.js .eos-phone__stack {
		position: absolute;
		inset: 0;
		pointer-events: none;
	}

	.js .eos-phone__screen {
		position: absolute;
		inset: 0;
		display: flex;
		flex-direction: column;
		background: var(--surface);
		pointer-events: auto;
		transform: translateX(100%);
		transition:
			transform var(--speed) var(--ease),
			visibility 0s linear 0s;
	}

	.js .eos-phone__home:focus,
	.js .eos-phone__screen:focus {
		outline: none;
	}

	.js .eos-phone__screen[data-phase="open"] {
		transform: none;
	}

	.js .eos-phone__screen[data-phase="closing"] {
		transform: translateX(100%);
	}

	/* The nav bar: back on the left, the app's name in the middle. */
	.js .eos-phone__bar {
		flex: none;
		display: grid;
		grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
		align-items: center;
		gap: 6px;
		padding: calc(env(safe-area-inset-top, 0px) + 6px) 8px 6px;
		border-bottom: 1px solid var(--line3);
		background: var(--glass5);
		-webkit-backdrop-filter: blur(40px) saturate(1.8);
		backdrop-filter: blur(40px) saturate(1.8);
	}

	.js .eos-phone__back {
		display: flex;
		align-items: center;
		gap: 4px;
		justify-self: start;
		min-width: 0;
		height: 44px;
		padding: 0 10px;
		border: 0;
		background: none;
		color: var(--accent-text);
		font: 500 15px var(--font);
		cursor: pointer;
		-webkit-tap-highlight-color: transparent;
	}

	.js .eos-phone__back > span:last-child {
		white-space: nowrap;
		overflow: hidden;
		text-overflow: ellipsis;
	}

	/* The chevron, drawn rather than typed, so it sits on the text baseline. */
	.js .eos-phone__chevron {
		flex: none;
		width: 8px;
		height: 8px;
		border-left: 2px solid currentColor;
		border-bottom: 2px solid currentColor;
		border-radius: 1px;
		transform: rotate(45deg);
	}

	.js .eos-phone__title {
		margin: 0;
		font-size: 17px;
		font-weight: 600;
		letter-spacing: -.01em;
		white-space: nowrap;
		overflow: hidden;
		text-overflow: ellipsis;
	}

	.js .eos-phone__accessory {
		justify-self: end;
		width: 44px;
		height: 44px;
	}

	/* ---------------------------------------------------------------------
	 * What a screen holds
	 *
	 * The same handover the window body makes: the view gets the padding, the
	 * scrolling and the status bar, and the body becomes the container its
	 * layout responds to.
	 * ------------------------------------------------------------------ */

	.js .eos-phone__body {
		flex: 1;
		min-height: 0;
		display: flex;
		overflow: hidden;
		container: eos-app / inline-size;
	}

	/* The section's document spacing belongs to the document, not to a screen. */
	.js .eos-phone__body .eos-app {
		padding: 0;
		border-top: 0;
	}

	.js .eos-phone__body > .eos-app,
	.js .eos-phone__body .eos-app__body,
	.js .eos-phone__body .eos-view,
	.js .eos-phone__body .eos-view__frame,
	.js .eos-phone__body .eos-loading {
		display: flex;
		flex-direction: column;
		flex: 1;
		min-width: 0;
		min-height: 0;
	}

	/* The screen's own bar names the app; the section's heading would repeat it. */
	.js .eos-phone__body .eos-app__title {
		position: absolute;
		width: 1px;
		height: 1px;
		padding: 0;
		margin: -1px;
		overflow: hidden;
		clip: rect(0 0 0 0);
		clip-path: inset(50%);
		white-space: nowrap;
		border: 0;
	}

	/* Visible when a fetch failed: the content the page was served with. */
	.js .eos-phone__body .eos-static {
		flex: 1;
		min-height: 0;
		overflow-y: auto;
		overscroll-behavior: contain;
		padding: 16px 18px 24px;
	}

	.js .eos-phone__body .eos-view[data-state="error"] {
		flex: none;
		order: -1;
	}

	.js .eos-phone__body .eos-scroll {
		padding-bottom: calc(env(safe-area-inset-bottom, 0px) + 106px);
	}

	/*
	 * The app bar is the view's own footer. On a phone the tab bar floats over
	 * the bottom of the screen, so it sits above it rather than under it.
	 */
	.js .eos-phone__body .eos-appbar {
		display: none;
	}

	/*
	 * A filter row has more chips than a phone has width. It scrolls sideways
	 * rather than clipping the last category out of reach, and keeps its
	 * padding at both ends of the scroll.
	 */
	.js .eos-phone__body .eos-toolbar {
		overflow-x: auto;
		scrollbar-width: none;
		overscroll-behavior-x: contain;
	}

	.js .eos-phone__body .eos-toolbar::-webkit-scrollbar {
		display: none;
	}

	.js .eos-phone__body .eos-segmented,
	.js .eos-phone__body .eos-filter {
		flex: none;
	}

	.js .eos-phone__body .eos-filter {
		min-height: 30px;
		white-space: nowrap;
	}

	/*
	 * The reader draws its own way back to the list, for the window it opens
	 * in on a desktop. A screen already has one in its bar, and two of them
	 * pointing at the same place is one too many.
	 */
	.js .eos-phone__body .eos-reader__back {
		display: none;
	}

	/*
	 * The two views with something fixed to their bottom edge keep it clear of
	 * the tab bar. Their surface still runs underneath — the glass has the
	 * terminal's dark screen and the compose form's footer to blur — but Send
	 * and the prompt are never behind it.
	 */
	.js .eos-phone__body .eos-term__row {
		padding-bottom: calc(env(safe-area-inset-bottom, 0px) + 96px);
	}

	/*
	 * iOS Safari zooms the page when a field smaller than 16px takes focus,
	 * and never zooms back out. Every field that can be typed into is given
	 * the size that prevents it — including the Terminal, whose input takes
	 * the screen's own type so the line a visitor types matches the lines
	 * above it.
	 */
	.js .eos-phone__body .eos-term__screen {
		font-size: 16px;
	}

	/* ---------------------------------------------------------------------
	 * The tab bar
	 *
	 * The dock, as the design's floating glass bar. Four tabs: the registry
	 * marks which, and the home screen's grid carries the other four.
	 * ------------------------------------------------------------------ */

	.js .eos-dock {
		position: fixed;
		z-index: 3;
		right: 16px;
		bottom: calc(env(safe-area-inset-bottom, 0px) + 12px);
		left: 16px;
		max-width: none;
		margin: 0;
		padding: 0 8px;
		border: 1px solid var(--edge);
		border-radius: 28px;
		background: var(--glass2);
		-webkit-backdrop-filter: blur(40px) saturate(1.8);
		backdrop-filter: blur(40px) saturate(1.8);
		box-shadow: var(--shadow-dock);
	}

	.js .eos-dock__list {
		display: flex;
		align-items: center;
		justify-content: space-around;
		gap: 0;
		height: 72px;
	}

	/* The four that are not favourites live on the home screen instead. */
	.js .eos-dock__item[data-favourite="false"] {
		display: none;
	}

	.js .eos-dock__item {
		display: flex;
		flex-direction: column;
		align-items: center;
		gap: 4px;
	}

	.js .eos-dock__link {
		display: grid;
		place-items: center;
		width: 60px;
		height: 52px;
		-webkit-tap-highlight-color: transparent;
	}

	.js .eos-dock__tile {
		width: 44px;
		height: 44px;
		border-radius: 13px;
		box-shadow:
			0 2px 6px rgba(20, 40, 50, .14),
			inset 0 0 0 1px var(--line4);
		transition: transform var(--speed) var(--ease);
	}

	.js .eos-dock__link:active .eos-dock__tile {
		transform: scale(.94);
	}

	.js .eos-dock__glyph {
		width: 22px;
		height: 22px;
	}

	/* The tiles are the icon set; a label under each would only crowd them. */
	.js .eos-dock__label {
		position: absolute;
		width: 1px;
		height: 1px;
		padding: 0;
		margin: -1px;
		overflow: hidden;
		clip: rect(0 0 0 0);
		clip-path: inset(50%);
		white-space: nowrap;
	}

	.js .eos-dock__dot {
		display: block;
		width: 4px;
		height: 4px;
		margin-bottom: 6px;
		border-radius: 50%;
		background: var(--tile-ink);
		opacity: 0;
		transition: opacity var(--speed) var(--ease);
	}

	.js .eos-dock__item[data-open="true"] .eos-dock__dot {
		opacity: .8;
	}

	/* ---------------------------------------------------------------------
	 * Fallbacks
	 * ------------------------------------------------------------------ */

	@supports not ((-webkit-backdrop-filter: blur(1px)) or (backdrop-filter: blur(1px))) {
		.js .eos-dock,
		.js .eos-phone__status,
		.js .eos-phone__bar,
		.js .eos-phone__cards .eos-widget {
			background: var(--glass6);
		}
	}

	@media (prefers-reduced-motion: reduce) {
		.js .eos-phone__screen,
		.js .eos-phone__home,
		.js .eos-phone__tile,
		.js .eos-dock__tile,
		.js .eos-dock__dot {
			transition-duration: 1ms !important;
		}

		.js .eos-phone__screen[data-phase="opening"] {
			transform: none;
		}
	}
}
