/**
 * Newsletter subscribe modal. Global (every page). Sizing/spacing values
 * verified against the exact literal CSS in Design Refrance's TSI
 * About.html (grepped directly) after a user spot-check caught the first
 * version was approximated rather than exact (wrong overlay tint, card
 * width, border-radius, several literal font-sizes that don't map cleanly
 * onto the token scale — kept as literals for those, per explicit
 * pixel-fidelity request).
 *
 * Every COLOR below is a var() — none of this modal's own neutral palette
 * (muted text, field backgrounds, borders) is close enough to an existing
 * sitewide --color-ink-mid/--color-line token to reuse it without visibly
 * drifting off that same confirmed-exact reference, so each one got its
 * own dedicated --color-modal-* token in variables.css instead of being
 * repeated here as raw hex. The one unavoidable exception: the <select>
 * chevron's SVG data-URI below has its stroke color baked into the
 * encoded string itself — a CSS var() cannot be interpolated inside a
 * url(), and that SVG has no live DOM presence for `currentColor` to
 * resolve against either, so that one stays a literal hex by necessity,
 * not oversight.
 */

.ui-sub-ov {
	position: fixed;
	inset: 0;
	z-index: var(--z-modal);
	background: var(--color-modal-overlay);
	display: none;
	align-items: center;
	justify-content: center;
	padding: 24px;
	opacity: 0;
	transition: opacity 0.2s ease;
	overscroll-behavior: contain;
}

.ui-sub-ov.open {
	display: flex;
	opacity: 1;
}

.ui-sub-card {
	width: 560px;
	max-width: 100%;
	max-height: 90vh;
	max-height: 90dvh;
	background: var(--color-white);
	border-radius: 10px;
	overflow: hidden;
	box-shadow: 0 30px 80px rgba(0, 0, 0, 0.45);
	position: relative;
	font-family: var(--font-primary);
	display: flex;
	flex-direction: column;
}

.ui-sub-card .head {
	background: var(--color-white);
	padding: 34px 40px 12px;
	position: relative;
	flex-shrink: 0;
}

.ui-sub-card .head .kk {
	font-size: 10.5px;
	font-weight: 700;
	letter-spacing: 3px;
	text-transform: uppercase;
	color: var(--color-modal-muted);
}

.ui-sub-card .head .tt {
	font-family: var(--font-secondary);
	font-weight: 800;
	font-size: 28px;
	color: var(--color-ink);
	margin-top: 8px;
	line-height: 1.1;
}

.ui-sub-card .head .ds {
	font-size: 12.5px;
	color: var(--color-modal-muted);
	margin-top: 8px;
	line-height: 1.5;
}

.ui-sub-card .x {
	position: absolute;
	top: 16px;
	right: 18px;
	font-size: 20px;
	color: var(--color-modal-muted);
	background: none;
	border: 0;
	cursor: pointer;
	z-index: 10;
}

.ui-sub-card .x:hover,
.ui-sub-card .x:focus-visible {
	color: var(--color-ink);
}

.ui-sub-card .body {
	padding: 16px 40px 34px;
	overflow-y: auto;
	-webkit-overflow-scrolling: touch;
	flex: 1 1 auto;
}

.ui-sub-card .fld {
	margin-bottom: 16px;
}

/* :not(.seg-opt, .plan-opt, .chk) is load-bearing, not decorative: this
   selector's specificity (2 classes + a type selector) is HIGHER than
   .seg-opt/.plan-opt/.chk's own rules (2 classes only), so without this
   exclusion its "display: block" silently won over their own "display:
   flex"/"grid" — those 3 are also <label> elements nested inside a .fld,
   so this generic rule was matching them too. That's what was actually
   causing the plan price text to wrap back underneath the radio, and the
   checkbox/segmented control to never quite align right, no matter how
   the -opt/.chk rules themselves were tuned. */
.ui-sub-card .fld label:not(.seg-opt):not(.plan-opt):not(.chk) {
	display: block;
	font-size: 11px;
	font-weight: 700;
	letter-spacing: 1.2px;
	text-transform: uppercase;
	color: var(--color-modal-text-dark);
}

.ui-sub-card .fld input:not([type="radio"]):not([type="checkbox"]),
.ui-sub-card .fld select,
.ui-sub-card .fld textarea {
	width: 100%;
	font-family: var(--font-primary);
	font-size: 14px;
	color: var(--color-ink);
	background: var(--color-modal-field-bg);
	border: 1.5px solid var(--color-modal-border);
	border-radius: 6px;
	padding: 11px 14px;
	outline: none;
}

.ui-sub-card .fld textarea {
	resize: vertical;
	min-height: 56px;
	line-height: 1.5;
}

.ui-sub-card .fld .fld-note {
	text-transform: none;
	font-weight: 400;
	letter-spacing: 0;
	color: var(--color-modal-muted);
}

/* ── Sign-up type / Plan — segmented + card radio groups ───────────────── */

.ui-sub-card .seg-group,
.ui-sub-card .plan-group {
	display: flex;
	gap: 8px;
}

.ui-sub-card .seg-group {
	background: var(--color-modal-field-bg);
	border: 1.5px solid var(--color-modal-border);
	border-radius: 8px;
	padding: 4px;
}

.ui-sub-card .seg-opt {
	flex: 1 1 0;
	display: flex;
	align-items: center;
	justify-content: center;
	text-align: center;
	font-size: 12.5px;
	font-weight: 700;
	letter-spacing: 0.4px;
	line-height: 1;
	color: var(--color-modal-text-soft);
	/* Equal on every side — the previous 9px/10px pairing looked lopsided
	   once the segment's own line-height was added on top of it. */
	padding: 12px 14px;
	border-radius: 6px;
	cursor: pointer;
	transition: background-color 0.15s ease, color 0.15s ease, box-shadow 0.15s ease;
}

.ui-sub-card .seg-opt:hover {
	color: var(--color-ink);
}

.ui-sub-card .seg-opt input {
	position: absolute;
	opacity: 0;
	width: 0;
	height: 0;
}

.ui-sub-card .seg-opt input:checked + span {
	color: var(--color-ink);
}

.ui-sub-card .seg-opt:has(input:checked) {
	background: var(--color-accent);
	/* rgba(28, 38, 32, .15) was literally var(--color-ink) at 15% alpha,
	   just spelled out as its own separate hardcoded triplet instead of
	   reusing the actual Customizer-managed color it was copied from —
	   color-mix() lets it stay a genuine reference, not a frozen copy that
	   silently drifts out of sync if Text Color is ever changed. */
	box-shadow: 0 1px 3px color-mix(in srgb, var(--color-ink) 15%, transparent);
}

.ui-sub-card .seg-opt:has(input:focus-visible) {
	box-shadow: 0 0 0 2px var(--color-primary);
}

.ui-sub-card .seg-group.is-invalid {
	border-color: var(--color-error);
}

.ui-sub-card .plan-group {
	flex-direction: column;
}

/* Radio strictly in its own left column, all text strictly in its own
   right column — the name and price stack as two rows inside that SAME
   right column, so the price line can never end up spanning back under
   the radio (what a flex "space-between" row does the moment the price
   text is too long to fit next to the name and wraps). The radio only
   occupies row 1's column-1 cell (not both rows), so it lines up with —
   and is vertically centered against — the name line specifically, not
   the combined height of both lines. */
.ui-sub-card .plan-opt {
	display: grid;
	grid-template-columns: 18px 1fr;
	column-gap: 12px;
	font-size: 13.5px;
	background: var(--color-modal-field-bg);
	border: 1.5px solid var(--color-modal-border);
	border-radius: 6px;
	padding: 12px 14px;
	cursor: pointer;
	transition: border-color 0.15s ease, background-color 0.15s ease;
}

.ui-sub-card .plan-opt input {
	grid-column: 1;
	grid-row: 1;
	align-self: center;
	margin: 0;
	width: 18px;
	height: 18px;
	accent-color: var(--color-primary);
}

.ui-sub-card .plan-opt-name {
	grid-column: 2;
	grid-row: 1;
	font-weight: 700;
	color: var(--color-ink);
}

.ui-sub-card .plan-opt-price {
	grid-column: 2;
	grid-row: 2;
	margin-top: 4px;
	font-size: 12px;
	color: var(--color-modal-text-soft);
}

.ui-sub-card .plan-opt:has(input:checked) {
	border-color: var(--color-primary);
	background: var(--color-primary-wash);
}

.ui-sub-card .plan-group.is-invalid .plan-opt {
	border-color: var(--color-error);
}

/* Small footnote under the Plan field — matches the paper form's own
   highlighted "Nationwide postage is via Pos Malaysia's regular mail"
   note directly under Hardcopies/the plan options. */
.ui-sub-card .fld-hint {
	margin: 8px 0 0;
	font-size: 12px;
	font-weight: 700;
	line-height: 1.5;
	color: var(--color-modal-text-dark);
}

/* ── Contact number — Landline / Mobile side by side, like the paper
   form's "(L) | (M)" ──────────────────────────────────────────────────── */

.ui-sub-card .contact-row {
	display: flex;
	gap: 10px;
}

.ui-sub-card .contact-col {
	flex: 1 1 0;
}

/* ── Terms & Conditions checkbox ────────────────────────────────────────── */

.ui-sub-card .fld-terms {
	margin-bottom: 12px;
}

.ui-sub-card .chk {
	/* Grid, not flex — pins the checkbox to its own fixed column so it
	   never drifts out of alignment with the text next to it. align-items:
	   center (not "start") is deliberate: this row is realistically always
	   one line ("I agree to the Terms & Conditions and Notice"), so
	   centering the checkbox against the FULL row is the same as centering
	   it against that one line — and stays correct even if it ever wraps
	   to two lines on a very narrow screen. */
	display: grid;
	grid-template-columns: 16px 1fr;
	align-items: center;
	gap: 10px;
	background: var(--color-modal-field-bg);
	border: 1.5px solid var(--color-modal-border);
	border-radius: 6px;
	padding: 12px 14px;
	cursor: pointer;
	text-transform: none;
	font-weight: 400;
	letter-spacing: 0;
	font-size: 12.5px;
	line-height: 1.5;
	color: var(--color-modal-text-dark);
	transition: border-color 0.15s ease;
}

.ui-sub-card .chk:hover {
	border-color: var(--color-modal-border-hover);
}

.ui-sub-card .chk input {
	margin: 0;
	width: 16px;
	height: 16px;
	accent-color: var(--color-primary);
}

/* No outline/border on the checkbox itself when invalid — per explicit
   request. The inline .fld-error message under the whole row (same
   pattern every other field on this form already uses) is the only error
   indicator here now. */

.ui-sub-card .terms-link {
	background: none;
	border: 0;
	padding: 0;
	margin: 0;
	font: inherit;
	color: var(--color-primary-deep);
	text-decoration: underline;
	cursor: pointer;
}

.ui-sub-card .terms-link:hover,
.ui-sub-card .terms-link:focus-visible {
	color: var(--color-primary);
}

/* ── Terms & Notice modal — reuses .ui-sub-ov/.ui-sub-card, layered above
   the subscribe modal so both can be open at once. ─────────────────────── */

.ui-terms-ov {
	z-index: var(--z-modal-top);
}

.ui-terms-card {
	width: 640px;
}

.ui-terms-card .head {
	padding: 30px 44px 18px;
	border-bottom: 1px solid var(--color-modal-border-soft);
}

.ui-terms-card .body.terms-body {
	padding: 24px 44px 36px;
}

.terms-body {
	font-size: 13.5px;
	line-height: 1.7;
	color: var(--color-modal-text-dark);
}

.terms-body h4 {
	margin: 24px 0 10px;
	font-family: var(--font-primary);
	font-size: 11.5px;
	font-weight: 800;
	letter-spacing: 1px;
	text-transform: uppercase;
	color: var(--color-primary-deep);
}

.terms-body h4:first-child {
	margin-top: 0;
}

.terms-body p {
	margin: 0 0 12px;
}

.terms-body ul {
	margin: 0 0 12px;
	padding-left: 20px;
	list-style: none;
}

.terms-body li {
	position: relative;
	margin-bottom: 10px;
	padding-left: 16px;
}

.terms-body li::before {
	content: "";
	position: absolute;
	left: 0;
	top: 8px;
	width: 5px;
	height: 5px;
	border-radius: 50%;
	background: var(--color-primary);
}

.terms-body > *:last-child {
	margin-bottom: 0;
}

/* select had no chevron styling of its own — it was inheriting the exact
   same rules as text inputs, so the browser's own NATIVE arrow rendered
   instead, which ignores this field's padding and sits flush against the
   very edge of the box (varies by browser, but always looks cramped/
   touching the border). Hiding the native one and drawing a custom SVG
   chevron at a fixed, deliberate inset fixes that everywhere at once. */
.ui-sub-card .fld select {
	appearance: none;
	-webkit-appearance: none;
	-moz-appearance: none;
	padding-right: 38px;
	background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8' fill='none'%3E%3Cpath d='M1 1.5L6 6.5L11 1.5' stroke='%234C574F' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
	background-repeat: no-repeat;
	background-position: right 14px center;
	background-size: 12px 8px;
	cursor: pointer;
}

.ui-sub-card .fld input:focus,
.ui-sub-card .fld select:focus {
	border-color: var(--color-primary);
	background-color: var(--color-white);
}

.ui-sub-card .fld input.is-invalid,
.ui-sub-card .fld select.is-invalid {
	border-color: var(--color-error);
}

.ui-sub-card .fld input.is-invalid:focus,
.ui-sub-card .fld select.is-invalid:focus {
	/* Was its own hardcoded rgba(198,40,40,...) — a near-duplicate of
	   var(--color-error) (#C0392B) rather than a reference to it, so the
	   two could silently drift apart if the Customizer's Error color ever
	   changes. color-mix() derives the tint straight from the real var. */
	box-shadow: 0 0 0 3px color-mix(in srgb, var(--color-error) 12%, transparent);
}

/* Same pattern as the Contact form's .cf-error (contact-page.css) — an
   inline message directly under the invalid field, not a shared banner. */
.fld-error {
	display: block;
	font-size: 12px;
	line-height: 1.4;
	color: var(--color-error);
	margin-top: 6px;
}

.ui-sub-card .go {
	width: 100%;
	background: var(--color-accent);
	color: var(--color-ink);
	border: 0;
	border-radius: 6px;
	font-family: var(--font-primary);
	font-size: 13px;
	font-weight: 700;
	letter-spacing: 1px;
	text-transform: uppercase;
	padding: 14px;
	cursor: pointer;
	margin-top: 6px;
}

.ui-sub-card .go:hover,
.ui-sub-card .go:focus-visible {
	/* Was its own separate hardcoded hex instead of a lightened version of
	   the actual Accent Customizer color — color-mix() derives the hover
	   tint straight from var(--color-accent), so it can't drift out of
	   sync with it if that setting is ever changed. */
	background: color-mix(in srgb, var(--color-accent) 85%, white);
}

.ui-sub-card .go:disabled {
	opacity: 0.6;
	cursor: not-allowed;
}

/* Same "visibly busy" pulse as the Contact form's .ct-submit.is-loading
   (contact-page.css) — duplicated here (not shared) since this modal is
   global chrome loaded on every page, while contact-page.css only loads
   on the Contact page itself. */
.ui-sub-card .go.is-loading {
	animation: malasiya-submit-pulse 1.1s ease-in-out infinite;
}

@keyframes malasiya-submit-pulse {
	0%, 100% { opacity: .6; }
	50% { opacity: .85; }
}

@media (max-width: 768px) {
	.ui-sub-ov {
		padding: 16px 12px;
	}

	.ui-sub-card {
		max-height: 92dvh;
		border-radius: 12px;
	}

	.ui-sub-card .head {
		padding: 24px 20px 10px;
	}

	.ui-sub-card .head .tt {
		font-size: 22px;
		padding-right: 28px;
	}

	.ui-sub-card .x {
		top: 14px;
		right: 14px;
		font-size: 22px;
		padding: 4px;
	}

	.ui-sub-card .body {
		padding: 16px 20px 24px;
	}

	/* Higher-specificity desktop rule (.ui-terms-card .body.terms-body)
	   would otherwise keep winning over the generic .ui-sub-card .body
	   rule just above regardless of this media query — specificity, not
	   cascade order, decides between two same-media rules. */
	.ui-terms-card .body.terms-body {
		padding: 16px 20px 24px;
	}

	.ui-terms-card .head {
		padding: 24px 20px 10px;
	}
}

@media (max-width: 480px) {
	.ui-sub-card .head {
		padding: 20px 16px 8px;
	}

	.ui-sub-card .body {
		padding: 14px 16px 20px;
	}

	.ui-terms-card .body.terms-body {
		padding: 14px 16px 20px;
	}

	.ui-sub-card .seg-opt {
		font-size: 11.5px;
		padding: 10px 8px;
	}

	.ui-sub-card .plan-opt {
		grid-template-columns: 16px 1fr;
		padding: 10px 12px;
		font-size: 12.5px;
	}

	.ui-sub-card .plan-opt input {
		width: 16px;
		height: 16px;
	}

	/* Landline/Mobile stack instead of staying side-by-side — at this
	   width, two half-width fields left too little room to comfortably
	   type a phone number in either one. */
	.ui-sub-card .contact-row {
		flex-direction: column;
		gap: 10px;
	}

	.ui-sub-card .chk {
		grid-template-columns: 15px 1fr;
		padding: 10px 12px;
		font-size: 12px;
	}

	.ui-sub-card .chk input {
		width: 15px;
		height: 15px;
	}
}
