/* Barrie & District Christmas Cheer — shared brand system
   Palette lifted from the organisation's logo: cranberry script, spruce
   lettering, handprint-tree greens and the gold star. */

:root {
	--cheer-red: #d8232a;
	--cheer-red-dark: #ab171d;
	--cheer-red-soft: #fdeceb;
	--cheer-green: #0e7a3c;
	--cheer-green-bright: #3fae49;
	--cheer-green-soft: #e8f5ec;
	--cheer-gold: #f0b429;
	--cheer-gold-soft: #fdf3dc;

	--ink: #1f2421;
	--ink-muted: #5b6560;
	--ink-faint: #8a938e;
	--paper: #fbf8f4;
	--surface: #ffffff;
	--line: #e4ded6;
	--line-strong: #cfc7bc;

	--amber: #b7791f;
	--amber-soft: #fdf3dc;

	--radius: 12px;
	--radius-lg: 18px;
	--shadow-sm: 0 1px 2px rgba(31, 36, 33, 0.06), 0 1px 3px rgba(31, 36, 33, 0.04);
	--shadow: 0 2px 4px rgba(31, 36, 33, 0.05), 0 8px 20px rgba(31, 36, 33, 0.08);

	--font-body: ui-sans-serif, system-ui, -apple-system, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
	--font-display: ui-serif, Georgia, 'Iowan Old Style', 'Times New Roman', serif;

	color-scheme: light;
}

* {
	box-sizing: border-box;
}

html {
	-webkit-text-size-adjust: 100%;
}

body {
	margin: 0;
	background: var(--paper);
	color: var(--ink);
	font-family: var(--font-body);
	font-size: 16px;
	line-height: 1.55;
	-webkit-font-smoothing: antialiased;
}

h1,
h2,
h3 {
	font-family: var(--font-display);
	font-weight: 600;
	line-height: 1.2;
	margin: 0 0 0.4em;
	letter-spacing: -0.01em;
}

h1 {
	font-size: clamp(1.6rem, 4.5vw, 2.2rem);
}
h2 {
	font-size: clamp(1.25rem, 3.4vw, 1.55rem);
}
h3 {
	font-size: 1.08rem;
}

p {
	margin: 0 0 1em;
}

a {
	color: var(--cheer-green);
}

/* --- Layout ------------------------------------------------------------ */

.shell {
	max-width: 780px;
	margin: 0 auto;
	padding: 0 18px 96px;
}

/* The staff portal only. Its pages are wide data tables rather than prose, so
   capping them at reading width left several hundred pixels idle either side
   while the table itself scrolled sideways. */
.shell-wide {
	max-width: 1680px;
}

.site-header {
	background: var(--surface);
	border-bottom: 3px solid var(--cheer-red);
	padding: 18px;
	text-align: center;
}

.site-header img {
	max-width: min(330px, 74vw);
	height: auto;
	display: block;
	margin: 0 auto;
}

.site-header .tagline {
	margin: 10px 0 0;
	color: var(--ink-muted);
	font-size: 0.92rem;
}

.card {
	background: var(--surface);
	border: 1px solid var(--line);
	border-radius: var(--radius-lg);
	box-shadow: var(--shadow-sm);
	padding: clamp(18px, 4vw, 30px);
	margin-bottom: 20px;
}

.card-tight {
	padding: 18px;
}

/* Standfirst under a page title. The staff portal puts the title in its top
   bar, so a view opens on this rather than repeating its own name. */
.lead {
	font-size: 1.02rem;
	color: var(--ink-muted);
	margin: 0 0 20px;
	max-width: 68ch;
}

/* A heading inside a page, set in the body face so it reads as a label rather
   than competing with the display-face page title above it. */
.section-title {
	font-family: var(--font-body);
	font-size: 1.1rem;
	font-weight: 600;
	letter-spacing: 0;
	margin: 0 0 14px;
}

.stack > * + * {
	margin-top: 18px;
}

.row {
	display: flex;
	flex-wrap: wrap;
	gap: 14px;
}

.row > * {
	flex: 1 1 200px;
	min-width: 0;
}

.grid {
	display: grid;
	gap: 14px;
	grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
}

/* --- Forms ------------------------------------------------------------- */

.field {
	display: block;
	margin-bottom: 4px;
}

.field > label,
.label {
	display: flex;
	align-items: center;
	gap: 6px;
	font-weight: 600;
	font-size: 0.93rem;
	margin-bottom: 6px;
	color: var(--ink);
}

/* In a multi-column row some labels run to one line and some to two ("Work
   income" beside "OW, ODSP, CPP, pension or disability"), which left the inputs
   on that row sitting at different heights.

   Each field lends its three parts — label, control, hint — to the parent's own
   row tracks, so every control on a row starts at the same height and so does
   every hint beneath them. Reserving a fixed two lines of label would do the
   same job but would strand short labels miles above their input; this only
   spends the space where a label actually wraps. Without subgrid the fields
   simply keep their natural heights, which is what they did before. */
.grid > .field > label,
.row > .field > label {
	align-items: flex-start;
}

.grid > .field > label > .help,
.row > .field > label > .help {
	margin-top: 1px;
}

/* Only .grid — subgrid needs a grid parent, and .row is a flex container. */
@supports (grid-template-rows: subgrid) {
	.grid > .field {
		display: grid;
		grid-template-rows: subgrid;
		grid-row: span 3;
		gap: 0;
		margin-bottom: 0;
	}
}

/* A red star on its own was easy to miss, so the marker spells it out as a
   small red tag beside the question. */
.required-dot {
	display: inline-block;
	margin-left: 6px;
	padding: 1px 8px;
	border-radius: 999px;
	background: var(--cheer-red-soft);
	color: var(--cheer-red-dark);
	font-size: 0.7rem;
	font-weight: 700;
	letter-spacing: 0.03em;
	line-height: 1.6;
	text-transform: uppercase;
	white-space: nowrap;
	vertical-align: 1px;
}

.required-legend {
	margin: -4px 0 16px;
	font-size: 0.9rem;
	color: var(--ink-muted);
}

input[type='text'],
input[type='email'],
input[type='tel'],
input[type='number'],
input[type='password'],
input[type='search'],
input[type='date'],
select,
textarea {
	width: 100%;
	padding: 12px 13px;
	font: inherit;
	font-size: 16px; /* keeps iOS from zooming on focus */
	color: var(--ink);
	background: var(--surface);
	border: 1.5px solid var(--line-strong);
	border-radius: var(--radius);
	transition: border-color 0.12s ease, box-shadow 0.12s ease;
}

textarea {
	min-height: 96px;
	resize: vertical;
}

input:focus,
select:focus,
textarea:focus {
	outline: none;
	border-color: var(--cheer-green);
	box-shadow: 0 0 0 3px var(--cheer-green-soft);
}

input[aria-invalid='true'],
select[aria-invalid='true'],
textarea[aria-invalid='true'] {
	border-color: var(--cheer-red);
	border-width: 2px;
	background: #fff7f7;
}

.field.is-missing > label,
.field.is-missing > .label {
	color: var(--cheer-red-dark);
}

.field.is-missing::after {
	content: 'This needs an answer';
	display: block;
	margin-top: 6px;
	font-size: 0.84rem;
	font-weight: 600;
	color: var(--cheer-red-dark);
}

.hint {
	font-size: 0.84rem;
	color: var(--ink-muted);
	margin: 6px 0 0;
}

/* Applicant lookup — anywhere staff have to name a person, they pick them from
   the data rather than retyping a number that is easy to get wrong. */
.lookup {
	position: relative;
	flex: 1 1 260px;
}

/* Room for the chevron, so a long name never runs under it. */
.lookup-input {
	padding-right: 40px;
}

/* The picker has its own clear button; the browser's search-box cross would
   sit under the chevron. */
.lookup-input::-webkit-search-cancel-button,
.lookup-input::-webkit-search-decoration {
	-webkit-appearance: none;
	appearance: none;
	display: none;
}

.lookup.has-value .lookup-input {
	padding-right: 74px;
}

.lookup-clear {
	position: absolute;
	top: 0;
	right: 38px;
	height: 100%;
	width: 34px;
	display: none;
	align-items: center;
	justify-content: center;
	border: 0;
	background: none;
	color: var(--ink-muted);
	cursor: pointer;
}

.lookup.has-value .lookup-clear {
	display: flex;
}

.lookup-clear svg {
	width: 16px;
	height: 16px;
}

.lookup-clear:hover {
	color: var(--cheer-red);
}

/* The affordance that says this is a list you can open, not just a box to type
   into. Deliberately looks like a select's caret. */
.lookup-toggle {
	position: absolute;
	top: 0;
	right: 0;
	height: 100%;
	width: 38px;
	display: flex;
	align-items: center;
	justify-content: center;
	border: 0;
	background: none;
	color: var(--ink-muted);
	cursor: pointer;
	border-radius: 0 var(--radius) var(--radius) 0;
}

.lookup-toggle svg {
	width: 18px;
	height: 18px;
}

.lookup-toggle:hover {
	color: var(--cheer-green);
}

.lookup-results {
	position: absolute;
	z-index: 40;
	left: 0;
	right: 0;
	top: calc(100% + 4px);
	max-height: 320px;
	overflow-y: auto;
	background: var(--surface);
	border: 1.5px solid var(--line-strong);
	border-radius: var(--radius);
	box-shadow: var(--shadow);
}

.lookup-item {
	display: flex;
	justify-content: space-between;
	align-items: baseline;
	gap: 10px;
	width: 100%;
	padding: 9px 12px;
	border: 0;
	background: none;
	text-align: left;
	font: inherit;
	color: var(--ink);
	cursor: pointer;
	border-bottom: 1px solid var(--line);
}

.lookup-item:last-child {
	border-bottom: 0;
}

.lookup-item:hover,
.lookup-item.is-active {
	background: var(--cheer-green-soft);
}

.lookup-item .lookup-name {
	font-weight: 600;
}

.lookup-item .lookup-meta {
	font-size: 0.82rem;
	color: var(--ink-muted);
	white-space: nowrap;
}

.lookup-empty {
	padding: 10px 12px;
	font-size: 0.86rem;
	color: var(--ink-muted);
}

/* Help guides: the whole heading is the toggle, so there is no small target to
   hunt for. */
.help-head {
	display: flex;
	justify-content: space-between;
	align-items: flex-start;
	gap: 12px;
	width: 100%;
	padding: 0;
	border: 0;
	background: none;
	font: inherit;
	color: var(--ink);
	text-align: left;
	cursor: pointer;
}

.help-head:hover strong {
	color: var(--cheer-green);
}

.help-steps {
	margin: 0;
	padding-left: 20px;
}

.help-steps li {
	margin-bottom: 7px;
	line-height: 1.5;
}

/* The household total is added up from the answers above it, so it is shown as
   a derived figure rather than a box to type a number into. */
.computed-total {
	display: flex;
	align-items: baseline;
	gap: 10px;
	flex-wrap: wrap;
	padding: 12px 14px;
	background: var(--cheer-green-soft);
	border: 1.5px solid var(--cheer-green);
	border-radius: var(--radius);
}

.computed-total .computed-value {
	font-family: var(--font-display);
	font-size: 1.55rem;
	font-weight: 700;
	line-height: 1.1;
	color: #0a5029;
}

.computed-total .computed-parts {
	font-size: 0.86rem;
	color: #0a5029;
}

/* Every field carries a help bubble — a stated requirement for the rebuild. */
.help {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 18px;
	height: 18px;
	flex: 0 0 18px;
	border-radius: 50%;
	background: var(--cheer-green);
	color: #fff;
	font-size: 11px;
	font-weight: 700;
	font-family: var(--font-body);
	cursor: help;
	border: none;
	padding: 0;
	line-height: 1;
	position: relative;
}

/* The button is drawn at 18px but answers a tap anywhere in a 42px-wide strip
   around it, a fingertip's width. Kept shallow above and below, so it never
   reaches into the control above or the input below. */
.help::after {
	content: '';
	position: absolute;
	top: -4px;
	right: -12px;
	bottom: -8px;
	left: -12px;
}

.help:focus-visible {
	outline: 2px solid var(--cheer-gold);
	outline-offset: 2px;
}

.help-bubble {
	position: fixed;
	z-index: 90;
	max-width: 280px;
	background: var(--ink);
	color: #fff;
	font-size: 0.84rem;
	line-height: 1.45;
	padding: 9px 12px;
	border-radius: 10px;
	box-shadow: var(--shadow);
	pointer-events: none;
}

.money-input {
	position: relative;
}

.money-input::before {
	content: '$';
	position: absolute;
	left: 13px;
	top: 50%;
	transform: translateY(-50%);
	color: var(--ink-faint);
	font-weight: 600;
	pointer-events: none;
}

.money-input input {
	padding-left: 26px;
}

fieldset {
	border: 1px solid var(--line);
	border-radius: var(--radius);
	padding: 14px;
	margin: 0;
}

legend {
	font-weight: 600;
	font-size: 0.93rem;
	padding: 0 6px;
}

.choice {
	display: flex;
	align-items: flex-start;
	gap: 10px;
	padding: 13px 14px;
	border: 1.5px solid var(--line-strong);
	border-radius: var(--radius);
	cursor: pointer;
	background: var(--surface);
	margin-bottom: 9px;
	transition: border-color 0.12s ease, background 0.12s ease;
}

.choice:last-child {
	margin-bottom: 0;
}

.choice:hover {
	border-color: var(--cheer-green-bright);
}

.choice input {
	margin: 3px 0 0;
	width: 18px;
	height: 18px;
	flex: 0 0 18px;
	accent-color: var(--cheer-green);
}

.choice-body strong {
	display: block;
	font-size: 0.95rem;
}

.choice-body span {
	display: block;
	font-size: 0.85rem;
	color: var(--ink-muted);
}

.choice.is-selected {
	border-color: var(--cheer-green);
	background: var(--cheer-green-soft);
}

/* --- Buttons ----------------------------------------------------------- */

.btn {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: 8px;
	padding: 13px 22px;
	min-height: 48px;
	font: inherit;
	font-weight: 600;
	font-size: 0.97rem;
	border-radius: var(--radius);
	border: 1.5px solid transparent;
	cursor: pointer;
	text-decoration: none;
	transition: background 0.12s ease, border-color 0.12s ease, transform 0.06s ease;
}

.btn:active {
	transform: translateY(1px);
}

.btn:disabled {
	opacity: 0.5;
	cursor: not-allowed;
}

.btn-primary {
	background: var(--cheer-red);
	color: #fff;
}
.btn-primary:hover:not(:disabled) {
	background: var(--cheer-red-dark);
}

.btn-approve {
	background: var(--cheer-green);
	color: #fff;
}
.btn-approve:hover:not(:disabled) {
	background: #0a5e2e;
}

/* The card type being scanned at the stuffing table, whatever its colour. */
.btn.is-selected {
	box-shadow: 0 0 0 2px var(--surface), 0 0 0 4px var(--ink);
}

.btn-secondary {
	background: var(--surface);
	color: var(--ink);
	border-color: var(--line-strong);
}
.btn-secondary:hover:not(:disabled) {
	border-color: var(--ink-muted);
}

.btn-ghost {
	background: transparent;
	color: var(--cheer-green);
	border-color: transparent;
	padding: 8px 10px;
	min-height: 40px;
}
.btn-ghost:hover:not(:disabled) {
	background: var(--cheer-green-soft);
}

.btn-danger {
	background: var(--surface);
	color: var(--cheer-red-dark);
	border-color: var(--cheer-red);
}
.btn-danger:hover:not(:disabled) {
	background: var(--cheer-red-soft);
}

.btn-sm {
	padding: 8px 14px;
	min-height: 38px;
	font-size: 0.88rem;
}

.btn-block {
	width: 100%;
}

.btn-row {
	display: flex;
	gap: 12px;
	flex-wrap: wrap;
}

/* --- Status and feedback ----------------------------------------------- */

.note {
	padding: 13px 15px;
	border-radius: var(--radius);
	border-left: 4px solid;
	font-size: 0.92rem;
}

.note-error {
	background: var(--cheer-red-soft);
	border-color: var(--cheer-red);
	color: #7d1116;
}
.note-ok {
	background: var(--cheer-green-soft);
	border-color: var(--cheer-green);
	color: #0a5029;
}
.note-warn {
	background: var(--amber-soft);
	border-color: var(--cheer-gold);
	color: #7c5310;
}
.note-info {
	background: #eef4fb;
	border-color: #3b7cc4;
	color: #1d4f85;
}

.pill {
	display: inline-flex;
	align-items: center;
	gap: 5px;
	padding: 3px 10px;
	border-radius: 999px;
	font-size: 0.78rem;
	font-weight: 600;
	white-space: nowrap;
}

.pill-red {
	background: var(--cheer-red-soft);
	color: #9b1319;
}
.pill-amber {
	background: var(--amber-soft);
	color: var(--amber);
}
.pill-green {
	background: var(--cheer-green-soft);
	color: #0a5e2e;
}
.pill-grey {
	background: #eeeae4;
	color: var(--ink-muted);
}

/* The Stage 2 traffic lights: status, auditor and flag. */
.lights {
	display: inline-flex;
	gap: 4px;
	align-items: center;
}

.light {
	width: 11px;
	height: 11px;
	border-radius: 50%;
	background: var(--line-strong);
	box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.12);
}

.light[data-colour='Red'] {
	background: var(--cheer-red);
}
.light[data-colour='Amber'] {
	background: var(--cheer-gold);
}
.light[data-colour='Green'] {
	background: var(--cheer-green-bright);
}

/* --- Tables ------------------------------------------------------------ */

.table-wrap {
	overflow-x: auto;
	-webkit-overflow-scrolling: touch;
	border: 1px solid var(--line);
	border-radius: var(--radius);
	background: var(--surface);
}

/* A table that must never scroll sideways: the columns share the width it has
   rather than each demanding what its longest cell wants. Content wraps instead,
   which on these pages is always better than losing the right-hand columns. */
.table-fit {
	table-layout: fixed;
	width: 100%;
}

.table-fit th,
.table-fit td {
	overflow-wrap: anywhere;
	white-space: normal;
}

/* Counts stay on one line and centred so a column of them can be read down. */
/* Narrow fixed columns leave no room for a letter-spaced uppercase heading, so
   the headings give the ground up rather than clipping or splitting a word. */
.table-fit th {
	font-size: 0.72rem;
	letter-spacing: 0.01em;
	overflow-wrap: normal;
	word-break: keep-all;
	padding-left: 8px;
	padding-right: 8px;
}

.table-fit .num {
	text-align: center;
	white-space: nowrap;
}

.table-fit th.num {
	white-space: normal;
}

/* Stacked, full-width actions so a cell of buttons cannot force the table wider. */
.table-fit .row-actions {
	display: flex;
	flex-direction: column;
	gap: 4px;
	align-items: stretch;
}

.table-fit .row-actions .btn {
	width: 100%;
	justify-content: center;
	/* The cell may break long data, but never a button's own label: "Withdraw"
	   splitting into "With draw" is worse than any amount of empty space. */
	overflow-wrap: normal;
	word-break: keep-all;
	hyphens: none;
	padding-left: 6px;
	padding-right: 6px;
}

/* Application numbers and card barcodes are long unbroken strings; they may
   wrap mid-token because there is nowhere else to break them. */
.table-fit .mono {
	overflow-wrap: anywhere;
}

table {
	width: 100%;
	border-collapse: collapse;
	font-size: 0.9rem;
}

th,
td {
	text-align: left;
	padding: 11px 13px;
	border-bottom: 1px solid var(--line);
	white-space: nowrap;
}

/* Column headings sort the table (staff.js, makeSortable). */
.th-sort {
	display: inline-flex;
	align-items: center;
	gap: 4px;
	margin: 0;
	padding: 0;
	border: 0;
	background: none;
	font: inherit;
	color: inherit;
	text-transform: inherit;
	letter-spacing: inherit;
	text-align: inherit;
	cursor: pointer;
}
.th-sort::after {
	content: '\2195';
	opacity: 0.35;
	font-size: 0.95em;
}
.th-sort:hover {
	color: var(--ink);
}
.th-sort:hover::after {
	opacity: 0.7;
}
.th-sort:focus-visible {
	outline: 2px solid var(--cheer-gold);
	outline-offset: 2px;
	border-radius: 3px;
}
th[aria-sort='ascending'] .th-sort,
th[aria-sort='descending'] .th-sort {
	color: var(--ink);
}
th[aria-sort='ascending'] .th-sort::after {
	content: '\2191';
	opacity: 1;
}
th[aria-sort='descending'] .th-sort::after {
	content: '\2193';
	opacity: 1;
}

/* Admin > Reminders: the merge-field picker and the previews. */
.insert-field {
	width: auto;
	min-width: 0;
	max-width: 100%;
	min-height: 40px;
	padding: 6px 10px;
	font-size: 0.9rem;
}
.reminder-preview {
	display: grid;
	gap: 6px;
	margin-top: 4px;
}
.reminder-sms {
	max-width: 420px;
	padding: 10px 14px;
	border-radius: 16px 16px 16px 4px;
	background: var(--cheer-green-soft);
	white-space: pre-wrap;
	overflow-wrap: anywhere;
	font-size: 0.95rem;
}
.reminder-email {
	padding: 14px 16px;
	border: 1px solid var(--line);
	border-radius: 10px;
	background: var(--surface);
	font-size: 0.95rem;
}
.reminder-email > div {
	margin-top: 10px;
	white-space: pre-wrap;
	overflow-wrap: anywhere;
}

/* A phone hides the headings of a restacked table, so it sorts from here. */
.sort-bar {
	display: none;
}

th {
	background: #f6f2ec;
	font-weight: 600;
	font-size: 0.82rem;
	text-transform: uppercase;
	letter-spacing: 0.03em;
	color: var(--ink-muted);
	position: sticky;
	top: 0;
	box-shadow: inset 0 -1px 0 var(--line);
}

/* Long queues are read across, so the row under the cursor is picked out. */
tbody tr {
	transition: background 0.1s ease;
}

tbody tr:hover {
	background: #faf7f3;
}

@media (prefers-reduced-motion: reduce) {
	tbody tr {
		transition: none;
	}
}

tbody tr:last-child td {
	border-bottom: none;
}

tbody tr:hover {
	background: #faf7f3;
}

td.wrap {
	white-space: normal;
	min-width: 180px;
}

/* Breaks the label run into the groups the envelopes are staged in, so the
   stuffing team can see where one table's pile ends and the next begins. */
.group-row td {
	background: var(--cheer-green-soft);
	font-weight: 700;
	font-size: 0.78rem;
	text-transform: uppercase;
	letter-spacing: 0.05em;
	color: var(--cheer-green);
	padding-top: 8px;
	padding-bottom: 8px;
}

.group-row:hover td {
	background: var(--cheer-green-soft);
}

/* The labels list: its row buttons sit side by side, so an envelope's row is
   one line high instead of three buttons tall. */
.table-labels .row-actions {
	flex-direction: row;
	flex-wrap: wrap;
	align-items: center;
	gap: 4px;
}

.table-labels .row-actions .btn {
	width: auto;
	flex: 0 0 auto;
	min-height: 32px;
	padding: 4px 8px;
}

/* A row just changed, picked out for a moment after the list is redrawn. */
tr.is-flash > td {
	animation: row-flash 1.8s ease-out;
}

@keyframes row-flash {
	from {
		background: var(--amber-soft);
	}
}

/* --- Tables on a phone --------------------------------------------------
   Nothing scrolls sideways on a phone. A table of four or more columns is
   restacked into one block per row, each value beside its column's name
   (copied onto every cell as data-label by staff.js); a narrower one keeps
   its columns and gives up padding and one-line headings instead. Screen
   only: the printed copies keep their columns. */
@media screen and (max-width: 700px) {
	.stack-table,
	.stack-table > tbody,
	.stack-table > tbody > tr,
	.stack-table > tfoot,
	.stack-table > tfoot > tr {
		display: block;
		width: 100%;
	}

	.stack-table > thead,
	.stack-table > colgroup {
		display: none;
	}

	.sort-bar {
		display: flex;
		justify-content: flex-end;
		margin: 0 0 8px;
		font-size: 0.85rem;
		color: var(--ink-muted);
	}
	.sort-bar label {
		display: flex;
		align-items: center;
		gap: 8px;
		margin: 0;
		max-width: 100%;
	}
	.sort-bar select {
		width: auto;
		min-width: 0;
		max-width: 70vw;
		min-height: 40px;
		padding: 6px 10px;
	}

	.stack-table > tbody > tr {
		padding: 7px 0;
		border-bottom: 1px solid var(--line);
	}

	.stack-table > tbody > tr:last-child {
		border-bottom: none;
	}

	.stack-table > tbody > tr > td,
	.stack-table > tbody > tr > th {
		display: flow-root;
		width: auto;
		min-width: 0;
		padding: 3px 12px 3px 124px;
		border-bottom: none;
		white-space: normal;
		overflow-wrap: anywhere;
		text-align: left;
	}

	/* The column's name sits in the cell's own left padding, so a value that
	   wraps keeps to its side. */
	.stack-table > tbody > tr > td::before {
		content: attr(data-label);
		float: left;
		font-family: var(--font-body);
		width: 102px;
		margin-left: -112px;
		font-size: 0.72rem;
		font-weight: 600;
		text-transform: uppercase;
		letter-spacing: 0.02em;
		line-height: 1.5;
		color: var(--ink-muted);
		overflow-wrap: normal;
		word-break: normal;
	}

	.stack-table > tbody > tr > td[data-label=''],
	.stack-table > tbody > tr > th {
		padding-left: 12px;
	}

	.stack-table > tbody > tr > td[data-label='']::before {
		content: none;
	}

	/* A row's own heading (Compare's field names) leads its block. */
	.stack-table > tbody > tr > th {
		position: static;
		background: none;
		box-shadow: none;
		padding-top: 6px;
	}

	.stack-table .num {
		text-align: left;
	}

	.stack-table .row-actions {
		flex-direction: row;
		flex-wrap: wrap;
		align-items: center;
	}

	.stack-table .row-actions .btn {
		width: auto;
		flex: 0 0 auto;
	}

	.stack-table td.wrap,
	.stack-table td {
		min-width: 0;
	}

	/* A heading with buttons in it stays, one line per column. */
	.stack-table.stack-head > thead,
	.stack-table.stack-head > thead > tr {
		display: block;
	}

	.stack-table.stack-head > thead > tr > th {
		display: block;
		position: static;
		white-space: normal;
		padding: 8px 12px;
	}

	.stack-table.stack-head > thead > tr > th:empty {
		display: none;
	}

	.tight-table th,
	.tight-table td {
		padding: 9px 8px;
		white-space: normal;
		overflow-wrap: anywhere;
	}

	.tight-table th {
		letter-spacing: 0;
		overflow-wrap: normal;
	}

	.tight-table td,
	.tight-table th {
		min-width: 0;
	}

	/* Some boxes carry an inline minimum for the desktop table. */
	.tight-table input,
	.tight-table select,
	.stack-table input,
	.stack-table select {
		min-width: 0 !important;
	}

	.tight-table .bar {
		min-width: 40px;
	}

	/* A long unbroken string (an email address, a web link, a server's error
	   text) breaks rather than pushing the page sideways. */
	body {
		overflow-wrap: break-word;
	}

	.note,
	.hint,
	.small {
		overflow-wrap: anywhere;
	}

	/* A button never sets the width of its row: a long label wraps between
	   its words instead. */
	.btn {
		max-width: 100%;
	}

	.stack-table .btn,
	.tight-table .btn {
		white-space: normal;
		text-align: center;
	}
}

/* --- Stat tiles -------------------------------------------------------- */

.stats {
	display: grid;
	gap: 12px;
	grid-template-columns: repeat(auto-fit, minmax(146px, 1fr));
}

.stat {
	background: var(--surface);
	border: 1px solid var(--line);
	border-radius: var(--radius);
	padding: 15px 16px;
}

.stat .value {
	font-family: var(--font-display);
	font-size: 1.85rem;
	font-weight: 600;
	line-height: 1.1;
	display: block;
}

.stat .label {
	font-size: 0.82rem;
	color: var(--ink-muted);
	margin-top: 3px;
	display: block;
}

/* Year-on-year movement, under a headline figure and inside report tables. */
.delta {
	font-size: 0.74rem;
	color: var(--ink-muted);
}

.stat .delta {
	display: block;
	margin-top: 4px;
}

.delta[data-dir='up'] {
	color: var(--cheer-green);
}

.delta[data-dir='down'] {
	color: var(--cheer-red);
}

.stat-red .value {
	color: var(--cheer-red);
}
.stat-green .value {
	color: var(--cheer-green);
}
.stat-amber .value {
	color: var(--amber);
}

/* --- Progress ---------------------------------------------------------- */

.progress {
	margin: 20px 0 24px;
}

.progress-bar {
	height: 7px;
	background: var(--line);
	border-radius: 999px;
	overflow: hidden;
}

.progress-fill {
	height: 100%;
	background: var(--cheer-green);
	border-radius: 999px;
	transition: width 0.3s ease;
}

.progress-label {
	display: flex;
	justify-content: space-between;
	font-size: 0.85rem;
	color: var(--ink-muted);
	margin-bottom: 8px;
	gap: 12px;
}

.progress-label strong {
	color: var(--ink);
}

/* --- Misc -------------------------------------------------------------- */

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

.small {
	font-size: 0.85rem;
}

.mono {
	font-family: ui-monospace, SFMono-Regular, 'SF Mono', Menlo, Consolas, monospace;
}

.divider {
	height: 1px;
	background: var(--line);
	border: 0;
	margin: 22px 0;
}

.center {
	text-align: center;
}

.hidden {
	display: none !important;
}

/* The browser's own [hidden] rule loses to any display set here (.field is
   display: block), which left hidden questions showing. */
[hidden] {
	display: none !important;
}

.spinner {
	width: 17px;
	height: 17px;
	border: 2.5px solid rgba(255, 255, 255, 0.35);
	border-top-color: #fff;
	border-radius: 50%;
	animation: spin 0.7s linear infinite;
}

@keyframes spin {
	to {
		transform: rotate(360deg);
	}
}

@media print {
	.no-print {
		display: none !important;
	}
	body {
		background: #fff;
	}
	.card {
		box-shadow: none;
		border: 1px solid #999;
		break-inside: avoid;
	}
	/* A wide table fits the page on paper instead of being clipped behind a
	   scrollbar nobody can use: headings wrap, cells are packed closer and a
	   name column gives up its screen minimum. */
	.table-wrap {
		overflow: visible;
	}
	.table-wrap th,
	.table-wrap td {
		white-space: normal;
		padding: 6px 7px;
	}
	.table-wrap th {
		letter-spacing: 0;
	}
	.table-wrap td.wrap {
		min-width: 0;
	}
}

/* --- In-app dialogs and toasts ----------------------------------------- */
/* Replaces window.alert / confirm / prompt so the portal never hands the
   viewer a browser chrome popup. */

.dialog-backdrop {
	position: fixed;
	inset: 0;
	background: rgba(31, 36, 33, 0.5);
	z-index: 200;
	display: flex;
	align-items: center;
	justify-content: center;
	padding: 18px;
	animation: dialog-fade 0.12s ease;
}

@keyframes dialog-fade {
	from {
		opacity: 0;
	}
}

.dialog {
	background: var(--surface);
	border-radius: var(--radius-lg);
	box-shadow: 0 18px 50px rgba(31, 36, 33, 0.28);
	width: min(460px, 100%);
	max-height: 90vh;
	overflow-y: auto;
	padding: 22px;
	animation: dialog-rise 0.14s ease;
}

@keyframes dialog-rise {
	from {
		transform: translateY(10px);
		opacity: 0;
	}
}

.dialog h2 {
	margin: 0 0 8px;
	font-size: 1.2rem;
}

.dialog .dialog-body {
	font-size: 0.95rem;
	color: var(--ink-muted);
	margin: 0 0 16px;
	white-space: pre-wrap;
	word-break: break-word;
}

.dialog .dialog-body strong {
	color: var(--ink);
}

.dialog input[type='text'],
.dialog input[type='password'] {
	margin-bottom: 4px;
}

.dialog-actions {
	display: flex;
	gap: 10px;
	justify-content: flex-end;
	flex-wrap: wrap;
	margin-top: 18px;
}

.dialog-actions .btn {
	min-width: 104px;
}

.dialog-icon {
	width: 38px;
	height: 38px;
	border-radius: 50%;
	display: flex;
	align-items: center;
	justify-content: center;
	font-size: 20px;
	font-weight: 700;
	margin-bottom: 12px;
}

.dialog-icon[data-tone='danger'] {
	background: var(--cheer-red-soft);
	color: var(--cheer-red);
}
.dialog-icon[data-tone='warn'] {
	background: var(--amber-soft);
	color: var(--amber);
}
.dialog-icon[data-tone='ok'] {
	background: var(--cheer-green-soft);
	color: var(--cheer-green);
}
.dialog-icon[data-tone='info'] {
	background: #eef4fb;
	color: #1d4f85;
}

.toast-host {
	position: fixed;
	bottom: 18px;
	right: 18px;
	z-index: 210;
	display: flex;
	flex-direction: column;
	gap: 9px;
	max-width: min(370px, calc(100vw - 36px));
}

.toast {
	background: var(--surface);
	border: 1px solid var(--line);
	border-left: 4px solid var(--cheer-green);
	border-radius: var(--radius);
	box-shadow: var(--shadow);
	padding: 12px 15px;
	font-size: 0.9rem;
	animation: toast-in 0.16s ease;
}

.toast[data-tone='error'] {
	border-left-color: var(--cheer-red);
}
.toast[data-tone='warn'] {
	border-left-color: var(--cheer-gold);
}

.toast.is-leaving {
	animation: toast-out 0.2s ease forwards;
}

@keyframes toast-in {
	from {
		transform: translateX(16px);
		opacity: 0;
	}
}

@keyframes toast-out {
	to {
		transform: translateX(16px);
		opacity: 0;
	}
}

/* --- Admin sub-navigation ---------------------------------------------- */

.subtabs {
	display: flex;
	gap: 6px;
	flex-wrap: wrap;
	margin-bottom: 20px;
	border-bottom: 1px solid var(--line);
	padding-bottom: 12px;
}

.subtab {
	padding: 8px 14px;
	border: 1.5px solid var(--line-strong);
	background: var(--surface);
	border-radius: 999px;
	font: inherit;
	font-size: 0.88rem;
	font-weight: 600;
	color: var(--ink-muted);
	cursor: pointer;
	white-space: nowrap;
}

.subtab:hover {
	border-color: var(--cheer-green-bright);
}

.subtab.is-active {
	background: var(--cheer-green);
	border-color: var(--cheer-green);
	color: #fff;
}

.danger-zone {
	border-color: var(--cheer-red);
	background: linear-gradient(180deg, var(--cheer-red-soft) 0%, var(--surface) 90px);
}

/* Open escalations on the Distribution screen */
.esc-summary {
	cursor: pointer;
}

.esc-open {
	border-left: 4px solid var(--cheer-red);
}

/* --- Sponsor credit ---------------------------------------------------- */
/* "Powered by [logo] VettaTech": under the public form and at the foot of
   the staff sidebar. Kept small and quiet, and never printed. The gradient
   matches the VettaTech wordmark. */
.powered-by {
	display: inline-flex;
	align-items: center;
	gap: 5px;
	font-size: 0.74rem;
	line-height: 1;
	color: var(--ink-faint);
	text-decoration: none;
	opacity: 0.85;
	transition: opacity 0.15s ease;
}

.powered-by:hover,
.powered-by:focus-visible {
	opacity: 1;
}

.powered-by img {
	display: block;
	width: auto;
	height: 13px;
	/* The V's point sits on the text baseline; its tail rises past the caps. */
	position: relative;
	top: -1px;
}

.powered-by strong {
	font-weight: 700;
	color: #40bcc2;
}

@supports ((-webkit-background-clip: text) or (background-clip: text)) {
	.powered-by strong {
		background: linear-gradient(90deg, #36c1e0, #4cb8a4);
		-webkit-background-clip: text;
		background-clip: text;
		-webkit-text-fill-color: transparent;
	}
}

.site-credit {
	text-align: center;
	margin: 34px 0 0;
}

@media print {
	.powered-by,
	.site-credit {
		display: none !important;
	}
}

/* "Primary Applicant Name" above the applicant's own name boxes (Ian, 2026-11-08). */
.form-subhead {
	font-size: 1.05rem;
	margin: 4px 0 10px;
	color: var(--ink, inherit);
}
