/**
 * Jobs in Kampala — site styles.
 *
 * Loaded after Kadence's own stylesheet (declared as a dependency on 'kadence-global'), so
 * these rules win without needing !important or inflated selectors.
 *
 * Every colour pairing used for text here was measured against WCAG 2.1 rather than eyeballed.
 * The measurements are noted inline, and two of them drove real decisions:
 *
 *   - White on the brand red is 5.11:1 and passes AA, so Apply is a red button with a white
 *     label.
 *   - Red on navy is 2.25:1 and fails outright, so the accent may never sit on the navy
 *     chrome. Red belongs on white or wash only.
 *
 * The accent is the red already in the logo and in Kadence's palette 1, chosen over an amber
 * accent so that nothing in the interface contradicts the brand mark.
 */

/* ---------------------------------------------------------------------------
 * Fonts
 *
 * Both are variable fonts: one file each covers the whole weight axis, so the
 * `font-weight` range below is what unlocks 400 through 800 from 75 KB total.
 * font-display: swap shows fallback text immediately rather than leaving a
 * blank screen on a slow connection — for a job board, text people can read
 * beats text in the right typeface.
 * ------------------------------------------------------------------------- */

@font-face {
	font-family: 'Inter';
	src: url('../fonts/inter-var.woff2') format('woff2-variations'),
	     url('../fonts/inter-var.woff2') format('woff2');
	font-weight: 100 900;
	font-style: normal;
	font-display: swap;
}

@font-face {
	font-family: 'Plus Jakarta Sans';
	src: url('../fonts/plus-jakarta-sans-var.woff2') format('woff2-variations'),
	     url('../fonts/plus-jakarta-sans-var.woff2') format('woff2');
	font-weight: 200 800;
	font-style: normal;
	font-display: swap;
}

/* ---------------------------------------------------------------------------
 * Design tokens
 * ------------------------------------------------------------------------- */

:root {
	--jik-ink:    #0F172A;  /* headings and body   17.06:1 on wash  (AAA) */
	--jik-navy:   #1E3A5F;  /* chrome and links    10.99:1 on wash  (AAA) */

	/* The accent is the brand red already carried by the logo and by Kadence's
	 * palette 1. Using it for actions means nothing on the page contradicts the
	 * logo, and red reads as urgency, which suits a closing date.
	 *
	 * HARD CONSTRAINT: red must never sit on navy. Measured at 2.25:1, it is
	 * unreadable. Red buttons belong on white or wash only — never in the navy
	 * header. White on red is 5.11:1 and passes AA.
	 */
	--jik-red:      #D81E05;
	--jik-red-dark: #B81A04;  /* Kadence palette 2 — hover/active */

	--jik-slate:  #64748B;  /* meta text            4.55:1 on wash  (AA)  */
	--jik-paper:  #FFFFFF;
	--jik-wash:   #F8FAFC;
	--jik-line:   #E2E8F0;

	--jik-sans:    'Inter', system-ui, -apple-system, 'Segoe UI', sans-serif;
	--jik-display: 'Plus Jakarta Sans', var(--jik-sans);

	--jik-radius: 10px;
	--jik-shadow: 0 1px 2px rgba(15, 23, 42, .06), 0 4px 12px rgba(15, 23, 42, .04);

	/* Retarget Kadence's own font variables.
	 *
	 * Kadence has no `heading_font` entry in theme_mods, so it falls back to its built-in
	 * default of 'inherit' — which the PHP filter never sees, because that filter can only
	 * rewrite keys that exist. The result on the first staging deploy was
	 * `--global-heading-font-family: inherit`: Plus Jakarta Sans was downloaded on every
	 * page and then never used.
	 *
	 * Overriding the variable here fixes it at the source, so EVERY Kadence rule that reads
	 * it picks up the display face, not just the h1-h6 rule this file also sets. Kadence
	 * declares these on :root in inline CSS earlier in the head, so this later declaration
	 * of equal specificity wins. */
	--global-heading-font-family: 'Plus Jakarta Sans', system-ui, sans-serif;
	--global-body-font-family: 'Inter', system-ui, -apple-system, 'Segoe UI', sans-serif;
}

/* ---------------------------------------------------------------------------
 * Base
 * ------------------------------------------------------------------------- */

body {
	font-family: var(--jik-sans);
	font-size: 17px;
	line-height: 1.65;
	color: var(--jik-ink);
	background: var(--jik-wash);
	/* Inter ships old-style figures off by default; contextual alternates keep
	   the spacing even in job titles that mix caps and numerals. */
	font-feature-settings: 'cv05' 1, 'calt' 1;
	-webkit-font-smoothing: antialiased;
}

h1, h2, h3, h4, h5, h6,
.entry-title,
.site-title {
	font-family: var(--jik-display);
	color: var(--jik-ink);
	/* Display faces set too loose at large sizes read as amateur. Negative
	   tracking is what makes a heading look typeset rather than default. */
	letter-spacing: -0.02em;
	line-height: 1.2;
	/* Defensive only. Some listings DO render as "HR & ADMIN INTERN", but that is
	   stored uppercase in the database by the autoposter, not applied by CSS — so
	   this rule does not fix those (see jik_title_case in the n8n generator).
	   It is kept so that a future Kadence typography setting cannot introduce
	   all-caps headings, which are measurably slower to read because they remove
	   the word-shape cues readers rely on. */
	text-transform: none;
}

h1, .entry-title { font-weight: 800; }
h2, h3           { font-weight: 700; }
h4, h5, h6       { font-weight: 600; }

a {
	color: var(--jik-navy);
	text-underline-offset: 2px;
}

a:hover { color: var(--jik-red); }

/* Keyboard focus must stay visible. Kadence's default outline is easy to lose
   against a dark header, so it is restated with an offset. */
a:focus-visible,
button:focus-visible,
input:focus-visible,
select:focus-visible {
	outline: 2px solid var(--jik-red);
	outline-offset: 2px;
}

/* ---------------------------------------------------------------------------
 * Job listings
 * ------------------------------------------------------------------------- */

/* The archive's job cards sat 34px right of the search panel above them, so their
   left edges did not line up (the right edges already did). WP Job Manager ships a
   reset for this but it was not applying, leaving the browser default
   padding-inline-start of 2em — which resolves against the body's 17px, not the
   16px root, giving exactly 34px. Measured: .job_filters left 56px, li.job_listing
   left 90px.

   Reset with LOGICAL properties rather than padding-left so the rule mirrors
   correctly under RTL instead of pinning the gap to the physical left. */
ul.job_listings {
	padding-inline-start: 0;
	padding-inline-end: 0;
	margin: 0;
	list-style: none;
}

ul.job_listings > li.job_listing {
	margin-inline-start: 0;
	list-style: none;
}

ul.job_listings li.job_listing a,
ul.job_listings li.no_job_listings_found {
	background: var(--jik-paper);
	border: 1px solid var(--jik-line);
	border-radius: var(--jik-radius);
	margin-bottom: 10px;
	box-shadow: var(--jik-shadow);
	transition: border-color .15s ease, transform .15s ease;
}

ul.job_listings li.job_listing a:hover {
	border-color: var(--jik-navy);
	transform: translateY(-1px);
}

ul.job_listings li.job_listing .position h3 {
	font-family: var(--jik-display);
	font-weight: 700;
	font-size: 1.05rem;
	letter-spacing: -0.015em;
}

/* Meta text colour — an accessibility fix, not a preference.
 *
 * WP Job Manager sets `color: #999` on all of these, which measures 2.85:1 on white and
 * FAILS WCAG AA. It is the company name, location and posted date on every card: exactly
 * the text a visitor scans to triage. `--jik-slate` (#64748B) measures 4.76:1 and passes.
 *
 * The token was always correct; it never reached the page. The plugin's selectors run to
 * (0,4,4) — `ul.job_listings li.job_listing a div.position .company` — and the earlier rule
 * here was (0,3,2), so it lost silently. Every selector below therefore carries the `a` and
 * the element types. Proof it was delivery and not the token: `.jik-related__meta`, which is
 * our own markup with no plugin competing, rendered #64748b and passed all along.
 */
ul.job_listings li.job_listing a div.position div.company,
ul.job_listings li.job_listing a div.position div.company .tagline,
ul.job_listings li.job_listing a div.location,
ul.job_listings li.job_listing a ul.meta,
ul.job_listings li.job_listing a ul.meta li,
.single_job_listing ul.meta li,
.single_job_listing div.company .tagline {
	color: var(--jik-slate);
}

ul.job_listings li.job_listing a div.position div.company,
ul.job_listings li.job_listing a div.location,
ul.job_listings li.job_listing a ul.meta {
	font-size: .875rem;
}

/* The single listing's job-type pill keeps WP Job Manager's own colour and white label,
 * which varies per job type and is not a pairing we control or have measured. Giving it
 * the same navy-on-tint treatment as the archive pill makes it both consistent and a known
 * 10.23:1 — and keeps the coloured-badge vocabulary from competing with the red Apply
 * button, which is the only thing on the page that should read as an action. */
.single_job_listing ul.meta li.job-type,
.single_job_listing .meta li.job-type {
	background: #EEF2F7;
	color: var(--jik-navy);
	border-radius: 999px;
	padding: 2px 10px;
	font-weight: 600;
	text-transform: none;
}

/* The search placeholders were #777 — 4.48:1, failing AA by 0.02. Slate passes. */
.job_filters input::placeholder,
.search_jobs input::placeholder {
	color: var(--jik-slate);
	opacity: 1;   /* Firefox dims placeholders by default, which would undo the fix */
}

/* Job type pills. The colour here is informational, never the accent — red is
   reserved so it always means "act". */
ul.job_listings li.job_listing .meta .job-type {
	background: #EEF2F7;
	color: var(--jik-navy);
	border-radius: 999px;
	padding: 2px 10px;
	font-weight: 600;
	font-size: .75rem;
	text-transform: none;
}

/* ---------------------------------------------------------------------------
 * The Apply action — the one job of the accent colour
 * ------------------------------------------------------------------------- */

.single_job_listing .application .application_button,
input.application_button,
a.application_button {
	background: var(--jik-red) !important;
	/* White on brand red is 5.11:1 and passes AA. */
	color: #FFFFFF !important;
	font-family: var(--jik-display);
	font-weight: 700;
	border: none;
	border-radius: var(--jik-radius);
	/* 15px vertical clears the 44px minimum: the button measured 42.0px and missed by
	   two. It is the one control on the page that must never be awkward to hit. */
	padding: 15px 26px;
	min-height: 48px;
	font-size: 1rem;
	letter-spacing: -0.01em;
	cursor: pointer;
	transition: background-color .15s ease;
}

/* The Apply button had NO focus indicator at all — invisible to a keyboard user on the
 * site's single most important control. WP Job Manager declares
 * `.single_job_listing .application .application_button { outline: 0 }` at (0,3,0), which
 * beat the generic `input:focus-visible` rule at (0,1,1). Matching (0,4,0) wins.
 *
 * The ring is INK, not red: a red ring on a red button is invisible. Ink on the page
 * background measures 17.85:1, and the 3px offset keeps it clear of the fill. */
.single_job_listing .application .application_button:focus-visible,
input.application_button:focus-visible,
a.application_button:focus-visible {
	outline: 3px solid var(--jik-ink);
	outline-offset: 3px;
}

.single_job_listing .application .application_button:hover,
a.application_button:hover {
	/* An explicit darker red rather than a brightness() filter, so the hover state
	   stays a known measured colour (white on #B81A04 is 6.59:1) instead of whatever
	   the filter happens to produce. */
	background: var(--jik-red-dark) !important;
	color: #FFFFFF !important;
}

/* The archive's Search Jobs button already inherits Kadence palette 1, which IS the
   brand red, so it needs no colour override — only the shared button shape. */
.job_filters input[type="submit"],
.search_submit input[type="submit"] {
	font-family: var(--jik-display);
	font-weight: 700;
	border-radius: var(--jik-radius);
	letter-spacing: -0.01em;
}

/* ---------------------------------------------------------------------------
 * Featured listings
 *
 * WP Job Manager gives featured listings a cream background, which read as an
 * accident against this palette — and it is applied to the inner <a>, not the
 * <li>, via `.job_position_featured a`. That selector carries one more class than
 * the card rule above, so it outranks it; matching the specificity is what makes
 * this stick. 3 of 10 listings on the archive are featured.
 *
 * Featured is marked with a red inline-start edge instead. Red already means
 * "important" here, and the marker cannot be confused with an Apply button
 * because it is a border rather than a filled control.
 * ------------------------------------------------------------------------- */

ul.job_listings li.job_listing.job_position_featured a {
	background: var(--jik-paper);
}

/* The accent is GATED ON .jik-open (see inc/listing-state.php).
 *
 * Before this, the red edge marked every featured listing regardless of state — and all
 * three featured listings on page one were 9-11 months old, two of them already closed.
 * Red is declared in this file to mean "act", so spending it on a vacancy nobody can act on
 * was the design contradicting its own rule. `.jik-undated` is excluded too: a listing with
 * no date is not provably open, and the accent should never be a guess. */
ul.job_listings li.job_listing.job_position_featured.jik-open a {
	border-inline-start: 3px solid var(--jik-red);
}

/* De-emphasised employers keep their placement and their traffic, but not the accent.
 * Endorsing them with the site's "act" colour is the part that was indefensible.
 *
 * This selector carries .job_position_featured deliberately. A shorter
 * `.jik-deemphasised a` measures (0,3,2) and LOSES to the gating rule above at (0,4,2) —
 * which, being a border-inline-start shorthand, re-sets the colour it just cleared. That
 * exact miss shipped once: the card was correctly tagged and still drew the red edge. */
ul.job_listings li.job_listing.job_position_featured.jik-deemphasised a {
	border-inline-start: 3px solid var(--jik-line);
}

/* ---------------------------------------------------------------------------
 * Open / closed state
 *
 * The critique's sharpest finding: "Closed: January 26, 2026" and "Closes: September 30,
 * 2026" rendered identically, in the same 14px grey as the location. One letter of
 * difference carried the entire signal, on the one question the whole site exists to
 * answer.
 * ------------------------------------------------------------------------- */

/* A closed listing recedes. It stays reachable — a dead listing still answers "did I
 * already miss this?" — but it stops competing with live ones for attention. */
ul.job_listings li.job_listing.jik-closed a {
	background: var(--jik-wash);
}

ul.job_listings li.job_listing.jik-closed .position h3 {
	color: var(--jik-slate);
	font-weight: 600;
}

/* Closed and closing-soon are marked with WEIGHT and a label, never with colour alone —
 * colour alone is invisible to a screen reader and to anyone who cannot distinguish it.
 * The plugin already emits .application-deadline with .expiring / .expired, so these ride
 * its own semantics rather than a parallel system. */
li.application-deadline {
	font-weight: 600;
}

li.application-deadline.expiring {
	color: var(--jik-red);
}

li.application-deadline.expired {
	color: var(--jik-slate);
	font-weight: 600;
}

/* Closed badge: ink on a neutral tint, so it reads as a status rather than an action.
 * Deliberately NOT red — red is reserved for things worth doing. */
ul.job_listings li.job_listing.jik-closed .position h3::before {
	content: "Closed";
	display: inline-block;
	margin-inline-end: 8px;
	padding: 1px 8px;
	border-radius: 999px;
	background: #E2E8F0;
	color: var(--jik-ink);
	font-family: var(--jik-sans);
	font-size: .6875rem;
	font-weight: 700;
	letter-spacing: 0;
	text-transform: uppercase;
	vertical-align: middle;
}

/* ---------------------------------------------------------------------------
 * Ad zones (mu-plugins/jik-ads.php)
 *
 * Deliberately NOT styled like a job card. An ad that mimics a listing on a job
 * board is a trap for exactly the people this site exists to help — an audience
 * already targeted by recruitment scams. It gets its own tinted panel, a dashed
 * edge, and a permanent "Sponsored" label.
 *
 * The label is never the accent colour: red means "act" here, and an ad is not
 * the action the page is asking for.
 * ------------------------------------------------------------------------- */

.jik-ad {
	display: block;
	position: relative;
	background: #FBFCFD;
	border: 1px dashed #CBD5E1;
	border-radius: var(--jik-radius);
	padding: 14px 16px 16px;
	margin: 26px 0;
}

.jik-ad__label {
	display: block;
	margin-bottom: 8px;
	font-family: var(--jik-sans);
	font-size: .625rem;
	font-weight: 700;
	letter-spacing: .12em;
	text-transform: uppercase;
	color: var(--jik-slate);
}

.jik-ad__link {
	display: block;
	text-decoration: none;
	color: inherit;
}

.jik-ad__link:hover { color: inherit; }

.jik-ad__link:focus-visible {
	outline: 2px solid var(--jik-navy);
	outline-offset: 3px;
}

/* The body wrapper must be a block for BOTH variants. It is a <span>, and leaving it
   inline for image ads meant the image sized against an inline box — which is how a
   1200x630 banner ended up rendering 296px wide and 1500px tall. */
.jik-ad__body {
	display: block;
}

/* Image ads: CONTAIN, never stretch.
 *
 * `width: 100%` alone was the whole problem Em hit. An advertiser hands you whatever
 * they have — usually a square logo — and stretching it to the column width turns a
 * 500x500 logo into a 300px-tall block that dwarfs the job it sits next to. Capping
 * the height and using object-fit means a square logo, a wide banner and a tall
 * portrait all render at a sane size without anyone having to prepare artwork.
 */
.jik-ad img {
	display: block;
	max-width: 100%;
	width: auto;
	height: auto;
	max-height: 180px;
	margin-inline: auto;
	object-fit: contain;
	border-radius: 6px;
}

/* The footer strip is chrome, not content — it gets a tighter ceiling so it can never
   push the actual footer down the page. */
.jik-ad--footer_strip img { max-height: 90px; }

/* In-feed sits among job cards, which are ~106-206px tall. Matching that keeps the
   feed's rhythm instead of one oversized block interrupting it. */
.jik-ad--archive_feed img { max-height: 140px; }

/* Native text ads are set in the site's own type so they read as a message rather
   than a banner, but the panel and label keep them honest. */
.jik-ad--native .jik-ad__body {
	display: block;
	font-family: var(--jik-sans);
	color: var(--jik-ink);
	line-height: 1.55;
}

.jik-ad--native .jik-ad__body p { margin: 0 0 .5em; }
.jik-ad--native .jik-ad__body p:last-child { margin-bottom: 0; }

.jik-ad--native .jik-ad__link .jik-ad__body { text-decoration: underline; text-underline-offset: 3px; }

/* In-feed: it is an <li> inside ul.job_listings, so it must opt out of every job
   card rule — including the mobile grid — or it inherits a layout meant for a
   listing and starts looking like one. */
ul.job_listings > li.jik-ad-slot {
	display: block;
	list-style: none;
	margin: 10px 0;
	padding: 0;
	border: none;
	background: none;
}

ul.job_listings > li.jik-ad-slot .jik-ad { margin: 0; }

.jik-ad-strip {
	max-width: 1290px;
	margin-inline: auto;
	padding-inline: 24px;
}

.jik-ad--footer_strip { margin: 22px 0 0; }

@media (max-width: 599px) {
	.jik-ad { padding: 12px 14px 14px; margin: 20px 0; }
	.jik-ad-strip { padding-inline: 24px; }
}

/* ---------------------------------------------------------------------------
 * Key facts (inc/apply.php)
 *
 * The description ran 878 words without stating the salary or the closing date,
 * so the decision Apply asks for could not be made from anything above it. These
 * are the fields a job seeker actually decides on, in one screen.
 * ------------------------------------------------------------------------- */

.jik-facts {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
	gap: 1px;
	margin: 0 0 26px;
	padding: 0;
	background: var(--jik-line);
	border: 1px solid var(--jik-line);
	border-radius: var(--jik-radius);
	overflow: hidden;
}

.jik-facts__item {
	background: var(--jik-paper);
	padding: 12px 14px;
}

.jik-facts dt {
	margin: 0 0 3px;
	font-size: .6875rem;
	font-weight: 700;
	letter-spacing: .06em;
	text-transform: uppercase;
	color: var(--jik-slate);
}

.jik-facts dd {
	margin: 0;
	font-family: var(--jik-display);
	font-weight: 700;
	font-size: .9375rem;
	line-height: 1.3;
	color: var(--jik-ink);
	overflow-wrap: anywhere;
}

/* Urgency earns the accent: a closing date inside a week is the one fact here that
   should change what someone does today. */
.jik-facts__item.is-urgent dd { color: var(--jik-red); }
.jik-facts__item.is-closed dd { color: var(--jik-slate); }

/* ---------------------------------------------------------------------------
 * Sticky apply bar (inc/apply.php + assets/js/apply-bar.js)
 *
 * Small screens only. On desktop the button is already reachable and a fixed bar
 * would just take space.
 * ------------------------------------------------------------------------- */

.jik-applybar { display: none; }

@media (max-width: 767px) {
	.jik-applybar {
		display: block;
		position: fixed;
		inset-inline: 0;
		bottom: 0;
		z-index: 400;
		background: var(--jik-paper);
		border-top: 1px solid var(--jik-line);
		box-shadow: 0 -2px 12px rgba(15, 23, 42, .08);
		/* Clears the iOS home indicator, which would otherwise sit over the button. */
		padding-bottom: env(safe-area-inset-bottom, 0px);
		transition: transform .2s ease, opacity .2s ease;
	}

	/* Slid away rather than display:none, so it does not jump when it returns. */
	.jik-applybar.is-hidden {
		transform: translateY(110%);
		opacity: 0;
		pointer-events: none;
	}

	.jik-applybar__inner {
		display: flex;
		align-items: center;
		gap: 12px;
		padding: 10px 16px;
	}

	.jik-applybar__meta {
		min-width: 0;   /* lets the title truncate instead of shoving the button off */
		flex: 1 1 auto;
		display: flex;
		flex-direction: column;
		line-height: 1.25;
	}

	.jik-applybar__title {
		font-family: var(--jik-display);
		font-weight: 700;
		font-size: .875rem;
		color: var(--jik-ink);
		white-space: nowrap;
		overflow: hidden;
		text-overflow: ellipsis;
	}

	.jik-applybar__company {
		font-size: .75rem;
		color: var(--jik-slate);
		white-space: nowrap;
		overflow: hidden;
		text-overflow: ellipsis;
	}

	.jik-applybar__button {
		flex: 0 0 auto;
		min-height: 48px;
		padding: 0 26px;
		background: var(--jik-red);
		color: #FFFFFF;
		font-family: var(--jik-display);
		font-weight: 700;
		font-size: 1rem;
		border: none;
		border-radius: var(--jik-radius);
		cursor: pointer;
	}

	.jik-applybar__button:active { background: var(--jik-red-dark); }

	.jik-applybar__button:focus-visible {
		outline: 3px solid var(--jik-ink);
		outline-offset: 3px;
	}

	/* Stop the bar covering the last of the page — the footer's Telegram link in
	   particular sat underneath it. */
	body.single-job_listing { padding-bottom: 76px; }
}

@media (prefers-reduced-motion: reduce) {
	.jik-applybar { transition: none; }
}

/* ---------------------------------------------------------------------------
 * Result count (inc/listings-render.php)
 * ------------------------------------------------------------------------- */

.jik-count {
	display: flex;
	flex-wrap: wrap;
	align-items: baseline;
	gap: 4px 10px;
	margin: 0 0 14px;
	font-family: var(--jik-display);
	font-size: 1.0625rem;
	letter-spacing: -0.01em;
}

.jik-count strong { font-weight: 800; }

.jik-count__fresh {
	font-family: var(--jik-sans);
	font-size: .875rem;
	font-weight: 500;
	color: var(--jik-slate);
}

.jik-count__fresh::before {
	content: "";
	display: inline-block;
	width: 7px;
	height: 7px;
	margin-inline-end: 6px;
	border-radius: 50%;
	/* Green reads as "live" without borrowing the action colour. */
	background: #16A34A;
	vertical-align: middle;
}

/* ---------------------------------------------------------------------------
 * Empty search results (job_manager/content-no-jobs-found.php)
 *
 * Replaces one sentence over a thousand pixels of blank wash. This is the
 * moment a visitor is most likely to leave for good, so it gets a way onward
 * rather than an apology.
 * ------------------------------------------------------------------------- */

li.no_job_listings_found.jik-empty,
p.no_job_listings_found.jik-empty {
	list-style: none;
	background: var(--jik-paper);
	border: 1px solid var(--jik-line);
	border-radius: var(--jik-radius);
	padding: 0;
	margin: 0;
}

.jik-empty__inner { padding: 28px 24px 24px; }

.jik-empty__heading {
	font-size: 1.2rem;
	font-weight: 700;
	margin: 0 0 8px;
}

.jik-empty__blurb {
	margin: 0 0 18px;
	color: var(--jik-slate);
	max-width: 46ch;
}

.jik-empty__actions { margin: 0 0 22px; }

.jik-empty__cta {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-height: 48px;
	padding: 0 24px;
	background: var(--jik-red);
	color: #FFFFFF;
	font-family: var(--jik-display);
	font-weight: 700;
	border-radius: var(--jik-radius);
	text-decoration: none;
}

.jik-empty__cta:hover { background: var(--jik-red-dark); color: #FFFFFF; }

.jik-empty__label {
	margin: 0 0 10px;
	font-size: .8125rem;
	font-weight: 700;
	letter-spacing: .06em;
	text-transform: uppercase;
	color: var(--jik-slate);
}

/* The class alone is (0,1,0) and lost to a nested-list rule that indented the chips
   ~100px from the heading above them. Scoping through the wrapper and the element type
   raises it to (0,3,2) and wins. */
.jik-empty .jik-empty__inner ul.jik-empty__chips {
	list-style: none;
	margin: 0 0 20px;
	padding-inline-start: 0;
	margin-inline-start: 0;
	text-indent: 0;
	display: flex;
	flex-wrap: wrap;
	gap: 8px;
}

.jik-empty .jik-empty__inner ul.jik-empty__chips > li {
	margin: 0;
	padding: 0;
	list-style: none;
}

.jik-empty__chips a {
	display: inline-flex;
	align-items: center;
	gap: 7px;
	min-height: 44px;
	padding: 0 14px;
	border: 1px solid var(--jik-line);
	border-radius: 999px;
	background: var(--jik-wash);
	color: var(--jik-ink);
	font-weight: 600;
	font-size: .9375rem;
	text-decoration: none;
}

.jik-empty__chips a:hover {
	border-color: var(--jik-navy);
	color: var(--jik-navy);
}

.jik-empty__count {
	color: var(--jik-slate);
	font-size: .8125rem;
	font-variant-numeric: tabular-nums;
}

.jik-empty__telegram { margin: 0; }

@media (max-width: 599px) {
	.jik-empty__inner { padding: 22px 18px 20px; }
	.jik-empty__cta { width: 100%; }
}

/* ---------------------------------------------------------------------------
 * Related jobs (see inc/related-jobs.php)
 * ------------------------------------------------------------------------- */

.jik-related {
	margin: 40px 0 8px;
	padding: 24px;
	background: var(--jik-paper);
	border: 1px solid var(--jik-line);
	border-radius: var(--jik-radius);
}

.jik-related__heading {
	font-size: 1.15rem;
	font-weight: 700;
	margin: 0 0 14px;
}

/* Kadence indents lists inside post content, which pushed these items ~68px right
   of their own heading and made the block look misaligned. The indent is reset on
   both the list and the item, since the padding can land on either. */
.jik-related__list,
.jik-related .jik-related__list {
	list-style: none;
	margin: 0;
	padding-inline-start: 0;
	text-indent: 0;
}

.jik-related__item {
	padding: 11px 0;
	margin-inline-start: 0;
	border-top: 1px solid var(--jik-line);
	list-style: none;
}

.jik-related__item::marker { content: none; }

.jik-related__item:first-child { border-top: none; }

.jik-related__link {
	display: block;
	font-weight: 600;
	line-height: 1.35;
	text-decoration: none;
}

.jik-related__meta {
	display: block;
	color: var(--jik-slate);
	font-size: .8125rem;
	margin-top: 2px;
}

.jik-related__more {
	margin: 16px 0 0;
	font-size: .875rem;
	font-weight: 600;
}

/* ---------------------------------------------------------------------------
 * Telegram link (the [jik_telegram] shortcode)
 * ------------------------------------------------------------------------- */

.jik-telegram {
	display: inline-flex;
	align-items: center;
	gap: 7px;
	font-weight: 600;
	text-decoration: none;
	color: var(--jik-navy);
}

.jik-telegram::before {
	content: "";
	width: 17px;
	height: 17px;
	flex: 0 0 17px;
	background: currentColor;
	/* Inlined as a mask so the icon inherits colour and costs no extra request. */
	-webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M9.78 18.65l.28-4.23 7.68-6.92c.34-.31-.07-.46-.52-.19L7.74 13.3 3.64 12c-.88-.25-.89-.86.2-1.3l15.97-6.16c.73-.33 1.43.18 1.15 1.3l-2.72 12.81c-.19.91-.74 1.13-1.5.71L12.6 16.3l-1.99 1.93c-.23.23-.42.42-.83.42z'/%3E%3C/svg%3E") no-repeat center / contain;
	        mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M9.78 18.65l.28-4.23 7.68-6.92c.34-.31-.07-.46-.52-.19L7.74 13.3 3.64 12c-.88-.25-.89-.86.2-1.3l15.97-6.16c.73-.33 1.43.18 1.15 1.3l-2.72 12.81c-.19.91-.74 1.13-1.5.71L12.6 16.3l-1.99 1.93c-.23.23-.42.42-.83.42z'/%3E%3C/svg%3E") no-repeat center / contain;
}

.site-footer .jik-telegram { color: inherit; }

/* ---------------------------------------------------------------------------
 * Top bar (inc/chrome.php)
 *
 * Navy, never red: the accent may not sit on navy at 2.25:1. White on navy is
 * 11.50:1. Kept to ~36px because the archive already spends 688px of mobile
 * height before the first job card, and this must not make that worse.
 * ------------------------------------------------------------------------- */

.jik-topbar {
	background: var(--jik-navy);
	color: #FFFFFF;
}

.jik-topbar__inner {
	max-width: 1290px;
	margin: 0 auto;
	padding: 7px 24px;
	display: flex;
	align-items: center;
	/* Account actions left, Telegram right. Both sit in the bar that already exists, so
	   neither costs the header any extra height — the mobile space Chunk 4 reclaimed. */
	justify-content: space-between;
	gap: 12px;
	font-size: .875rem;
}

.jik-topbar__actions {
	display: flex;
	align-items: center;
	gap: 6px;
	min-width: 0;
}

.jik-topbar__link,
.jik-topbar__cta {
	display: inline-flex;
	align-items: center;
	min-height: 44px;
	padding: 0 12px;
	color: #FFFFFF;
	font-weight: 600;
	text-decoration: none;
	white-space: nowrap;
	border-radius: 8px;
}

.jik-topbar__link:hover { color: #FFFFFF; text-decoration: underline; }

/* The employer path is the revenue one, so it is the filled control. White on the brand red
   measures 5.11:1; red never sits ON the navy bar itself, which is 2.25:1 and unreadable. */
.jik-topbar__cta {
	background: var(--jik-red);
	padding: 0 16px;
	min-height: 36px;
}

.jik-topbar__cta:hover { background: var(--jik-red-dark); color: #FFFFFF; }

.jik-topbar__link:focus-visible,
.jik-topbar__cta:focus-visible {
	outline: 2px solid #FFFFFF;
	outline-offset: 2px;
}

.jik-topbar .jik-telegram {
	color: #FFFFFF;
	/* 44px min target: the critique measured 17 controls under 44px, and a link in a
	   slim bar is the easiest one to get wrong. Padding does the work so the bar
	   itself stays short. */
	min-height: 44px;
	align-items: center;
	padding: 0 2px;
}

.jik-topbar .jik-telegram:hover { color: #FFFFFF; text-decoration: underline; }

.jik-topbar .jik-telegram:focus-visible {
	outline: 2px solid #FFFFFF;
	outline-offset: 2px;
}

@media (max-width: 767px) {
	.jik-topbar__inner { padding: 4px 16px; gap: 8px; }
	/* Tighter, but nothing is hidden: a signed-out visitor still sees both paths, and the
	   bar wraps rather than overflowing. */
	.jik-topbar__link, .jik-topbar__cta { padding: 0 9px; font-size: .8125rem; }
	.jik-topbar .jik-telegram { font-size: .8125rem; }
	.jik-topbar .jik-telegram span,
	.jik-topbar__actions { min-width: 0; }
}

/* Below 420px the Telegram wording is what gives, not an account action. */
@media (max-width: 419px) {
	.jik-topbar .jik-telegram { font-size: 0; gap: 0; }
	.jik-topbar .jik-telegram::before { margin-inline-end: 0; width: 20px; height: 20px; flex-basis: 20px; }
}

/* ---------------------------------------------------------------------------
 * Footer (inc/chrome.php)
 *
 * Renders ABOVE Kadence's own footer, which keeps the copyright and agency
 * credit intact as the bottom bar.
 * ------------------------------------------------------------------------- */

.jik-footer {
	background: var(--jik-paper);
	border-top: 1px solid var(--jik-line);
}

.jik-footer__inner {
	max-width: 1290px;
	/* 24px matches the theme's own .site-container. At 20px the footer's content
	   started 4px left of the header logo and .site-main — close enough to look like
	   a mistake rather than a choice. Logical properties, consistent with the
	   job-listings reset. */
	margin-inline: auto;
	margin-block: 0;
	padding-inline: 24px;
	padding-block: 44px 36px;

	/* Flex, not grid.
	 *
	 * `repeat(auto-fit, minmax(210px, 1fr))` resolved to FIVE tracks — four real ones
	 * at 291.5px and a phantom at 0px — because auto-fit lays out as many tracks as
	 * the container allows and collapses the unused ones. Harmless to look at, but it
	 * makes `gap` apply to a track that is not there, and the column count is dynamic
	 * anyway: the Browse column disappears when no category has listings.
	 *
	 * Wrapping flex items size to their own content, so there is no phantom track and
	 * a long category name still cannot force a horizontal scrollbar. */
	display: flex;
	flex-wrap: wrap;
	gap: 32px 28px;
}

.jik-footer__col {
	flex: 1 1 210px;
	min-width: 0;   /* lets a long word wrap instead of stretching the column */
}

.jik-footer__heading {
	font-family: var(--jik-display);
	font-size: .8125rem;
	font-weight: 700;
	letter-spacing: .06em;
	text-transform: uppercase;
	color: var(--jik-slate);
	margin: 0 0 14px;
}

.jik-footer__list {
	list-style: none;
	margin: 0;
	padding-inline-start: 0;
}

.jik-footer__list li { margin: 0; }

.jik-footer__list a {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 10px;
	/* 44px tap target. The critique measured the existing footer links at 36px. */
	min-height: 44px;
	color: var(--jik-ink);
	text-decoration: none;
	font-weight: 500;
}

.jik-footer__list a:hover { color: var(--jik-red); }

.jik-footer__count {
	color: var(--jik-slate);
	font-size: .8125rem;
	font-variant-numeric: tabular-nums;
}

.jik-footer__blurb {
	margin: 0 0 14px;
	color: var(--jik-slate);
	font-size: .9375rem;
	line-height: 1.55;
}

.jik-footer__col--cta .jik-telegram {
	min-height: 44px;
	font-weight: 600;
}

@media (max-width: 767px) {
	.jik-footer__inner {
		padding-inline: 24px;
		padding-block: 32px 28px;
		gap: 26px 20px;
	}
}

/* ---------------------------------------------------------------------------
 * Mobile menu toggle
 *
 * Measured 36.8 x 31.2px against the 44px minimum. The icon is the right size —
 * it is the HIT AREA that is short, so this grows the padding and leaves the
 * glyph alone. Scaling the icon instead would make the header heavier for no
 * usability gain.
 * ------------------------------------------------------------------------- */

.site-header #mobile-toggle,
.site-header .menu-toggle,
.site-header button.menu-toggle-close {
	min-width: 44px;
	min-height: 44px;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	padding: 0;
}

/* ---------------------------------------------------------------------------
 * Remaining small tap targets
 *
 * Measured under the 44px minimum: the six job-type checkboxes at 13x13, the RSS
 * link at 35.6x21.9, and pagination at 25.8-34.9 x 32. Grown by padding on the
 * clickable element, never by scaling the control, so the layout keeps its size
 * and only the hit area changes.
 * ------------------------------------------------------------------------- */

/* The checkbox itself stays 13px; its LABEL becomes the target, which is what a
   user aims at anyway and what a screen reader already associates with it. */
.job_filters .job_types li label,
.job_filters .job_types label,
.job_filters .search_categories label,
.job_filters li label {
	display: inline-flex;
	align-items: center;
	gap: 8px;
	min-height: 44px;
	cursor: pointer;
}

.job_filters input[type="checkbox"] {
	/* A larger box is easier to hit AND easier to see as checked. */
	width: 18px;
	height: 18px;
	margin: 0;
	flex: 0 0 18px;
	accent-color: var(--jik-red);
}

.job_filters a.rss_link,
.job_filters .showing_jobs a {
	display: inline-flex;
	align-items: center;
	min-height: 44px;
	padding-inline: 6px;
}

nav.job-manager-pagination a,
nav.job-manager-pagination span,
.job-manager-pagination .page-numbers {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-width: 44px;
	min-height: 44px;
}

/* ---------------------------------------------------------------------------
 * Sticky header
 *
 * A job listing runs to roughly 5,600px on a phone. Once a reader is a few
 * screens in, the only way back to search or the menu was to scroll all the way
 * up. The header now follows.
 *
 * Only the header sticks — the Telegram bar above it scrolls away, so the
 * permanent cost is the header alone rather than both. On a 844px phone that is
 * the difference between giving up ~9% of the viewport and ~14%.
 * ------------------------------------------------------------------------- */

/* `#masthead` carries the ID because Kadence declares `#masthead{position:relative}` in
 * header.min.css — an ID selector at (1,0,0) that a plain `.site-header` rule (0,1,0)
 * cannot beat no matter how late it loads. The first attempt shipped a header that
 * reported position:relative and did not stick at all. */
#masthead.site-header,
.site-header {
	position: sticky;
	top: 0;
	/* Above Kadence's own header items and the job list, below the mobile drawer
	   (which Kadence puts at 1000+) so the menu still covers the page. */
	z-index: 500;
	background: var(--jik-paper);
	/* A hairline rather than a drop shadow: the header sits directly on white
	   cards, and a shadow there reads as a smudge. */
	box-shadow: 0 1px 0 var(--jik-line);
}

/* The WordPress admin bar is itself fixed at the top, so a sticky header at
   top:0 would sit underneath it for logged-in users. */
.admin-bar .site-header { top: 32px; }

@media (max-width: 782px) {
	.admin-bar .site-header { top: 46px; }
}

/* Anchor links and in-page jumps must not land under the sticky header. */
html {
	scroll-padding-top: 96px;
}

/* ---------------------------------------------------------------------------
 * Small screens
 *
 * Most visitors arrive on an inexpensive Android handset, so this is the case
 * that actually matters rather than an afterthought.
 * ------------------------------------------------------------------------- */

/* ---------------------------------------------------------------------------
 * Job cards on small screens
 *
 * WP Job Manager keeps its desktop two-column layout all the way down. At 390px
 * that left .position 174px wide, so titles broke mid-word, the posted date
 * wrapped onto three lines, and the company logo was set to visibility:hidden —
 * present, occupying nothing, invisible. The card is the primary scanning unit
 * of the whole site and it was the worst-laid-out thing on the page.
 *
 * Rebuilt as an explicit grid so the source order (logo, position, location,
 * meta) can render as: logo, then title and company, then ONE horizontal meta
 * row. Grid areas are what make location and meta share a row without needing a
 * wrapper element the plugin does not give us.
 * ------------------------------------------------------------------------- */

@media (max-width: 599px) {
	ul.job_listings li.job_listing a {
		display: grid;
		grid-template-columns: auto minmax(0, 1fr);
		grid-template-areas:
			"logo   logo"
			"title  title"
			"loc    meta";
		gap: 8px 12px;
		padding: 14px 16px;
		/* The whole card is one tap target; nothing inside it is separately
		   tappable, so the minimum applies here. */
		min-height: 44px;
		align-items: center;
	}

	/* Every selector below carries the `a` and the element type on purpose.
	 *
	 * WP Job Manager styles these at `ul.job_listings li.job_listing a img.company_logo`
	 * — specificity (0,3,4). The first attempt used (0,3,3) and (0,3,2), lost silently,
	 * and shipped a grid whose children were still floated at 55%/60% width: the card
	 * reported display:grid while .position stayed 174px and the logo stayed hidden.
	 * Matching (0,3,4) and loading later is what actually wins. */

	/* The logo is worth showing: it is the fastest employer-recognition cue there
	   is, and WPJM's `visibility: hidden` left a 42px hole doing nothing. */
	ul.job_listings li.job_listing a img.company_logo {
		grid-area: logo;
		position: static;
		visibility: visible;
		float: none;
		width: 40px;
		height: 40px;
		margin: 0;
		left: auto;
		object-fit: contain;
	}

	ul.job_listings li.job_listing a div.position {
		grid-area: title;
		float: none;
		width: auto;
		padding: 0;
		margin: 0;
	}

	ul.job_listings li.job_listing a div.location {
		grid-area: loc;
		float: none;
		width: auto;
		padding: 0;
		margin: 0;
		text-align: start;
		font-size: .8125rem;
		line-height: 1.3;
		color: var(--jik-slate);
		white-space: nowrap;
	}

	ul.job_listings li.job_listing a ul.meta {
		grid-area: meta;
		float: none;
		width: auto;
		margin: 0;
		padding: 0;
		display: flex;
		flex-wrap: wrap;
		align-items: center;
		/* Flow left, continuing the row that starts with the location. Right-aligning
		   (WPJM's desktop behaviour) left a gap after "kampala" and read as two
		   disconnected fragments rather than one meta line. */
		justify-content: flex-start;
		gap: 4px 8px;
		text-align: start;
		font-size: .8125rem;
		line-height: 1.3;
	}

	/* The plugin emits `<label>Closes:</label> September 30` and relies on the text
	   node between them for the space. Flex removes it, giving "Closes:September". */
	ul.job_listings li.job_listing a ul.meta li label {
		margin-inline-end: .3em;
	}

	/* WPJM indents the tagline to sit under the logo on desktop; with the logo on its
	   own row that 7px indent is orphaned and the tagline sits off the company name.
	   Full element chain because a (0,4,4) selector still lost to the plugin. */
	ul.job_listings li.job_listing a div.position div.company span.tagline {
		padding-inline-start: 0;
		margin-inline-start: 0;
		margin-block-start: 1px;
	}

	ul.job_listings li.job_listing a ul.meta li {
		margin: 0;
		padding: 0;
		float: none;
		display: inline-flex;
		align-items: center;
	}

	/* Long single tokens — "Developer/Designer/SEO", an unspaced employer name —
	   are what actually broke mid-word once the column narrowed. `anywhere` also
	   lets the browser shrink the element's min-content width, which `break-word`
	   does not, so the grid column can stay narrow instead of overflowing. */
	ul.job_listings li.job_listing .position h3,
	ul.job_listings li.job_listing .company,
	ul.job_listings li.job_listing .location {
		overflow-wrap: anywhere;
	}

	ul.job_listings li.job_listing .position h3 {
		font-size: 1rem;
		line-height: 1.3;
		margin: 0 0 2px;
	}

	ul.job_listings li.job_listing .company {
		display: block;
		margin: 0;
	}

	ul.job_listings li.job_listing .company .tagline {
		display: block;
		margin: 0;
	}

	/* A closed listing's badge sits inline with a now-wrapping title, so it needs
	   to stay on its own baseline rather than stretch the line box. */
	ul.job_listings li.job_listing.jik-closed .position h3::before {
		margin-block-end: 2px;
	}
}

@media (max-width: 767px) {
	body { font-size: 16px; }

	h1, .entry-title { font-size: 1.6rem; }

	.jik-related { padding: 18px; }

	/* A full-width Apply button is far easier to hit with a thumb. */
	.single_job_listing .application .application_button,
	a.application_button {
		display: block;
		width: 100%;
		text-align: center;
	}
}

@media (prefers-reduced-motion: reduce) {
	* { transition: none !important; }
	ul.job_listings li.job_listing a:hover { transform: none; }
}
