/**
 * Vakanssi careers front-end design system.
 *
 * Conventions:
 * - Every color, size, and radius flows through the `--vakanssi-*` custom
 *   properties below so a future dark scheme (or the Custom CSS setting) only
 *   has to override tokens, never component rules.
 * - Each `var()` declaration is preceded by a static fallback, and each logical
 *   property by its physical equivalent, so browsers without custom-property or
 *   logical-property support still render a sane layout.
 * - Typography inherits from the active theme; sizes are em-based so the
 *   components scale with whatever context they are embedded in.
 */

:root {
	/* Ink (text). */
	--vakanssi-ink: #1e2936;
	--vakanssi-text: #3a4552;
	--vakanssi-muted: #5f6b7a;
	--vakanssi-faint: #98a2b0;

	/* Surfaces and lines. */
	--vakanssi-surface: #ffffff;
	--vakanssi-surface-subtle: #f6f8fa;
	--vakanssi-border: #e2e6eb;
	--vakanssi-border-strong: #c9d1da;

	/* Accent — the brand teal by default. Overridden at runtime from the one
	   brand accent (Settings -> Emails -> Branding) via wp_add_inline_style, so
	   every candidate-facing surface, the emails, and the admin's chosen color
	   all agree. These values are the default that shows before that override
	   (and the fallback if inline styles are removed). */
	--vakanssi-accent: #0f766e;
	--vakanssi-accent-strong: #0c615a;
	--vakanssi-accent-contrast: #ffffff;
	--vakanssi-accent-tint: #e7f1f1;
	--vakanssi-accent-tint-border: #bcd9d6;
	--vakanssi-focus-ring: rgba(15, 118, 110, 0.28);

	/* Feedback. */
	--vakanssi-success-text: #1d5a34;
	--vakanssi-success-bg: #f2f8f4;
	--vakanssi-success-border: #b9dcc6;
	--vakanssi-danger-text: #9f3a38;
	--vakanssi-danger-bg: #fbf4f4;
	--vakanssi-danger-border: #e7c6c5;

	/* Shape and elevation. */
	--vakanssi-radius-sm: 4px;
	--vakanssi-radius: 6px;
	--vakanssi-radius-lg: 10px;
	--vakanssi-shadow-sm: 0 1px 2px rgba(20, 30, 45, 0.05);
	--vakanssi-shadow-md: 0 4px 14px rgba(20, 30, 45, 0.07);

	/* Type scale. Each step is a ratio of the UI base below, because every
	   candidate surface sets that base on its outermost wrapper. */
	--vakanssi-text-2xs: 0.75em;
	--vakanssi-text-xs: 0.8125em;
	--vakanssi-text-sm: 0.875em;
	--vakanssi-text-md: 0.9375em;
	--vakanssi-text-lg: 1.0625em;

	/* The UI base: the theme's own size, held between 15 and 17px. Themes run
	   their body text from 14px (OceanWP) to 22px (Twenty Twenty-Five), and
	   every size above used to copy that prose size into the controls, rows
	   and labels. The upper bound follows the visitor's own text size setting
	   (1.0625rem is 17px at the browser default). The em in it resolves where
	   the token is used: on a font-size, against the parent's size. */
	--vakanssi-ui-size: clamp(15px, 1em, max(17px, 1.0625rem));

	/* Reading measure: 60 of the UI base, held to 960px at the default text
	   size (60rem; more for a visitor who enlarged their text). Caps the list
	   layout and the job page column so the chevron and the description stay
	   in reach of the title. Computes the same on an element whose own font is
	   the UI base (the board) as on one that inherits the theme size (the job
	   page), because the clamp is evaluated on the element itself. */
	--vakanssi-measure: min(calc(60 * clamp(15px, 1em, max(17px, 1.0625rem))), max(60rem, 960px));

	/* One space between the blocks the plugin adds to a job page (Apply jump,
	   details, form, related roles, back link), in em of the UI base. */
	--vakanssi-block-gap: 1.75em;

	/* Controls: one border, one focus ring, one hover timing for every
	   candidate control. The border is the lightest that still clears 3:1
	   on the surface the control sits on (it read as near black at 4.6:1).
	   Form controls sit on the form's own white surface: 3.0:1. The jobs
	   bar, its selects and the page arrows sit on the theme's page, which
	   may be tinted, so theirs clears 3:1 on every page measured: white
	   3.9:1, Twenty Twenty-One's green 3.0:1, Twenty Twenty's cream 3.4:1.
	   Hover darkens to 4.6:1 on white; focus turns it to the accent, and
	   the ring is a solid outline in the accent, which Branding darkens
	   until it clears 4.5:1 on white. */
	--vakanssi-control-border: #8c95a3;
	--vakanssi-control-border-page: #758091;
	--vakanssi-control-border-hover: #6b7686;
	--vakanssi-focus-width: 2px;
	--vakanssi-focus-offset: 2px;
	/* The invalid mark's start edge: a field the server named in its error
	   draws its start border this wide, in the danger colour. One width for
	   every kind of field: a text box, a select, a group of checkboxes. */
	--vakanssi-invalid-edge: 4px;
	--vakanssi-hover-duration: 0.2s;
}

/* ------------------------------------------------------------------ *
 *  The UI base on every candidate surface's outermost wrapper
 * ------------------------------------------------------------------ */

/* The board (and its empty state: both carry data-vakanssi-jobs), the job
   page blocks the plugin appends (Apply jump and button, details, the form,
   related roles), and the fixed notice. The job description is not here: it
   is the theme's prose and keeps the theme's size. Wrappers with a size of
   their own (pagination, back link) state it as a ratio of the same base
   below. The weight floor is for themes that set light body text (Twenty
   Twenty-Five uses 300), which reads faint at UI sizes; bold parts set their
   own weight. Nested wrappers are safe: a clamp of a value already inside
   the range returns it unchanged. */
[data-vakanssi-jobs],
.vakanssi-job-details,
.vakanssi-apply,
.vakanssi-apply-form,
.vakanssi-related,
.vakanssi-apply-result {
	font-size: 1em;
	font-size: var(--vakanssi-ui-size, clamp(15px, 1em, max(17px, 1.0625rem)));
	font-weight: 400;
	line-height: 1.5;
}

/* ------------------------------------------------------------------ *
 *  Careers archive wrapper (templates/archive-jobs.php)
 * ------------------------------------------------------------------ */

/* The `:where(:not(.wp-block-group))` guard makes this the CLASSIC-theme rule
   only, and costs nothing: :where() contributes zero specificity, so the weight
   is still (0,1,0), well under the (0,5,0) Custom CSS boost.

   On a block theme the same class rides on the constrained-layout `wp:group`
   that CareersArchive::register_block_template() emits. That group already caps
   its children at the content size and carries the theme's root padding, so
   applying the box below there would cap inside a cap and pad twice: a visibly
   narrower, double-padded column. There, the class is purely a Custom CSS hook
   and the theme owns the column, which is the right answer on a block theme. */
.vakanssi-careers-archive:where(:not(.wp-block-group, .vakanssi-theme-column)) {
	/* Match the theme's own content column when it publishes one (theme.json
	   contentSize -> --wp--style--global--content-size; Astra, Kadence, Hello,
	   GeneratePress with global styles). The reading measure is the fallback
	   for themes that publish nothing, and the floor for the rest: the careers
	   list on a classic theme sits in the theme's page column and caps at the
	   measure whatever the theme publishes, so a smaller published size (Hello
	   Elementor's 800px, which its own pages do not use) made this column
	   narrower than the list. The two are as wide as each other unless the
	   theme's pages carry a sidebar (GeneratePress, OceanWP), which this
	   template does not print. It used to be 46rem, which is 460px on a theme
	   whose root size is 10px. */
	max-width: 960px;
	max-inline-size: 960px;
	max-width: max(var(--wp--style--global--content-size, 0px), var(--vakanssi-measure, 960px));
	max-inline-size: max(var(--wp--style--global--content-size, 0px), var(--vakanssi-measure, 960px));
	margin: 2.5rem auto 3.5rem;
	margin-block: 2.5rem 3.5rem;
	margin-inline: auto;
	padding: 0 1.25rem;
	padding-block: 0;
	padding-inline: 1.25rem;
}

/* Block themes: the careers page (the plugin's "Careers" page template,
   CareersPageTemplate), the jobs archive and the job page share ONE column,
   the theme's wide size held to 60rem (960px at the default text size). On a
   block theme every constrained child is sized by these two variables, so
   setting them on the template's main group moves the title, the listing
   and the job description together, and the job page comes out exactly as
   wide as the careers page. They were the theme's prose column (645px on
   Twenty Twenty-Five), a strip under a wide header.

   The variable is read on body, where WordPress defines the theme's sizes,
   then handed down. The rule below weighs (0,1,0), so a site's own
   `.vakanssi-careers-page { --wp--style--global--content-size: ...; }` in
   Additional CSS (printed after this sheet) wins. */
body {
	--vakanssi-column: min(var(--wp--style--global--wide-size, 60rem), 60rem);
	/* The theme's own prose measure, read here before the rule below widens
	   the content size to the column (the job description's cap). */
	--vakanssi-prose-measure: var(--wp--style--global--content-size, 50ch);
}

:where(.vakanssi-careers-page, .vakanssi-careers-archive, .vakanssi-single-job).wp-block-group {
	--wp--style--global--content-size: var(--vakanssi-column, 60rem);
	--wp--style--global--wide-size: var(--vakanssi-column, 60rem);
}

/* The jobs list below provides its own top rule, so the header stays quiet.

   Guarded like the wrapper above, and for the same reason stated once here for
   every remaining wrapper rule: on a block theme these classes ride on core
   blocks (wp:group, wp:post-title, wp:post-featured-image) whose spacing and
   presentation the THEME already owns through theme.json. Leaving our
   declarations to fight that produced exactly one real difference in testing,
   a 10px border-radius appearing on featured images that had none, which is a
   visual change no one asked for on upgrade. So on block themes these are pure
   Custom CSS hooks and nothing else, which is also what the docs promise. */
.vakanssi-careers-header:where(:not(.wp-block-group)) {
	margin-bottom: 1.75rem;
	margin-block-end: 1.75rem;
}

.vakanssi-careers-header:where(:not(.wp-block-group)) h1 {
	margin: 0;
}

/* ------------------------------------------------------------------ *
 *  Single job page (templates/single-jobs.php)
 *  Owns the content column only; the details block, apply CTA, related
 *  roles, and back link are appended by JobDetails and bring their own
 *  (archive-shared) styles.
 * ------------------------------------------------------------------ */

/* Classic-theme only, for the same reason as .vakanssi-careers-archive above:
   on a block theme this class sits on a constrained-layout group that already
   owns the column, and re-applying the box would double-constrain it. */
.vakanssi-single-job:where(:not(.wp-block-group, .vakanssi-theme-column)) {
	/* Same rule as the archive above: the job page shares the careers page's
	   column instead of a second, plugin-imposed width. The template also
	   gives the article and the body the theme's own `entry-content` class,
	   so a theme that lays its posts out through it (Twenty Twenty-One, Twenty
	   Twenty) sets this column, the description's rhythm and its word
	   wrapping exactly as on its own posts and pages. */
	/* The column plus the padding below, which keeps the text off the screen
	   edges on a phone: the text itself gets the full column. The full
	   width is stated because some themes open a flex container in their
	   header (Astra's .ast-container), where an auto-width item shrinks to its
	   content and was centred 120px in from the theme's own column. */
	box-sizing: border-box;
	width: 100%;
	inline-size: 100%;
	max-width: calc(960px + 2.5rem);
	max-inline-size: calc(960px + 2.5rem);
	max-width: calc(max(var(--wp--style--global--content-size, 0px), var(--vakanssi-measure, 960px)) + 2.5rem);
	max-inline-size: calc(max(var(--wp--style--global--content-size, 0px), var(--vakanssi-measure, 960px)) + 2.5rem);
	margin: 2.5rem auto 3.5rem;
	margin-block: 2.5rem 3.5rem;
	margin-inline: auto;
	padding: 0 1.25rem;
	padding-block: 0;
	padding-inline: 1.25rem;
}

/* Classic themes that size the page column themselves
   (ThemeShell::COLUMN_CLASSES: the template borrows the theme's column class,
   or sits in the column the theme's header opened): the box above is left
   out, so the job page and the archive start on the theme's content edge,
   where the careers list starts, and the theme's own breakpoints and gutters
   apply. Only the vertical rhythm stays. The flex line fills a header that
   opened a flex container (Astra's .ast-container) and does nothing
   anywhere else. */
.vakanssi-careers-archive.vakanssi-theme-column,
.vakanssi-single-job.vakanssi-theme-column {
	flex: 1 1 100%;
	margin-top: 2.5rem;
	margin-bottom: 3.5rem;
	margin-block: 2.5rem 3.5rem;
}

/* A long unbroken word or URL in the job title or the description breaks
   instead of pushing the page sideways (754px of sideways scroll at 320px on
   Twenty Twenty-One), on both theme kinds and whether or not the theme
   styles .entry-content. Inherited, so the theme's prose keeps its own
   rules for everything else. */
.vakanssi-single-job {
	overflow-wrap: break-word;
}

/* Inside a wide theme column (Astra 1200px, Kadence 1242px) the title and
   the body stop at the reading measure, on the column's start edge, like the
   careers list. A theme that centres its content children (Twenty
   Twenty-One's `.entry-content > *` rule) out-weighs this and keeps its own. */
.vakanssi-single-job__article:where(:not(.wp-block-group)) > * {
	max-width: 960px;
	max-inline-size: var(--vakanssi-measure, 960px);
	margin-inline: 0 auto;
}

/* Twenty Twenty and Twenty-One set their own prose measure on every
   `.entry-content` child (580px / 610px, centred), as on their pages, where
   the careers list takes it too. The header and the body carry that class, so
   there they stay full width and the theme places what is inside them. */
.vakanssi-theme-prose .vakanssi-single-job__article:where(:not(.wp-block-group)) > * {
	max-width: none;
	max-inline-size: none;
	margin-inline: 0;
}

.vakanssi-single-job__title:where(:not(.wp-block-post-title)) {
	margin: 0 0 1rem;
	margin-block: 0 1rem;
}

/* The job description's own rhythm, classic themes only.

   A classic theme spaces post prose through its content wrapper, almost always
   `.entry-content > *`, and resets the elements themselves to zero: Twenty
   Twenty-One ships `p, ul, ol, h1-h6 { margin: 0 }`. This template owns the
   content column and prints the body in `.vakanssi-single-job__body`, not in
   the theme's wrapper, so that reset was all that applied and the description
   rendered as one wall of text. Hello Elementor left lists with no space below.

   (0,1,0) clears the element resets (0,0,1). `:where()` keeps it there, and the
   `:not([class*="vakanssi-"])` filter leaves the blocks this plugin appends to
   the same column (details, apply CTA, back link) to their own rules. On a
   block theme the class rides on core's post-content block, whose flow layout
   already applies the theme's block gap, so these stay out of its way. */
.vakanssi-single-job__body:where(:not(.wp-block-post-content)) > :where(p, ul, ol, dl, blockquote, figure, pre, table, h2, h3, h4, h5, h6):where(:not([class*="vakanssi-"])) {
	margin-top: 0;
	margin-bottom: 1em;
	margin-block: 0 1em;
}

.vakanssi-single-job__body:where(:not(.wp-block-post-content)) > :where(h2, h3, h4, h5, h6):where(:not([class*="vakanssi-"])) {
	margin-top: 1.25em;
	margin-bottom: 0.5em;
	margin-block: 1.25em 0.5em;
}

.vakanssi-single-job__body:where(:not(.wp-block-post-content)) > :where(:first-child) {
	margin-top: 0;
	margin-block-start: 0;
}

.vakanssi-single-job__body:where(:not(.wp-block-post-content)) > :where(ul, ol):where(:not([class*="vakanssi-"])) {
	padding: 0 0 0 1.5em;
	padding-block: 0;
	padding-inline: 1.5em 0;
}

.vakanssi-single-job__body:where(:not(.wp-block-post-content)) > :where(ul, ol):where(:not([class*="vakanssi-"])) > :where(li + li) {
	margin-top: 0.35em;
	margin-block-start: 0.35em;
}

/* Block themes: the job description's prose keeps the theme's prose size
   and the theme's prose measure, its content size (645px on Twenty
   Twenty-Five, 59 to 75 characters a line), on the column's start edge (the
   post-content block lays out as flow, so nothing centres it). The
   job column is the careers column (960px), and 22px text ran 99 characters
   a line across it. Every block of the description is held to it, the way
   the theme's constrained layout holds a post's blocks (images, tables,
   groups and columns too, not only text). Core's layout caps wide blocks
   at the wide size, which on the job page is the column, so wide keeps the
   column; full blocks and left and right floats are left out by core too,
   and here. Only the description's own blocks: the facts, the Apply area, the form
   and the related roles carry vakanssi- classes and keep the full column.
   The fallback, for a theme that publishes no content size, is about 65
   characters a line at the theme's text size.

   Classic themes publish no measure their posts use (Hello Elementor's 800px
   is its editor's; its posts are 1140px wide), and a fixed one would make
   the description narrower than the theme's own posts on GeneratePress,
   Neve, Blocksy, OceanWP and Hello, so there the column stays; Twenty Twenty
   and Twenty-One set their own prose measure through `entry-content`. */
.vakanssi-single-job__body:where(.wp-block-post-content) > :where(:not([class*="vakanssi-"], .alignwide, .alignfull, .alignleft, .alignright)) {
	max-width: 50ch;
	max-inline-size: 50ch;
	max-width: var(--vakanssi-prose-measure, 50ch);
	max-inline-size: var(--vakanssi-prose-measure, 50ch);
}

/* A separator (an <hr>, the Separator block's and the classic editor's)
   held to that measure would be centred by the browser's own
   `hr { margin-inline: auto }`, off the text's start edge. On the theme's
   posts it spans the text column exactly, so it starts where the text
   starts here too. (0,1,0), the hr in :where(): over the browser's rule,
   while a site's own one-class separator rule printed after this sheet
   (Additional CSS) still wins and can centre it. */
.vakanssi-single-job__body:where(.wp-block-post-content) > :where(hr):where(:not([class*="vakanssi-"], .alignwide, .alignfull)) {
	margin-left: 0;
	margin-right: 0;
	margin-inline: 0;
}

/* ------------------------------------------------------------------ *
 *  Jobs listing — [vakanssi_jobs]
 * ------------------------------------------------------------------ */

/* Reserve the scrollbar gutter on the listing page only, so filtering to a
   shorter result set can't toggle the scrollbar and shift the centred content
   sideways. Scoped via :has() so other pages are untouched. */
html:has(.vakanssi-jobs-board),
html:has(.vakanssi-single-job) {
	scrollbar-gutter: stable;
}

/* Decorative inline SVGs carry their size as width/height attributes. A theme
   reset of `svg { width: 100%; height: auto }` — Tailwind preflight and every
   theme built on it ships one — overrides those attributes and blows the icon
   up to its container's width; the sort chevron became a 91px arrow across the
   control. `auto` restores the attribute-declared intrinsic size. Icons that
   must not move are additionally pinned in px where they are defined. */
[class*="vakanssi-"] svg {
	inline-size: auto;
	block-size: auto;
	max-inline-size: 100%;
}

/* <bdi> is only worth shipping while it still isolates. Its whole behaviour is
   one UA declaration (`unicode-bidi: isolate`), which any theme reset that
   touches generic inline elements can flatten, and the failure is invisible in
   LTR: a page-range readout that quietly reads "20-1" under he_IL. Declared on
   our own markup so nothing outside it is affected. */
[class*="vakanssi-"] bdi {
	unicode-bidi: isolate;
}

/* A list stops at a reading width. In a wide theme column (Astra 1200px,
   Blocksy 1282px, Kadence 1178px) a full-width row put the chevron and the
   salary a screen's width from the title. The cap is on the INNER wrapper
   only, on the start edge of the box the board gets: the board and the nav
   are what the theme and the block layout size and place (centred columns,
   constrained layouts), so they are never given a width or a margin here.
   A grid board keeps the container's width: its cards share it out. */
.vakanssi-jobs-board:not(.vakanssi-jobs-board--grid) > .vakanssi-jobs-board__inner,
.vakanssi-jobs-board:not(.vakanssi-jobs-board--grid) + .vakanssi-jobs-pagination > .vakanssi-jobs-pagination__inner {
	max-width: 960px;
	max-inline-size: var(--vakanssi-measure, 960px);
}

/* Command bar (search / team / remote / sort). Progressive enhancement, but
   the bar renders visible unconditionally; nothing reveals or hides it.

   It used to be hidden here and revealed when careers.js added
   `.vakanssi-enhanced`. That reveal landed after first paint, so the bar pushed
   the meta line and the whole results list down about 59px roughly a second in:
   a measured 0.034 CLS on every careers page. A <noscript> hide for the (rare)
   no-JS visitor followed, and was dropped in turn because the wordpress.org
   enqueue policy cannot express it (see Shortcodes::render_jobs). With
   scripting off the controls simply do nothing. */
.vakanssi-jobs-bar {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 0.6em;
	margin-block-end: 0.9em;
}

/* Search grows to own the row; the controls after it keep their own width.
   The label — not the input — carries the field chrome, and the icon is a real
   flex item rather than an absolutely-positioned overlay. That is deliberate:
   the overlay reserved room for the icon with padding on the input, so any
   theme whose reset restyles `input[type="search"]` padding (Hello Elementor
   and every other normalize/preflight descendant does) dropped the gutter and
   ran the placeholder underneath the icon. With the icon in flow there is no
   padding contract left for a theme to break. */
.vakanssi-jobs-search {
	box-sizing: border-box;
	display: inline-flex;
	align-items: center;
	gap: 0.45em;
	flex: 1 1 13.75em;
	min-inline-size: 9em;
	padding-block: 0.5em;
	padding-inline: 0.7em;
	background: #ffffff;
	background: var(--vakanssi-surface, #ffffff);
	border: 1px solid #758091;
	border: 1px solid var(--vakanssi-control-border-page, #758091);
	border-radius: 6px;
	border-radius: var(--vakanssi-radius, 6px);
	transition: border-color 0.2s ease;
	transition: border-color var(--vakanssi-hover-duration, 0.2s) ease;
}

/* The search box and the remote switch are <label>s, and themes style bare
   `label`: Twenty Twenty-One gives every label a 10px bottom margin, its form
   font size and a 500 weight. That margin made the search field's margin box
   taller than the selects', so the centred row put its border 4px above
   theirs. These (0,2,0) rules restate only what a label reset reaches;
   everything else stays on the single-class rules, where a site's Custom CSS
   can still restyle it.

   The label's font size is the one the selects use, and the input inherits it
   (1em below), so the field's padding (0.5em) and line box (1.4) resolve
   against the same size as a select's, and the two come out the same height
   whatever size the theme's label rule asks for. */
.vakanssi-jobs-bar .vakanssi-jobs-search {
	margin: 0;
	font-size: 0.875em;
	font-size: var(--vakanssi-text-sm, 0.875em);
	font-weight: 400;
	line-height: 1.4;
}

.vakanssi-jobs-bar .vakanssi-jobs-remote {
	margin: 0;
	font-weight: 400;
	line-height: 1.4;
}

/* Hover darkens the field's border; focus turns it to the accent, and the
   ring itself comes from the one focus rule under "Focus, hover and control
   borders" near the end of this sheet. */
.vakanssi-jobs-search:hover {
	border-color: #6b7686;
	border-color: var(--vakanssi-control-border-hover, #6b7686);
}

.vakanssi-jobs-search:focus-within {
	border-color: #0f766e;
	border-color: var(--vakanssi-accent, #0f766e);
	box-shadow: none;
}

/* Explicit box: themes shipping `svg { width: 100%; height: auto }` would
   otherwise stretch the icon and squeeze the input out of the row. */
.vakanssi-jobs-search .vakanssi-jobs-searchicon {
	flex: none;
	inline-size: 16px;
	block-size: 16px;
	color: #98a2b0;
	color: var(--vakanssi-faint, #98a2b0);
	pointer-events: none;
}

/* The input is chrome-less — the label above draws the field. Every property a
   theme reset is likely to touch is restated so the control renders the same
   under any theme. Scoped to clear the specificity floor enforced by
   bin/check-frontend-css.php.

   `appearance: auto` rather than `none`: the search box is the one control here
   whose native widget earns its keep, because it carries the browser's clear
   button and nothing else on the board clears the query (the active-filter
   chips only cover team and remote). Themes toggle that button on and off at
   random — Hello Elementor's `[type="search"] { appearance: textfield }` hides
   it — so pinning it to `auto` is what makes the affordance consistent. Author
   border/background still win over the native paint on a text control, so the
   field stays flat. */
.vakanssi-jobs-bar .vakanssi-jobs-searchinput {
	flex: 1 1 auto;
	box-sizing: border-box;
	inline-size: 100%;
	min-inline-size: 0;
	max-inline-size: 100%;
	/* Astra gives every search input a fixed 40px height, which made the
	   search field 16px taller than the team select beside it. */
	height: auto;
	block-size: auto;
	min-block-size: 0;
	margin: 0;
	padding: 0;
	font: inherit;
	font-size: 1em;
	line-height: 1.4;
	color: #1e2936;
	color: var(--vakanssi-ink, #1e2936);
	background: none;
	border: 0;
	border-radius: 0;
	box-shadow: none;
	outline: none;
	appearance: auto;
}

/* Focus is drawn on the wrapper, so the input must stay quiet — and must not
   re-acquire the theme's own focus border. */
.vakanssi-jobs-bar .vakanssi-jobs-searchinput:focus {
	border: 0;
	box-shadow: none;
	outline: none;
}

/* Styled native selects (team in the bar, sort on the meta line): the native
   arrow is replaced by our own chevron so both controls match the search
   field. */
.vakanssi-jobs-select {
	position: relative;
	display: inline-flex;
	align-items: center;
	/* A select is as wide as its longest option, so one long team name
	   widened the bar past a phone screen (8px of sideways scroll at 320px).
	   Held to the bar, the select shows the start of a long name instead. */
	min-inline-size: 0;
	max-inline-size: 100%;
}

.vakanssi-jobs-bar .vakanssi-jobs-select-input,
.vakanssi-jobs-meta .vakanssi-jobs-select-input {
	box-sizing: border-box;
	margin: 0;
	font: inherit;
	font-size: 0.875em;
	font-size: var(--vakanssi-text-sm, 0.875em);
	line-height: 1.4;
	color: #1e2936;
	color: var(--vakanssi-ink, #1e2936);
	background: #ffffff;
	background: var(--vakanssi-surface, #ffffff);
	border: 1px solid #758091;
	border: 1px solid var(--vakanssi-control-border-page, #758091);
	border-radius: 6px;
	border-radius: var(--vakanssi-radius, 6px);
	padding-block: 0.5em;
	padding-inline: 0.7em 1.9em;
	/* `inline-size: auto` is load-bearing: theme resets routinely set
	   `select { width: 100% }`, which would stretch the control past the
	   shrink-to-fit wrapper the chevron is positioned against. */
	inline-size: auto;
	max-inline-size: 100%;
	/* Astra fixes select heights at 40px; the field sizes from its padding
	   and line, like the search field beside it. */
	height: auto;
	block-size: auto;
	min-block-size: 0;
	box-shadow: none;
	cursor: pointer;
	transition: border-color 0.2s ease;
	transition: border-color var(--vakanssi-hover-duration, 0.2s) ease;
	-webkit-appearance: none;
	-moz-appearance: none;
	appearance: none;
}

.vakanssi-jobs-bar .vakanssi-jobs-select-input:hover,
.vakanssi-jobs-meta .vakanssi-jobs-select-input:hover {
	border-color: #6b7686;
	border-color: var(--vakanssi-control-border-hover, #6b7686);
}

.vakanssi-jobs-bar .vakanssi-jobs-select-input:focus,
.vakanssi-jobs-meta .vakanssi-jobs-select-input:focus {
	border-color: #0f766e;
	border-color: var(--vakanssi-accent, #0f766e);
	box-shadow: none;
}

.vakanssi-jobs-select .vakanssi-jobs-select-chevron {
	position: absolute;
	inline-size: 15px;
	block-size: 15px;
	inset-inline-end: 0.6em;
	color: #98a2b0;
	color: var(--vakanssi-faint, #98a2b0);
	pointer-events: none;
}

/* Remote — an accessible toggle switch. The checkbox is visually hidden but
   stays focusable and drives the state; the track/thumb are the visual. */
.vakanssi-jobs-remote {
	display: inline-flex;
	align-items: center;
	gap: 0.55em;
	font-size: 0.8125em;
	font-size: var(--vakanssi-text-xs, 0.8125em);
	color: #5f6b7a;
	color: var(--vakanssi-muted, #5f6b7a);
	cursor: pointer;
	-webkit-user-select: none;
	user-select: none;
}

/* Kept 1px and transparent rather than `display: none` so it stays focusable.
   `appearance: none` and the explicit box matter here: several popular themes
   restyle `input[type="checkbox"]` with a custom box at a fixed em size, which
   out-specifies a bare class and would surface a stray square beside the
   toggle track. */
.vakanssi-jobs-bar .vakanssi-jobs-switch-input {
	position: absolute;
	box-sizing: border-box;
	inline-size: 1px;
	block-size: 1px;
	min-inline-size: 0;
	min-block-size: 0;
	margin: 0;
	padding: 0;
	font-size: 1em;
	line-height: 1;
	border: 0;
	border-radius: 0;
	background: none;
	box-shadow: none;
	opacity: 0;
	-webkit-appearance: none;
	appearance: none;
}

/* The off track is the control border colour, so the switch clears 3:1
   against the page (it was 1.54:1 on white, 1.16:1 on Twenty Twenty-One's
   green). A transparent border costs nothing here and is what forced-colours
   mode paints (see the forced-colors block below). */
.vakanssi-jobs-switch {
	position: relative;
	box-sizing: content-box;
	display: inline-block;
	flex: none;
	inline-size: 2.1em;
	block-size: 1.2em;
	background: #758091;
	background: var(--vakanssi-control-border-page, #758091);
	border: 1px solid transparent;
	border-radius: 999px;
	transition: background 0.2s ease;
	transition: background var(--vakanssi-hover-duration, 0.2s) ease;
}

.vakanssi-jobs-remote:hover .vakanssi-jobs-switch {
	background: #3a4552;
	background: var(--vakanssi-text, #3a4552);
}

.vakanssi-jobs-remote:hover :checked + .vakanssi-jobs-switch {
	background: #0c615a;
	background: var(--vakanssi-accent-strong, #0c615a);
}

.vakanssi-jobs-switch-thumb {
	position: absolute;
	inset-block-start: 0.15em;
	inset-inline-start: 0.15em;
	inline-size: 0.9em;
	block-size: 0.9em;
	background: #ffffff;
	background: var(--vakanssi-surface, #ffffff);
	border-radius: 50%;
	box-shadow: 0 1px 2px rgba(20, 30, 45, 0.35);
	transition: inset-inline-start 0.2s ease;
	transition: inset-inline-start var(--vakanssi-hover-duration, 0.2s) ease;
}

.vakanssi-jobs-switch-input:checked + .vakanssi-jobs-switch {
	background: #0f766e;
	background: var(--vakanssi-accent, #0f766e);
}

.vakanssi-jobs-switch-input:checked + .vakanssi-jobs-switch .vakanssi-jobs-switch-thumb {
	inset-inline-start: 1.05em;
}

/* Meta line — the live open-role count, the removable active-filter chips,
   and the sort. Always visible (the count works with no JS); chips are added
   by careers.js.

   Two grid columns: the count and its chips (.vakanssi-jobs-summary) take
   what is left, the sort takes its own width. Grid columns do not wrap, so
   the sort stays level with the count whatever the theme's column width, the
   language, or the chips: two earlier flex layouts each found a width where
   the sort fell onto a line of its own. In RTL the columns flow from the
   right, so the sort sits on the left. */
.vakanssi-jobs-meta {
	display: grid;
	grid-template-columns: minmax(0, 1fr) auto;
	align-items: start;
	column-gap: 0.85em;
	/* Reserve the active-filter chip's height so selecting a team or toggling
	   remote surfaces a chip without growing the row (and shifting the list),
	   as long as it fits beside the count. The chip pins its own line-height
	   below, so its height is known here (~1.55em) whatever line-height the
	   theme gives inline text; 1.75em leaves a little to spare. Content-box
	   on purpose: under a theme's `* { box-sizing: border-box }` (Tailwind
	   preflight, every normalize descendant) the reservation would have to
	   cover the row's own top padding and border too, and the chip outgrew
	   what was left. */
	box-sizing: content-box;
	min-height: 1.75em;
	min-block-size: 1.75em;
	margin-block-end: 1.1em;
}

/* Column 1: the count, then each chip, wrapping under the count when they do
   not fit beside it. `min-inline-size: 0` down this chain lets a long chip
   shrink to the column and end in an ellipsis (below) instead of widening
   the page. Chips sit 0.4em apart; the count keeps a little more room
   before the first one. */
.vakanssi-jobs-meta .vakanssi-jobs-summary {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 0.4em;
	min-inline-size: 0;
}

/* The count's line is as tall as the sort (its 1.4 line, 0.5em padding top
   and bottom, the same as the team select's, and a 1px border, all at the
   same text size), with the text centred in it: the sort's top edge and the
   count's first line start level, and the text reads centred on the control.
   The text may wrap inside the column on a very narrow screen rather than
   push the sort.

   `unicode-bidi: plaintext` takes the line's reading direction from its own
   words: an untranslated "96 open roles" on a right-to-left page read "open
   roles 96". The line still sits at the page's start edge. */
.vakanssi-jobs-meta .vakanssi-jobs-count {
	display: flex;
	align-items: center;
	unicode-bidi: plaintext;
	min-block-size: calc(2.4em + 2px);
	min-inline-size: 0;
	margin-inline-end: 0.5em;
}

/* Column 2: the sort, at the line's end. */
.vakanssi-jobs-meta .vakanssi-jobs-select--sort {
	grid-column: 2;
	grid-row: 1;
}

.vakanssi-jobs-count {
	margin: 0;
	font-size: 0.875em;
	font-size: var(--vakanssi-text-sm, 0.875em);
	color: #5f6b7a;
	color: var(--vakanssi-muted, #5f6b7a);
}

/* Listing pagination (the built-in archive, and paginated Pages): a range
   readout on the left ("Showing 21–40 of 112 roles"), "Page 2 of 6" and two
   round arrow buttons on the right. Says where the reader is in the roles,
   not in the pages, and closes the loop with the count line above the list.
   Every reset-prone property is declared and every selector sits at
   (0,2,0)+ so a theme's `a`, `p` and button rules cannot restyle it. */
.vakanssi-jobs-pagination {
	/* Block margins only: the nav's width and its place in the column are
	   the theme's (centred columns, constrained layouts). */
	margin-top: 2.5em;
	margin-bottom: 0;
	margin-block: 2.5em 0;
	padding: 0;
	/* A wrapper of its own (it follows the board, not inside it), so it
	   takes the UI base itself; its text is one step down, below, so the
	   inner wrapper's reading width is the board's. */
	font-size: 1em;
	font-size: var(--vakanssi-ui-size, clamp(15px, 1em, max(17px, 1.0625rem)));
	font-weight: 400;
	line-height: 1.4;
}

.vakanssi-jobs-pagination .vakanssi-jobs-pagination__inner {
	display: flex;
	flex-wrap: wrap;
	justify-content: space-between;
	align-items: center;
	gap: 0.75em 1em;
}

/* The gap above the nav, restated at (0,2,0): themes space content
   children with an equal-specificity "owl" rule (`.entry-content > * + *`,
   block themes' `.is-layout-flow > *`) that loads after this sheet and won
   the tie, leaving the nav 1.1rem under the last row. */
.vakanssi-jobs-board + .vakanssi-jobs-pagination,
.vakanssi-jobs-board .vakanssi-jobs-pagination {
	margin-block-start: 2.5em;
	margin-top: 2.5em;
}

.vakanssi-jobs-pagination .vakanssi-jobs-pagination__range {
	margin: 0;
	padding: 0;
	color: #5f6b7a;
	color: var(--vakanssi-muted, #5f6b7a);
	font-size: 0.9375em;
	font-size: var(--vakanssi-text-md, 0.9375em);
	font-variant-numeric: tabular-nums;
}

.vakanssi-jobs-pagination .vakanssi-jobs-pagination__range strong {
	color: #1e2936;
	color: var(--vakanssi-ink, #1e2936);
	font-weight: 600;
}

.vakanssi-jobs-pagination .vakanssi-jobs-pagination__controls {
	font-size: 0.9375em;
	font-size: var(--vakanssi-text-md, 0.9375em);
	display: inline-flex;
	align-items: center;
	gap: 0.55em;
	margin-inline-start: auto;
}

.vakanssi-jobs-pagination .vakanssi-jobs-pagination__page {
	margin-inline-end: 0.35em;
	color: #5f6b7a;
	color: var(--vakanssi-muted, #5f6b7a);
	font-variant-numeric: tabular-nums;
	white-space: nowrap;
}

/* The two round arrow buttons. */
.vakanssi-jobs-pagination .vakanssi-jobs-pagination__arrow {
	box-sizing: border-box;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	/* Whole pixels on purpose (not em): with a 16px icon inside, an em-sized
	   button lands on half pixels at most theme sizes (2.5em = 37.5px) and
	   the chevron cannot centre exactly. 36px also matches the Apply
	   button's height on the rows above. */
	inline-size: 36px;
	block-size: 36px;
	margin: 0;
	padding: 0;
	border: 1px solid #758091;
	border: 1px solid var(--vakanssi-control-border-page, #758091);
	border-radius: 999px;
	background: #ffffff;
	background: var(--vakanssi-surface, #ffffff);
	color: #3a4552;
	color: var(--vakanssi-text, #3a4552);
	box-shadow: 0 1px 2px rgba(20, 30, 45, 0.05);
	box-shadow: var(--vakanssi-shadow-sm, 0 1px 2px rgba(20, 30, 45, 0.05));
	text-decoration: none;
	line-height: 1;
	transition: background 0.2s ease, border-color 0.2s ease, color 0.2s ease;
	transition: background var(--vakanssi-hover-duration, 0.2s) ease, border-color var(--vakanssi-hover-duration, 0.2s) ease, color var(--vakanssi-hover-duration, 0.2s) ease;
}

.vakanssi-jobs-pagination .vakanssi-jobs-pagination__arrow > svg {
	display: block;
	inline-size: 16px;
	block-size: 16px;
}

.vakanssi-jobs-pagination a.vakanssi-jobs-pagination__arrow:hover,
.vakanssi-jobs-pagination a.vakanssi-jobs-pagination__arrow:focus-visible {
	border-color: #0f766e;
	border-color: var(--vakanssi-accent, #0f766e);
	background: #e7f1f1;
	background: var(--vakanssi-accent-tint, #e7f1f1);
	color: #0c615a;
	color: var(--vakanssi-accent-strong, #0c615a);
	text-decoration: none;
}

/* First / last page: the button stays so the row keeps its shape, but reads
   as off. */
.vakanssi-jobs-pagination .vakanssi-jobs-pagination__arrow.is-disabled {
	color: #98a2b0;
	color: var(--vakanssi-faint, #98a2b0);
	border-color: #e2e6eb;
	border-color: var(--vakanssi-border, #e2e6eb);
	box-shadow: none;
	opacity: 0.7;
	cursor: default;
}

/* RTL: the chevrons point the way the reader travels. */
[dir="rtl"] .vakanssi-jobs-pagination .vakanssi-jobs-pagination__arrow > svg {
	transform: scaleX(-1);
}

/* Narrow screens: the readout takes its own line, the controls keep the end. */
@media (max-width: 30em) {
	.vakanssi-jobs-pagination .vakanssi-jobs-pagination__range {
		flex: 1 1 100%;
	}
}

@media (prefers-reduced-motion: reduce) {
	.vakanssi-jobs-pagination .vakanssi-jobs-pagination__arrow {
		transition: none;
	}
}

/* A hairline separates the bar from the results meta. Applied unconditionally
   for the same reason the bar is: adding it later moved the list down. */
.vakanssi-jobs-bar + .vakanssi-jobs-meta {
	/* Same distance from the hairline above as to the list's top rule below,
	   so the count line sits centred between the two (it used to be 0.85rem
	   above and 1.1rem below, and read as sitting high). */
	padding-block-start: 1em;
	margin-block-end: 1em;
	border-block-start: 1px solid #e2e6eb;
	border-block-start: 1px solid var(--vakanssi-border, #e2e6eb);
}

.vakanssi-jobs-activefilters {
	display: inline-flex;
	flex-wrap: wrap;
	gap: 0.4em;
}

/* On the results line the chip container drops its own box, so each chip is
   an item of the summary column next to the count: the first chip can sit
   beside the count while a second wraps under it, and with no chips there is
   no box to cost the column a gap. Clicks still reach the container
   (careers.js delegates the clear buttons to it); only its box is gone. */
.vakanssi-jobs-meta .vakanssi-jobs-activefilters {
	display: contents;
}

.vakanssi-jobs-meta .vakanssi-jobs-activefilter {
	min-inline-size: 0;
	max-inline-size: 100%;
}

.vakanssi-jobs-activefilter {
	display: inline-flex;
	align-items: center;
	gap: 0.2em;
	font-size: 0.8125em;
	font-size: var(--vakanssi-text-xs, 0.8125em);
	color: #0c615a;
	color: var(--vakanssi-accent-strong, #0c615a);
	background: #e7f1f1;
	background: var(--vakanssi-accent-tint, #e7f1f1);
	border: 1px solid #bcd9d6;
	border: 1px solid var(--vakanssi-accent-tint-border, #bcd9d6);
	border-radius: 999px;
	/* Pinned: a theme's body line-height (1.6, 1.7…) would otherwise set the
	   chip's height and outgrow the room .vakanssi-jobs-meta reserves for it. */
	line-height: 1.25;
	padding-block: 0.25em;
	padding-inline: 0.7em 0.35em;
	/* Pin the line so the chip's total height stays within the row's reserved
	   min-height regardless of the theme's inherited line-height. */
	line-height: 1.4;
}

/* A long team name ends in an ellipsis inside its chip rather than running
   past its column and widening the page. The full name stays in the clear
   button's aria-label and in the team picker above. */
.vakanssi-jobs-activefilter-text {
	min-inline-size: 0;
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}

/* Scoped past the theme's `button` / `[type="button"]` reset, which otherwise
   paints the chip's ✕ with the theme's own outline-button border and radius. */
.vakanssi-jobs-activefilter .vakanssi-jobs-activefilter-x {
	box-sizing: border-box;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	/* A 24px target (the WCAG 2.2 minimum); the negative block margin keeps
	   the chip at the height the meta line reserves for it. */
	inline-size: 24px;
	block-size: 24px;
	min-inline-size: 0;
	min-block-size: 0;
	margin: 0;
	margin-block: -4px;
	margin-inline: 0 -0.2em;
	padding: 0;
	font: inherit;
	color: inherit;
	background: transparent;
	border: 0;
	border-radius: 50%;
	box-shadow: none;
	cursor: pointer;
	transition: background 0.2s ease;
	transition: background var(--vakanssi-hover-duration, 0.2s) ease;
	-webkit-appearance: none;
	appearance: none;
}

.vakanssi-jobs-activefilter .vakanssi-jobs-activefilter-x > svg {
	inline-size: 12px;
	block-size: 12px;
}

.vakanssi-jobs-activefilter .vakanssi-jobs-activefilter-x:hover {
	background: #bcd9d6;
	background: var(--vakanssi-accent-tint-border, #bcd9d6);
}

/* The list */
.vakanssi-jobs {
	list-style: none;
	margin: 0;
	padding: 0;
	border-top: 1px solid #e2e6eb;
	border-block-start: 1px solid var(--vakanssi-border, #e2e6eb);
}

.vakanssi-job {
	border-bottom: 1px solid #e2e6eb;
	border-block-end: 1px solid var(--vakanssi-border, #e2e6eb);
}

/* careers.js hides rows (filtering, rows adopted from other pages) and the
   page nav (while a filter spans every page) with the `hidden` attribute.
   The UA's [hidden]{display:none} loses to ANY author display rule — the
   nav's own display:flex below, a theme's `li { display: block }` — so the
   attribute is honoured explicitly here, at a specificity a theme reset
   cannot beat. Same lesson as .hp-set-card[hidden] in settings.css. */
.vakanssi-jobs-board .vakanssi-job[hidden],
.vakanssi-jobs-pagination[hidden] {
	display: none;
}

/* Theme-proofing for the list box model, at (0,2,0) on purpose. Themes
   routinely indent every list in the content column and space its items
   (`.entry-content ul { padding-left: 1.3rem }`, `li + li { margin-top }`),
   which out-specified the (0,1,0) resets above: the rows sat ~20px right of
   the search bar and count line they hang under, and gaps opened between
   them. Every reset-prone property is spelled out here so no theme rule has
   anything left to win. */
.vakanssi-jobs-board .vakanssi-jobs,
.vakanssi-jobs-board .vakanssi-job {
	list-style: none;
	margin: 0;
	padding: 0;
}

.vakanssi-job-link {
	display: grid;
	grid-template-columns: minmax(0, 1fr) auto;
	align-items: center;
	column-gap: 1em;
	/* Equal air above and below every row. */
	padding-block: 1.25em;
	/* Flush with the column: the title shares its left edge with the heading,
	   the search field and the count line above, and the chevron shares its
	   right edge with the sort control (and with the Apply button on rows
	   that carry one). The hover band spans the same width as the rules
	   between rows. */
	padding-inline: 0;
	text-decoration: none;
	color: inherit;
}

/* The row content must not move on hover; the tint lives on the row's
   hover band below, not on the link. Keyboard focus adds the accent ring
   (the focus system near the end of this sheet), so focus no longer looks
   exactly like hover. */
.vakanssi-job-link {
	border-radius: 6px;
	border-radius: var(--vakanssi-radius, 6px);
}

/* Hover band. Painted by a pseudo-element behind the row so it can be wider
   than the row itself: the title and the chevron (or the Apply button) stay
   on the column edges, aligned with the heading and the sort control above,
   while the band bleeds past them so a filled button never sits on its edge.
   Rounded and inset from the hairlines so it reads as a highlight, not a
   stripe. Flush on phones (a bleed could overflow a zero-padding section);
   grid cards keep their own border-and-shadow hover instead. */
.vakanssi-jobs-board .vakanssi-jobs:not(.vakanssi-jobs--grid) .vakanssi-job {
	position: relative;
	isolation: isolate;
}

.vakanssi-jobs-board .vakanssi-jobs:not(.vakanssi-jobs--grid) .vakanssi-job::before {
	content: "";
	position: absolute;
	inset-block: 0.25em;
	inset-inline: 0;
	z-index: -1;
	border-radius: 6px;
	border-radius: var(--vakanssi-radius, 6px);
	background: #f6f8fa;
	background: var(--vakanssi-surface-subtle, #f6f8fa);
	opacity: 0;
	transition: opacity 0.2s ease;
	transition: opacity var(--vakanssi-hover-duration, 0.2s) ease;
	pointer-events: none;
}

/* No `.vakanssi-jobs-board` ancestor here on purpose: with it these land on
   (0,5,1), which ties the Custom CSS boost and would let a hover state beat a
   site owner's branding (bin/check-frontend-css.php gates this). The row above
   is the only rule that gives this pseudo-element `content`, so outside the
   board there is nothing for the raised opacity to reveal. */
.vakanssi-jobs:not(.vakanssi-jobs--grid) .vakanssi-job:hover::before,
.vakanssi-jobs:not(.vakanssi-jobs--grid) .vakanssi-job:focus-within::before {
	opacity: 1;
}

@media (min-width: 37.5em) {
	.vakanssi-jobs-board .vakanssi-jobs:not(.vakanssi-jobs--grid) .vakanssi-job::before {
		inset-inline: -0.75em;
	}
}

@media (prefers-reduced-motion: reduce) {
	.vakanssi-jobs-board .vakanssi-jobs:not(.vakanssi-jobs--grid) .vakanssi-job::before,
	.vakanssi-job-link .vakanssi-job-go {
		transition: none;
	}
}

.vakanssi-job-main {
	min-inline-size: 0;
}

.vakanssi-job-dept {
	display: block;
	overflow-wrap: anywhere;
	font-size: 0.75em;
	font-size: var(--vakanssi-text-2xs, 0.75em);
	font-weight: 700;
	letter-spacing: 0.05em;
	text-transform: uppercase;
	color: #0f766e;
	color: var(--vakanssi-accent, #0f766e);
	/* 0.3em of the UI base between the team and the title. */
	margin-block-end: 0.4em;
}

.vakanssi-job-title {
	display: block;
	/* A title typed as one long word wraps inside the row instead of pushing
	   the page sideways (an 80-letter title ran 368px out at 320px). */
	overflow-wrap: anywhere;
	font-size: 1.0625em;
	font-size: var(--vakanssi-text-lg, 1.0625em);
	font-weight: 600;
	line-height: 1.3;
	color: #1e2936;
	color: var(--vakanssi-ink, #1e2936);
}

.vakanssi-job-link:hover .vakanssi-job-title,
.vakanssi-job-link:focus-visible .vakanssi-job-title {
	text-decoration: underline;
	text-underline-offset: 2px;
}

/* Meta: one quiet line beneath the title — no pills. Salary carries weight,
   "Remote" a subtle accent; middot separators are added in CSS (RTL-safe). */
.vakanssi-job-meta {
	display: flex;
	flex-wrap: wrap;
	column-gap: 1.25em;
	/* A little space between wrapped lines of facts, so a second line
	   reads as more facts, not as a new row. */
	row-gap: 0.15em;
	overflow: hidden;
	/* 0.4em of the UI base between the title and the facts. */
	margin-block-start: 0.45em;
	color: #5f6b7a;
	color: var(--vakanssi-muted, #5f6b7a);
	font-size: 0.875em;
	font-size: var(--vakanssi-text-sm, 0.875em);
	line-height: 1.45;
}

/* The facts wrap as whole units: on a phone the line breaks between facts,
   never inside a short one ("Full-" / "time"). A fact longer than the whole
   line wraps inside itself: `min-inline-size: 0` lets the flex item shrink
   below its longest word, and `overflow-wrap: anywhere` breaks a single
   unbroken word (a long location typed without spaces) rather than letting
   the meta box clip it.

   Each fact's separator sits in the gap before it. On the first fact of a
   line that gap is outside the meta box, where `overflow: hidden` above clips
   it, so no line opens with a stray dot. Logical inset, so it mirrors in RTL. */
.vakanssi-job-fact {
	position: relative;
	min-inline-size: 0;
	overflow-wrap: anywhere;
}

.vakanssi-job-fact::before {
	content: "\00B7";
	position: absolute;
	inset-inline-start: -1.25em;
	inline-size: 1.25em;
	text-align: center;
	color: #98a2b0;
	color: var(--vakanssi-faint, #98a2b0);
}

.vakanssi-job-fact--remote,
.vakanssi-job-fact--workplace {
	color: #0c615a;
	color: var(--vakanssi-accent-strong, #0c615a);
	font-weight: 600;
}

.vakanssi-job-fact--salary {
	color: #1e2936;
	color: var(--vakanssi-ink, #1e2936);
	font-weight: 600;
	font-variant-numeric: tabular-nums;
}

/* Currency and amount stay on one line ("EUR 4,000–5,500"); the period after
   them may wrap. Used in the careers row and the job page's details box. A
   range wider than the whole line (nine digits a side in a 320px card) may
   break after its dash, and only there: each side is a nowrap part. */
.vakanssi-salary-amount {
	white-space: nowrap;
}

.vakanssi-salary-amount.vakanssi-salary-amount--range {
	white-space: normal;
}

.vakanssi-salary-amount .vakanssi-salary-part {
	white-space: nowrap;
}

.vakanssi-job-go {
	display: inline-flex;
	color: #98a2b0;
	color: var(--vakanssi-faint, #98a2b0);
	transition: color 0.2s ease, transform 0.2s ease;
	transition: color var(--vakanssi-hover-duration, 0.2s) ease, transform var(--vakanssi-hover-duration, 0.2s) ease;
}

.vakanssi-job-link .vakanssi-job-go > svg {
	inline-size: 16px;
	block-size: 16px;
}

.vakanssi-job-link:hover .vakanssi-job-go,
.vakanssi-job-link:focus-visible .vakanssi-job-go {
	color: #0f766e;
	color: var(--vakanssi-accent, #0f766e);
	transform: translateX(3px);
}

/* RTL: the "go" chevron points toward the reading direction. Mirror the
   right-pointing glyph to point left, and slide it left (not right) on hover. */
[dir="rtl"] .vakanssi-job-go > svg {
	transform: scaleX(-1);
}
[dir="rtl"] .vakanssi-job-link:hover .vakanssi-job-go,
[dir="rtl"] .vakanssi-job-link:focus-visible .vakanssi-job-go {
	transform: translateX(-3px);
}

/* ---- Optional per-row Apply control (apply_button="true") ----------------
   The control is a sibling of the row link, never a child: an <a> inside an <a>
   is invalid and breaks keyboard navigation. So the <li> takes over the
   two-column job, and the link's stretched ::after keeps the whole row
   clickable underneath while the control sits above it on its own z-index.
   Rules are scoped under .vakanssi-jobs (0,2,0) so they out-specify the
   unscoped anchor/button resets themes ship. */
.vakanssi-jobs .vakanssi-job--apply {
	position: relative;
	display: grid;
	grid-template-columns: minmax(0, 1fr) auto;
	align-items: center;
	column-gap: 1em;
}

.vakanssi-jobs .vakanssi-job--apply .vakanssi-job-link::after {
	content: "";
	position: absolute;
	inset: 0;
}

.vakanssi-jobs .vakanssi-job-apply {
	position: relative;
	z-index: 1;
	display: inline-flex;
	align-items: center;
	gap: 0.35em;
	box-sizing: border-box;
	margin: 0;
	padding-block: 0.75em;
	padding-inline: 1.15em;
	border: 1px solid #0f766e;
	border: 1px solid var(--vakanssi-accent, #0f766e);
	border-radius: 7px;
	background: transparent;
	color: #0f766e;
	color: var(--vakanssi-accent, #0f766e);
	font-family: inherit;
	font-size: 0.8125em;
	font-weight: 600;
	line-height: 1;
	text-align: center;
	text-decoration: none;
	text-transform: none;
	white-space: nowrap;
	transition: background 0.2s ease, color 0.2s ease, border-color 0.2s ease;
	transition: background var(--vakanssi-hover-duration, 0.2s) ease, color var(--vakanssi-hover-duration, 0.2s) ease, border-color var(--vakanssi-hover-duration, 0.2s) ease;
}

/* Filling on row hover keeps the whole row reading as one target. */
.vakanssi-jobs .vakanssi-job--apply:hover .vakanssi-job-apply,
.vakanssi-jobs .vakanssi-job-apply:hover,
.vakanssi-jobs .vakanssi-job-apply:focus-visible {
	background: #0f766e;
	background: var(--vakanssi-accent, #0f766e);
	border-color: #0f766e;
	border-color: var(--vakanssi-accent, #0f766e);
	color: #ffffff;
	color: var(--vakanssi-accent-contrast, #ffffff);
}

.vakanssi-jobs .vakanssi-job-apply-ext {
	flex: 0 0 auto;
}

/* RTL: the outbound arrow mirrors, like the row chevron above. */
[dir="rtl"] .vakanssi-jobs .vakanssi-job-apply-ext {
	transform: scaleX(-1);
}

@media (prefers-reduced-motion: reduce) {
	.vakanssi-jobs .vakanssi-job-apply {
		transition: none;
	}
}

.vakanssi-jobs-noresults {
	margin-block: 1.35em 0;
	padding-block: 2.15em;
	padding-inline: 1.6em;
	text-align: center;
	color: #5f6b7a;
	color: var(--vakanssi-muted, #5f6b7a);
	font-size: 0.9375em;
	font-size: var(--vakanssi-text-md, 0.9375em);
	background: #f6f8fa;
	background: var(--vakanssi-surface-subtle, #f6f8fa);
	border: 1px dashed #c9d1da;
	border: 1px dashed var(--vakanssi-border-strong, #c9d1da);
	border-radius: 10px;
	border-radius: var(--vakanssi-radius-lg, 10px);
}

/* [vakanssi_jobs layout="grid"] — a responsive card grid, as wide as the
   container. Cards are at least 16.5em of the UI base (about 260px): the old
   15rem minimum made 158px cards, five to a row, on a 10px-root theme
   (OceanWP). min() lets one card shrink to a container narrower than that
   instead of overflowing it. */
.vakanssi-jobs--grid {
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(16.5em, 1fr));
	grid-template-columns: repeat(auto-fill, minmax(min(100%, 16.5em), 1fr));
	gap: 1em;
	border-top: 0;
	border-block-start: 0;
}

.vakanssi-jobs--grid .vakanssi-job {
	border-bottom: 0;
	border-block-end: 0;
	background: #ffffff;
	background: var(--vakanssi-surface, #ffffff);
	border: 1px solid #e2e6eb;
	border: 1px solid var(--vakanssi-border, #e2e6eb);
	border-radius: 10px;
	border-radius: var(--vakanssi-radius-lg, 10px);
	box-shadow: 0 1px 2px rgba(20, 30, 45, 0.05);
	box-shadow: var(--vakanssi-shadow-sm, 0 1px 2px rgba(20, 30, 45, 0.05));
	transition: border-color 0.2s ease, box-shadow 0.2s ease;
	transition: border-color var(--vakanssi-hover-duration, 0.2s) ease, box-shadow var(--vakanssi-hover-duration, 0.2s) ease;
}

.vakanssi-jobs--grid .vakanssi-job:hover,
.vakanssi-jobs--grid .vakanssi-job:focus-within {
	border-color: #c9d1da;
	border-color: var(--vakanssi-border-strong, #c9d1da);
	box-shadow: 0 4px 14px rgba(20, 30, 45, 0.07);
	box-shadow: var(--vakanssi-shadow-md, 0 4px 14px rgba(20, 30, 45, 0.07));
}

.vakanssi-jobs--grid .vakanssi-job-link {
	grid-template-columns: 1fr;
	padding-block: 1.25em;
	padding-inline: 1.25em;
	border-radius: 10px;
	border-radius: var(--vakanssi-radius-lg, 10px);
}

.vakanssi-jobs--grid .vakanssi-job-link:hover,
.vakanssi-jobs--grid .vakanssi-job-link:focus-visible {
	background: transparent;
}

.vakanssi-jobs--grid .vakanssi-job-go {
	display: none;
}

/* Empty state. */
.vakanssi-jobs-empty {
	margin: 1.6em 0;
	margin-block: 1.6em;
	margin-inline: 0;
	padding: 2.65em 1.6em;
	padding-block: 2.65em;
	padding-inline: 1.6em;
	text-align: center;
	color: #5f6b7a;
	color: var(--vakanssi-muted, #5f6b7a);
	font-size: 0.9375em;
	font-size: var(--vakanssi-text-md, 0.9375em);
	background: #f6f8fa;
	background: var(--vakanssi-surface-subtle, #f6f8fa);
	border: 1px dashed #c9d1da;
	border: 1px dashed var(--vakanssi-border-strong, #c9d1da);
	border-radius: 10px;
	border-radius: var(--vakanssi-radius-lg, 10px);
}

/* ------------------------------------------------------------------ *
 *  Single-job details block
 * ------------------------------------------------------------------ */

.vakanssi-job-details {
	box-sizing: border-box;
	margin: 1.75em 0;
	margin-block: var(--vakanssi-block-gap, 1.75em);
	margin-inline: 0;
	padding: 0.6em 1.35em;
	padding-block: 0.6em;
	padding-inline: 1.35em;
	background: #f6f8fa;
	background: var(--vakanssi-surface-subtle, #f6f8fa);
	border: 1px solid #e2e6eb;
	border: 1px solid var(--vakanssi-border, #e2e6eb);
	border-radius: 10px;
	border-radius: var(--vakanssi-radius-lg, 10px);
}

.vakanssi-job-details .vakanssi-detail {
	display: flex;
	flex-wrap: wrap;
	align-items: baseline;
	gap: 0.25em 1.25em;
	padding: 0.65em 0;
	padding-block: 0.65em;
	padding-inline: 0;
}

.vakanssi-job-details .vakanssi-detail + .vakanssi-detail {
	border-top: 1px solid #e2e6eb;
	border-block-start: 1px solid var(--vakanssi-border, #e2e6eb);
}

.vakanssi-job-details dt {
	flex: 0 0 9.5em;
	margin: 0;
	padding: 0;
	font-size: 0.75em;
	font-size: var(--vakanssi-text-2xs, 0.75em);
	font-weight: 600;
	letter-spacing: 0.05em;
	text-transform: uppercase;
	color: #5f6b7a;
	color: var(--vakanssi-muted, #5f6b7a);
}

/* `padding: 0` too: Twenty Twenty-One indents every dd with
   `padding-left: calc(2 * var(--global--spacing-horizontal))`, which pushed
   each value 40px off its label. */
.vakanssi-job-details dd {
	/* A long location typed without spaces wraps inside the box (it ran
	   515px out of a 235px box at 320px). min-inline-size lets the flex item
	   shrink below its longest word in the first place. */
	min-inline-size: 0;
	overflow-wrap: anywhere;
	margin: 0;
	padding: 0;
	font-size: 0.9375em;
	font-size: var(--vakanssi-text-md, 0.9375em);
	color: #1e2936;
	color: var(--vakanssi-ink, #1e2936);
}

/* ------------------------------------------------------------------ *
 *  Other open roles + back-to-listing (single job)
 * ------------------------------------------------------------------ */

.vakanssi-related {
	margin-block: 1.75em;
	margin-block: var(--vakanssi-block-gap, 1.75em);
}

.vakanssi-related-heading {
	/* The space a careers board leaves between its count line and the
	   list's top rule, in this heading's own em (it is 0.75 of the base). */
	margin: 0 0 1.35em;
	margin-block: 0 1.35em;
	font-size: 0.75em;
	font-size: var(--vakanssi-text-2xs, 0.75em);
	font-weight: 600;
	letter-spacing: 0.05em;
	text-transform: uppercase;
	color: #5f6b7a;
	color: var(--vakanssi-muted, #5f6b7a);
}

/* Theme-proofing for the list box model, at (0,2,0) on purpose, exactly as the
   listing does above. "Other open roles" sits INSIDE the job's content column,
   so it meets `.entry-content ul { padding-left }` and `.entry-content li +
   li { margin-top }` (0,1,1) head on: at (0,1,0) the rows sat indented from
   the body copy above them and grew gaps between them.
   `.vakanssi-related-item` had no rule at all, so every list reset a theme
   ships landed on it unopposed. Every reset-prone property is spelled out;
   winning the cascade only wins the properties actually declared. */
.vakanssi-related .vakanssi-related-list,
.vakanssi-related .vakanssi-related-item {
	list-style: none;
	margin: 0;
	padding: 0;
}

/* The careers list's row language: hairlines above the list and under each
   row (no boxed cards), the row link, title, facts and chevron of a careers
   row (JobDetails::related_html() reuses those classes, so the type roles
   are the same rules), and the same hover band and focus ring. */
.vakanssi-related .vakanssi-related-list {
	display: block;
	border-top: 1px solid #e2e6eb;
	border-block-start: 1px solid var(--vakanssi-border, #e2e6eb);
}

.vakanssi-related .vakanssi-related-item {
	position: relative;
	isolation: isolate;
	min-inline-size: 0;
	border-bottom: 1px solid #e2e6eb;
	border-block-end: 1px solid var(--vakanssi-border, #e2e6eb);
}

.vakanssi-related .vakanssi-related-item::before {
	content: "";
	position: absolute;
	inset-block: 0.25em;
	inset-inline: 0;
	z-index: -1;
	border-radius: 6px;
	border-radius: var(--vakanssi-radius, 6px);
	background: #f6f8fa;
	background: var(--vakanssi-surface-subtle, #f6f8fa);
	opacity: 0;
	transition: opacity 0.2s ease;
	transition: opacity var(--vakanssi-hover-duration, 0.2s) ease;
	pointer-events: none;
}

.vakanssi-related .vakanssi-related-item:hover::before,
.vakanssi-related .vakanssi-related-item:focus-within::before {
	opacity: 1;
}

@media (min-width: 37.5em) {
	.vakanssi-related .vakanssi-related-item::before {
		inset-inline: -0.75em;
	}
}

@media (prefers-reduced-motion: reduce) {
	.vakanssi-related .vakanssi-related-item::before {
		transition: none;
	}
}

/* A long title or an unbroken location wraps inside the row instead of
   pushing the page sideways (it ran 453px out of a 280px column at 320px,
   and off the left edge in RTL). */
.vakanssi-related .vakanssi-related-role,
.vakanssi-related .vakanssi-related-meta {
	min-inline-size: 0;
	overflow-wrap: anywhere;
}

.vakanssi-single-back {
	/* The block gap of the UI base, stated in this element's own em. */
	margin-block: 2em 0;
	/* A wrapper of its own, so it takes the UI base itself, one step down. */
	font-size: 0.875em;
	font-size: calc(0.875 * var(--vakanssi-ui-size, clamp(15px, 1em, max(17px, 1.0625rem))));
	font-weight: 400;
}

/* A 44 px tall tap target on a phone; the text was a 22 px one. Weighs
   (0,2,1) with :any-link, over the (0,2,0) floor for candidate CSS, and
   declares what a theme's link reset could move: a stray padding, border,
   underline shadow or line-height would otherwise change the target. */
.vakanssi-single-back a:any-link {
	display: inline-flex;
	align-items: center;
	box-sizing: border-box;
	min-height: 44px;
	min-block-size: 44px;
	margin: 0;
	padding: 0;
	border: 0;
	background: transparent;
	box-shadow: none;
	line-height: 1.4;
	color: #0f766e;
	color: var(--vakanssi-accent, #0f766e);
	text-decoration: none;
}

/* (0,4,2): over the link reset under "Focus, hover and control borders". */
:root p.vakanssi-single-back a:any-link:hover,
:root p.vakanssi-single-back a:any-link:focus-visible {
	text-decoration: underline;
	text-underline-offset: 2px;
}

/* ------------------------------------------------------------------ *
 *  Apply call-to-action
 * ------------------------------------------------------------------ */

.vakanssi-apply {
	margin: 1.75em 0;
	margin-block: var(--vakanssi-block-gap, 1.75em);
	margin-inline: 0;
}

/* The primary CTA renders as an <a> on the job detail page (.vakanssi-apply)
   and as a <button type="submit"> in the form (.vakanssi-apply-form). Both
   scopes are listed rather than relying on the bare class, because every theme
   reset descended from normalize styles `[type="submit"], button` — at equal
   weight to a single class, so source order alone decided whether the brand
   button or the theme's outline button won. Hello Elementor lost us this one:
   the Apply CTA rendered transparent with the theme's link-coloured border.

   The link half weighs (0,3,2), and its states (0,4,2): Astra underlines
   every link in post content at (0,2,1) (`.ast-single-post .entry-content
   a`), the job page's body carries the theme's entry-content class, and
   Twenty Twenty-One paints every focused link at (0,4,1). Those are the
   weights the Appearance settings and the readme tell site owners to match:
   `:root p.vakanssi-apply a.vakanssi-apply-button` for the link and
   `.vakanssi-apply-form .vakanssi-apply-button` for the Submit button, each
   with its states. Additional CSS prints after this sheet, so an equal
   weight wins (tests/Unit/CustomCssAdviceTest.php holds every state to it). */
:root p.vakanssi-apply a.vakanssi-apply-button,
.vakanssi-apply-form .vakanssi-apply-button {
	box-sizing: border-box;
	display: inline-block;
	inline-size: auto;
	min-block-size: 0;
	margin: 0;
	padding: 0.65em 1.4em;
	border: 1px solid transparent;
	border-radius: 6px;
	border-radius: var(--vakanssi-radius, 6px);
	background: #0f766e;
	background: var(--vakanssi-accent, #0f766e);
	color: #ffffff;
	color: var(--vakanssi-accent-contrast, #ffffff);
	font-family: inherit;
	font-size: 0.9375em;
	font-size: var(--vakanssi-text-md, 0.9375em);
	font-weight: 600;
	line-height: 1.3;
	text-align: center;
	text-decoration: none;
	text-transform: none;
	letter-spacing: normal;
	cursor: pointer;
	box-shadow: 0 1px 2px rgba(20, 30, 45, 0.05);
	box-shadow: var(--vakanssi-shadow-sm, 0 1px 2px rgba(20, 30, 45, 0.05));
	transition: background-color 0.2s ease, box-shadow 0.2s ease;
	transition: background-color var(--vakanssi-hover-duration, 0.2s) ease, box-shadow var(--vakanssi-hover-duration, 0.2s) ease;
	-webkit-appearance: none;
	appearance: none;
}

:root p.vakanssi-apply a.vakanssi-apply-button:hover,
:root p.vakanssi-apply a.vakanssi-apply-button:focus,
:root p.vakanssi-apply a.vakanssi-apply-button:active,
.vakanssi-apply-form .vakanssi-apply-button:hover,
.vakanssi-apply-form .vakanssi-apply-button:focus,
.vakanssi-apply-form .vakanssi-apply-button:active {
	background: #0c615a;
	background: var(--vakanssi-accent-strong, #0c615a);
	color: #ffffff;
	color: var(--vakanssi-accent-contrast, #ffffff);
	border-color: transparent;
	text-decoration: none;
}

/* The jump to the form under the job's title. It is the same link as the
   Apply CTA and takes the same rules (and any Custom CSS a site wrote for
   `:root p.vakanssi-apply a.vakanssi-apply-button`), so the page has one
   apply style. It sits between the title and the description, so it takes
   less air than the CTA block. */
.vakanssi-apply.vakanssi-apply--jump {
	margin: 0 0 1.75em;
	margin-block: 0 var(--vakanssi-block-gap, 1.75em);
	margin-inline: 0;
}

:root p.vakanssi-apply--jump a.vakanssi-apply-button {
	display: inline-flex;
	align-items: center;
	gap: 0.45em;
}

.vakanssi-apply--jump .vakanssi-apply-jump-icon {
	flex: none;
	inline-size: 1em;
	block-size: 1em;
}

/* Where the jump lands: keep the form's top edge off the very top of the
   window. The admin bar logged-in staff see needs nothing extra here: core's
   admin-bar.css already gives the page `scroll-padding-top` of the bar's
   height, and a jump adds that to this margin. */
.vakanssi-apply-form {
	scroll-margin-block-start: 1.5em;
}

.vakanssi-apply--soon {
	color: #5f6b7a;
	color: var(--vakanssi-muted, #5f6b7a);
	font-style: italic;
}

.vakanssi-apply--closed {
	color: #9f3a38;
	color: var(--vakanssi-danger-text, #9f3a38);
	font-weight: 600;
}

/* ------------------------------------------------------------------ *
 *  Application form
 * ------------------------------------------------------------------ */

.vakanssi-apply-form {
	box-sizing: border-box;
	margin: 1.75em 0;
	margin-block: var(--vakanssi-block-gap, 1.75em);
	margin-inline: 0;
	padding: 1.5em;
	padding-block: 1.5em;
	padding-inline: 1.5em;
	background: #ffffff;
	background: var(--vakanssi-surface, #ffffff);
	border: 1px solid #e2e6eb;
	border: 1px solid var(--vakanssi-border, #e2e6eb);
	border-radius: 10px;
	border-radius: var(--vakanssi-radius-lg, 10px);
	box-shadow: 0 1px 2px rgba(20, 30, 45, 0.05);
	box-shadow: var(--vakanssi-shadow-sm, 0 1px 2px rgba(20, 30, 45, 0.05));
	color: #3a4552;
	color: var(--vakanssi-text, #3a4552);
}

/* Phones: the card's 1.5em sides cost the fields about 50px of a 360px
   screen, on top of the theme's own gutter. 1em gives that width back; the
   card still reads as a card. */
@media (max-width: 30em) {
	.vakanssi-apply-form {
		padding-inline: 1em;
	}
}

.vakanssi-apply-form h3 {
	margin: 0 0 1em;
	margin-block: 0 1em;
	margin-inline: 0;
	font-size: 1.25em;
	color: #1e2936;
	color: var(--vakanssi-ink, #1e2936);
}

.vakanssi-field {
	margin: 0 0 1.1em;
	margin-block: 0 1.1em;
	margin-inline: 0;
	/* Where an error notice's link lands (careers.js scrolls the field's
	   wrapper to the top): its label or legend sits a line below the
	   window's edge, not against it. */
	scroll-margin-block-start: 1em;
}

.vakanssi-field > label {
	display: block;
	margin-bottom: 0.4em;
	margin-block-end: 0.4em;
	font-size: 0.875em;
	font-size: var(--vakanssi-text-sm, 0.875em);
	font-weight: 600;
	color: #1e2936;
	color: var(--vakanssi-ink, #1e2936);
}

.vakanssi-field label span[aria-hidden="true"],
.vakanssi-field > legend span[aria-hidden="true"] {
	color: #9f3a38;
	color: var(--vakanssi-danger-text, #9f3a38);
}

.vakanssi-apply-form .vakanssi-field input[type="text"],
.vakanssi-apply-form .vakanssi-field input[type="email"],
.vakanssi-apply-form .vakanssi-field input[type="tel"],
.vakanssi-apply-form .vakanssi-field input[type="url"],
.vakanssi-apply-form .vakanssi-field select,
.vakanssi-apply-form .vakanssi-field textarea {
	display: block;
	box-sizing: border-box;
	width: 100%;
	inline-size: 100%;
	min-block-size: 0;
	margin: 0;
	padding: 0.55em 0.8em;
	background: #ffffff;
	background: var(--vakanssi-surface, #ffffff);
	border: 1px solid #8c95a3;
	border: 1px solid var(--vakanssi-control-border, #8c95a3);
	border-radius: 6px;
	border-radius: var(--vakanssi-radius, 6px);
	box-shadow: none;
	color: #1e2936;
	color: var(--vakanssi-ink, #1e2936);
	font: inherit;
	line-height: 1.4;
	transition: border-color 0.2s ease;
	transition: border-color var(--vakanssi-hover-duration, 0.2s) ease;
}

.vakanssi-apply-form .vakanssi-field input[type="text"]:hover,
.vakanssi-apply-form .vakanssi-field input[type="email"]:hover,
.vakanssi-apply-form .vakanssi-field input[type="tel"]:hover,
.vakanssi-apply-form .vakanssi-field input[type="url"]:hover,
.vakanssi-apply-form .vakanssi-field input[type="file"]:hover,
.vakanssi-apply-form .vakanssi-field select:hover,
.vakanssi-apply-form .vakanssi-field textarea:hover {
	border-color: #6b7686;
	border-color: var(--vakanssi-control-border-hover, #6b7686);
}

/* Text controls drop native chrome. The select deliberately keeps its platform
   arrow: themes that null a select's appearance substitute their own arrow as
   a background image, which the background we set above would paint over. */
.vakanssi-apply-form .vakanssi-field input[type="text"],
.vakanssi-apply-form .vakanssi-field input[type="email"],
.vakanssi-apply-form .vakanssi-field input[type="tel"],
.vakanssi-apply-form .vakanssi-field input[type="url"],
.vakanssi-apply-form .vakanssi-field textarea {
	-webkit-appearance: none;
	appearance: none;
}

.vakanssi-apply-form .vakanssi-field select {
	appearance: auto;
}

/* An email address and a web address read left to right in every language,
   so the form prints them with dir="ltr" (on Hebrew pages the LinkedIn
   placeholder showed its leading slash at the wrong end). On a right-to-left
   page they still line up with the fields around them. */
[dir="rtl"] .vakanssi-apply-form .vakanssi-field input[type="email"],
[dir="rtl"] .vakanssi-apply-form .vakanssi-field input[type="tel"],
[dir="rtl"] .vakanssi-apply-form .vakanssi-field input[type="url"] {
	text-align: right;
}

.vakanssi-apply-form .vakanssi-field textarea {
	resize: vertical;
}

.vakanssi-apply-form .vakanssi-field input:focus,
.vakanssi-apply-form .vakanssi-field select:focus,
.vakanssi-apply-form .vakanssi-field textarea:focus {
	border-color: #0f766e;
	border-color: var(--vakanssi-accent, #0f766e);
	box-shadow: none;
}

/* Placeholders are hints a candidate has to read: muted (5.4:1), not
   faint (2.6:1). The search box's placeholder is the same hint. */
.vakanssi-field ::placeholder,
.vakanssi-jobs-bar .vakanssi-jobs-searchinput::placeholder {
	color: #5f6b7a;
	color: var(--vakanssi-muted, #5f6b7a);
	opacity: 1;
}

/* File input: same field chrome, with a quiet secondary chooser button. */
.vakanssi-apply-form .vakanssi-field input[type="file"] {
	display: block;
	box-sizing: border-box;
	width: 100%;
	inline-size: 100%;
	min-block-size: 0;
	margin: 0;
	box-shadow: none;
	line-height: 1.4;
	-webkit-appearance: none;
	appearance: none;
	padding: 0.45em 0.5em;
	background: #f6f8fa;
	background: var(--vakanssi-surface-subtle, #f6f8fa);
	border: 1px solid #8c95a3;
	border: 1px solid var(--vakanssi-control-border, #8c95a3);
	border-radius: 6px;
	border-radius: var(--vakanssi-radius, 6px);
	color: #5f6b7a;
	color: var(--vakanssi-muted, #5f6b7a);
	font-family: inherit;
	font-size: 0.875em;
	font-size: var(--vakanssi-text-sm, 0.875em);
}

.vakanssi-apply-form .vakanssi-field input[type="file"]:focus {
	border-color: #0f766e;
	border-color: var(--vakanssi-accent, #0f766e);
	box-shadow: none;
}

.vakanssi-apply-form .vakanssi-field input[type="file"]::file-selector-button {
	margin-inline-end: 0.75em;
	padding: 0.35em 0.9em;
	background: #ffffff;
	background: var(--vakanssi-surface, #ffffff);
	/* On the field's subtle fill, not on white: the page value clears 3.8:1 there. */
	border: 1px solid #758091;
	border: 1px solid var(--vakanssi-control-border-page, #758091);
	border-radius: 4px;
	border-radius: var(--vakanssi-radius-sm, 4px);
	color: #3a4552;
	color: var(--vakanssi-text, #3a4552);
	font-family: inherit;
	font-size: 1em;
	font-weight: 500;
	cursor: pointer;
}

/* Checkboxes and radios keep the platform widget on purpose — `accent-color`
   brands it and it stays legible in forced-colors mode. The work here is only
   undoing what theme resets do to it: several popular themes null the
   appearance and paint a custom box at a fixed em size with its own border and
   background, which on our form reads as a second, mismatched control. */
.vakanssi-apply-form .vakanssi-field input[type="checkbox"],
.vakanssi-apply-form .vakanssi-field input[type="radio"] {
	box-sizing: border-box;
	inline-size: auto;
	block-size: auto;
	min-block-size: 0;
	margin: 0;
	background: none;
	border: 0;
	box-shadow: none;
	appearance: auto;
	accent-color: #0f766e;
	accent-color: var(--vakanssi-accent, #0f766e);
}

/* Consent checkbox row: exactly two flex items — the checkbox and one text
   span — so the privacy-policy link flows inline with the sentence and wraps
   like text (never as its own far-side column). The checkbox centers on the
   FIRST text line whatever font/line-height the host theme brings: 1lh is
   the label's line box (line-height: inherit guards against theme input
   resets like normalize's 1.15); the static 0.15em stays as the fallback
   for browsers without the lh unit.

   `font-size: inherit` is what makes the em sizes below mean the label's
   text. Form controls do not inherit font size: the browser gives an input
   its own 13.33px, so on a theme that leaves inputs alone (Twenty
   Twenty-Five) the old `1em` box rendered 13px beside 16px text, and its
   `1lh` was the input's line, not the label's. At 1.25em of the label's
   0.875em the box is about 20px on an 18px body. */
.vakanssi-consent label {
	display: flex;
	gap: 0.6em;
	align-items: flex-start;
	font-size: 0.875em;
	font-size: var(--vakanssi-text-sm, 0.875em);
	font-weight: 400;
	color: #3a4552;
	color: var(--vakanssi-text, #3a4552);
}

.vakanssi-apply-form .vakanssi-consent input[type="checkbox"] {
	flex: 0 0 auto;
	font-size: inherit;
	inline-size: 1.25em;
	block-size: 1.25em;
	line-height: inherit;
	margin: 0.15em 0 0;
	margin-block: 0.15em 0;
	margin-inline: 0;
	margin-block-start: calc( ( 1lh - 1.25em ) / 2 );
	cursor: pointer;
}

.vakanssi-consent-text {
	/* Let the span shrink (flex min-size:auto would pin it at the longest
	   word) and break pathological words in narrow theme containers. */
	min-inline-size: 0;
	overflow-wrap: break-word;
}

/* Consent row: a little space above it (so it clears the questions/fields), and
   it sits close to the submit button below — the final acknowledgement before it. */
.vakanssi-consent {
	margin: 1.25em 0 0;
	margin-block: 1.25em 0;
	margin-inline: 0;
}

/* Field notes: the eligibility hint under the country select and the optional
   retention disclosure under the submit button. A footnote to the thing above
   it, never a second label: one step smaller, muted, on its own line.
   Theme-proofed like every other candidate rule (specificity 0,2,0 and every
   reset-prone property declared), because a bare span inherits the theme's
   body size and reads as a stray paragraph. */
.vakanssi-apply-form .vakanssi-field-note {
	display: block;
	margin: 0.4em 0 0;
	margin-block: 0.4em 0;
	margin-inline: 0;
	font-size: 0.8125em;
	font-size: var(--vakanssi-text-xs, 0.8125em);
	font-weight: 400;
	line-height: 1.5;
	color: #5f6b7a;
	color: var(--vakanssi-muted, #5f6b7a);
}

/* The retention note is fine print beneath the button, the way sign-up and
   checkout forms carry their "by continuing" line: a little more air above it
   than a field note gets, capped at a readable measure so it never runs the
   full width of a wide theme column. Muted (not faint): it is candidate-facing
   text and still has to clear 4.5:1 on white; the size and position are what
   keep it out of the way. */
.vakanssi-apply-form .vakanssi-retention-note {
	margin: 0.75em 0 0;
	margin-block: 0.75em 0;
	margin-inline: 0;
	max-width: 34em;
	max-inline-size: 34em;
}

.vakanssi-submit {
	margin: 1.25em 0 0;
	margin-block: 1.25em 0;
	margin-inline: 0;
}

/* Two-column name/contact rows on wider screens; single column elsewhere. */
@supports (display: grid) {
	@media (min-width: 37.5em) {
		.vakanssi-form {
			display: grid;
			grid-template-columns: 1fr 1fr;
			column-gap: 1em;
		}

		.vakanssi-form > * {
			grid-column: 1 / -1;
		}

		.vakanssi-form > .vakanssi-field--half {
			grid-column: auto / span 1;
		}

		.vakanssi-apply-form {
			padding: 2em;
			padding-block: 2em;
			padding-inline: 2em;
		}
	}
}

/* ------------------------------------------------------------------ *
 *  Application sent (replaces the form after a successful submission)
 *  ApplicationForm::sent_panel(). Sits inside the same .vakanssi-apply-form
 *  card, so the page keeps its shape and #vakanssi-apply still lands here.
 * ------------------------------------------------------------------ */

.vakanssi-apply-form .vakanssi-apply-sent {
	display: grid;
	grid-template-columns: auto minmax(0, 1fr);
	column-gap: 0.9em;
	align-items: center;
}

/* Focus arrives here from careers.js, never from the keyboard: the panel is not
   a control, so it draws no ring. */
.vakanssi-apply-form .vakanssi-apply-sent:focus {
	outline: none;
}

.vakanssi-apply-sent .vakanssi-apply-sent__icon {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	box-sizing: border-box;
	inline-size: 2.5em;
	block-size: 2.5em;
	border-radius: 50%;
	background: #e7f1f1;
	background: var(--vakanssi-accent-tint, #e7f1f1);
	color: #0c615a;
	color: var(--vakanssi-accent-strong, #0c615a);
}

.vakanssi-apply-sent .vakanssi-apply-sent__icon > svg {
	inline-size: 20px;
	block-size: 20px;
}

/* (0,2,0) to clear `.vakanssi-apply-form h3` (0,1,1), which spaces the form's
   own heading, as well as any theme heading rule. */
.vakanssi-apply-sent .vakanssi-apply-sent__title {
	margin: 0;
	padding: 0;
	font-size: 1.25em;
	line-height: 1.3;
	color: #1e2936;
	color: var(--vakanssi-ink, #1e2936);
}

.vakanssi-apply-sent .vakanssi-apply-sent__lead,
.vakanssi-apply-sent .vakanssi-apply-sent__next,
.vakanssi-apply-sent .vakanssi-apply-sent__steps {
	grid-column: 2;
}

.vakanssi-apply-sent .vakanssi-apply-sent__lead {
	margin: 0.2em 0 0;
	margin-block: 0.2em 0;
	padding: 0;
	color: #3a4552;
	color: var(--vakanssi-text, #3a4552);
}

.vakanssi-apply-sent .vakanssi-apply-sent__next {
	margin: 1.65em 0 0.8em;
	margin-block: 1.65em 0.8em;
	padding: 1.45em 0 0;
	padding-block: 1.45em 0;
	border-top: 1px solid #e2e6eb;
	border-block-start: 1px solid var(--vakanssi-border, #e2e6eb);
	font-size: 0.75em;
	font-size: var(--vakanssi-text-2xs, 0.75em);
	font-weight: 600;
	letter-spacing: 0.05em;
	text-transform: uppercase;
	color: #5f6b7a;
	color: var(--vakanssi-muted, #5f6b7a);
}

/* A real sequence, so a numbered list, drawn with our own counters: themes
   reset ol padding and list-style in every direction. */
.vakanssi-apply-sent .vakanssi-apply-sent__steps {
	margin: 0;
	padding: 0;
	list-style: none;
	counter-reset: vakanssi-step;
}

/* The number is a grid cell on the item's first baseline, so it lines up with
   the first line of text whatever line height the theme sets. */
.vakanssi-apply-sent .vakanssi-apply-sent__steps > li {
	display: grid;
	grid-template-columns: 1.4em minmax(0, 1fr);
	column-gap: 0.6em;
	align-items: baseline;
	margin: 0;
	padding: 0;
	color: #3a4552;
	color: var(--vakanssi-text, #3a4552);
	counter-increment: vakanssi-step;
}

.vakanssi-apply-sent .vakanssi-apply-sent__steps > li + li {
	margin-top: 0.6em;
	margin-block-start: 0.6em;
}

.vakanssi-apply-sent .vakanssi-apply-sent__steps > li::before {
	content: counter(vakanssi-step);
	display: inline-flex;
	align-items: center;
	justify-content: center;
	inline-size: 1.85em;
	block-size: 1.85em;
	border-radius: 50%;
	background: #e7f1f1;
	background: var(--vakanssi-accent-tint, #e7f1f1);
	color: #0c615a;
	color: var(--vakanssi-accent-strong, #0c615a);
	font-size: 0.75em;
	font-size: var(--vakanssi-text-2xs, 0.75em);
	font-weight: 600;
	line-height: 1;
}

/* Narrow screens: the text takes the full card width instead of keeping the
   icon's column as an empty gutter all the way down. */
@media (max-width: 30em) {
	.vakanssi-apply-sent .vakanssi-apply-sent__lead,
	.vakanssi-apply-sent .vakanssi-apply-sent__next,
	.vakanssi-apply-sent .vakanssi-apply-sent__steps {
		grid-column: 1 / -1;
	}

	.vakanssi-apply-sent .vakanssi-apply-sent__lead {
		margin-top: 0.75em;
		margin-block-start: 0.75em;
	}
}

/* ------------------------------------------------------------------ *
 *  Notices (post-submission success / error)
 * ------------------------------------------------------------------ */

.vakanssi-apply-result {
	position: fixed;
	z-index: 100000;
	top: 1rem;
	inset-inline: 1rem;
	max-width: 40rem;
	margin-inline: auto;
	box-sizing: border-box;
}

.vakanssi-notice {
	margin: 0 0 1.35em;
	margin-block: 0 1.35em;
	margin-inline: 0;
	padding: 0.8em 1.05em;
	padding-block: 0.8em;
	padding-inline: 1.05em;
	border: 1px solid #e2e6eb;
	border: 1px solid var(--vakanssi-border, #e2e6eb);
	border-inline-start-width: 3px;
	border-radius: 6px;
	border-radius: var(--vakanssi-radius, 6px);
	font-size: 0.9375em;
	font-size: var(--vakanssi-text-md, 0.9375em);
	line-height: 1.5;
}

.vakanssi-notice--success {
	background: #f2f8f4;
	background: var(--vakanssi-success-bg, #f2f8f4);
	border-color: #b9dcc6;
	border-color: var(--vakanssi-success-border, #b9dcc6);
	border-inline-start-color: var(--vakanssi-success-text, #1d5a34);
	color: #1d5a34;
	color: var(--vakanssi-success-text, #1d5a34);
}

.vakanssi-notice--error {
	background: #fbf4f4;
	background: var(--vakanssi-danger-bg, #fbf4f4);
	border-color: #e7c6c5;
	border-color: var(--vakanssi-danger-border, #e7c6c5);
	border-inline-start-color: var(--vakanssi-danger-text, #9f3a38);
	color: #9f3a38;
	color: var(--vakanssi-danger-text, #9f3a38);
}

/* ------------------------------------------------------------------ *
 *  Focus, hover and control borders: one system for every control
 * ------------------------------------------------------------------ */

/* Theme link styles reach the plugin's links: Astra underlines every link in
   post content at (0,2,1) (`.ast-single-post .entry-content a`), and its
   hover rule weighs (0,3,1), so every text run in a careers row was
   underlined. Twenty Twenty-One gives every focused link a white wash and a
   dotted underline at (0,4,1) (`.site a:focus:not(...):not(...)`), which left
   the Apply buttons' white text on white (1.03:1). Each selector below weighs
   (0,3,2), or (0,4,2) with a state, so it clears both and still sits under
   the (0,5,0) ceiling bin/check-frontend-css.php keeps for a site's own CSS.
   (The job's Apply link takes its states from its own rules, above.) */
.vakanssi-jobs li.vakanssi-job a.vakanssi-job-link,
.vakanssi-jobs li.vakanssi-job a.vakanssi-job-apply,
:root .vakanssi-related li.vakanssi-related-item > a,
:root p.vakanssi-apply--closed a.vakanssi-closed-action,
:root p.vakanssi-single-back a:any-link,
:root nav.vakanssi-jobs-pagination a.vakanssi-jobs-pagination__arrow {
	text-decoration: none;
}

/* The link's resting paint, restated for its focused state: a theme's focus
   wash must not replace it. */
.vakanssi-jobs li.vakanssi-job a.vakanssi-job-link:focus,
:root .vakanssi-related li.vakanssi-related-item > a:focus {
	background: transparent;
	color: inherit;
	text-decoration: none;
}

.vakanssi-jobs li.vakanssi-job a.vakanssi-job-apply:focus {
	background: #0f766e;
	background: var(--vakanssi-accent, #0f766e);
	color: #ffffff;
	color: var(--vakanssi-accent-contrast, #ffffff);
	text-decoration: none;
}

:root nav.vakanssi-jobs-pagination a.vakanssi-jobs-pagination__arrow:focus,
:root p.vakanssi-apply--closed a.vakanssi-closed-action:focus {
	background: #e7f1f1;
	background: var(--vakanssi-accent-tint, #e7f1f1);
	color: #0c615a;
	color: var(--vakanssi-accent-strong, #0c615a);
	text-decoration: none;
}

:root p.vakanssi-single-back a:any-link:focus {
	background: transparent;
	color: #0f766e;
	color: var(--vakanssi-accent, #0f766e);
}

/* The ring. One solid outline in the accent, set off from the control, on
   every candidate control: it replaces a 3px glow at 28% of the accent that
   measured 1.4 to 1.6:1, and the rows and cards that had no ring at all, so
   focus looked exactly like hover. An outline is also what forced-colours
   mode keeps (as a system colour), where a box-shadow is dropped. Text
   fields show it whenever they are focused; the rest only for keyboard
   focus. What script focuses without being a control draws none (below). */
.vakanssi-jobs-search:focus-within,
.vakanssi-jobs-bar .vakanssi-jobs-select-input:focus-visible,
.vakanssi-jobs-meta .vakanssi-jobs-select-input:focus-visible,
.vakanssi-jobs-bar .vakanssi-jobs-switch-input:focus-visible + .vakanssi-jobs-switch,
.vakanssi-jobs-activefilter .vakanssi-jobs-activefilter-x:focus-visible,
.vakanssi-jobs li.vakanssi-job a.vakanssi-job-link:focus-visible,
.vakanssi-jobs li.vakanssi-job a.vakanssi-job-apply:focus-visible,
:root nav.vakanssi-jobs-pagination a.vakanssi-jobs-pagination__arrow:focus-visible,
:root p.vakanssi-apply a.vakanssi-apply-button:focus-visible,
:root p.vakanssi-apply--closed a.vakanssi-closed-action:focus-visible,
:root .vakanssi-related li.vakanssi-related-item > a:focus-visible,
:root p.vakanssi-single-back a:any-link:focus-visible,
.vakanssi-apply-form .vakanssi-apply-button:focus-visible,
.vakanssi-apply-form .vakanssi-field input:focus-visible,
.vakanssi-apply-form .vakanssi-field select:focus-visible,
.vakanssi-apply-form .vakanssi-field textarea:focus-visible {
	outline: 2px solid #0f766e;
	outline: var(--vakanssi-focus-width, 2px) solid var(--vakanssi-accent, #0f766e);
	outline-offset: 2px;
	outline-offset: var(--vakanssi-focus-offset, 2px);
}

/* Mouse focus: no ring. The one ring above is keyboard focus
   (:focus-visible), and a click still focuses the link or button, so the
   theme's own :focus outline showed instead: a black box round an "Other
   open roles" link on Twenty Twenty-Five, whose rule weighs nothing, and
   Twenty Twenty-One's link rule weighs (0,4,1). (0,4,1) and, for links,
   (0,4,2): over both, under the (0,5,0) ceiling. Every candidate surface:
   the board (rows, cards, chips, the bar), the page nav, the Apply jump and
   button, the form, the job facts, related roles and the back link.
   Keyboard focus, which forced colours also shows, keeps the ring. */
:root body :is(.vakanssi-jobs-board, .vakanssi-jobs-pagination, .vakanssi-apply, .vakanssi-apply-form, .vakanssi-job-details, .vakanssi-related, .vakanssi-single-back) :focus:not(:focus-visible),
:root body :is(.vakanssi-jobs-board, .vakanssi-jobs-pagination, .vakanssi-apply, .vakanssi-apply-form, .vakanssi-job-details, .vakanssi-related, .vakanssi-single-back) a:focus:not(:focus-visible) {
	outline: none;
}

/* Focus moved from script onto something that is not a control: the apply
   form's heading after the Apply jump, the error notice after a failed
   submission, the jobs board's results line after a filter chip is cleared
   by a click (careers.js gives each tabindex -1). Keyboard and screen-reader
   users land in the right place, but a heading or a notice is nothing to
   operate, so it draws no ring; the theme's :focus outline showed instead
   (an amber box across the column on Twenty Twenty-Five). (0,3,0) and
   (0,3,1): over a theme's :focus rule, under the (0,5,0) ceiling. A control
   carrying tabindex -1 keeps its ring. */
.vakanssi-apply-form [tabindex="-1"]:not(a, button, input, select, textarea, summary):focus,
.vakanssi-jobs-board [tabindex="-1"]:not(a, button, input, select, textarea, summary):focus,
:root .vakanssi-notice[tabindex="-1"]:focus {
	outline: none;
}

/* A field the server named in its error (aria-invalid="true", set by
   ApplicationForm on the field the message is about) takes the danger
   colour, 6.5:1 on white, and a 4px start edge, so it reads as marked
   without relying on colour. A checkbox keeps its platform box and gets a
   ring in the danger colour instead (a box-shadow, so the focus outline
   still draws over it). (0,4,1): over the hover and focus border rules, under
   the (0,5,0) ceiling. Written as a state, :is([aria-invalid]), because it
   is one: the field's resting box is declared on its base rule. */
.vakanssi-apply-form .vakanssi-field input[type="text"]:is([aria-invalid="true"]),
.vakanssi-apply-form .vakanssi-field input[type="email"]:is([aria-invalid="true"]),
.vakanssi-apply-form .vakanssi-field input[type="tel"]:is([aria-invalid="true"]),
.vakanssi-apply-form .vakanssi-field input[type="url"]:is([aria-invalid="true"]),
.vakanssi-apply-form .vakanssi-field input[type="file"]:is([aria-invalid="true"]),
.vakanssi-apply-form .vakanssi-field select:is([aria-invalid="true"]),
.vakanssi-apply-form .vakanssi-field textarea:is([aria-invalid="true"]) {
	border-color: #9f3a38;
	border-color: var(--vakanssi-danger-text, #9f3a38);
	border-inline-start-width: 4px;
	border-inline-start-width: var(--vakanssi-invalid-edge, 4px);
}

/* A group of checkboxes the server named (aria-invalid="true" on its
   fieldset) takes the same mark: its border in the danger colour and the
   same start edge. A group draws no border at rest, so the start edge is all
   that shows, a bar beside the question and its choices, set off by a
   little padding; in right-to-left it is on the right. The bar and its
   padding are pulled out into the gutter by an equal negative start margin,
   so the question and its boxes do not move when the mark comes or goes
   (ticking a box clears it, and the box under the pointer must stay put).
   The gutter is the questions box's or the card's padding, 1em or more, and
   the bar with its padding takes 4px + 0.5em. Any fieldset in the form, so
   a group an extension adds gets it too. (0,3,1): over the group's own flat
   rule and a theme's fieldset rule, under the (0,5,0) ceiling. */
:root .vakanssi-apply-form fieldset:is([aria-invalid="true"]) {
	border-color: #9f3a38;
	border-color: var(--vakanssi-danger-text, #9f3a38);
	border-inline-start-style: solid;
	border-inline-start-width: 4px;
	border-inline-start-width: var(--vakanssi-invalid-edge, 4px);
	padding-inline-start: 0.5em;
	margin-inline-start: calc(-4px - 0.5em);
	margin-inline-start: calc(-1 * var(--vakanssi-invalid-edge, 4px) - 0.5em);
}

.vakanssi-apply-form .vakanssi-field input[type="checkbox"]:is([aria-invalid="true"]) {
	box-shadow: 0 0 0 2px #9f3a38;
	box-shadow: 0 0 0 2px var(--vakanssi-danger-text, #9f3a38);
}

/* The closed job page's one action: a quiet button, 44px tall, on its own
   line under the notice. */
:root p.vakanssi-apply--closed a.vakanssi-closed-action {
	box-sizing: border-box;
	display: inline-flex;
	align-items: center;
	min-height: 44px;
	min-block-size: 44px;
	margin: 0.75em 0 0;
	margin-block: 0.75em 0;
	margin-inline: 0;
	padding: 0.5em 1.1em;
	padding-block: 0.5em;
	padding-inline: 1.1em;
	border: 1px solid #0f766e;
	border: 1px solid var(--vakanssi-accent, #0f766e);
	border-radius: 6px;
	border-radius: var(--vakanssi-radius, 6px);
	background: transparent;
	box-shadow: none;
	color: #0f766e;
	color: var(--vakanssi-accent, #0f766e);
	font-size: 0.9375em;
	font-size: var(--vakanssi-text-md, 0.9375em);
	font-weight: 600;
	line-height: 1.3;
	transition: background 0.2s ease, color 0.2s ease;
	transition: background var(--vakanssi-hover-duration, 0.2s) ease, color var(--vakanssi-hover-duration, 0.2s) ease;
}

:root p.vakanssi-apply--closed a.vakanssi-closed-action:hover {
	background: #e7f1f1;
	background: var(--vakanssi-accent-tint, #e7f1f1);
	color: #0c615a;
	color: var(--vakanssi-accent-strong, #0c615a);
}

/* The notice above it sits on its own line. */
.vakanssi-apply.vakanssi-apply--closed {
	display: flex;
	flex-direction: column;
	align-items: flex-start;
}

/* Forced-colours mode (Windows High Contrast) paints every background with
   the page colour, so the track and the thumb of the Remote switch both
   became the same black and the switch vanished. It keeps its own system
   colours here instead: an outlined track with a thumb in the text colour,
   and the highlight colour when on. */
@media (forced-colors: active) {
	.vakanssi-jobs-remote .vakanssi-jobs-switch,
	.vakanssi-jobs-remote:hover .vakanssi-jobs-switch {
		forced-color-adjust: none;
		background: Canvas;
		border-color: ButtonText;
	}

	.vakanssi-jobs-remote .vakanssi-jobs-switch-thumb {
		forced-color-adjust: none;
		background: ButtonText;
		box-shadow: none;
	}

	.vakanssi-jobs-remote :checked + .vakanssi-jobs-switch,
	.vakanssi-jobs-remote:hover :checked + .vakanssi-jobs-switch {
		background: Highlight;
		border-color: Highlight;
	}

	.vakanssi-jobs-remote :checked + .vakanssi-jobs-switch .vakanssi-jobs-switch-thumb {
		background: HighlightText;
	}

	/* forced-color-adjust: none above keeps the accent the ring would
	   otherwise be repainted with, so it is named as a system colour. */
	.vakanssi-jobs-bar .vakanssi-jobs-switch-input:focus-visible + .vakanssi-jobs-switch {
		outline-color: Highlight;
	}
}

/* Touch screens: every board control gets a 44px target. The search box,
   the team and sort selects, the Remote switch's label (its whole row is the
   target) and the page arrows; the count line grows with the sort so the two
   stay level. */
@media (pointer: coarse) {
	.vakanssi-jobs-bar .vakanssi-jobs-search,
	.vakanssi-jobs-bar .vakanssi-jobs-select-input,
	.vakanssi-jobs-meta .vakanssi-jobs-select-input,
	.vakanssi-jobs-bar .vakanssi-jobs-remote,
	.vakanssi-jobs-meta .vakanssi-jobs-count {
		min-block-size: 44px;
	}

	.vakanssi-jobs-pagination .vakanssi-jobs-pagination__arrow {
		inline-size: 44px;
		block-size: 44px;
	}
}

/* ------------------------------------------------------------------ *
 *  Utilities
 * ------------------------------------------------------------------ */

/* Fallback for themes that don't define WordPress's screen-reader class. */
.vakanssi-apply .screen-reader-text,
.vakanssi-apply-form .screen-reader-text {
	position: absolute;
	width: 1px;
	height: 1px;
	overflow: hidden;
	clip: rect(1px, 1px, 1px, 1px);
	clip-path: inset(50%);
	white-space: nowrap;
}

/* Narrow screens: stack detail labels above values. */
@media (max-width: 30em) {
	.vakanssi-job-details .vakanssi-detail {
		display: block;
	}

	.vakanssi-job-details dt {
		margin-bottom: 0.15em;
		margin-block-end: 0.15em;
	}
}

/* Each selector here weighs at least as much as the rule that set the
   transition, so reduced motion always wins. */
@media (prefers-reduced-motion: reduce) {
	.vakanssi-jobs--grid .vakanssi-job,
	.vakanssi-jobs-search,
	.vakanssi-jobs-bar .vakanssi-jobs-select-input,
	.vakanssi-jobs-meta .vakanssi-jobs-select-input,
	.vakanssi-jobs-switch,
	.vakanssi-jobs-switch-thumb,
	.vakanssi-jobs-activefilter .vakanssi-jobs-activefilter-x,
	:root p.vakanssi-apply a.vakanssi-apply-button,
	.vakanssi-apply-form .vakanssi-apply-button,
	:root p.vakanssi-apply--closed a.vakanssi-closed-action,
	.vakanssi-apply-form .vakanssi-field input[type],
	.vakanssi-apply-form .vakanssi-field select,
	.vakanssi-apply-form .vakanssi-field textarea {
		transition: none;
	}
}

/* 1.3.9 form additions */

/* The polite status line careers.js fills while the application sends: for
   screen readers only, since the button itself shows the busy label. */
.vakanssi-apply-form .vakanssi-form-status {
	position: absolute;
	width: 1px;
	height: 1px;
	margin: 0;
	padding: 0;
	overflow: hidden;
	clip: rect(1px, 1px, 1px, 1px);
	clip-path: inset(50%);
	white-space: nowrap;
	border: 0;
}

/* The submit button while the application sends (careers.js adds the
   is-busy class and this spinner before the busy label, and holds the
   button's idle width so the label change does not resize it). The button
   itself is not restyled, so a site's own button colours stay. */
.vakanssi-apply-form .vakanssi-busy-spinner {
	display: inline-block;
	box-sizing: border-box;
	inline-size: 1em;
	block-size: 1em;
	margin: 0 0.5em 0 0;
	margin-inline: 0 0.5em;
	vertical-align: -0.15em;
	border: 2px solid currentColor;
	border-inline-end-color: transparent;
	border-radius: 50%;
	animation: vakanssi-busy-spin 0.8s linear infinite;
}

/* While it is disabled the button is busy (the submit guard, or the
   spam check before it): the pointer says so instead of offering a
   click that does nothing. (0,2,0), the state in :where(): it follows the
   button's (0,2,0) base, so it wins on order and beats a theme's
   `button:disabled` (0,1,1), while a site's own Custom CSS for the button
   at the same weight, printed later, still wins. */
.vakanssi-apply-form .vakanssi-apply-button:where(:disabled) {
	cursor: progress;
}

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

/* The chosen CV's full name, on its own line under the control: it wraps
   rather than being cut off, with a Remove button beside it. A file that is
   empty or over the limit adds its message on a line below. */
.vakanssi-apply-form .vakanssi-file-chosen {
	display: block;
	margin: 0.5em 0 0;
	margin-block: 0.5em 0;
	margin-inline: 0;
	font-size: 0.875em;
	font-size: var(--vakanssi-text-sm, 0.875em);
	font-weight: 400;
	line-height: 1.5;
	color: #3a4552;
	color: var(--vakanssi-text, #3a4552);
	overflow-wrap: anywhere;
}

.vakanssi-apply-form .vakanssi-file-chosen .vakanssi-file-chosen__name {
	margin-inline-end: 0.5em;
}

/* The name exactly as the file has it: repeated spaces kept, and its own
   direction (the span is dir="auto"). */
.vakanssi-apply-form .vakanssi-file-chosen .vakanssi-file-chosen__file {
	unicode-bidi: isolate;
	white-space: pre-wrap;
}

.vakanssi-apply-form .vakanssi-file-chosen .vakanssi-file-chosen__problem {
	display: block;
	margin: 0.25em 0 0;
	margin-block: 0.25em 0;
	color: #9f3a38;
	color: var(--vakanssi-danger-text, #9f3a38);
}

.vakanssi-apply-form .vakanssi-file-chosen .vakanssi-file-chosen__remove {
	box-sizing: border-box;
	display: inline-flex;
	align-items: center;
	vertical-align: middle;
	inline-size: auto;
	min-block-size: 44px;
	margin: 0;
	padding: 0 0.85em;
	border: 1px solid #8c95a3;
	border: 1px solid var(--vakanssi-control-border, #8c95a3);
	border-radius: 6px;
	border-radius: var(--vakanssi-radius, 6px);
	background: #ffffff;
	background: var(--vakanssi-surface, #ffffff);
	color: #1e2936;
	color: var(--vakanssi-ink, #1e2936);
	font-family: inherit;
	font-size: 1em;
	font-weight: 600;
	line-height: 1.2;
	text-decoration: none;
	text-transform: none;
	letter-spacing: normal;
	box-shadow: none;
	cursor: pointer;
	-webkit-appearance: none;
	appearance: none;
}

.vakanssi-apply-form .vakanssi-file-chosen .vakanssi-file-chosen__remove:hover {
	background: #f6f8fa;
	background: var(--vakanssi-surface-subtle, #f6f8fa);
}

.vakanssi-apply-form .vakanssi-file-chosen .vakanssi-file-chosen__remove:focus-visible {
	outline: 2px solid #0f766e;
	outline: 2px solid var(--vakanssi-accent, #0f766e);
	outline-offset: 2px;
}

/* The size in the CV label ("5 MB"): never split across two lines. */
.vakanssi-apply-form .vakanssi-cv-limit {
	white-space: nowrap;
}

/* Several problems in one notice: a list, each line a link to its field. */
.vakanssi-notice .vakanssi-notice__list {
	margin: 0.4em 0 0;
	margin-block: 0.4em 0;
	margin-inline: 0;
	padding: 0;
	padding-inline-start: 1.25em;
	list-style: disc;
}

.vakanssi-notice .vakanssi-notice__list li {
	margin: 0.2em 0 0;
	margin-block: 0.2em 0;
}

.vakanssi-notice--error a {
	color: inherit;
	text-decoration: underline;
}

@media (prefers-reduced-motion: reduce) {
	.vakanssi-apply-form .vakanssi-busy-spinner {
		animation: none;
		border-inline-end-color: currentColor;
		opacity: 0.6;
	}
}
