/**
 * WIZSP Design Language — the member portal on the public site.
 *
 * The portal is a theme surface, not a backoffice one, so it follows the public
 * theme patterns: the navy block for the one thing the reader came to find,
 * white cards on a #F8FAFC ground, borders instead of shadows, and body copy at
 * theme size rather than backoffice size.
 *
 * Everything is scoped under .sot-portal because this markup lands inside
 * whatever theme the association runs.
 *
 * @package MA62_Treasury
 */

/*
 * No card, and the width the page gives it.
 *
 * It used to draw a bordered white box 720px wide, centred, which is the right
 * shape for a plugin that cannot know what it lands in — and the wrong one
 * here, where the theme already draws a white page with its own container. The
 * result was a box inside a box, and a statement of five columns squeezed into
 * two thirds of the room the page had. It now sits on the page itself: no
 * border, no ground of its own, and as wide as it is given.
 */
.sot-portal {
	color: var(--wizspTextPrimary);
	font-family: var(--wizspFontFamily);
	font-size: 16px;
	line-height: 1.6;
	margin: 0 0 var(--wizspSpace6);
	max-width: none;
	width: 100%;
}

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

.sot-portal h2 {
	color: var(--wizspTextPrimary);
	font-family: var(--wizspFontFamily);
	font-size: var(--wizspSizeHeading);
	font-weight: var(--wizspWeightHeavy);
	letter-spacing: -0.01em;
	line-height: 1.25;
	margin: 0 0 var(--wizspSpace2);
}

.sot-portal h3 {
	color: var(--wizspTextPrimary);
	font-size: var(--wizspSizeSection);
	font-weight: var(--wizspWeightBold);
	margin: var(--wizspSpace5) 0 var(--wizspSpace3);
}

/*
 * Nothing inside the portal is narrower than the portal.
 *
 * The prose used to be capped at 75 characters, which is the right measure for
 * an article and the wrong one here: on a wide page the paragraphs ended two
 * thirds across while the table beside them ran to the edge, and the block
 * read as though it had not finished loading. Every child now takes the width
 * it is given; the lines that matter on this page are short anyway.
 */
.sot-portal p {
	margin: 0 0 var(--wizspSpace3);
}

/* ------------------------------------------------------------------- Head */

.sot-portal__head {
	border-bottom: var(--wizspHairline);
	margin-bottom: var(--wizspSpace5);
	padding-bottom: var(--wizspSpace4);
}

/*
 * The association's name is the eyebrow above the member's own name: small,
 * spaced, muted. It identifies the sender of the statement, not its subject.
 */
.sot-portal__association {
	color: var(--wizspTextMuted);
	font-size: var(--wizspSizeMicro);
	font-weight: var(--wizspWeightBold);
	letter-spacing: 0.05em;
	margin: 0 0 var(--wizspSpace2);
	text-transform: uppercase;
}

.sot-portal__small {
	color: var(--wizspTextSecondary);
	font-size: var(--wizspSizeControl);
	margin: 0;
}

/* ---------------------------------------------------------------- Balance */

/*
 * The one thing the member opened the link to read. It gets the navy block —
 * the single dark highlight the design language allows per surface — except
 * when money is owed, where the amount is a real danger state and says so.
 */
.sot-portal__balance {
	background: var(--wizspPrimaryBase);
	border: 1px solid var(--wizspPrimaryBase);
	border-radius: var(--wizspRadiusLg);
	margin-bottom: var(--wizspSpace5);
	padding: var(--wizspSpace5);
}

.sot-portal__amount {
	color: #ffffff;
	display: block;
	font-size: var(--wizspSizeDisplay);
	font-variant-numeric: tabular-nums;
	font-weight: var(--wizspWeightHeavy);
	line-height: 1.15;
}

.sot-portal__balance p {
	color: rgba( 255, 255, 255, 0.78 );
	font-size: var(--wizspSizeControl);
	margin: var(--wizspSpace2) 0 0;
}

.sot-portal__balance--owed {
	background: var(--wizspDangerWash);
	border-color: var(--wizspStatusDanger);
}

.sot-portal__balance--owed .sot-portal__amount {
	color: var(--wizspStatusDanger);
}

.sot-portal__balance--owed p {
	color: var(--wizspStatusDanger);
}

.sot-portal__balance--credit {
	background: var(--wizspSuccessWash);
	border-color: var(--wizspStatusSuccess);
}

.sot-portal__balance--credit .sot-portal__amount,
.sot-portal__balance--credit p {
	color: var(--wizspStatusSuccess);
}

/* Nothing owed is not an achievement to celebrate in colour: it is the navy. */
.sot-portal__balance--clear .sot-portal__amount {
	color: #ffffff;
}

/* ------------------------------------------------------------------ Table */

.sot-portal__table {
	border-collapse: collapse;
	font-size: var(--wizspSizeBody);
	table-layout: fixed;
	width: 100%;
}

.sot-portal__table th,
.sot-portal__table td {
	border-bottom: var(--wizspHairline);
	padding: var(--wizspSpace3) var(--wizspSpace2);
	text-align: left;
}

.sot-portal__table thead th {
	color: var(--wizspTextMuted);
	font-size: var(--wizspSizeMicro);
	font-weight: var(--wizspWeightBold);
	letter-spacing: 0.04em;
	text-transform: uppercase;
	white-space: nowrap;
}

/*
 * Money aligns right here too, and for the third time this had to be written
 * against the table as well as against the cell: the rule giving every cell in
 * this table its padding sets text-align:left with the same specificity and
 * stands above, so a plain .sot-portal__num lost on order and the member's own
 * statement read left-aligned. It shows on a wide page more than a narrow one,
 * which is how it came to light.
 */
.sot-portal__num,
.sot-portal__table th.sot-portal__num,
.sot-portal__table td.sot-portal__num {
	font-variant-numeric: tabular-nums;
	text-align: right;
	white-space: nowrap;
}

/*
 * The columns are apportioned rather than left to the width of their digits,
 * which on a wide page left a gulf of blank between the description and the
 * first figure. Only above the stacking breakpoint: below it every cell is a
 * line of its own, and a width here would make each one a sixth of the row.
 */
@media screen and ( min-width: 601px ) {

	.sot-portal__table th:first-child,
	.sot-portal__table td:first-child {
		width: 12%;
	}

	.sot-portal__table th.sot-portal__num,
	.sot-portal__table td.sot-portal__num {
		width: 15%;
	}

	/*
	 * The receipt column needs a share of its own. It was given the width of
	 * its contents, which under a fixed layout is none at all — the other
	 * columns had already been apportioned the whole table — and the buttons
	 * were cut off at the right edge of the page.
	 */
	.sot-portal__table th.sot-portal__receipt,
	.sot-portal__table td.sot-portal__receipt {
		width: 11%;
	}
}

.sot-portal__table td.sot-portal__num {
	color: var(--wizspTextPrimary);
}

/* On a telephone each entry becomes a stack of labelled lines. */
@media screen and ( max-width: 600px ) {

	.sot-portal__table thead {
		clip: rect( 0 0 0 0 );
		height: 1px;
		overflow: hidden;
		position: absolute;
		width: 1px;
	}

	.sot-portal__table tr {
		border-bottom: var(--wizspHairline);
		display: block;
		padding: var(--wizspSpace3) 0;
	}

	.sot-portal__table td {
		border: 0;
		display: flex;
		gap: var(--wizspSpace3);
		justify-content: space-between;
		padding: 3px 0;
		text-align: right;
	}

	/*
	 * A stacked row prints its own labels, so an empty cell would announce a
	 * heading with nothing under it — "You paid" against a blank. On a phone
	 * the line is simply absent instead.
	 */
	.sot-portal__table td:empty {
		display: none;
	}

	.sot-portal__table td::before {
		color: var(--wizspTextSecondary);
		content: attr( data-label );
		font-size: var(--wizspSizeControl);
		font-weight: var(--wizspWeightMedium);
		text-align: left;
	}

	.sot-portal__table td:first-child {
		font-weight: var(--wizspWeightBold);
	}
}

/* ------------------------------------------------------------------- Form */

/*
 * The one thing that does not take the full width. An email address is a short
 * line, and a field stretched across a wide page is harder to aim at, not
 * easier. Everything else on the portal is a figure or a table and reads
 * better with the room.
 */
.sot-portal__form {
	margin: 0 0 var(--wizspSpace4);
	max-width: 420px;
}

.sot-portal__form label {
	color: var(--wizspTextSecondary);
	display: block;
	font-size: var(--wizspSizeLabel);
	font-weight: var(--wizspWeightMedium);
	margin-bottom: var(--wizspSpace2);
}

.sot-portal input[type="email"] {
	background: var(--wizspSurface);
	border: var(--wizspHairline);
	border-radius: var(--wizspRadiusSm);
	color: var(--wizspTextPrimary);
	display: block;
	font-family: var(--wizspFontFamily);
	font-size: var(--wizspSizeBody);
	line-height: 1.4;
	margin-bottom: var(--wizspSpace3);
	padding: 12px;
	width: 100%;
}

.sot-portal input[type="email"]:focus {
	border-color: var(--wizspPrimaryBase);
	outline: 0;
}

.sot-portal button {
	background: var(--wizspPrimaryBase);
	border: 1px solid var(--wizspPrimaryBase);
	border-radius: var(--wizspRadiusSm);
	color: #ffffff;
	cursor: pointer;
	font-family: var(--wizspFontFamily);
	font-size: var(--wizspSizeControl);
	font-weight: var(--wizspWeightBold);
	line-height: 1.4;
	padding: 12px 18px;
}

.sot-portal__form button {
	width: 100%;
}

.sot-portal button:hover {
	background: var(--wizspPrimaryHover);
	border-color: var(--wizspPrimaryHover);
}

.sot-portal button:active {
	background: var(--wizspPrimaryActive);
	border-color: var(--wizspPrimaryActive);
}

.sot-portal button:focus-visible,
.sot-portal input:focus-visible {
	outline: 2px solid var(--wizspPrimaryBase);
	outline-offset: 2px;
}

/*
 * Leaving is a secondary act next to printing, and printing is itself
 * secondary on this page: the statement is the primary thing, so neither
 * button competes with it for the one filled action.
 */
.sot-portal__actions {
	border-top: var(--wizspHairline);
	display: flex;
	flex-wrap: wrap;
	gap: var(--wizspSpace2);
	margin-top: var(--wizspSpace5);
	padding-top: var(--wizspSpace4);
}

.sot-portal__actions .sot-portal__print,
.sot-portal__actions .sot-portal__print:hover {
	background: var(--wizspPrimaryBase);
	border-color: var(--wizspPrimaryBase);
	color: #ffffff;
}

.sot-portal__actions .sot-portal__print:hover {
	background: var(--wizspPrimaryHover);
	border-color: var(--wizspPrimaryHover);
}

.sot-portal__actions button,
.sot-portal__logout button {
	background: var(--wizspSurface);
	border-color: var(--wizspBorder);
	color: var(--wizspTextPrimary);
	font-weight: var(--wizspWeightMedium);
	width: auto;
}

.sot-portal__actions button:hover,
.sot-portal__logout button:hover {
	background: var(--wizspPageBackground);
	border-color: var(--wizspTextMuted);
}

.sot-portal__logout {
	display: inline;
}

/* --------------------------------------------------------------- Messages */

.sot-portal__notice {
	background: var(--wizspSurface);
	border: var(--wizspHairline);
	border-left: 3px solid var(--wizspPrimaryBase);
	border-radius: var(--wizspRadiusSm);
	color: var(--wizspTextSecondary);
	font-size: var(--wizspSizeControl);
	margin: 0 0 var(--wizspSpace4);
	padding: var(--wizspSpace3) var(--wizspSpace4);
}

.sot-portal__notice--warn {
	border-left-color: var(--wizspStatusWarning);
	color: var(--wizspStatusWarning);
}

/* --------------------------------------------------------------- Figures */

/*
 * The association-wide summary. Read by an officer, not a member, and never
 * shown on a page a member can reach — see the shortcode's capability check.
 */
.sot-portal__figures {
	display: grid;
	gap: var(--wizspSpace3);
	grid-template-columns: repeat( auto-fit, minmax( 180px, 1fr ) );
	margin-bottom: var(--wizspSpace4);
}

.sot-portal__figure {
	background: var(--wizspSurface);
	border: var(--wizspHairline);
	border-radius: var(--wizspRadiusLg);
	display: flex;
	flex-direction: column;
	gap: var(--wizspSpace1);
	padding: var(--wizspSpace4);
}

.sot-portal__figure span {
	color: var(--wizspTextSecondary);
	font-size: var(--wizspSizeLabel);
}

.sot-portal__figure strong {
	color: var(--wizspTextPrimary);
	font-size: var(--wizspSizeHeading);
	font-variant-numeric: tabular-nums;
	font-weight: var(--wizspWeightHeavy);
}

/*
 * The paper copy of the account, which exists only on paper.
 *
 * The member reads the association's own theme on screen; what comes out of
 * his printer is the lodge's letterhead, the same sheet a report is printed
 * on. Both are built from one array of entries, so they cannot disagree, and
 * exactly one of them is ever visible.
 */
.sot-portal__sheet {
	display: none;
}

/* The link to the receipt beside the line that records the money. */
.sot-portal__receipt {
	text-align: right;
	white-space: nowrap;
}

/*
 * The two shapes a control takes here. Filled navy is the thing to do —
 * print this, open the receipt, see how to pay; outlined white is the way
 * back and the way out. Nothing on this page is filled that is not an action
 * the member came to take.
 */
.sot-portal__receipt a,
.sot-portal__pay {
	background: var(--wizspPrimaryBase);
	border: 1px solid var(--wizspPrimaryBase);
	border-radius: var(--wizspRadiusSm);
	color: #ffffff;
	cursor: pointer;
	display: inline-block;
	font-family: var(--wizspFontFamily);
	font-size: var(--wizspSizeControl);
	font-weight: var(--wizspWeightBold);
	line-height: 1.4;
	padding: 6px 12px;
	text-decoration: none;
}

.sot-portal__receipt a:hover,
.sot-portal__pay:hover {
	background: var(--wizspPrimaryHover);
	border-color: var(--wizspPrimaryHover);
	color: #ffffff;
}

/* The button under a balance shown in danger red keeps its own navy. */
.sot-portal__pay {
	margin-top: var(--wizspSpace4);
	padding: 10px 16px;
}

.sot-portal__button {
	background: var(--wizspSurface);
	border: 1px solid var(--wizspBorder);
	border-radius: var(--wizspRadiusSm);
	color: var(--wizspTextPrimary);
	display: inline-block;
	font-family: var(--wizspFontFamily);
	font-size: var(--wizspSizeControl);
	font-weight: var(--wizspWeightMedium);
	line-height: 1.4;
	padding: 12px 18px;
	text-decoration: none;
}

.sot-portal__button:hover {
	background: var(--wizspPageBackground);
	border-color: var(--wizspTextMuted);
	color: var(--wizspTextPrimary);
}

/* --------------------------------------------------------- Ways to pay */

.sot-portal__dialog {
	background: var(--wizspSurface);
	border: var(--wizspHairline);
	border-radius: var(--wizspRadiusLg);
	color: var(--wizspTextPrimary);
	font-family: var(--wizspFontFamily);
	font-size: var(--wizspSizeBody);
	line-height: 1.6;
	max-width: 46rem;
	padding: var(--wizspSpace5);
	width: calc( 100% - 2rem );
}

.sot-portal__dialog::backdrop {
	background: rgba( 15, 23, 42, 0.55 );
}

.sot-portal__dialog h3 {
	margin: 0 0 var(--wizspSpace3);
}

.sot-portal__dialog code {
	font-size: var(--wizspSizeControl);
	letter-spacing: 0.02em;
}

.sot-portal__dialog form {
	margin-top: var(--wizspSpace4);
}

@media print {
	.sot-no-print {
		display: none !important;
	}

	/*
	 * On paper the sheet is the page and nothing else is. The theme's header,
	 * the page's own title and the site footer are not part of a document the
	 * lodge issues, and they were printing around it. The sheet is echoed at
	 * the foot of the body, so it is a child of the body itself and everything
	 * that is not it can be hidden by one rule that names no theme.
	 */
	body > *:not(.sot-portal__sheet) {
		display: none !important;
	}

	.sot-portal__sheet {
		display: block;
	}

	.sot-portal {
		border: 0;
		max-width: none;
		padding: 0;
	}

	.sot-portal__balance {
		background: transparent;
		border: var(--wizspHairline);
	}

	.sot-portal__amount,
	.sot-portal__balance p {
		color: var(--wizspTextPrimary);
	}
}
