/* ==========================================================================
   Confession App
   Mobile-first, theme-aware stylesheet. No framework, no build step.
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. Design tokens
   -------------------------------------------------------------------------- */

:root {
	color-scheme: light dark;

	/* Opt into iOS Dynamic Type.
	   Mobile Safari does not apply the system text size to ordinary web CSS; a
	   page has to ask for it. The -apple-system-body keyword carries whatever
	   the user has chosen under Settings › Display & Text Size › Larger Text.
	   Since every size in this file is expressed in rem, setting it on the root
	   scales the entire interface with that preference.

	   Non-Apple browsers treat the keyword as invalid and drop the whole `font`
	   declaration, falling back to their own default root size — which is the
	   user's browser text-size setting, so they scale correctly too.

	   The shorthand also resets font-family, so restore our stack immediately
	   after while keeping the size it computed. */
	font: -apple-system-body;
	font-family: var(--font-ui);

	/* Brand */
	--brand-500: #3e72ae;
	--brand-600: #33608f;
	--brand-700: #274a70;
	--accent-500: #6d4aa7;
	/* penitential violet */
	--danger-500: #c0392b;

	/* Light theme surfaces */
	--bg: #f1f4f8;
	--surface: #ffffff;
	--surface-2: #f7f9fc;
	--surface-sunk: #e9eef5;
	--line: #dbe3ec;
	--line-strong: #c3cfdd;

	/* Light theme ink */
	--text: #16202c;
	--text-muted: #566677;
	--text-onbrand: #ffffff;

	/* Selection state */
	--pick-bg: #fdf1f1;
	--pick-line: #f0c9c6;
	--pick-ink: #a02b20;

	/* Shape & depth */
	--r-sm: 8px;
	--r-md: 12px;
	--r-lg: 18px;
	--r-pill: 999px;
	--shadow-1: 0 1px 2px rgb(16 32 48 / 6%), 0 1px 3px rgb(16 32 48 / 8%);
	--shadow-2: 0 4px 12px rgb(16 32 48 / 10%), 0 2px 4px rgb(16 32 48 / 6%);
	--shadow-3: 0 18px 48px rgb(16 32 48 / 22%);

	/* Rhythm */
	--sp-1: 4px;
	--sp-2: 8px;
	--sp-3: 12px;
	--sp-4: 16px;
	--sp-5: 24px;
	--sp-6: 32px;
	--sp-7: 48px;

	/* Type */
	--font-ui: ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
	--font-serif: ui-serif, Georgia, "Iowan Old Style", "Times New Roman", serif;

	/* Chrome heights, used for scroll padding and to reserve room under the
	   fixed tab bar. Expressed in rem so they grow with the text: the bars are
	   min-height and will expand at large Dynamic Type sizes, and the space
	   reserved for them has to expand by the same amount or content ends up
	   hidden underneath. Identical to 56px / 60px at a 16px root. */
	--appbar-h: clamp(56px, 3.5rem, 72px);
	--tabbar-h: clamp(60px, 3.75rem, 104px);

	/* Minimum comfortable touch target: never below 44px, but allowed to grow
	   with the user's text size. */
	--tap: max(44px, 2.75rem);
}

@media (prefers-color-scheme: dark) {
	:root {
		--brand-500: #6c9cd4;
		--brand-600: #85afe0;
		--brand-700: #a8c8ec;
		--accent-500: #a78bda;
		--danger-500: #e0685a;

		--bg: #10151c;
		--surface: #18202b;
		--surface-2: #1e2833;
		--surface-sunk: #131a23;
		--line: #2a3644;
		--line-strong: #3a4959;

		--text: #e6edf5;
		--text-muted: #98a7b8;
		--text-onbrand: #0d141d;

		--pick-bg: #2b1d1f;
		--pick-line: #4d2f30;
		--pick-ink: #f0a49a;

		--shadow-1: 0 1px 2px rgb(0 0 0 / 40%);
		--shadow-2: 0 4px 12px rgb(0 0 0 / 45%);
		--shadow-3: 0 18px 48px rgb(0 0 0 / 60%);
	}
}

/* --------------------------------------------------------------------------
   2. Reset & base
   -------------------------------------------------------------------------- */

*,
*::before,
*::after {
	box-sizing: border-box;
}

* {
	margin: 0;
}

html {
	-webkit-text-size-adjust: 100%;
	scroll-behavior: smooth;
	scroll-padding-top: calc(var(--appbar-h) + var(--sp-4));
}

body {
	min-height: 100dvh;
	font-family: var(--font-ui);
	/* 1rem, not 16px: this inherits the root size, which is whatever the user
	   has set as their browser's default text size. Hard-coding 16px here would
	   pin every element that has no explicit font-size — dialog bodies, prose,
	   callouts — while everything sized in rem scaled around them. */
	font-size: 1rem;
	line-height: 1.5;
	color: var(--text);
	background: var(--bg);
	-webkit-font-smoothing: antialiased;
	/* `anywhere` rather than `break-word`: both only break a word that does not
	   fit, but `anywhere` also lets the min-content width collapse. Without it a
	   long word sets a floor on how narrow a grid column can be, and at large
	   Dynamic Type sizes that pushes cards wider than the screen. Verified: with
	   `break-word` the layout overflows at the largest accessibility size. */
	overflow-wrap: anywhere;
}

img,
svg {
	display: block;
	max-width: 100%;
}

button,
input,
select,
textarea {
	font: inherit;
	color: inherit;
}

/* iOS Safari zooms the page when a text field smaller than 16px takes focus.
   These already inherit 16px from the body, but state it outright so a future
   tweak to a font-size cannot quietly reintroduce the zoom. */
input,
select,
textarea {
	font-size: max(16px, 1rem);
}

/* Disable double-tap-to-zoom on anything tappable. "manipulation" keeps
   scrolling and pinch-zoom working — it only drops the double-tap gesture,
   which also removes the ~300ms delay before a tap registers.

   Deliberately NOT using `user-scalable=no` / `maximum-scale=1` in the viewport
   meta: that would block pinch-zoom for anyone who needs to enlarge the text,
   and iOS ignores it in Safari anyway. */
html,
body,
a,
button,
summary,
label,
input,
select,
textarea,
.sin,
.stepper,
.tabbar__tab,
.keypad__key {
	touch-action: manipulation;
}

h1,
h2,
h3 {
	line-height: 1.25;
	text-wrap: balance;
	font-weight: 650;
}

h2 {
	font-size: 1.3rem;
}

h3 {
	font-size: 1.05rem;
}

:where(a) {
	color: var(--brand-600);
	text-underline-offset: 2px;
}

:focus-visible {
	outline: 3px solid var(--brand-500);
	outline-offset: 2px;
	border-radius: var(--r-sm);
}

@media (prefers-reduced-motion: reduce) {

	html {
		scroll-behavior: auto;
	}

	*,
	*::before,
	*::after {
		animation-duration: 0.01ms !important;
		animation-iteration-count: 1 !important;
		transition-duration: 0.01ms !important;
	}
}

/* --------------------------------------------------------------------------
   3. Utilities
   -------------------------------------------------------------------------- */

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

.small {
	font-size: 0.875rem;
}

.prose>*+* {
	margin-top: var(--sp-3);
}

.prose p {
	color: var(--text);
}

.sr-only {
	position: absolute;
	width: 1px;
	height: 1px;
	padding: 0;
	overflow: hidden;
	clip-path: inset(50%);
	white-space: nowrap;
}

[hidden] {
	display: none !important;
}

/* --------------------------------------------------------------------------
   4. Boot shield & privacy blur
   -------------------------------------------------------------------------- */

.boot-shield {
	position: fixed;
	inset: 0;
	z-index: 200;
	background: var(--bg);
}

body:not(.is-booting) .boot-shield {
	display: none;
}

/* Blur the content while the app is backgrounded so it does not show up in the
   OS app switcher. */
body.is-obscured .appbar,
body.is-obscured .main,
body.is-obscured .tabbar {
	filter: blur(18px);
}

/* --------------------------------------------------------------------------
   5. App bar
   -------------------------------------------------------------------------- */

.appbar {
	position: sticky;
	top: 0;
	z-index: 30;
	background: color-mix(in srgb, var(--surface) 88%, transparent);
	backdrop-filter: saturate(1.6) blur(12px);
	border-bottom: 1px solid var(--line);
	padding-top: env(safe-area-inset-top);
}

.appbar__inner {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: var(--sp-3);
	max-width: 46rem;
	min-height: var(--appbar-h);
	margin-inline: auto;
	padding-inline: var(--sp-4);
}

.wordmark {
	display: grid;
	min-width: 0;
	text-decoration: none;
	color: inherit;
	line-height: 1.1;
}

.wordmark__eyebrow {
	/* Branding, not content: allowed to grow a little with Dynamic Type but
	   capped, or the wordmark pushes the buttons off the top bar entirely. */
	font-size: min(0.625rem, 13px);
	font-weight: 700;
	letter-spacing: 0.12em;
	text-transform: uppercase;
	color: var(--brand-500);
}

.wordmark__name {
	font-family: var(--font-serif);
	font-size: min(1.35rem, 30px);
	font-weight: 600;
	letter-spacing: 0.01em;
}

.appbar__actions {
	display: flex;
	gap: var(--sp-1);
}

.iconbtn {
	display: grid;
	place-items: center;
	width: clamp(44px, var(--tap), 56px);
	height: clamp(44px, var(--tap), 56px);
	padding: 0;
	background: none;
	border: 0;
	border-radius: var(--r-md);
	color: var(--text-muted);
	cursor: pointer;
	transition: background-color 0.15s, color 0.15s;
}

.iconbtn:hover {
	background: var(--surface-sunk);
	color: var(--text);
}

.iconbtn svg {
	width: 22px;
	height: 22px;
	fill: none;
	stroke: currentColor;
	stroke-width: 1.8;
	stroke-linecap: round;
	stroke-linejoin: round;
}

/* --------------------------------------------------------------------------
   6. Layout
   -------------------------------------------------------------------------- */

.main {
	max-width: 46rem;
	margin-inline: auto;
	padding: var(--sp-4);
	padding-bottom: calc(var(--tabbar-h) + env(safe-area-inset-bottom) + var(--sp-6));
}

.view {
	display: grid;
	grid-template-columns: minmax(0, 1fr);
	gap: var(--sp-4);
}

/* --------------------------------------------------------------------------
   7. Cards
   -------------------------------------------------------------------------- */

.card {
	padding: var(--sp-4);
	background: var(--surface);
	border: 1px solid var(--line);
	border-radius: var(--r-lg);
	box-shadow: var(--shadow-1);
}

.card__eyebrow {
	font-size: 0.6875rem;
	font-weight: 700;
	letter-spacing: 0.1em;
	text-transform: uppercase;
	color: var(--text-muted);
}

.card--interval {
	display: grid;
	grid-template-columns: minmax(0, 1fr);
	justify-items: start;
	gap: var(--sp-2);
	background: linear-gradient(160deg,
			color-mix(in srgb, var(--brand-500) 12%, var(--surface)),
			var(--surface) 65%);
}

.interval__headline {
	font-family: var(--font-serif);
	font-size: clamp(1.5rem, 6vw, 1.9rem);
	line-height: 1.15;
	font-weight: 600;
}

.interval__detail {
	font-size: 0.9rem;
}

/* The native disclosure triangle sits outside the summary's content box, which
   puts it hard against the card's padding edge. Replace it with a chevron laid
   out in flow, matching the section accordions. */
.card--about summary {
	display: flex;
	align-items: center;
	gap: var(--sp-3);
	font-weight: 600;
	cursor: pointer;
	list-style: none;
}

.card--about summary::-webkit-details-marker {
	display: none;
}

.card--about summary::before {
	content: '';
	flex: none;
	width: 8px;
	height: 8px;
	border-right: 2px solid var(--brand-500);
	border-bottom: 2px solid var(--brand-500);
	transform: rotate(-45deg);
	transform-origin: center;
	transition: transform 0.2s ease;
}

.card--about[open] summary::before {
	transform: rotate(45deg);
}

.card--about[open] summary {
	margin-bottom: var(--sp-3);
}

.card--commit {
	display: grid;
	gap: var(--sp-3);
	border-color: color-mix(in srgb, var(--accent-500) 40%, var(--line));
	background: linear-gradient(160deg,
			color-mix(in srgb, var(--accent-500) 10%, var(--surface)),
			var(--surface) 70%);
}

.script {
	font-family: var(--font-serif);
	font-size: 1.075rem;
	line-height: 1.65;
}

.script__slot {
	color: var(--brand-600);
	white-space: nowrap;
}

.prayer {
	font-family: var(--font-serif);
	font-size: 1.05rem;
	line-height: 1.7;
	padding-left: var(--sp-4);
	border-left: 3px solid color-mix(in srgb, var(--accent-500) 55%, transparent);
}

/* --------------------------------------------------------------------------
   8. Buttons
   -------------------------------------------------------------------------- */

.btn {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: var(--sp-2);
	min-height: var(--tap);
	padding: 0 var(--sp-4);
	font-size: 0.95rem;
	font-weight: 600;
	color: var(--text);
	background: var(--surface-2);
	border: 1px solid var(--line-strong);
	border-radius: var(--r-md);
	cursor: pointer;
	transition: background-color 0.15s, border-color 0.15s, transform 0.08s;
}

.btn:hover {
	background: var(--surface-sunk);
}

.btn:active {
	transform: scale(0.985);
}

.btn--primary {
	color: var(--text-onbrand);
	background: var(--brand-500);
	border-color: var(--brand-500);
}

.btn--primary:hover {
	background: var(--brand-600);
	border-color: var(--brand-600);
}

.btn--danger-ghost {
	color: var(--danger-500);
	background: none;
	border-color: color-mix(in srgb, var(--danger-500) 40%, transparent);
}

.btn--danger-ghost:hover {
	background: color-mix(in srgb, var(--danger-500) 10%, transparent);
}

.btn--ghost {
	background: none;
	border-color: transparent;
	color: var(--brand-600);
	padding-inline: 0;
}

.btn--ghost:hover {
	background: none;
	text-decoration: underline;
}

.btn--sm {
	min-height: 32px;
	font-size: 0.875rem;
}

.btn--block {
	width: 100%;
}

.linkbtn {
	padding: 0;
	font: inherit;
	color: var(--brand-600);
	background: none;
	border: 0;
	text-decoration: underline;
	text-underline-offset: 2px;
	cursor: pointer;
}

/* --------------------------------------------------------------------------
   9. Toolbar: search + audience filter
   -------------------------------------------------------------------------- */

.toolbar {
	display: grid;
	gap: var(--sp-3);
}

.search {
	position: relative;
	display: flex;
	align-items: center;
}

.search__icon {
	position: absolute;
	left: var(--sp-3);
	width: 18px;
	height: 18px;
	fill: none;
	stroke: var(--text-muted);
	stroke-width: 1.8;
	stroke-linecap: round;
	pointer-events: none;
}

.search__input {
	width: 100%;
	min-height: var(--tap);
	padding: 0 var(--sp-3) 0 calc(var(--sp-3) * 2 + 18px);
	background: var(--surface);
	border: 1px solid var(--line-strong);
	border-radius: var(--r-pill);
	appearance: none;
}

.search__input::-webkit-search-cancel-button {
	cursor: pointer;
}

.segmented {
	display: flex;
	gap: var(--sp-1);
	padding: var(--sp-1);
	background: var(--surface-sunk);
	border-radius: var(--r-pill);
}

.segmented__btn {
	flex: 1;
	min-height: 36px;
	padding: 0 var(--sp-2);
	font-size: 0.85rem;
	font-weight: 600;
	color: var(--text-muted);
	background: none;
	border: 0;
	border-radius: var(--r-pill);
	cursor: pointer;
	white-space: nowrap;
}

.segmented__btn.is-active {
	color: var(--text);
	background: var(--surface);
	box-shadow: var(--shadow-1);
}

.search-status {
	font-size: 0.9rem;
	margin-top: calc(var(--sp-2) * -1);
}

.loading {
	padding: var(--sp-6) 0;
	text-align: center;
	color: var(--text-muted);
}

/* --------------------------------------------------------------------------
   10. Examination sections
   -------------------------------------------------------------------------- */

.sections {
	display: grid;
	grid-template-columns: minmax(0, 1fr);
	gap: var(--sp-4);
}

.section {
	background: var(--surface);
	border: 1px solid var(--line);
	border-radius: var(--r-lg);
	box-shadow: var(--shadow-1);
	overflow: hidden;
}

.section__summary {
	display: flex;
	align-items: center;
	gap: var(--sp-3);
	padding: var(--sp-4);
	cursor: pointer;
	list-style: none;
	user-select: none;
}

.section__summary::-webkit-details-marker {
	display: none;
}

.section__chevron {
	flex: none;
	width: 18px;
	height: 18px;
	fill: none;
	stroke: var(--text-muted);
	stroke-width: 2.2;
	stroke-linecap: round;
	stroke-linejoin: round;
	transition: transform 0.2s ease;
}

.section[open] .section__chevron {
	transform: rotate(90deg);
}

.section__heading {
	flex: 1;
	min-width: 0;
}

.section__title {
	font-family: var(--font-serif);
	font-size: 1.1rem;
	font-weight: 600;
}

.section__scripture {
	margin-top: 2px;
	font-size: 0.85rem;
	font-style: italic;
	color: var(--text-muted);
}

.section__count {
	flex: none;
	display: grid;
	place-items: center;
	min-width: max(26px, 1.9em);
	min-height: max(26px, 1.9em);
	padding: 0.15em var(--sp-2);
	font-size: 0.8rem;
	font-weight: 700;
	color: #fff;
	background: var(--danger-500);
	border-radius: var(--r-pill);
}

.sin-list {
	list-style: none;
	padding: 0 var(--sp-2) var(--sp-2);
	margin: 0;
	display: grid;
	gap: var(--sp-1);
}

/* ---- One examination row ---- */

.sin {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: var(--sp-2);
	padding: var(--sp-1) var(--sp-2);
	border-radius: var(--r-md);
	border: 1px solid transparent;
	transition: background-color 0.15s, border-color 0.15s;
}

.sin:nth-child(even) {
	background: var(--surface-2);
}

.sin.is-picked {
	background: var(--pick-bg);
	border-color: var(--pick-line);
}

.sin__label {
	flex: 1 1 12ch;
	min-width: 0;
	min-height: var(--tap);
	padding: var(--sp-2) var(--sp-1);
	font-size: 0.95rem;
	line-height: 1.45;
	text-align: left;
	color: inherit;
	background: none;
	border: 0;
	border-radius: var(--r-sm);
	cursor: pointer;
}

.sin.is-picked .sin__label {
	color: var(--pick-ink);
	font-weight: 550;
}

.stepper {
	flex: none;
	margin-left: auto;
	display: flex;
	align-items: center;
	gap: 2px;
	padding: 2px;
	background: var(--surface-sunk);
	border-radius: var(--r-pill);
}

.sin.is-picked .stepper {
	background: color-mix(in srgb, var(--danger-500) 14%, transparent);
}

.stepper__btn {
	display: grid;
	place-items: center;
	min-width: max(36px, 1.7em);
	min-height: max(36px, 1.7em);
	padding: 0;
	font-size: 1.25rem;
	font-weight: 700;
	line-height: 1;
	color: var(--text-muted);
	background: none;
	border: 0;
	border-radius: 50%;
	cursor: pointer;
	transition: background-color 0.15s, color 0.15s;
}

.stepper__btn:hover:not(:disabled) {
	background: var(--surface);
	color: var(--text);
}

.stepper__btn:disabled {
	opacity: 0.32;
	cursor: default;
}

.stepper__count {
	min-width: 24px;
	font-size: 0.95rem;
	font-weight: 700;
	font-variant-numeric: tabular-nums;
	text-align: center;
	color: var(--text-muted);
}

.sin.is-picked .stepper__count,
.sin.is-picked .stepper__btn {
	color: var(--pick-ink);
}

/* --------------------------------------------------------------------------
   11. Confession list
   -------------------------------------------------------------------------- */

.confession-list {
	display: grid;
	grid-template-columns: minmax(0, 1fr);
	gap: var(--sp-3);
}

.conf-group {
	padding: var(--sp-3) var(--sp-4);
	background: var(--surface);
	border: 1px solid var(--line);
	border-radius: var(--r-lg);
	box-shadow: var(--shadow-1);
}

.conf-group__title {
	font-size: 0.6875rem;
	font-weight: 700;
	letter-spacing: 0.1em;
	text-transform: uppercase;
	color: var(--text-muted);
	margin-bottom: var(--sp-2);
}

.conf-items {
	list-style: none;
	padding: 0;
	display: grid;
	gap: var(--sp-2);
}

.conf-item {
	display: flex;
	align-items: center;
	gap: var(--sp-3);
	padding: var(--sp-2) var(--sp-3);
	background: var(--pick-bg);
	border: 1px solid var(--pick-line);
	border-radius: var(--r-md);
}

.conf-item__text {
	flex: 1;
	font-family: var(--font-serif);
	font-size: 1rem;
	line-height: 1.5;
	color: var(--pick-ink);
}

.conf-item__count {
	flex: none;
	display: grid;
	place-items: center;
	min-width: max(28px, 1.9em);
	min-height: max(28px, 1.9em);
	padding: 0.15em var(--sp-2);
	font-size: 0.85rem;
	font-weight: 700;
	font-variant-numeric: tabular-nums;
	color: #fff;
	background: var(--danger-500);
	border-radius: var(--r-pill);
}

.conf-item__remove {
	flex: none;
	display: grid;
	place-items: center;
	width: 32px;
	height: 32px;
	padding: 0;
	color: var(--pick-ink);
	background: none;
	border: 0;
	border-radius: 50%;
	cursor: pointer;
	opacity: 0.65;
}

.conf-item__remove:hover {
	opacity: 1;
	background: color-mix(in srgb, var(--danger-500) 14%, transparent);
}

.conf-item__remove svg {
	width: 16px;
	height: 16px;
	fill: none;
	stroke: currentColor;
	stroke-width: 2.2;
	stroke-linecap: round;
}

/* Persistent reassurance line, shown under both tabs. */
.privacy-note {
	display: flex;
	align-items: center;
	justify-content: center;
	flex-wrap: wrap;
	gap: var(--sp-1) var(--sp-2);
	padding: var(--sp-3) var(--sp-4);
	font-size: 0.8rem;
	line-height: 1.4;
	text-align: center;
	color: var(--text-muted);
}

.privacy-note svg {
	flex: none;
	width: 14px;
	height: 14px;
	fill: none;
	stroke: currentColor;
	stroke-width: 1.9;
	stroke-linecap: round;
	stroke-linejoin: round;
}

.privacy-note .linkbtn {
	font-size: inherit;
}

.disclosure summary {
	font-weight: 600;
	cursor: pointer;
	color: var(--brand-600);
}

.disclosure[open] summary {
	margin-bottom: var(--sp-2);
}

.disclosure .prose>*+* {
	margin-top: var(--sp-2);
}

.callout {
	padding: var(--sp-4);
	color: var(--text-muted);
	background: var(--surface-2);
	border: 1px dashed var(--line-strong);
	border-radius: var(--r-lg);
	text-align: center;
}

.callout--warn {
	color: var(--text);
	background: color-mix(in srgb, var(--danger-500) 8%, var(--surface));
	border: 1px solid color-mix(in srgb, var(--danger-500) 35%, transparent);
	text-align: left;
}

/* --------------------------------------------------------------------------
   12. Bottom tab bar
   -------------------------------------------------------------------------- */

.tabbar {
	position: fixed;
	inset: auto 0 0;
	z-index: 30;
	display: flex;
	background: color-mix(in srgb, var(--surface) 92%, transparent);
	backdrop-filter: saturate(1.6) blur(12px);
	border-top: 1px solid var(--line);
	padding-bottom: env(safe-area-inset-bottom);
}

.tabbar__tab {
	position: relative;
	flex: 1;
	display: grid;
	justify-items: center;
	align-content: center;
	gap: 2px;
	min-height: var(--tabbar-h);
	padding: var(--sp-2) var(--sp-1);
	font-size: min(0.7rem, 15px);
	font-weight: 600;
	color: var(--text-muted);
	background: none;
	border: 0;
	cursor: pointer;
}

.tabbar__tab svg {
	width: 22px;
	height: 22px;
	fill: none;
	stroke: currentColor;
	stroke-width: 1.7;
	stroke-linecap: round;
	stroke-linejoin: round;
}

.tabbar__tab.is-active {
	color: var(--brand-600);
}

.badge {
	position: absolute;
	top: 6px;
	left: 50%;
	margin-left: 6px;
	display: grid;
	place-items: center;
	min-width: max(18px, 1.7em);
	min-height: max(18px, 1.7em);
	padding: 0.1em 5px;
	font-size: 0.65rem;
	font-weight: 700;
	color: #fff;
	background: var(--danger-500);
	border-radius: var(--r-pill);
}

/* --------------------------------------------------------------------------
   13. Lock screen
   -------------------------------------------------------------------------- */

.lock {
	position: fixed;
	inset: 0;
	z-index: 100;
	display: grid;
	place-items: center;
	padding: var(--sp-5) var(--sp-4);
	padding-top: calc(var(--sp-5) + env(safe-area-inset-top));
	padding-bottom: calc(var(--sp-5) + env(safe-area-inset-bottom));
	background: var(--bg);
	overflow-y: auto;
}

.lock__panel {
	display: grid;
	justify-items: center;
	gap: var(--sp-4);
	width: 100%;
	max-width: 20rem;
	text-align: center;
}

/* The logo artwork is dark ink on transparency, so it always sits on a light
   plate rather than inheriting the surface colour. */
.lock__plate {
	padding: var(--sp-3) var(--sp-4);
	background: #fff;
	border-radius: var(--r-lg);
	box-shadow: var(--shadow-2);
}

.lock__plate img {
	width: 100%;
	height: auto;
}

.lock__title {
	font-family: var(--font-serif);
	font-size: 1.35rem;
	font-weight: 600;
}

.lock__message {
	min-height: 2.6em;
	font-size: 0.9rem;
	color: var(--text-muted);
}

.lock__message.is-error {
	color: var(--danger-500);
	font-weight: 600;
}

.pin-dots {
	display: flex;
	gap: var(--sp-3);
	min-height: 16px;
}

.pin-dot {
	width: 14px;
	height: 14px;
	border: 2px solid var(--line-strong);
	border-radius: 50%;
	transition: background-color 0.15s, border-color 0.15s, transform 0.15s;
}

.pin-dot.is-filled {
	background: var(--brand-500);
	border-color: var(--brand-500);
	transform: scale(1.12);
}

.lock__panel.is-shaking {
	animation: shake 0.4s;
}

@keyframes shake {

	0%,
	100% {
		transform: translateX(0);
	}

	20%,
	60% {
		transform: translateX(-9px);
	}

	40%,
	80% {
		transform: translateX(9px);
	}
}

.keypad {
	display: grid;
	grid-template-columns: repeat(3, 1fr);
	gap: var(--sp-3);
	width: 100%;
}

.keypad__key {
	min-height: 62px;
	font-size: 1.5rem;
	font-weight: 500;
	font-variant-numeric: tabular-nums;
	color: var(--text);
	background: var(--surface);
	border: 1px solid var(--line);
	border-radius: var(--r-pill);
	box-shadow: var(--shadow-1);
	cursor: pointer;
	transition: transform 0.08s, background-color 0.15s;
}

.keypad__key:active {
	transform: scale(0.94);
	background: var(--surface-sunk);
}

.keypad__key--muted {
	font-size: 0.9rem;
	font-weight: 600;
	color: var(--text-muted);
	background: none;
	border-color: transparent;
	box-shadow: none;
}

.keypad[data-busy="true"] .keypad__key {
	opacity: 0.45;
	pointer-events: none;
}

/* --------------------------------------------------------------------------
   14. Dialogs
   -------------------------------------------------------------------------- */

.dlg {
	/* The `* { margin: 0 }` reset above overrides the UA stylesheet's
	   `dialog { margin: auto }`, which is what centres a modal inside its
	   inset box. Restore it, and keep the height content-sized so the
	   vertical auto margins have something to centre. */
	margin: auto;
	height: fit-content;
	max-height: calc(100dvh - 2 * var(--sp-5));

	width: min(34rem, calc(100vw - 2 * var(--sp-4)));
	padding: 0;
	color: var(--text);
	background: var(--surface);
	border: 1px solid var(--line);
	border-radius: var(--r-lg);
	box-shadow: var(--shadow-3);
}

.dlg--narrow {
	width: min(24rem, calc(100vw - 2 * var(--sp-4)));
}

.dlg::backdrop {
	background: rgb(6 12 20 / 55%);
	backdrop-filter: blur(3px);
}

.dlg__form {
	display: grid;
	gap: var(--sp-5);
	padding: var(--sp-5);
	max-height: 85dvh;
	overflow-y: auto;
}

.dlg__title {
	font-family: var(--font-serif);
	font-size: 1.35rem;
}

.dlg__section {
	display: grid;
	gap: var(--sp-2);
	justify-items: start;
}

.dlg__heading {
	font-size: 0.6875rem;
	font-weight: 700;
	letter-spacing: 0.1em;
	text-transform: uppercase;
	color: var(--text-muted);
}

.dlg__section+.dlg__section {
	padding-top: var(--sp-4);
	border-top: 1px solid var(--line);
}

.dlg__row {
	display: flex;
	flex-wrap: wrap;
	gap: var(--sp-2);
}

.dlg__row--end {
	justify-content: flex-end;
}

.dlg__footer {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: var(--sp-3);
	padding-top: var(--sp-4);
	border-top: 1px solid var(--line);
}

.dlg__version {
	font-size: 0.8rem;
}

.field {
	display: grid;
	gap: var(--sp-1);
	width: 100%;
}

.field__label {
	font-size: 0.85rem;
	font-weight: 600;
	color: var(--text-muted);
}

.field__input {
	width: 100%;
	min-height: var(--tap);
	padding: 0 var(--sp-3);
	background: var(--surface-2);
	border: 1px solid var(--line-strong);
	border-radius: var(--r-md);
}

input[type="password"].field__input {
	font-size: 1.25rem;
	letter-spacing: 0.3em;
}

/* --------------------------------------------------------------------------
   15. Toast
   -------------------------------------------------------------------------- */

.toast {
	position: fixed;
	left: 50%;
	bottom: calc(var(--tabbar-h) + env(safe-area-inset-bottom) + var(--sp-4));
	z-index: 60;
	min-width: min(20rem, calc(100vw - 2 * var(--sp-4)));
	max-width: calc(100vw - 2 * var(--sp-4));
	padding: var(--sp-4) var(--sp-5);
	font-size: 0.9rem;
	font-weight: 550;
	text-align: center;
	color: var(--text-onbrand);
	background: var(--brand-500);
	border-radius: var(--r-pill);
	box-shadow: var(--shadow-2);
	transform: translate(-50%, 0);
	animation: toast-in 0.24s ease-out;
}

@keyframes toast-in {
	from {
		opacity: 0;
		transform: translate(-50%, 12px);
	}
}

/* --------------------------------------------------------------------------
   16. Wider screens
   -------------------------------------------------------------------------- */

@media (min-width: 40rem) {
	.toolbar {
		grid-template-columns: 1fr auto;
		align-items: center;
	}

	.segmented__btn {
		padding-inline: var(--sp-4);
	}
}

@media (min-width: 52rem) {
	.tabbar {
		position: sticky;
		bottom: var(--sp-4);
		width: min(24rem, 100%);
		margin: 0 auto;
		border: 1px solid var(--line);
		border-radius: var(--r-pill);
		box-shadow: var(--shadow-2);
		overflow: hidden;
	}

	.main {
		padding-bottom: var(--sp-4);
	}

	.toast {
		bottom: calc(var(--tabbar-h) + var(--sp-6));
	}
}

@media print {

	.appbar,
	.tabbar,
	.toolbar,
	.card--about,
	.card--commit,
	.boot-shield,
	.lock {
		display: none !important;
	}

	body {
		background: #fff;
	}

	.card,
	.conf-group {
		border: 0;
		box-shadow: none;
	}
}
