/* ── Site-wide mobile polish ─────────────────────────────────────────────
 * Loaded after every page-specific stylesheet so the rules below win on
 * equal specificity. Scope is intentionally narrow: cross-cutting iOS
 * Safari / mobile-Chrome platform quirks that bite every page. Per-page
 * mobile layout still lives in each page's own stylesheet.
 */

/* Tap-highlight + 300ms delay. Coarse-pointer media query keeps these off
 * desktop, where tap-highlight is irrelevant and touch-action would
 * suppress double-click-to-zoom in some contexts. */
@media (hover: none) and (pointer: coarse) {
	a,
	button,
	[role='button'],
	summary,
	input[type='submit'],
	input[type='button'],
	input[type='reset'] {
		-webkit-tap-highlight-color: transparent;
		touch-action: manipulation;
	}
	label,
	select,
	input[type='checkbox'],
	input[type='radio'] {
		-webkit-tap-highlight-color: transparent;
	}
}

/* Horizontal-scroll guard. A few px of off-by-one overflow on one child
 * shouldn't give the whole page a horizontal scrollbar on a phone.
 * overflow-x: clip is safer than overflow: hidden because it does not
 * also clamp vertical scrolling — and unlike hidden it cannot create a
 * new scroll container that breaks position: sticky higher in the tree. */
@media (max-width: 768px) {
	html,
	body {
		overflow-x: clip;
	}
}

/* iOS Safari zooms the viewport on focus when an input's computed
 * font-size is < 16px. Bump unstyled inputs/textareas/selects so that
 * tapping a search/email field doesn't punt the layout sideways. Pages
 * that intentionally use small inputs use class selectors with higher
 * specificity, so designed sizes still win where they matter. */
@media (max-width: 768px) {
	input:not([type='checkbox']):not([type='radio']):not([type='range']):not([type='color']),
	textarea,
	select {
		font-size: max(16px, 1em);
	}
}

/* Reusable safe-area utility for any fixed-bottom UI that doesn't already
 * handle the iPhone home indicator. Apply via class — no automatic
 * targeting, so existing layouts are untouched. */
@supports (padding: env(safe-area-inset-bottom)) {
	.mobile-safe-bottom {
		padding-bottom: env(safe-area-inset-bottom);
	}
	.mobile-safe-top {
		padding-top: env(safe-area-inset-top);
	}
}

/* ── Home-page specific mobile polish ──────────────────────────────────
 * Fixes that span across home.css but are best kept here
 * so the load order guarantees they win on equal-specificity conflicts.
 */

@media (max-width: 768px) {
	/* Chapter rail navigation dots — only useful on wide viewports. */
	.h-chapter-rail {
		display: none !important;
	}

	/* Ghost model loads a full GLB at opacity 0.1 — invisible on mobile,
	   pure bandwidth waste. The layer div still occupies its z-index slot. */
	.h-ghost-model {
		display: none !important;
	}

	/* Hero: on phones the sticky/margin-bottom trick (used for the parallax
	   text pin) causes a big blank gap.  The media query in home.css already
	   resets it to relative but misses some padding edge-cases. */
	.h-hero-text {
		padding-top: 1.5rem;
		padding-bottom: 2rem;
	}

	/* Title size: clamp already handles it but add a hard cap so it never
	   wraps oddly on 320-360px screens. */
	.h-title {
		font-size: clamp(2.6rem, 11vw, 4rem);
		letter-spacing: -0.03em;
	}

	.h-act-title {
		font-size: clamp(2rem, 8.5vw, 3.2rem);
	}

	/* Subtitle / lede: tighten line-height slightly on narrow screens */
	.h-subtitle {
		font-size: 1rem;
		line-height: 1.5;
	}

	.h-act-lede {
		font-size: 1rem;
		line-height: 1.5;
	}

	/* CTA row: stack on very small phones */
	.h-cta-row {
		gap: 0.65rem;
	}

	.h-btn-primary,
	.h-btn-ghost {
		min-height: 48px;
		padding: 0.9rem 1.4rem;
		font-size: 0.92rem;
	}

	/* Standards list: allow 2-per-line on tiny screens */
	.h-standards {
		gap: 0.5rem 0.9rem;
		font-size: 0.62rem;
	}

	/* Pillars: already single-column via home.css, add breathing room */
	.h-pillars {
		padding: 3rem 1.25rem;
	}

	.h-pillar p {
		font-size: 0.9rem;
	}

	/* Bento section */
	.h-bento-section {
		padding: 3rem 1rem;
	}

	.h-bento-body {
		padding: 1rem 1.2rem;
	}

	/* Dev section code block: allow horizontal scroll without breaking layout */
	.h-dev-pre {
		font-size: 0.74rem;
	}

	/* Final CTA section */
	.h-cta-section {
		padding: 3.5rem 1.25rem;
	}

	.h-cta-section h2 {
		font-size: clamp(2rem, 9vw, 3.2rem);
	}

	.h-cta-section p {
		font-size: 1rem;
	}

	.h-cta-row-center {
		flex-direction: column;
		align-items: stretch;
	}

	.h-cta-row-center .h-btn-primary,
	.h-cta-row-center .h-btn-ghost {
		text-align: center;
		justify-content: center;
	}

	/* Footer */
	.h-footer-horizon {
		padding: 2.5rem 1.25rem 1.25rem !important;
	}

	.h-footer-watermark {
		font-size: clamp(5rem, 18vw, 10rem);
	}
}

/* Very small phones (≤ 380px) — tighten further */
@media (max-width: 380px) {
	.h-title {
		font-size: clamp(2.2rem, 12vw, 3rem);
	}

	.h-cta-row {
		flex-direction: column;
		align-items: stretch;
	}

	.h-btn-primary,
	.h-btn-ghost {
		width: 100%;
		text-align: center;
		justify-content: center;
	}
}

/* ── Safe-area insets for fixed/sticky UI ──────────────────────────────
 * Applied globally so every page benefits. Modals and drawers that sit
 * at the viewport edge need padding-bottom to clear the iPhone home
 * indicator and Android navigation bar.
 */
@supports (padding: env(safe-area-inset-bottom)) {
	/* Modals anchored to full viewport height */
	.modal-content,
	.plugin-modal,
	.avatar-modal-side,
	.auth-form-wrap {
		padding-bottom: max(24px, env(safe-area-inset-bottom));
	}

	/* Toast / snackbar that sits at bottom-center */
	.agent-deploy-toast,
	.status-toast,
	.toast {
		bottom: max(1.5rem, calc(env(safe-area-inset-bottom) + 1rem));
	}

	/* Sticky bottom nav / tab bars */
	.nav-bottom,
	.bottom-bar,
	.mobile-tab-bar {
		padding-bottom: env(safe-area-inset-bottom);
	}

	/* Auth shell on very small iPhones */
	@media (max-width: 860px) {
		body:has(.shell) {
			padding-bottom: env(safe-area-inset-bottom);
		}
	}
}

/* ── 360px — very small Android phones ────────────────────────────────
 * Galaxy A series, Moto G, etc. sit at 360px.
 */
@media (max-width: 360px) {
	/* Marketplace: force single column so cards don't shrink below usable size */
	.market-grid {
		grid-template-columns: 1fr !important;
	}

	/* Create page: full-bleed cards */
	.card-grid {
		grid-template-columns: 1fr !important;
		max-width: none !important;
		padding: 0;
	}

	/* Auth: let the avatar panel compress more */
	.panel {
		min-height: 160px !important;
	}
	.agent-avatar {
		width: 140px !important;
		height: 140px !important;
	}

	/* Nav: shrink wordmark gap */
	.wordmark-logo {
		width: 18px;
		height: 18px;
	}
}

/* ── PWA standalone mode ────────────────────────────────────────────────
 * When installed as a PWA (no browser chrome), compensate for the absence
 * of the browser status bar and adjust top-anchored sticky headers.
 */
@media (display-mode: standalone) {
	/* Give the topmost sticky header extra top padding for the status bar area */
	header:first-of-type,
	.nav-top,
	.market-topbar,
	.agent-page-header {
		padding-top: max(0.75rem, env(safe-area-inset-top));
	}

	/* Bottom of scrollable main content — clear the home indicator */
	main,
	.stage,
	.market-main {
		padding-bottom: max(2rem, calc(env(safe-area-inset-bottom) + 1rem));
	}

	/* Hide browser-specific UI hints that don't apply in standalone */
	.h-scroll-hint {
		display: none;
	}
}

/* ── Marketplace mobile polish ─────────────────────────────────────────
 * Supplements marketplace.css at breakpoints it doesn't cover.
 */
@media (max-width: 480px) {
	/* Modal: full-screen bottom sheet on phones */
	.avatar-modal {
		position: fixed !important;
		inset: 0 !important;
		max-height: 100dvh !important;
		border-radius: 0 !important;
		grid-template-columns: 1fr !important;
		grid-template-rows: 48vw 1fr !important;
	}

	.avatar-modal-side {
		max-height: none;
		overflow-y: auto;
		-webkit-overflow-scrolling: touch;
	}

	/* Topbar: stack filter row below search on very narrow screens */
	.market-filter-chips {
		gap: 6px;
	}
	.market-filter-chip {
		font-size: 0.72rem;
		padding: 5px 10px;
	}
}

/* ── Create page mobile polish ─────────────────────────────────────────
 */
@media (max-width: 700px) {
	/* Upload drop zone: increase height so it's easier to tap */
	.upload-zone,
	[class*='drop-zone'] {
		min-height: 140px;
	}

	/* Card CTAs: full tap width */
	.create-card {
		-webkit-tap-highlight-color: transparent;
	}
}

/* ── Auth / login mobile polish ────────────────────────────────────────
 */
@media (max-width: 480px) {
	/* Sign-in form: use full available height */
	.shell {
		border-radius: 0;
		min-height: 100dvh;
	}

	/* Wallet connect button row: stack if too many */
	.wallet-list,
	.wallet-grid {
		grid-template-columns: 1fr !important;
	}
}

/* ── Scroll behaviour ──────────────────────────────────────────────────
 * Smooth momentum scroll on iOS for overflow containers.
 */
@media (hover: none) and (pointer: coarse) {
	[style*='overflow: auto'],
	[style*='overflow-y: auto'],
	[style*='overflow-y: scroll'],
	.scrollable,
	.avatar-modal-side,
	.market-main,
	.agent-chat-history {
		-webkit-overflow-scrolling: touch;
		scroll-behavior: smooth;
	}
}

/* ── Tap-target floor (touch only) ─────────────────────────────────────
 * Loaded last, so these win over page CSS on equal specificity. Gated on
 * pointer type (not viewport width) because a 768px+ tablet is still
 * touch-only and needs the same 44px floor — and desktop mouse visuals
 * must stay untouched. Scope is the controls the cross-page audit flagged
 * below 44px at 320/768: search/sort fields, marketplace + agents filter
 * controls, the dashboard/login form, and the onboarding pill.
 */
@media (hover: none) and (pointer: coarse) {
	/* Primary text fields & selects — comfortable height + 16px font (the
	   font rule above already prevents iOS focus-zoom). */
	#market-search,
	#ag-search,
	#skills-search,
	.market-sort,
	#ag-sort,
	#skills-sort {
		min-height: 44px;
	}

	/* Buttons that drive search/filter/auth flows. */
	.mkt-wallet-btn,
	.market-theme-cta,
	#skills-loadmore,
	.privy-row-btn,
	.privy-chain-btn,
	.onchain-toggle-btn,
	.card-see3d {
		min-height: 44px;
	}

	/* Square icon buttons need width too, not just height. */
	.password-toggle,
	.card-star {
		min-width: 44px;
		min-height: 44px;
	}

	/* Filter chips/segments: full 44px hit height with breathing room
	   between neighbours so dense rows stay easy to tap. */
	.market-chip,
	.market-cat-chip,
	.market-filter-chip {
		min-height: 44px;
		display: inline-flex;
		align-items: center;
	}
	.market-filter-chips,
	.market-cats {
		gap: 8px;
	}

	/* "On-chain only" style inline checkbox rows — give the whole label a
	   44px hit area and enlarge the box itself from its 13px default. */
	label:has(> #ag-onchain),
	label:has(> #remember) {
		min-height: 44px;
	}
	#ag-onchain,
	#remember {
		width: 18px;
		height: 18px;
	}
}

/* ── Tap-target floor, round 2 (touch only) ────────────────────────────
 * Every selector below was measured under 44x44 CSS px on a real Pixel 5
 * by `npm run audit:mobile-touch` (scripts/mobile-touch-audit.mjs); the
 * sizes in the comments are that run's measured boxes. Grouped by the
 * surface they came from so the next audit run can be traced back here.
 *
 * The technique is deliberately uniform: raise the box to a 44px floor and
 * centre the existing content inside it with inline-flex, so nothing moves
 * visually except the hit area growing. Gated on pointer type rather than
 * viewport width because a large tablet is still finger-driven, and a
 * desktop mouse must keep the designed compact sizing.
 */
@media (hover: none) and (pointer: coarse) {
	/* Skip links. Injected by /nav.js on every page and hand-written on a
	   few; they are the first focusable element, so a keyboard-plus-touch
	   user lands on them first. Measured 157x36, 152x40, 127x41, 393x26. */
	.nav-skip,
	.skip-link {
		min-height: 44px;
		display: inline-flex;
		align-items: center;
	}

	/* Shared footer. Present on most pages. Measured: the NVIDIA badge at
	   24x44 (too narrow, not too short) and the community button at 145x41. */
	.h-footer-nvidia {
		min-width: 44px;
		justify-content: center;
	}
	.h-footer-community-btn {
		min-height: 44px;
		display: inline-flex;
		align-items: center;
	}

	/* Docs shell. The sidebar is the single densest control list on the
	   site: 271 links measured at 267x30, stacked, with no gap between hit
	   areas. Raising the floor also separates neighbours. */
	.sidebar-link {
		min-height: 44px;
		display: flex;
		align-items: center;
	}
	.docs-pagetools-btn,
	.docs-pagetools-caret,
	.docs-logo,
	.docs-world-link {
		min-height: 44px;
		display: inline-flex;
		align-items: center;
	}
	.docs-pagetools-caret {
		min-width: 44px;
		justify-content: center;
	}

	/* /launches. Each launch row carries a strip of 29px actions plus a
	   37x10 tip button, which is the smallest control measured anywhere. */
	.lx-action,
	.lx-agent-row,
	.twc-make,
	.mp-tick {
		min-height: 44px;
		display: inline-flex;
		align-items: center;
	}
	.lx-agent-row,
	.mp-tick {
		display: flex;
	}
	.lx-action-watch {
		min-width: 44px;
		justify-content: center;
	}
	/* The ticker span carries a click handler, so it is a real target. */
	span.twc {
		min-height: 44px;
		display: inline-flex;
		align-items: center;
	}

	/* Home page. Avatar picker tiles (32x32), animation/emote chips (50x24),
	   the advent topic links (152x33) and the section CTAs (111x41). */
	.pg-avatar-item {
		min-width: 44px;
		min-height: 44px;
	}
	.pg-anim,
	.pg-chip,
	.hp-btn,
	.adv-topic,
	.har-cta-link,
	.wyg-card-link {
		min-height: 44px;
		display: inline-flex;
		align-items: center;
	}

	/* /forge. Showcase card actions and the generation-mode tabs. */
	.showcase-vote,
	.showcase-remix,
	.showcase-cat-badge,
	.fq-connect-btn {
		min-height: 44px;
		display: inline-flex;
		align-items: center;
	}
	#tab-text,
	#tab-image,
	#tab-sketch {
		min-height: 44px;
	}

	/* /play. The community picker, its name field, and the intro reopener. */
	.cc-card-holders,
	.cc-nav-brand,
	.cc-adventure,
	.cc-gallery-btn,
	.pi-reopen {
		min-height: 44px;
		display: inline-flex;
		align-items: center;
	}
	.cc-nav-toggle {
		min-width: 44px;
		min-height: 44px;
	}
	.cc-name-input {
		min-height: 44px;
	}

	/* /marketplace. Card title links (289x32) and the disclosure banner. */
	.card-profile-link,
	.tws-disc-cta {
		min-height: 44px;
		display: inline-flex;
		align-items: center;
	}
	.tws-disc-x {
		min-width: 44px;
		min-height: 44px;
	}

	/* /markets. Watchlist stars are the smallest tap target on the page. */
	.nw-star {
		min-width: 44px;
		min-height: 44px;
	}
	.mkt-more {
		min-height: 44px;
		display: inline-flex;
		align-items: center;
	}

	/* /changelog filter pills. */
	.cl-filter {
		min-height: 44px;
		display: inline-flex;
		align-items: center;
	}

	/* /walk. Share/copy row plus the standard button kit at mobile size. */
	.wl-copy-btn {
		min-height: 44px;
		display: inline-flex;
		align-items: center;
	}
	.btn {
		min-height: 44px;
	}

	/* /irl. Consent, calibration and bottom-sheet controls all sat at 32-43px. */
	.irl-consent-btn,
	.irl-sheet-btn,
	.irl-sheet-report,
	.irl-ob-learn,
	.tws-es-btn {
		min-height: 44px;
	}
	.irl-cal-step {
		min-width: 44px;
		min-height: 44px;
	}
	#irl-cal-save,
	#irl-cal-cancel {
		min-height: 44px;
	}
	/* Checkbox inputs default to 13-16px; the label row carries the hit area
	   and the box itself grows to a thumb-sized 22px. */
	#irl-consent-dontshow {
		width: 22px;
		height: 22px;
	}

	/* Auth / dashboard form. Fields measured 42px, the submit 41px. */
	#email,
	#password,
	#privy-email-input,
	#submit,
	.brand,
	.panel-brand,
	.forgot {
		min-height: 44px;
	}
	.brand,
	.panel-brand,
	.forgot {
		display: inline-flex;
		align-items: center;
	}
}

/* ── Canvas scroll posture ─────────────────────────────────────────────
 * A canvas with `touch-action: auto` that also calls preventDefault in a
 * pointer handler makes orbit gestures fight page scroll; one with
 * `touch-action: none` inside a scrolling page swallows the swipe outright.
 * Every canvas below is a decorative or preview surface embedded in a page
 * the user still has to scroll, so vertical panning belongs to the page and
 * horizontal drag belongs to the canvas.
 *
 * Full-screen application canvases (#kx-canvas on /play, #irl-canvas on
 * /irl) are deliberately absent: they own the whole viewport, there is
 * nothing to scroll behind them, and `touch-action: none` is correct there.
 */
#footer-bot-canvas,
.walk-companion-canvas,
.walk-preview-canvas,
#drop-canvas,
#lx-field,
#avatar-canvas,
#walk-minimap,
.mocap-waveform {
	touch-action: pan-y;
}

/* ── Safe-area insets for the bars the audit found unprotected ─────────
 * Each of these is fixed or sticky, hugs the bottom edge, and had no rule
 * mentioning safe-area-inset applying to it, so on an iPhone its last row
 * of controls sits under the home indicator.
 *
 * Each rule keeps the bar's own designed bottom padding as the floor (the
 * value the audit measured) and only grows past it on a device that
 * actually reports an inset, so nothing shifts on a phone without one.
 */
@supports (padding: env(safe-area-inset-bottom)) {
	.lx-toolbar {
		padding-bottom: max(6px, env(safe-area-inset-bottom));
	}
	.irl-bottom {
		padding-bottom: max(14px, env(safe-area-inset-bottom));
	}
	#irl-caption-panel,
	#irl-error-sheet,
	#irl-mypins-sheet,
	#irl-agents-sheet {
		padding-bottom: max(36px, env(safe-area-inset-bottom));
	}
	#irl-calibrate-panel {
		padding-bottom: max(18px, env(safe-area-inset-bottom));
	}
}

/* ── /marketplace card controls on touch ──────────────────────────────
 * The card grid is deliberately dense on desktop (hover reveals the compose
 * CTA, the heart is a 16px glyph, tags are 18px pills). Under a thumb every
 * one of those was below the 44px floor: 1358 of 1735 targets on the page.
 * Each rule below grows the tappable box to 44px in its smaller dimension
 * while the painted visual stays the size the card was designed around:
 * transparent borders with `background-clip: padding-box` extend the box
 * without extending the pill, and negative margins hand the extra height
 * back so the card layout does not shift. Selectors repeat the page's own
 * specificity because pages/marketplace.html styles the same controls with
 * three-class selectors and this sheet only wins on a tie.
 */
@media (hover: none) and (pointer: coarse) {
	/* Title link: the inline stylesheet floors it at 32px with a
	   three-class selector, so match that specificity. */
	.market-card-avatar .title-row .title.card-profile-link,
	.market-card-agent .title.card-profile-link,
	.market-grid .card-profile-link {
		min-height: 44px;
		line-height: 1.3;
		display: flex;
		align-items: center;
	}

	/* Heart: 17x21 glyph. The title row is already 44px tall, so the box
	   grows sideways into a square centred on the glyph. */
	.market-card-avatar .title-row .card-heart,
	.card-heart {
		min-width: 44px;
		min-height: 44px;
		margin-top: 0;
		padding: 0;
		display: inline-grid;
		place-items: center;
	}

	/* Author: a 19px name in the byline. */
	.market-card-avatar .byline .card-author,
	a.card-author {
		display: inline-flex;
		align-items: center;
		min-width: 44px;
		min-height: 44px;
		margin: -13px 0;
	}

	/* Tag pills: 18px tall. Vertical transparent border grows the box to
	   44px, background-clip keeps the pill at its painted size, and the
	   negative margin keeps the wrap rows where they were. */
	.market-card-avatar .card-tags .tag-pill,
	.market-grid button.tag-pill {
		box-sizing: border-box;
		min-height: 44px;
		min-width: 44px;
		border-color: transparent;
		border-width: 13px 1px;
		background-clip: padding-box;
		/* The pill's 1px outline moves from the (now transparent) border to
		   an inset shadow, which paints at the padding-box edge. */
		box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.12);
		margin: -13px 0;
		position: relative;
		z-index: 1;
	}
	.market-card-avatar .card-tags .tag-pill:active,
	.market-card-avatar .card-tags .tag-pill:focus-visible {
		box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.4);
		border-color: transparent;
	}

	/* Compose CTA: hidden until hover on desktop, which a touch screen never
	   fires, so it is both visible and tappable here. */
	.market-card-avatar .footer .compose-cta {
		color: #a5b4fc;
		background: rgba(99, 102, 241, 0.15);
		border-color: rgba(99, 102, 241, 0.3);
		pointer-events: auto;
		display: inline-flex;
		align-items: center;
		min-height: 44px;
		padding: 0 10px;
	}
	.market-card-avatar .footer .compose-cta:active {
		background: rgba(99, 102, 241, 0.25);
	}
	.market-card-avatar .footer .compose-cta:focus-visible {
		outline: var(--focus-ring-width, 2px) solid var(--focus-ring-color, #fff);
		outline-offset: var(--focus-ring-offset, 2px);
	}

	/* Hero actions (287x37), slide dots (38x32: a 4px bar inside invisible
	   padding, so grow the padding), the "All" chip (43px wide) and the
	   leaderboard link (113x19). */
	.market-hero-cta,
	.market-hero-secondary,
	a.market-hero-secondary {
		min-height: 44px;
	}
	.market-hero-dots button,
	.market-hero-dot {
		padding: 20px 9px;
	}
	.market-chip {
		min-width: 44px;
		min-height: 44px;
	}
	.mkt-top-see-all {
		display: inline-flex;
		align-items: center;
		min-height: 44px;
	}
	.tws-disc-x {
		width: 44px;
		height: 44px;
	}
}
