/**
 * Mattilan Hoiva - job applications: public styles (form + applicant portal).
 * One file, plain CSS, no build step, no external request; the three icons are
 * inline SVG data URIs.
 *
 * TOKEN API - re-theme everything from one block:
 *   .mhja-form-wrap, .mhja-form-container, .mhja-portal { --mhja-accent: #7a1f3d; }
 *   --mhja-surface / -2      panel fill / sunken fill (consent, notices, cards)
 *   --mhja-field-bg          input, select, textarea fill
 *   --mhja-text / -muted     body 16.1:1 / help + meta 7.6:1 on --mhja-surface
 *   --mhja-rule / --border   decorative hairline / control edge 4.5:1
 *   --mhja-heading           section + panel headings (brand indigo, 10.7:1)
 *   --mhja-accent + -strong, -ink, -wash   brand magenta #eb0064: 4.46:1 on
 *       white, so it fills the (large-bold) button, ticks and borders, while
 *       body-size text on white always takes -strong (6.0:1)
 *   --mhja-error   6.3:1 on -surface, 5.6:1 on its own -wash
 *   --mhja-ok      success = the brand indigo, 10.7:1 (the brand has no green)
 *   --mhja-focus             ring; >= 3:1 on every fill this file paints
 *   --mhja-font-display      "Baloo 2" - the brand face for headings + buttons
 *   --mhja-radius, -lg, -pill (buttons);  --mhja-gap;  --mhja-s1..-s5;
 *   --mhja-tap (44px);  --mhja-scroll-offset (sticky-header clearance for the
 *   programmatic focus jumps);  --mhja-dur
 *   --mhja-arrow, --mhja-icon-alert, --mhja-icon-ok   inline SVG data URIs
 * Declared ONLY on the plugin roots, never on :root/html/body, so nothing leaks
 * into the theme and no later :root block reaches in. Every name is --mhja-
 * prefixed because --gap, --accent, --global-*, --ast-* and --wp--* all exist
 * in the wild and inherit into our subtree.
 *
 * LIGHT / DARK. prefers-color-scheme is used for NOTHING here: it reports the
 * visitor's OS, not the page this form is embedded in, and CSS cannot read the
 * theme's rendered background - obeying it would drop a dark card into a light
 * layout for every dark-mode visitor, a certain defect for a guessed win. The
 * panel instead paints its own opaque surface, border and text and inherits
 * none of them, which is what keeps it legible on a light theme, a dark theme
 * and a photographic background alike. color-scheme: light aligns the chrome we
 * do NOT paint - date picker, select popup, scrollbars, autofill - with the
 * CARD rather than the OS. A dark site opts in explicitly: .mhja-theme-dark or
 * data-mhja-scheme="dark" on a plugin root or ANY ancestor, which a Group
 * block's "Additional CSS class(es)" field or a body_class() filter supplies
 * without touching markup. A site that truly wants to follow the OS wraps that
 * same token override in its own media query.
 *
 * SPECIFICITY. Plugin styles load before the theme's, so a tie is a loss;
 * themes routinely reach (0,2,1) (".entry-content input[type=text]") and Divi
 * reaches (1,1,1) with ids. Every rule is prefixed
 * `:root :is(#mhja,.mhja-form-wrap,.mhja-portal)` = (1,1,0), so plugin-class
 * rules land at (1,2,0) and control rules at (1,3,1) or above: clear of
 * anything a theme realistically ships, ids included. #mhja is a SPECIFICITY
 * ANCHOR and nothing else - no element in this plugin's markup carries that
 * id - and :is() takes the weight of its heaviest argument, so the id weight
 * applies to every rule while the real match is still made by the root
 * classes. The price is deliberate and must be stated: a site owner can no
 * longer override from the outside with a class. Doing so now needs an id of
 * their own, !important, or - the documented route - the token blocks in §1,
 * which are left at plain class weight (.mhja-form-wrap, …) precisely so that
 * a re-theme stays a one-block edit. No bare element selector exists outside
 * that scope; the sole exception is .mhja-notice--closed, which
 * FormShortcode.php returns with no plugin wrapper, hence literal var()
 * fallbacks and a doubled class. Cascade layers are deliberately not used:
 * their value is "let the theme win on cosmetics", but a theme's input chrome
 * is precisely what breaks an embedded form. !important is confined to seven
 * inline-justified cases - [hidden], honeypot, focus ring, .mhja-link reset,
 * checkbox/radio sizing, .mhja-option display, reduced-motion - each answering
 * either another !important or a Divi id, the two things specificity cannot
 * beat. Comments are English by house rule; no UI string appears in CSS.
 */

/* --- 1. Tokens ---------------------------------------------------------- */

/* .mhja-notice--closed is listed because it is the one element that renders
   outside every plugin root; without it, it could never follow a re-theme. */
.mhja-form-wrap,
.mhja-form-container,
.mhja-portal,
.mhja-notice--closed {
	color-scheme: light;
	/* Brand palette, measured from the live Elementor kit on mattilanhoiva.fi
	   (2026-08-26): primary #2c377d (indigo, Baloo 2 headings), accent #eb0064
	   (magenta pill CTAs), secondary #6e8cd2, body Lato #222. The magenta is
	   4.46:1 on white - enough for the large bold button label and for UI
	   borders, NOT for body-size link text, which therefore uses the darker
	   -strong shade (6.0:1). Headings and the focus ring take the indigo. */
	--mhja-surface: #fff; --mhja-surface-2: #f3f4fa; --mhja-field-bg: #fff;
	--mhja-text: #1e1e1e; --mhja-text-muted: #4a5162;
	--mhja-rule: #dcdff0; --mhja-border: #6f7591;
	--mhja-heading: #2c377d;
	--mhja-accent: #eb0064; --mhja-accent-strong: #c40053;
	--mhja-accent-ink: #fff; --mhja-accent-wash: #fce8f1;
	--mhja-error: #b32d2e; --mhja-error-wash: #fbeeee;
	--mhja-ok: #2c377d; --mhja-ok-wash: #eef0fa;
	--mhja-focus: #2c377d;
	--mhja-radius: 8px; --mhja-radius-lg: 12px; --mhja-radius-pill: 999px;
	--mhja-font-display: "Baloo 2", sans-serif;
	--mhja-gap: 1.375rem;
	--mhja-s1: .25rem; --mhja-s2: .5rem; --mhja-s3: .75rem; --mhja-s4: 1rem; --mhja-s5: 1.5rem;
	--mhja-tap: 2.75rem; --mhja-scroll-offset: 5rem; --mhja-dur: 140ms;
	/* The chevron clears 3:1 on both the light and the dark field fill, so the
	   dark twin below is polish, not contrast. The status icons are masks tinted
	   with currentColor: one URI each serves both palettes and any re-theme. */
	--mhja-arrow: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 8'%3E%3Cpath d='m1 1.6 5 5 5-5' fill='none' stroke='%23767d9e' stroke-width='2' stroke-linecap='round'/%3E%3C/svg%3E");
	--mhja-icon-alert: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M8 0a8 8 0 1 0 0 16A8 8 0 0 0 8 0Zm1 12.5H7v-2h2Zm0-3.5H7V3.5h2Z'/%3E%3C/svg%3E");
	--mhja-icon-ok: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M8 0a8 8 0 1 0 0 16A8 8 0 0 0 8 0ZM7 11.6 3.4 8l1.4-1.4L7 8.8l4.2-4.2L12.6 6Z'/%3E%3C/svg%3E");
}

/* Opt-in dark palette: the site owner's decision, never the OS's. */
.mhja-theme-dark :is(.mhja-form-wrap,.mhja-form-container,.mhja-portal,.mhja-notice--closed),
:is(.mhja-form-wrap,.mhja-form-container,.mhja-portal,.mhja-notice--closed).mhja-theme-dark,
[data-mhja-scheme="dark"] :is(.mhja-form-wrap,.mhja-form-container,.mhja-portal,.mhja-notice--closed),
:is(.mhja-form-wrap,.mhja-form-container,.mhja-portal,.mhja-notice--closed)[data-mhja-scheme="dark"] {
	color-scheme: dark;
	--mhja-surface: #171a2b; --mhja-surface-2: #20243a; --mhja-field-bg: #121526;
	--mhja-text: #eef0f7; --mhja-text-muted: #b6bcd1;
	--mhja-rule: #323753; --mhja-border: #8d93b0;
	--mhja-heading: #b9c3f7;
	--mhja-accent: #ff7fb1; --mhja-accent-strong: #ffa4c7;
	--mhja-accent-ink: #35001a; --mhja-accent-wash: #3a1c2b;
	--mhja-error: #ff9b96; --mhja-error-wash: #3a1f1f;
	--mhja-ok: #b9c3f7; --mhja-ok-wash: #232a4a;
	--mhja-focus: #ccd3fb;
	--mhja-arrow: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 8'%3E%3Cpath d='m1 1.6 5 5 5-5' fill='none' stroke='%23a3a9c4' stroke-width='2' stroke-linecap='round'/%3E%3C/svg%3E");
}

/* --- 2. Behavioural invariants - nothing below may regress these -------- */

/* !important 1/7. Both scripts drive every view through [hidden]. It must beat
   our own display:grid/flex AND a reset theme's `section { display: block }`,
   which outranks the UA [hidden] rule; losing this leaks whole views. It also
   has to beat the file's own !important display rules, which is why it carries
   the id anchor: at (1,2,0) it ties .mhja-option and .mhja-link, and a tie is
   decided by source order, which this rule loses by design. All three of those
   (plus .mhja-option.mhja-remove, heavier still at (1,3,0)) therefore carry
   :not([hidden]) as well, so they cannot match a hidden element at all. Every
   other display in this file is unimportant and loses outright. */
:root :is(#mhja,.mhja-form-wrap,.mhja-form-container,.mhja-form,.mhja-portal) [hidden] { display: none !important; }

/* !important 2/7. Honeypot. FormRenderer::honeypot() needs it in the render
   tree - display:none is what bots look for - so it is clipped, not moved: a
   -9999px offset becomes a horizontal scrollbar on an RTL site and no -rtl
   sheet is registered. No theme flex/grid/position rule and no a11y plugin's
   [aria-hidden] rule may pull it back on screen. */
.mhja-hp-wrap {
	position: absolute !important; display: block !important;
	width: 1px !important; height: 1px !important;
	margin: -1px !important; padding: 0 !important; border: 0 !important;
	overflow: hidden !important; clip: rect(0 0 0 0) !important;
	clip-path: inset(50%) !important; white-space: nowrap !important;
}

/* Themes may not ship this helper, and the required marker depends on it. */
:root :is(#mhja,.mhja-form-wrap,.mhja-portal) .screen-reader-text {
	position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0;
	overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%);
	white-space: nowrap; border: 0;
}

/* A theme with a display on bare inputs would give the token, UTM and
   locked-email mirror fields layout. */
:root :is(#mhja,.mhja-form-wrap,.mhja-portal) input[type="hidden"] { display: none; }

/* --- 3. Panel ----------------------------------------------------------- */

/* Painting our own surface IS the theme-independence device, and the reason
   every ratio in the token block is computable. min-width:0 stops the panel
   forcing an Elementor flex column wider; no fixed max-width, so a block
   theme's constrained-layout width still governs. */
:root :is(#mhja,.mhja-form-wrap,.mhja-portal) {
	box-sizing: border-box; min-width: 0; max-width: 100%;
	margin: 0 0 var(--mhja-gap, 1.375rem); padding: clamp(1.1rem, 4%, 1.75rem);
	background-color: var(--mhja-surface); background-image: none;
	color: var(--mhja-text); border: 1px solid var(--mhja-rule);
	border-radius: var(--mhja-radius-lg);
	font-size: 1rem; line-height: 1.6; text-align: start; overflow-wrap: break-word;
}

/* Never assume the theme ships a universal border-box reset. */
:root :is(#mhja,.mhja-form-wrap,.mhja-portal) *,
:root :is(#mhja,.mhja-form-wrap,.mhja-portal) *::before,
:root :is(#mhja,.mhja-form-wrap,.mhja-portal) *::after { box-sizing: border-box; }

/* One neutraliser for the four properties themes force onto form furniture.
   The doubled prefix lands it at (1,2,1): past "#page button" (1,1,2) yet still
   under the specific rules below, which carry two classes and come later.
   It saves repeating all four in every rule below. */
:root :is(.mhja-form-wrap,.mhja-portal):is(#mhja,.mhja-form-wrap,.mhja-portal) :is(label,legend,input,select,textarea,button,a) {
	font-family: inherit; font-style: normal; letter-spacing: normal; text-transform: none;
}

/* Query containers sit INSIDE the panel: container-type contains the inline
   axis, so a container in a shrink-to-fit context (an Elementor flex item, a
   table cell) collapses to zero. These two always have a definite width. */
:root :is(#mhja,.mhja-form-wrap,.mhja-portal) :is(.mhja-form-container,.mhja-portal-step) { container: mhja / inline-size; }

/* On success form.js deletes the <form>, leaving only .mhja-form-status here:
   a grid gap survives that, a margin between siblings would not. */
:root :is(#mhja,.mhja-form-wrap,.mhja-portal) .mhja-form-container { display: grid; gap: var(--mhja-gap); margin: 0; }

/* Both scripts move focus here; a sticky theme header would otherwise cover
   whatever they scrolled to. Scroll margin is read from the element actually
   scrolled into view, and both scripts call focus() on the CONTROL inside the
   field (form.js/portal.js after a failed submit, portal.js on the email and
   code inputs), never on the wrapper - so the controls carry it too, or a
   field reached from the error summary lands under the header (WCAG 2.4.11). */
:root :is(#mhja,.mhja-form-wrap,.mhja-portal) :is(.mhja-field,.mhja-error-summary,.mhja-form-status),
:root :is(#mhja,.mhja-form-wrap,.mhja-portal) .mhja-field :is(input,select,textarea,.mhja-option) {
	scroll-margin-block-start: var(--mhja-scroll-offset);
}

/* --- 4. Typography ------------------------------------------------------ */

:root :is(#mhja,.mhja-form-wrap,.mhja-portal) :is(.mhja-form-title,.mhja-section-title,.mhja-portal-step > h3,.mhja-portal-edit-title,.mhja-portal-item h4) {
	margin: 0 0 var(--mhja-s2); padding: 0; color: var(--mhja-heading);
	font-family: var(--mhja-font-display); font-weight: 600; line-height: 1.3;
	letter-spacing: normal; text-align: start; text-transform: none;
}

/* The group above carries an element component, so these are doubled or
   descendant-shaped to outweigh it. */
:root :is(#mhja,.mhja-form-wrap,.mhja-portal) .mhja-form-title.mhja-form-title {
	margin-bottom: var(--mhja-gap); padding-bottom: var(--mhja-s3);
	border-bottom: 1px solid var(--mhja-rule); font-size: 1.5em;
}
:root :is(#mhja,.mhja-form-wrap,.mhja-portal) :is(.mhja-portal-step > h3,.mhja-portal-edit-title) { font-size: 1.25em; }
:root :is(#mhja,.mhja-form-wrap,.mhja-portal) .mhja-portal-item h4 { margin-bottom: 0; font-size: 1.0625em; }
/* The divider heading is what makes a long application read as sections
   instead of one endless column. Brand indigo, not the magenta accent: on the
   site the magenta is reserved for calls to action. */
:root :is(#mhja,.mhja-form-wrap,.mhja-portal) .mhja-field--section .mhja-section-title { margin-bottom: var(--mhja-s1); color: var(--mhja-heading); font-size: 1.125em; }
/* portal.js fills this only when the edit step opens. */
:root :is(#mhja,.mhja-form-wrap,.mhja-portal) .mhja-portal-edit-title:empty { display: none; }

:root :is(#mhja,.mhja-form-wrap,.mhja-portal) :is(.mhja-help,.mhja-portal-item-meta,.mhja-portal-item-note,.mhja-portal-user,.mhja-file-list,.mhja-attachment) {
	color: var(--mhja-text-muted); font-size: .9375em; font-style: normal; line-height: 1.5;
}

/* Help sits in three places: before the control, inside the <fieldset> after
   the <legend>, and - on a portal file field - AFTER the input. A child or
   order-based selector misses at least one, so it is matched by class alone and
   the trailing case is anchored on the input instead. */
:root :is(#mhja,.mhja-form-wrap,.mhja-portal) .mhja-help { margin: 0 0 var(--mhja-s2); }
:root :is(#mhja,.mhja-form-wrap,.mhja-portal) .mhja-field input[type="file"] + .mhja-help { margin-block-start: var(--mhja-s2); }
:root :is(#mhja,.mhja-form-wrap,.mhja-portal) .mhja-field--section .mhja-help { margin-bottom: 0; }

/* Measure. The panel is a full-width block in most layouts, so prose rows can
   run to ~150 characters, well past the 80 that stays readable. The PANEL is
   deliberately not capped - the theme's layout owns that box - only the text
   rows are, which leaves controls and the two-up grid at full width. */
:root :is(#mhja,.mhja-form-wrap,.mhja-portal) :is(.mhja-help,.mhja-notice,.mhja-field--consent,.mhja-portal-step > p,.mhja-form-status p) {
	max-inline-size: 68ch;
}

:root :is(#mhja,.mhja-form-wrap,.mhja-portal) .mhja-required { margin-inline-start: .15em; color: var(--mhja-error); font-weight: 700; }

/* Every link this markup can produce; the summary link is re-coloured in §9. */
:root :is(#mhja,.mhja-form-wrap,.mhja-portal) :is(.mhja-privacy-link,.mhja-option-link,.mhja-attachment a,.mhja-error-summary a,.mhja-form-status a) {
	/* -strong, not the raw accent: body-size link text needs 4.5:1 and the
	   exact brand magenta is 4.46:1 on white - the darker shade is 6.0:1. */
	color: var(--mhja-accent-strong); font-weight: 600; text-decoration: underline; text-underline-offset: 3px;
}

/* --- 5. Field wrapper, labels, legends ---------------------------------- */

:root :is(#mhja,.mhja-form-wrap,.mhja-portal) .mhja-field { min-width: 0; margin: 0; }

/* A section opens a new block of the form - unless it opens the form. Both
   renderers always emit .mhja-error-summary as the form's first child, so the
   sibling case is the only one that can ever match; a :first-child twin would
   be dead code. */
:root :is(#mhja,.mhja-form-wrap,.mhja-portal) .mhja-field--section {
	margin-top: var(--mhja-s2); padding-top: var(--mhja-gap); border-top: 1px solid var(--mhja-rule);
}
:root :is(#mhja,.mhja-form-wrap,.mhja-portal) .mhja-error-summary + .mhja-field--section { margin-top: 0; padding-top: 0; border-top: 0; }

/* :not() keeps option labels out; they are rows, styled in §7. The legend reset
   is full on purpose: Bootstrap-derived themes give <legend> a border-bottom,
   width:100% and font-size:21px, drawing a grey rule across every radio group. */
:root :is(#mhja,.mhja-form-wrap,.mhja-portal) .mhja-field :is(label:not(.mhja-option),legend) {
	display: block; float: none; width: auto; max-width: 100%;
	margin: 0 0 var(--mhja-s1); padding: 0; background: none;
	color: var(--mhja-text); border: 0;
	font-size: 1em; font-weight: 600; line-height: 1.35;
}

/* min-inline-size:0 also kills the classic fieldset overflow inside a grid. */
:root :is(#mhja,.mhja-form-wrap,.mhja-portal) .mhja-field fieldset { min-inline-size: 0; margin: 0; padding: 0; background: none; border: 0; }

/* --- 6. Text-like controls: full reset, then the plugin's own chrome ----- */

:root :is(#mhja,.mhja-form-wrap,.mhja-portal) .mhja-field :is(input[type="text"],input[type="email"],input[type="tel"],input[type="number"],input[type="date"],textarea,select) {
	appearance: none; -webkit-appearance: none; box-sizing: border-box;
	display: block; width: 100%; max-width: 100%; min-width: 0;
	height: auto; min-height: var(--mhja-tap);
	margin: 0; padding: .625rem .75rem;
	background-color: var(--mhja-field-bg); background-image: none;
	color: var(--mhja-text); border: 1px solid var(--mhja-border);
	border-radius: var(--mhja-radius); box-shadow: none;
	/* outline is deliberately NOT reset: this rule weighs (0,4,1) and would
	   swallow the focus ring - §8 owns the outline. max() stops iOS zooming on
	   focus under a sub-16px root; line-height is pinned because
	   `body { line-height: 1.7 }` mis-centres date inputs and selects. */
	outline-offset: 2px;
	font-size: max(1rem, 16px); font-weight: 400; line-height: 1.4;
	transition: border-color var(--mhja-dur) ease, background-color var(--mhja-dur) ease;
}

/* The reset weighs (0,4,1), so per-type refinements repeat .mhja-field to match
   it and sit immediately after it. */
:root :is(#mhja,.mhja-form-wrap,.mhja-portal) .mhja-field.mhja-field textarea { min-height: 8rem; line-height: 1.55; resize: vertical; }

/* appearance:none dropped the native arrow, so ours is the only one drawn, and
   the padding reserves its lane so long options never run underneath. */
:root :is(#mhja,.mhja-form-wrap,.mhja-portal) .mhja-field.mhja-field select {
	padding-inline-end: 2.5rem; background-image: var(--mhja-arrow);
	background-repeat: no-repeat; background-position: right .85rem center;
	background-size: 12px 8px; cursor: pointer;
}
/* background-position has no logical form, so the lane is reserved logically
   (padding-inline-end) but painted physically: in RTL the arrow would land on
   top of the option text. The mirror repeats the anchor so it outweighs the
   rule above; this is the file's only physical-side positioning. */
[dir="rtl"] :is(#mhja,.mhja-form-wrap,.mhja-portal) .mhja-field.mhja-field select { background-position: left .85rem center; }
/* "Valitse…" reads as a prompt, not as an answer. */
:root :is(#mhja,.mhja-form-wrap,.mhja-portal) .mhja-field select:has(option[value=""]:checked) { color: var(--mhja-text-muted); }
/* iOS centres the date value inside the control unless told otherwise. */
:root :is(#mhja,.mhja-form-wrap,.mhja-portal) .mhja-field input[type="date"]::-webkit-date-and-time-value { text-align: start; }
:root :is(#mhja,.mhja-form-wrap,.mhja-portal) .mhja-field ::placeholder { color: var(--mhja-text-muted); opacity: 1; }

/* Chrome's autofill fill is UA-!important and unreadable on the dark palette.
   Own rule: Firefox drops an unknown pseudo-class and would lose the block. The
   inset shadow is safe because our focus ring is an outline. */
:root :is(#mhja,.mhja-form-wrap,.mhja-portal) .mhja-field :is(input,textarea,select):-webkit-autofill {
	-webkit-text-fill-color: var(--mhja-text);
	-webkit-box-shadow: inset 0 0 0 100px var(--mhja-field-bg);
}

/* The portal's locked email field and every control of a read-only application:
   intentionally inert, not accidentally broken. Text stays at 4.5:1;
   -webkit-text-fill-color stops iOS washing it out; background-color rather
   than the shorthand keeps the select arrow. */
:root :is(#mhja,.mhja-form-wrap,.mhja-portal) .mhja-field :is(input,textarea,select):disabled {
	background-color: var(--mhja-surface-2); color: var(--mhja-text-muted);
	-webkit-text-fill-color: var(--mhja-text-muted);
	border-style: dashed; opacity: 1; cursor: not-allowed;
}
:root :is(#mhja,.mhja-form-wrap,.mhja-portal) .mhja-field :is(input,textarea,select):hover:enabled { border-color: var(--mhja-text-muted); }

/* --- 7. Checkboxes, radios, option rows ---------------------------------
   Native and tinted with accent-color, not custom-drawn, for two structural
   reasons: .mhja-option is <label><input> text-node</label> with NO sibling
   element, so "hide the input, style the span" has nothing to match; and
   appearance:none throws away the platform tick in forced-colors mode, where an
   invisible consent box is an abandoned application. The 44px target lives on
   the label row instead, which buys more than a hand-drawn tick would. */

/* !important 3/7. Unqualified `input { width: 100% }` ships with GeneratePress
   and most ThemeForest themes and turns every radio into a full-width bar;
   explicit dimensions defeat it and size the box in one go. */
:root :is(#mhja,.mhja-form-wrap,.mhja-portal) .mhja-field :is(input[type="checkbox"],input[type="radio"]) {
	appearance: auto; -webkit-appearance: auto; flex: 0 0 auto;
	width: 1.15rem !important; height: 1.15rem !important; min-height: 0;
	/* The gap between box and text lives HERE, not on the row: as a flex gap it
	   also separated the trailing .mhja-required asterisk from the last word and
	   pushed it onto the first line of a wrapped consent sentence. */
	margin: 0; margin-block-start: .18em; margin-inline-end: var(--mhja-s2);
	padding: 0; background: none; border: 0; box-shadow: none;
	accent-color: var(--mhja-accent); cursor: pointer;
}
/* A disabled tick is not clickable; the cursor:pointer above ties with the
   :disabled rule in §6 and comes later, so it needs answering by name. */
:root :is(#mhja,.mhja-form-wrap,.mhja-portal) .mhja-field :is(input[type="checkbox"],input[type="radio"]):disabled { cursor: not-allowed; }

/* !important 4/7. Against `label { display: block }` and, more to the point,
   Divi's id-scoped label rules that specificity cannot reach. :not([hidden])
   keeps that !important from re-showing a hidden row (§2).
   gap is 0 on purpose: the label's children are <input> + text node + the
   .mhja-required asterisk, so any gap becomes a hole before the asterisk. The
   box/text spacing is a margin on the input instead. */
:root :is(#mhja,.mhja-form-wrap,.mhja-portal) .mhja-option:not([hidden]) {
	display: flex !important; align-items: flex-start; gap: 0;
	min-height: var(--mhja-tap); margin: 0; padding: var(--mhja-s2) var(--mhja-s3);
	background-color: transparent; background-image: none;
	color: var(--mhja-text); border: 1px solid transparent;
	border-radius: var(--mhja-radius);
	font-size: 1em; font-weight: 400; line-height: 1.45; cursor: pointer;
	transition: background-color var(--mhja-dur) ease, border-color var(--mhja-dur) ease;
}

/* FormRenderer and portal.js wrap the option text and its required marker in
   one span, so the asterisk follows the last word instead of becoming its own
   flex item and top-aligning beside a wrapping consent sentence. */
:root :is(#mhja,.mhja-form-wrap,.mhja-portal) .mhja-option-text { min-inline-size: 0; }

/* :has() is enhancement only - the native tick already states the value. */
:root :is(#mhja,.mhja-form-wrap,.mhja-portal) .mhja-option:hover { background-color: var(--mhja-surface-2); }
:root :is(#mhja,.mhja-form-wrap,.mhja-portal) .mhja-option:has(:checked) { background-color: var(--mhja-accent-wash); border-color: var(--mhja-accent); }
:root :is(#mhja,.mhja-form-wrap,.mhja-portal) .mhja-option:has(:disabled) { color: var(--mhja-text-muted); cursor: default; }

/* Consent is a decision, not a field: statement and link share one inset box.
   --mhja-border, not --mhja-rule: the fill alone is 1.09:1 against the panel
   and a --mhja-rule hairline only 1.34:1, so the box had no perceivable edge.
   --mhja-border is 4.21:1 light / 4.89:1 dark and actually draws it. */
:root :is(#mhja,.mhja-form-wrap,.mhja-portal) .mhja-field--consent {
	display: flex; flex-wrap: wrap; align-items: center; column-gap: var(--mhja-s2);
	padding: var(--mhja-s2); background-color: transparent;
	border: 1px solid var(--mhja-border); border-radius: var(--mhja-radius);
}

/* Statement and link ride the same line and the link drops under it only when
   the line runs out; help and error always claim a row of their own. */
:root :is(#mhja,.mhja-form-wrap,.mhja-portal) .mhja-field--consent > .mhja-option { flex: 0 1 auto; min-width: 0; }
:root :is(#mhja,.mhja-form-wrap,.mhja-portal) .mhja-field--consent > :is(.mhja-help,.mhja-error) { flex: 1 0 100%; }

/* The privacy link is a SIBLING of the label, never inside it: inside a label,
   a click on the link would tick the checkbox as well. The consent box seats it
   on the statement's line, so it needs no indent of its own. */
:root :is(#mhja,.mhja-form-wrap,.mhja-portal) .mhja-privacy-link {
	display: inline-flex; align-items: center; min-height: var(--mhja-tap);
	padding-inline: var(--mhja-s1);
}

/* Open-positions rows pair the option label with an "open the job posting"
   link — a sibling of the label for the same click-toggles-the-box reason as
   .mhja-privacy-link above. The label takes the flexible share; the link
   keeps its own tap-height box, never breaks mid-text, and wraps as a whole
   under the label on narrow screens. */
:root :is(#mhja,.mhja-form-wrap,.mhja-portal) .mhja-option-pair {
	display: flex; align-items: center; flex-wrap: wrap; gap: 0 var(--mhja-s2);
}

/* flex-basis 14rem, not auto: with auto the label claims its full content
   width, so a long job title pushed the link onto its own line even when the
   row had room. A small basis lets the TITLE wrap instead and keeps the link
   beside it; the link still wraps as a whole once the row is truly narrow. */
:root :is(#mhja,.mhja-form-wrap,.mhja-portal) .mhja-option-pair > .mhja-option { flex: 1 1 14rem; min-width: 0; }

:root :is(#mhja,.mhja-form-wrap,.mhja-portal) .mhja-option-link {
	display: inline-flex; align-items: center; min-height: var(--mhja-tap);
	/* No nowrap: with the "(avautuu uuteen välilehteen)" note the text is
	   long enough that forbidding wraps would overflow narrow viewports.
	   The gap is load-bearing, not decoration: this box is a flex container,
	   so the note span is a flex item and the whitespace before it in the
	   markup is dropped — without a gap the note would touch the link text. */
	flex-wrap: wrap; gap: 0 .35em;
	padding-inline: var(--mhja-s1); font-size: .875em;
}

/* The new-tab note is secondary to the link it qualifies: smaller, and not
   underlined. text-decoration:none on the note CANNOT achieve that — a
   decoration set on the link is painted through its in-flow descendants
   (these spans are flex items, i.e. block-level, so even the atomic-inline
   exemption does not apply) and computed style still reports "none" on the
   child while the line is drawn. So the underline is not declared on the
   link at all: it lives on the link TEXT, and the note simply never has
   one. This rule pair is what makes the §4 link rule's underline
   inapplicable here, hence the explicit none below. */
/* Doubled prefix, the §9 idiom — one COMPOUND on the root element, not two
   nested ancestors (there is only ever one plugin root in the DOM). It is
   needed because the §4 link rule lands at (1,2,1): its :is() list contains
   ".mhja-attachment a" and :is() takes its heaviest argument, so a plain
   (1,2,0) rule here would lose and the anchor would keep painting its
   underline through the note. These reach (1,3,0). */
:root :is(.mhja-form-wrap,.mhja-portal):is(#mhja,.mhja-form-wrap,.mhja-portal) .mhja-option-link { text-decoration: none; }
:root :is(.mhja-form-wrap,.mhja-portal):is(#mhja,.mhja-form-wrap,.mhja-portal) .mhja-option-link-text { text-decoration: underline; text-underline-offset: 3px; }

:root :is(#mhja,.mhja-form-wrap,.mhja-portal) .mhja-option-link-note { font-size: .85em; }

/* --- 8. Focus ----------------------------------------------------------- */

/* Drop the theme's mouse-click ring without losing keyboard indication. */
:root :is(#mhja,.mhja-form-wrap,.mhja-portal) :is(input,select,textarea,button,a,[tabindex]):focus:not(:focus-visible) { outline: none; }

/* !important 5/7. `*:focus { outline: none !important }` is shipped by real
   themes and losing it is an accessibility regression in a job-application
   form, so matching their weapon is the only option. One ring for everything:
   the 2px offset lands on the panel surface, which this file paints, so it
   reads over the accent button and every wash. The summary and status panels
   are focused PROGRAMMATICALLY after submit, where :focus-visible does not
   reliably match and showing where focus went is the whole point - hence plain
   :focus for those two. */
:root :is(#mhja,.mhja-form-wrap,.mhja-portal) :is(input,select,textarea,button,a,[tabindex]):focus-visible,
:root :is(#mhja,.mhja-form-wrap,.mhja-portal) :is(.mhja-error-summary,.mhja-form-status):focus {
	outline: 3px solid var(--mhja-focus) !important; outline-offset: 2px !important;
}

/* Safari 14.1-15.3 parses @supports selector() but not :focus-visible. */
@supports not selector(:focus-visible) {
	:root :is(#mhja,.mhja-form-wrap,.mhja-portal) :is(input,select,textarea,button,a,[tabindex]):focus {
		outline: 3px solid var(--mhja-focus) !important; outline-offset: 2px !important;
	}
}

/* .mhja-field is repeated to reach (1,4,1): the :hover:enabled rule in §6 sits
   at that weight, and for a mouse user the pointer is still over the field they
   just clicked - unrepeated, hover would cancel the accent focus border. */
:root :is(#mhja,.mhja-form-wrap,.mhja-portal) .mhja-field.mhja-field :is(input,select,textarea):focus { border-color: var(--mhja-accent); }

/* --- 9. Invalid state, messages, panels --------------------------------- */

/* Never colour alone: the border doubles in weight, the fill is tinted, the
   message carries an icon. box-sizing keeps the outer box identical when the
   border grows, and no padding shorthand appears here - it would wipe the
   select's reserved arrow lane. */
:root :is(#mhja,.mhja-form-wrap,.mhja-portal) .mhja-field.mhja-field :is(input,select,textarea)[aria-invalid="true"] {
	background-color: var(--mhja-error-wash); border-color: var(--mhja-error); border-width: 2px;
}
/* Both scripts set aria-invalid on EVERY control in the field, so a five-option
   radio group would otherwise paint five boxes. The ticks keep their own
   chrome; the row, the legend and the message carry the error instead. */
:root :is(#mhja,.mhja-form-wrap,.mhja-portal) .mhja-field.mhja-field :is(input[type="checkbox"],input[type="radio"])[aria-invalid="true"] { background: none; border: 0; }
/* No error class is ever put on the wrapper, so :has() is the only route in. */
:root :is(#mhja,.mhja-form-wrap,.mhja-portal) .mhja-field:has([aria-invalid="true"]) legend { color: var(--mhja-error); }
:root :is(#mhja,.mhja-form-wrap,.mhja-portal) .mhja-option:has([aria-invalid="true"]) { background-color: var(--mhja-error-wash); border-color: var(--mhja-error); }

/* One outline, never two. The consent box already draws the boundary, so the
   row inside it does not draw its own on hover, selection or error - that is
   what produced a rounded rectangle inside a rounded rectangle. The invalid
   state moves out to the box, where there is only one edge to colour. */
:root :is(#mhja,.mhja-form-wrap,.mhja-portal) .mhja-field--consent .mhja-option,
:root :is(#mhja,.mhja-form-wrap,.mhja-portal) .mhja-field--consent .mhja-option:hover,
:root :is(#mhja,.mhja-form-wrap,.mhja-portal) .mhja-field--consent .mhja-option:has(:checked),
:root :is(#mhja,.mhja-form-wrap,.mhja-portal) .mhja-field--consent .mhja-option:has([aria-invalid="true"]) {
	padding-inline: 0; background-color: transparent; border-color: transparent;
}
:root :is(#mhja,.mhja-form-wrap,.mhja-portal) .mhja-field--consent:has([aria-invalid="true"]) { border-color: var(--mhja-error); }

:root :is(#mhja,.mhja-form-wrap,.mhja-portal) :is(.mhja-error,.mhja-error-summary-title,.mhja-success-title) { display: flex; align-items: flex-start; gap: var(--mhja-s2); }
:root :is(#mhja,.mhja-form-wrap,.mhja-portal) .mhja-error {
	margin: var(--mhja-s1) 0 0; color: var(--mhja-error);
	font-size: .9375em; font-weight: 600; line-height: 1.45; overflow-wrap: anywhere;
}

/* Masked, not coloured: the glyph inherits currentColor, so one data URI covers
   both palettes and any re-theme. */
:root :is(#mhja,.mhja-form-wrap,.mhja-portal) :is(.mhja-error,.mhja-error-summary-title,.mhja-success-title)::before {
	content: ""; flex: 0 0 auto; width: 1.05em; height: 1.05em; margin-top: .2em;
	background-color: currentColor;
	-webkit-mask: var(--mhja-icon-alert) center / contain no-repeat;
	mask: var(--mhja-icon-alert) center / contain no-repeat;
}
:root :is(#mhja,.mhja-form-wrap,.mhja-portal) .mhja-success-title::before { -webkit-mask-image: var(--mhja-icon-ok); mask-image: var(--mhja-icon-ok); }

:root :is(#mhja,.mhja-form-wrap,.mhja-portal) :is(.mhja-error-summary,.mhja-form-status,.mhja-notice,.mhja-portal-message) {
	margin: 0; padding: var(--mhja-s3) var(--mhja-s4); color: var(--mhja-text);
	border-radius: var(--mhja-radius); font-style: normal;
}
:root :is(#mhja,.mhja-form-wrap,.mhja-portal) .mhja-error-summary { background-color: var(--mhja-surface); border: 1px solid var(--mhja-error); }
/* On success form.js deletes the <form>; this panel then IS the card content. */
:root :is(#mhja,.mhja-form-wrap,.mhja-portal) .mhja-form-status { padding: var(--mhja-s5); background-color: var(--mhja-surface); border: 1px solid var(--mhja-border); }
:root :is(#mhja,.mhja-form-wrap,.mhja-portal) .mhja-error-summary-title { margin: 0 0 var(--mhja-s2); color: var(--mhja-error); font-size: 1.05em; font-weight: 700; line-height: 1.4; }

/* Bullets are declared on the <li>: a theme's `li { list-style: none }` matches
   the li directly and beats any list-style we merely inherit down to it. */
:root :is(#mhja,.mhja-form-wrap,.mhja-portal) .mhja-error-summary ul { margin: 0; padding-inline-start: 1.3em; list-style: disc; }
:root :is(#mhja,.mhja-form-wrap,.mhja-portal) .mhja-error-summary li { margin: var(--mhja-s1) 0; color: inherit; list-style: disc; }
/* A classless <p> in the summary is form.js's network-failure shape. */
:root :is(#mhja,.mhja-form-wrap,.mhja-portal) .mhja-error-summary p:not(.mhja-error-summary-title) { margin: 0; font-weight: 600; }
/* Inline links are exempt from the 44px rule (WCAG 2.5.8), not from 4.5:1. */
:root :is(#mhja,.mhja-form-wrap,.mhja-portal) .mhja-error-summary a { display: inline-block; padding: .15rem 0; color: var(--mhja-error); }

:root :is(#mhja,.mhja-form-wrap,.mhja-portal) .mhja-form-status p { margin: 0; }
:root :is(#mhja,.mhja-form-wrap,.mhja-portal) .mhja-form-status p + p { margin-top: var(--mhja-s2); }
:root :is(#mhja,.mhja-form-wrap,.mhja-portal) .mhja-success-title { color: var(--mhja-ok); font-size: 1.1em; font-weight: 700; }

/* <noscript>, the empty application list, and the read-only portal form. */
:root :is(#mhja,.mhja-form-wrap,.mhja-portal) .mhja-notice {
	background-color: transparent; border: 1px solid var(--mhja-border);
	color: var(--mhja-text-muted); font-size: .9375em;
}

/* "Haku on päättynyt." FormShortcode returns this <p> with NO plugin wrapper,
   so it is never a descendant of a plugin root and the standard prefix could
   never match it: the class is doubled behind the same #mhja anchor instead,
   which reaches (1,1,0) outside any root. The tokens do reach it - §1 lists
   .mhja-notice--closed itself - and FormShortcode now enqueues this sheet
   before that early return; the literal var() fallbacks stay as insurance for
   a site that dequeues or re-scopes the tokens. */
:is(#mhja,.mhja-notice--closed).mhja-notice--closed {
	box-sizing: border-box; margin: 0; padding: 1rem 1.25rem;
	/* Opaque on purpose: this <p> is the one thing the plugin renders OUTSIDE
	   any panel, so it cannot borrow a surface and must paint its own or its
	   dark ink would land on whatever the theme puts behind it. */
	background-color: var(--mhja-surface, #fff); color: var(--mhja-text, #1e1e1e);
	border: 1px solid var(--mhja-border, #6f7591);
	border-radius: var(--mhja-radius, 6px);
	font-size: 1em; font-style: normal; font-weight: 600; text-align: start;
}

/* --- 10. Files ---------------------------------------------------------- */

/* Dashed reads as "put something here" without any extra chrome. */
:root :is(#mhja,.mhja-form-wrap,.mhja-portal) .mhja-field input[type="file"] {
	box-sizing: border-box; display: block; width: 100%; max-width: 100%;
	height: auto; min-height: var(--mhja-tap); margin: 0; padding: var(--mhja-s2);
	background-color: var(--mhja-surface-2); background-image: none;
	color: var(--mhja-text-muted); border: 1px dashed var(--mhja-border);
	border-radius: var(--mhja-radius); box-shadow: none;
	font: inherit; font-size: max(.9375rem, 15px); line-height: 1.5; cursor: pointer;
}

/* The two file-button pseudo-elements cannot share a selector list - an unknown
   pseudo-element invalidates the whole list - so the block is written twice. */
:root :is(#mhja,.mhja-form-wrap,.mhja-portal) .mhja-field input[type="file"]::file-selector-button {
	appearance: none; -webkit-appearance: none; min-height: 2rem;
	margin: 0; margin-inline-end: var(--mhja-s3); padding: .375rem .75rem;
	background-color: var(--mhja-surface); color: var(--mhja-accent-strong);
	border: 1px solid var(--mhja-border); border-radius: var(--mhja-radius);
	font: inherit; font-weight: 600; cursor: pointer;
}
:root :is(#mhja,.mhja-form-wrap,.mhja-portal) .mhja-field input[type="file"]::-webkit-file-upload-button {
	-webkit-appearance: none; min-height: 2rem;
	margin: 0; margin-inline-end: var(--mhja-s3); padding: .375rem .75rem;
	background-color: var(--mhja-surface); color: var(--mhja-accent-strong);
	border: 1px solid var(--mhja-border); border-radius: var(--mhja-radius);
	font: inherit; font-weight: 600; cursor: pointer;
}

/* An aria-live <ul> that is empty most of the time: it keeps its place in the
   accessibility tree (never display:none) and all spacing lives on the <li>, so
   it occupies exactly nothing until a file is chosen. */
:root :is(#mhja,.mhja-form-wrap,.mhja-portal) .mhja-file-list { margin: 0; padding: 0; list-style: none; }
:root :is(#mhja,.mhja-form-wrap,.mhja-portal) :is(.mhja-file-list li,.mhja-attachment) {
	display: flex; flex-wrap: wrap; align-items: center; gap: 0 var(--mhja-s2);
	margin: var(--mhja-s2) 0 0; padding: var(--mhja-s1) 0;
	background-color: transparent;
	list-style: none; overflow-wrap: anywhere;
}
:root :is(#mhja,.mhja-form-wrap,.mhja-portal) .mhja-attachments { margin: 0 0 var(--mhja-s2); }

/* Sits inline inside an attachment row, so it opts out of the option row. Both
   classes are named because .mhja-option and .mhja-remove are equal weight and
   source order alone is at the mercy of any minifier. !important 6/7 - it must
   answer the !important on .mhja-option's own display; :not([hidden]) keeps it
   from re-showing a hidden row (§2). It keeps the full --mhja-tap target: it is
   a destructive control sitting a hair from the download link, and every other
   target in this file is 44px. */
:root :is(#mhja,.mhja-form-wrap,.mhja-portal) .mhja-option.mhja-remove:not([hidden]) {
	display: inline-flex !important; min-height: var(--mhja-tap); margin-inline-start: auto;
	padding: var(--mhja-s1) var(--mhja-s2); border-color: transparent;
	color: var(--mhja-text-muted); font-size: .9375em;
}

/* --- 11. Buttons and link-buttons --------------------------------------- */

:root :is(#mhja,.mhja-form-wrap,.mhja-portal) .mhja-actions {
	display: flex; flex-wrap: wrap; align-items: center;
	gap: var(--mhja-s2) var(--mhja-s4); margin: var(--mhja-s2) 0 0; padding: 0;
}

:root :is(#mhja,.mhja-form-wrap,.mhja-portal) :is(.mhja-submit,.mhja-portal-logout,.mhja-portal-edit-button) {
	appearance: none; -webkit-appearance: none; box-sizing: border-box;
	display: inline-flex; align-items: center; justify-content: center;
	max-width: 100%; height: auto; min-height: var(--mhja-tap);
	margin: 0; padding: .6875rem 1.375rem;
	/* background-image, not just -color: Astra, GeneratePress, Kadence and Divi
	   paint their CTA with the `background` SHORTHAND, so a gradient survives
	   underneath our fill unless the image layer is explicitly cleared. */
	background-image: none;
	border: 1px solid transparent; box-shadow: none;
	/* The pill and the display face ARE the brand button (radius 30px, Baloo 2
	   500-600 on the site's own CTAs). */
	border-radius: var(--mhja-radius-pill, var(--mhja-radius));
	font-size: max(1rem, 16px); font-weight: 600; line-height: 1.3;
	text-align: center; text-decoration: none; text-shadow: none; cursor: pointer;
	transition: background-color var(--mhja-dur) ease, border-color var(--mhja-dur) ease, color var(--mhja-dur) ease;
}

/* The neutraliser in §3 sets font-family: inherit on every button at
   (1,2,1), which outweighs the shared rule above - so the brand face is
   applied with the doubled prefix, reaching (1,3,1). */
:root :is(.mhja-form-wrap,.mhja-portal):is(#mhja,.mhja-form-wrap,.mhja-portal) :is(.mhja-submit,.mhja-portal-logout,.mhja-portal-edit-button) {
	font-family: var(--mhja-font-display);
}

/* Full width until the container earns the room (--mhja-btn, §13).
   min-inline-size holds the box still when form.js swaps the label for
   "Lähetetään…"; min() so a 300px sidebar can never be overflowed. */
:root :is(#mhja,.mhja-form-wrap,.mhja-portal) .mhja-submit {
	width: var(--mhja-btn, 100%); min-inline-size: min(14rem, 100%);
	/* 18.67px is the WCAG large-BOLD threshold: at or above it the white label
	   on the brand magenta needs 3:1, which #eb0064's 4.46:1 clears. Below it
	   the requirement is 4.5:1, which the exact brand colour misses by 0.04 -
	   so the size is pinned rather than the brand colour altered. */
	font-size: max(1.0625em, 18.67px);
	background-color: var(--mhja-accent); color: var(--mhja-accent-ink); border-color: var(--mhja-accent);
}
:root :is(#mhja,.mhja-form-wrap,.mhja-portal) .mhja-submit:hover:enabled { background-color: var(--mhja-accent-strong); border-color: var(--mhja-accent-strong); }

/* Both are bare <button>s carrying neither .mhja-submit nor .mhja-link, so
   without this they inherit the theme's CTA - wrong for "Kirjaudu ulos" in a
   thin bar. Outlined, so neither competes with the primary action. */
:root :is(#mhja,.mhja-form-wrap,.mhja-portal) :is(.mhja-portal-logout,.mhja-portal-edit-button) {
	background-color: var(--mhja-surface); color: var(--mhja-accent-strong); border-color: var(--mhja-border);
}
:root :is(#mhja,.mhja-form-wrap,.mhja-portal) :is(.mhja-portal-logout,.mhja-portal-edit-button):hover { background-color: var(--mhja-accent-wash); border-color: var(--mhja-accent); }
:root :is(#mhja,.mhja-form-wrap,.mhja-portal) .mhja-portal-logout { padding: var(--mhja-s2) var(--mhja-s4); font-size: .9375em; }

/* !important 7/7. A button dressed as a link (resend code, back to list). Astra
   turns it into a 15px/30px filled CTA; GeneratePress, Kadence, Elementor and
   Divi all target bare `button`, and Divi does it from an id. Every property
   they set is answered; :not([hidden]) keeps the !important display from
   re-showing a hidden button (§2). */
:root :is(#mhja,.mhja-form-wrap,.mhja-portal) .mhja-link:not([hidden]) {
	appearance: none !important; -webkit-appearance: none !important;
	display: inline-flex !important; align-items: center !important;
	width: auto !important; min-height: var(--mhja-tap) !important;
	margin: 0 !important; padding: var(--mhja-s1) !important;
	background: none !important; color: var(--mhja-accent-strong) !important;
	border: 0 !important; border-radius: var(--mhja-radius) !important;
	box-shadow: none !important; font: inherit !important; font-size: 1em !important;
	font-weight: 600 !important; letter-spacing: normal !important;
	text-transform: none !important; text-decoration: underline !important;
	text-underline-offset: 3px !important; cursor: pointer !important;
}

/* Waiting is not invisible: both stay >= 4.5:1. The submit is disabled while a
   request is in flight, the resend button during its 60 s countdown. */
:root :is(#mhja,.mhja-form-wrap,.mhja-portal) .mhja-link:disabled { color: var(--mhja-text-muted) !important; text-decoration: none !important; cursor: default !important; }
:root :is(#mhja,.mhja-form-wrap,.mhja-portal) .mhja-submit:disabled { background-color: var(--mhja-text-muted); border-color: var(--mhja-text-muted); cursor: default; }

/* --- 12. Portal shell --------------------------------------------------- */

:root :is(#mhja,.mhja-portal) .mhja-portal-bar {
	display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between;
	gap: var(--mhja-s3) var(--mhja-s4); margin: 0 0 var(--mhja-gap);
	padding: 0 0 var(--mhja-s3); border-bottom: 1px solid var(--mhja-rule);
}
:root :is(#mhja,.mhja-portal) .mhja-portal-user { min-width: 0; font-weight: 600; overflow-wrap: anywhere; }

/* role="status" live region. Deliberately NOT display:none when empty: a region
   removed from the accessibility tree and restored in the same tick as its text
   change is silently skipped by some screen readers. Emptied, it collapses. */
:root :is(#mhja,.mhja-portal) .mhja-portal-message {
	margin: 0 0 var(--mhja-gap); padding: 0;
	background-color: transparent; border: 0; border-radius: 0;
	font-size: .9375em;
}
:root :is(#mhja,.mhja-portal) .mhja-portal-message:empty { margin: 0; padding: 0; background: none; border: 0; }

/* The status is carried by a masked icon in the text colour, the same device
   the field errors and the success title use. A tinted card with a coloured
   rail would say the same thing far more loudly. */
:root :is(#mhja,.mhja-portal) .mhja-portal-message:not(:empty) { display: flex; align-items: flex-start; gap: var(--mhja-s2); }
:root :is(#mhja,.mhja-portal) .mhja-portal-message:not(:empty)::before {
	content: ""; flex: 0 0 auto; width: 1.05em; height: 1.05em; margin-top: .2em;
	background-color: currentColor;
	-webkit-mask: var(--mhja-icon-ok) center / contain no-repeat;
	mask: var(--mhja-icon-ok) center / contain no-repeat;
}
:root :is(#mhja,.mhja-portal) .mhja-portal-message--error { color: var(--mhja-error); font-weight: 600; }
:root :is(#mhja,.mhja-portal) .mhja-portal-message--error:not(:empty)::before { -webkit-mask-image: var(--mhja-icon-alert); mask-image: var(--mhja-icon-alert); }

:root :is(#mhja,.mhja-portal) .mhja-portal-step { margin: 0; }
:root :is(#mhja,.mhja-portal) .mhja-portal-step > p { margin: 0 0 var(--mhja-gap); color: var(--mhja-text-muted); }
:root :is(#mhja,.mhja-portal) .mhja-portal-step--edit > p { margin: 0 0 var(--mhja-s3); }

/* Six digits: a short field reads as a short answer - but the box is
   border-box and inherits .75rem of inline padding plus two 1px borders, so a
   bare 9ch left room for about four of the six .25em-tracked digits. The
   padding and borders are added back explicitly. */
:root :is(#mhja,.mhja-portal) .mhja-portal-code-form .mhja-field input[type="text"] {
	inline-size: calc(11ch + 1.5rem + 2px); letter-spacing: .25em; font-variant-numeric: tabular-nums;
}

:root :is(#mhja,.mhja-portal) .mhja-portal-list { display: grid; gap: var(--mhja-s3); }

/* <article>, never div. A lighter echo of the panel, one level of nesting. */
:root :is(#mhja,.mhja-portal) .mhja-portal-item {
	display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--mhja-s2);
	margin: 0; padding: var(--mhja-s4); background-color: var(--mhja-surface);
	border: 1px solid var(--mhja-border); border-radius: var(--mhja-radius);
}
:root :is(#mhja,.mhja-portal) .mhja-portal-item-meta { margin: 0; overflow-wrap: anywhere; }
/* A closed application shows a state, not a dead button: a quiet outlined tag. */
:root :is(#mhja,.mhja-portal) .mhja-portal-item-note {
	margin: 0; padding: var(--mhja-s1) var(--mhja-s3);
	background-color: var(--mhja-surface); border: 1px solid var(--mhja-border);
	border-radius: 999px; font-size: .875em; font-weight: 600;
}
:root :is(#mhja,.mhja-portal) .mhja-portal-item :is(.mhja-portal-item-note,.mhja-portal-edit-button) { justify-self: start; }

/* Separates the regenerated edit form from the application title above it. */
:root :is(#mhja,.mhja-portal) .mhja-portal-edit { margin-top: var(--mhja-gap); padding-top: var(--mhja-gap); border-top: 1px solid var(--mhja-rule); }

/* --- 13. Layout ---------------------------------------------------------
   Single-column grids: the rhythm is the gap, so nothing collapses, no
   :last-child trim can mis-fire on a trailing --section, and nothing assumes a
   <form> is still present. The honeypot (absolute) and hidden inputs never
   become grid items. The widening step only sets custom properties, so the
   container query and its fallback are two lines each. The form can sit in a
   300px sidebar on a 1440px screen, so the viewport answers the wrong question:
   everything that reshapes queries the container it is actually in. */

:root :is(#mhja,.mhja-form-wrap,.mhja-portal) :is(.mhja-form,.mhja-portal-email-form,.mhja-portal-code-form) {
	display: grid; grid-template-columns: var(--mhja-cols, minmax(0, 1fr));
	gap: var(--mhja-gap); margin: 0; padding: 0; background: none; border: 0;
}
:root :is(#mhja,.mhja-form-wrap,.mhja-portal) .mhja-form > * { grid-column: 1 / -1; }

/* The one two-up pair, and only when both halves really are adjacent in the
   schema - otherwise a lone first_name would sit at half width. The wrappers
   already carry data-key, so this needs no markup change. */
:root :is(#mhja,.mhja-form-wrap,.mhja-portal) .mhja-form > [data-key="first_name"]:has(+ [data-key="last_name"]),
:root :is(#mhja,.mhja-form-wrap,.mhja-portal) .mhja-form > [data-key="first_name"]:has(+ [data-key="last_name"]) + * { grid-column: var(--mhja-pair, 1 / -1); }

@container mhja (min-width: 30rem) {
	:root :is(#mhja,.mhja-form-wrap,.mhja-portal) .mhja-form { --mhja-cols: minmax(0, 1fr) minmax(0, 1fr); --mhja-pair: auto; }
	:root :is(#mhja,.mhja-form-wrap,.mhja-portal) :is(.mhja-form,.mhja-portal-email-form,.mhja-portal-code-form) { --mhja-btn: auto; }
	:root :is(#mhja,.mhja-portal) .mhja-portal-item { grid-template-columns: minmax(0, 1fr) auto; align-items: center; }
	:root :is(#mhja,.mhja-portal) .mhja-portal-item > :is(.mhja-portal-item-note,.mhja-portal-edit-button) { grid-column: 2; grid-row: 1 / span 2; justify-self: end; }
}

/* One column is already the default, so only the wide case needs a viewport
   approximation where container queries are missing; @supports keeps it away
   from every browser that has them. */
@supports not (container-type: inline-size) {
	@media (min-width: 48em) {
		:root :is(#mhja,.mhja-form-wrap,.mhja-portal) .mhja-form { --mhja-cols: minmax(0, 1fr) minmax(0, 1fr); --mhja-pair: auto; }
		:root :is(#mhja,.mhja-form-wrap,.mhja-portal) :is(.mhja-form,.mhja-portal-email-form,.mhja-portal-code-form) { --mhja-btn: auto; }
	}
}

/* --- 14. Motion, forced colors, print ----------------------------------- */

/* Not counted among the seven: this block exists precisely to overrule
   `* { transition: all .3s }`, which Divi and most ThemeForest themes ship and
   which would otherwise fade error colours in and lag focus rings. */
@media (prefers-reduced-motion: reduce) {
	:root :is(#mhja,.mhja-form-wrap,.mhja-portal) *,
	:root :is(#mhja,.mhja-form-wrap,.mhja-portal) *::before,
	:root :is(#mhja,.mhja-form-wrap,.mhja-portal) *::after {
		transition-duration: .01ms !important; animation-duration: .01ms !important;
		animation-iteration-count: 1 !important;
	}
	/* The smooth scroll behind our focus jumps is the theme's
	   `html { scroll-behavior: smooth }`, on the scrolling element - nothing
	   inside the panel is a scroll container, and scroll-behavior does not
	   inherit, so a scoped declaration could never reach it. :has() reaches the
	   root, and only on a page that actually embeds this plugin. */
	:root:has(:is(.mhja-form-wrap,.mhja-portal)) { scroll-behavior: auto; }
}

/* The UA remaps our colours already; the job here is only to stop anything
   carried by background alone from vanishing and to hand the ring to Highlight.
   The width cues (2px invalid border, dashed disabled edge) are not colours and
   survive untouched. */
@media (forced-colors: active) {
	/* :not(:empty) on the live region: the border shorthand here outranks the
	   `:empty { border: 0 }` collapse in §12 and would draw an empty box on
	   every portal view. */
	:root :is(#mhja,.mhja-form-wrap,.mhja-portal),
	:root :is(#mhja,.mhja-form-wrap,.mhja-portal) :is(.mhja-field :is(input,select,textarea),.mhja-option:has(:checked),.mhja-file-list li,.mhja-attachment,.mhja-portal-item,.mhja-portal-message:not(:empty),.mhja-error-summary,.mhja-form-status,.mhja-notice,.mhja-field--consent) {
		border: 1px solid CanvasText;
	}
	/* No inline-start rail to restore any more: the panels are plain hairline
	   boxes, and what tells an error from a success once colour is gone is the
	   masked icon and the heading, both of which survive here. */
	/* A baked-in chevron cannot follow the system palette: give the select its
	   native arrow back rather than a possibly invisible image. */
	:root :is(#mhja,.mhja-form-wrap,.mhja-portal) .mhja-field.mhja-field select { appearance: auto; -webkit-appearance: auto; background-image: none; }
	/* The masked glyph is painted with currentColor, which forced colors can map
	   to the page background. Repainting it with a system colour keeps the icon
	   - hiding it would drop the only non-textual cue these messages have. */
	:root :is(#mhja,.mhja-form-wrap,.mhja-portal) :is(.mhja-error,.mhja-error-summary-title,.mhja-success-title)::before { background-color: CanvasText; }
	:root :is(#mhja,.mhja-form-wrap,.mhja-portal) :is(input,select,textarea,button,a,[tabindex]):focus-visible { outline-color: Highlight !important; }
}

/* Applicants do print the filled form and their application list. Re-pointing
   the tokens flattens the whole design in one block: every rule above reads
   through var(), so nothing needs restating and nothing needs !important.
   It carries the id anchor because the dark opt-in is (0,2,0) and a token
   block cannot be beaten by media type alone - unanchored, a site using
   .mhja-theme-dark printed a near-black card at 1.12:1 on white paper. Every
   token the palette defines is re-pointed here; leaving one out is how the
   dark value leaks through. Black on white, no greys: paper has no backlight
   and cheap printers dither mid-tones. */
@media print {
	:root :is(#mhja,.mhja-form-wrap,.mhja-form-container,.mhja-portal,.mhja-notice--closed) {
		color-scheme: light;
		--mhja-surface: #fff; --mhja-surface-2: #fff; --mhja-field-bg: #fff;
		--mhja-text: #000; --mhja-text-muted: #000;
		--mhja-rule: #000; --mhja-border: #000;
		--mhja-accent: #000; --mhja-accent-strong: #000;
		--mhja-accent-ink: #fff; --mhja-accent-wash: #fff;
		--mhja-error: #000; --mhja-error-wash: #fff;
		--mhja-ok: #000; --mhja-ok-wash: #fff;
		--mhja-focus: #000;
		--mhja-arrow: none;
	}
	:root :is(#mhja,.mhja-form-wrap,.mhja-portal) { margin: 0; padding: 0; border: 0; }
	:root :is(#mhja,.mhja-form-wrap,.mhja-portal) :is(.mhja-actions,.mhja-portal-bar,.mhja-portal-message,.mhja-field input[type="file"]) { display: none; }
	:root :is(#mhja,.mhja-form-wrap,.mhja-portal) :is(.mhja-field,.mhja-portal-item,.mhja-attachment,.mhja-error-summary,.mhja-form-status) { break-inside: avoid; }
	:root :is(#mhja,.mhja-form-wrap,.mhja-portal) :is(.mhja-form-title,.mhja-section-title) { break-after: avoid; }
}
