/*
Theme Name: EnglishOpportunities
Theme URI: https://englishopportunities.eu
Author: EnglishOpportunities.eu
Description: The presentation layer for EnglishOpportunities.eu (readme.md §41 Frontend Design). Contains no business logic — every data read goes through englishopportunities-core's public classes (Public_Query, EO\Homepage\Controller, the repositories), matching docs/ARCHITECTURE.md #1's theme/plugin separation. Fully replaceable: with this theme deactivated, every route still works via the plugin's own bundled fallback templates.
Version: 1.0.0
Requires PHP: 8.1
Requires Plugins: englishopportunities-core
Text Domain: englishopportunities
*/

/* -----------------------------------------------------------------------
   Design tokens
----------------------------------------------------------------------- */
:root {
	--eo-primary: #1d4ed8;
	--eo-primary-dark: #1e3a8a;
	--eo-accent: #0d9488;
	--eo-ink: #0f172a;
	--eo-body: #334155;
	--eo-muted: #64748b;
	--eo-border: #e2e8f0;
	--eo-surface: #ffffff;
	--eo-bg: #f8fafc;
	--eo-success: #15803d;
	--eo-warning: #b45309;
	--eo-radius: 10px;
	--eo-max-width: 1180px;
	--eo-font: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
}

/* -----------------------------------------------------------------------
   Base
----------------------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }

body {
	margin: 0;
	font-family: var(--eo-font);
	color: var(--eo-body);
	background: var(--eo-bg);
	line-height: 1.55;
}

img { max-width: 100%; height: auto; }

a { color: var(--eo-primary); text-decoration: none; }
a:hover { text-decoration: underline; }

h1, h2, h3, h4 {
	color: var(--eo-ink);
	line-height: 1.2;
	margin: 0 0 .5em;
}

.eo-container {
	max-width: var(--eo-max-width);
	margin: 0 auto;
	padding: 0 1.25rem;
}

.eo-visually-hidden {
	position: absolute;
	width: 1px; height: 1px;
	overflow: hidden;
	clip: rect(0,0,0,0);
	white-space: nowrap;
}

.eo-btn {
	display: inline-block;
	background: var(--eo-primary);
	color: #fff;
	border: none;
	border-radius: var(--eo-radius);
	padding: .65rem 1.1rem;
	font-size: .95rem;
	font-weight: 600;
	cursor: pointer;
	text-decoration: none;
}
.eo-btn:hover { background: var(--eo-primary-dark); color: #fff; text-decoration: none; }
.eo-btn-secondary { background: transparent; color: var(--eo-primary); border: 1px solid var(--eo-primary); }
.eo-btn-secondary:hover { background: var(--eo-primary); color: #fff; }

input[type=text], input[type=search], input[type=email], input[type=number],
input[type=password], input[type=date], select, textarea {
	font-family: inherit;
	font-size: .95rem;
	padding: .6rem .8rem;
	border: 1px solid var(--eo-border);
	border-radius: 12px;
	background: #fff;
	color: var(--eo-ink);
	line-height: 1.3;
	transition: border-color .15s ease, box-shadow .15s ease;
}
input[type=text]:hover, input[type=search]:hover, input[type=email]:hover, input[type=number]:hover,
input[type=password]:hover, input[type=date]:hover, select:hover, textarea:hover {
	border-color: color-mix(in srgb, var(--eo-primary) 40%, var(--eo-border));
}
input[type=text]:focus, input[type=search]:focus, input[type=email]:focus, input[type=number]:focus,
input[type=password]:focus, input[type=date]:focus, select:focus, textarea:focus {
	outline: none;
	border-color: var(--eo-primary);
	box-shadow: 0 0 0 3px color-mix(in srgb, var(--eo-primary) 18%, transparent);
}
input::placeholder, textarea::placeholder { color: var(--eo-muted); opacity: 1; }

/* Real, consistent dropdown arrow instead of each browser's own default
   select styling (a recurring "looks amateur" complaint) — a plain
   inline SVG chevron as a background image, `appearance:none` to
   suppress the native one. */
select {
	appearance: none;
	-webkit-appearance: none;
	padding-right: 2.3rem;
	background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='20' height='20' viewBox='0 0 24 24' fill='none' stroke='%2364748b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
	background-repeat: no-repeat;
	background-position: right .6rem center;
	cursor: pointer;
}

/* -----------------------------------------------------------------------
   Header / primary nav
----------------------------------------------------------------------- */
.eo-site-header {
	background: var(--eo-primary-dark);
	border-bottom: none;
	position: sticky;
	top: 0;
	z-index: 50;
}

.eo-header-inner {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 1.5rem;
	/* 🔴 Real bug found live: this shorthand fully overrides
	   .eo-container's own `padding: 0 1.25rem` (equal specificity, later
	   rule wins the *entire* shorthand, not just the sides it mentions) —
	   the header actually had zero horizontal padding, logo and hamburger
	   sitting flush against the viewport edge on mobile. */
	padding: .85rem 1.25rem;
}

.eo-logo {
	font-size: 1.15rem;
	font-weight: 800;
	color: #fff;
	white-space: nowrap;
	display: inline-flex;
	align-items: center;
}
.eo-logo:hover { text-decoration: none; opacity: .85; }
/* Width comes from an inline style (header.php, Branding\Controller::logo_width() —
   admin-configurable); max-height just keeps a very tall/square upload
   from blowing out the header's height. */
.eo-logo-img { max-height: 60px; display: block; }

.eo-primary-nav ul {
	list-style: none;
	display: flex;
	flex-wrap: wrap;
	gap: 1.1rem;
	margin: 0;
	padding: 0;
}
.eo-primary-nav a {
	color: rgba(255,255,255,.82);
	font-size: .92rem;
	font-weight: 500;
}
.eo-primary-nav a:hover { color: #fff; text-decoration: none; }

.eo-has-dropdown { position: relative; }
.eo-has-dropdown > a::after {
	content: "";
	display: inline-block;
	width: 6px;
	height: 6px;
	margin-left: .35em;
	border-right: 1.5px solid currentColor;
	border-bottom: 1.5px solid currentColor;
	transform: translateY(-2px) rotate(45deg);
}
/* 🔴 Real bug found live: .eo-dropdown is itself a <ul> nested inside
   .eo-primary-nav, so the earlier, more specific ".eo-primary-nav ul"
   rule (one class + one element, 0-1-1) was beating this plain
   ".eo-dropdown { display:none }" (one class, 0-1-0) regardless of
   source order — the dropdown rendered permanently open. Every selector
   below is qualified with .eo-primary-nav to guarantee it wins.
   Uses opacity/visibility rather than display so it can transition, and
   deliberately has NO margin-top gap between the trigger and the panel
   — the visual spacing comes from padding-top instead, which keeps the
   gap *inside* the panel's own hoverable box (a real dead zone there
   was the reported "vanishes too fast" cause: crossing that gap left
   .eo-has-dropdown's hover state with nothing under the cursor).
   Hiding is also delayed (transition-delay, only on the closed state —
   opening stays instant) so a brief, imprecise mouse path off the
   trigger doesn't close it before the pointer reaches the panel. */
.eo-primary-nav .eo-dropdown {
	display: flex;
	flex-direction: column;
	gap: 0;
	position: absolute;
	top: 100%;
	left: 0;
	margin-top: 0;
	padding: .6rem .4rem .4rem;
	background: #fff;
	border-radius: 10px;
	box-shadow: 0 12px 28px rgba(15,23,42,.18);
	min-width: 190px;
	z-index: 10;
	opacity: 0;
	visibility: hidden;
	pointer-events: none;
	transition: opacity .15s ease .35s, visibility 0s linear .5s;
}
.eo-primary-nav .eo-has-dropdown:hover .eo-dropdown,
.eo-primary-nav .eo-has-dropdown:focus-within .eo-dropdown {
	opacity: 1;
	visibility: visible;
	pointer-events: auto;
	transition-delay: 0s;
}
.eo-dropdown li { display: block; }
.eo-dropdown a {
	display: block;
	color: var(--eo-ink);
	padding: .55rem .7rem;
	border-radius: 6px;
	font-size: .9rem;
}
.eo-dropdown a:hover { background: var(--eo-bg); color: var(--eo-primary); text-decoration: none; }

.eo-header-actions {
	display: flex;
	align-items: center;
	gap: .75rem;
	flex-shrink: 0;
}

.eo-site-header .eo-btn-secondary { color: #fff; border-color: rgba(255,255,255,.5); background: transparent; }
.eo-site-header .eo-btn-secondary:hover { background: rgba(255,255,255,.15); color: #fff; }
.eo-site-header .eo-btn:not(.eo-btn-secondary) { background: #fff; color: var(--eo-primary-dark); }
.eo-site-header .eo-btn:not(.eo-btn-secondary):hover { background: rgba(255,255,255,.85); color: var(--eo-primary-dark); }

.eo-nav-toggle {
	display: none;
	align-items: center;
	background: none;
	border: 1px solid rgba(255,255,255,.4);
	color: #fff;
	border-radius: 6px;
	padding: .4rem .6rem;
	cursor: pointer;
}

/* -----------------------------------------------------------------------
   Icons (eo_icon() — functions.php)
----------------------------------------------------------------------- */
.eo-icon { width: 1em; height: 1em; vertical-align: -0.15em; }
.eo-icon-menu { width: 20px; height: 20px; }
.eo-icon-pin { width: 14px; height: 14px; color: var(--eo-primary); vertical-align: -0.1em; }
.eo-icon-check { width: 13px; height: 13px; vertical-align: -0.05em; }

@media (max-width: 900px) {
	.eo-nav-toggle { display: inline-flex; }
	.eo-primary-nav {
		display: none;
		width: 100%;
		order: 3;
	}
	.eo-primary-nav.is-open { display: block; }
	.eo-primary-nav ul { flex-direction: column; gap: .1rem; padding: .5rem 0; }
	.eo-primary-nav a { display: block; padding: .5rem 0; }
	/* No hover on touch, and focus-within only fires after the parent
	   link itself would already have navigated away — a real collapsible
	   accordion here instead of a hover flyout, toggled by nav.js
	   (intercepts the click at this breakpoint only; the link's real
	   href still works as a fallback with JS disabled). The caret from
	   the desktop rule above stays visible and rotates to show state,
	   rather than a permanently-open sub-list. */
	.eo-has-dropdown > a::after { transition: transform .15s ease; }
	.eo-has-dropdown.is-open > a::after { transform: translateY(0) rotate(225deg); }
	.eo-primary-nav .eo-dropdown {
		display: none;
		flex-direction: column;
		gap: 0;
		position: static;
		box-shadow: none;
		background: none;
		margin: .2rem 0 .4rem 1rem;
		padding: 0;
		opacity: 1;
		visibility: visible;
		pointer-events: auto;
		transition: none;
	}
	.eo-primary-nav .eo-has-dropdown.is-open .eo-dropdown { display: flex; }
	.eo-dropdown a { color: rgba(255,255,255,.75); padding: .4rem .7rem; }
	.eo-dropdown a:hover { background: rgba(255,255,255,.08); color: #fff; }
	.eo-header-inner { flex-wrap: wrap; }
	/* 🔴 Pre-existing overflow, found live while reviewing this header at a
	   real mobile width: .eo-header-actions is its own non-wrapping flex
	   row, so on narrow viewports the search box + Login + Sign Up +
	   Post a Job buttons ran off the right edge instead of wrapping like
	   the rest of the header already does. */
	.eo-header-actions { flex-wrap: wrap; row-gap: .5rem; }
}

/* -----------------------------------------------------------------------
   Hero / search
----------------------------------------------------------------------- */
.eo-hero {
	position: relative;
	background: linear-gradient(135deg, var(--eo-primary) 0%, var(--eo-primary-dark) 100%);
	background-size: cover;
	background-position: center;
	padding: 2.5rem 0 3rem;
	min-height: 440px;
	display: flex;
	align-items: flex-end;
	overflow: hidden;
}
/* Dark tint over whatever's behind the search card — the admin-uploaded
   hero photo (EO\Homepage\Controller::hero_background_url()) or, when
   none is set, the gradient fallback above — so the card's drop shadow
   still reads clearly against a bright uploaded photo either way. */
.eo-hero::before {
	content: "";
	position: absolute;
	inset: 0;
	background: linear-gradient(180deg, rgba(15,23,42,.25) 0%, rgba(15,23,42,.45) 100%);
}
.eo-hero .eo-container { position: relative; z-index: 1; }

/* Matches the sitewide content container (--eo-max-width: 1180px) exactly
   — a previous pass deliberately widened this to 1360px, which made the
   hero card overhang the sections below it instead of lining up with
   them; the search card's own max-width just needs to be >= the
   container's so it fills it, not a second, larger cap. */
.eo-hero-search-card {
	background: #fff;
	border-radius: 22px;
	box-shadow: 0 20px 45px rgba(15,23,42,.28);
	padding: 1.75rem 2.25rem;
	max-width: 100%;
	width: 100%;
	margin: 0 auto;
}
.eo-hero-search-card h1 {
	font-size: 1.35rem;
	margin-bottom: 1.1rem;
}

.eo-hero-search {
	display: flex;
	flex-wrap: wrap;
	gap: .6rem;
}
/* Keyword gets the lion's share of the row — the two selects only need
   enough room for their own (now much shorter, "English Level"/"Country")
   default text, freeing up width for the search placeholder instead. */
.eo-hero-field { flex: 1 1 150px; min-width: 130px; }
.eo-hero-field-keyword { flex: 2.4 1 260px; }
.eo-hero-field input,
.eo-hero-field select {
	width: 100%;
	padding: .75rem .9rem;
	border: 1px solid var(--eo-border);
	border-radius: 14px;
	background-color: #fff;
	color: var(--eo-ink);
}
.eo-hero-field select { padding-right: 2.3rem; }
.eo-hero-field-keyword input::placeholder { font-size: .85rem; }
.eo-hero-submit {
	flex: 0 0 auto;
	background: var(--eo-primary);
	color: #fff;
	border: none;
	border-radius: 14px;
	padding: .75rem 1.7rem;
	font-weight: 700;
	cursor: pointer;
	white-space: nowrap;
}
.eo-hero-submit:hover { background: var(--eo-primary-dark); }

.eo-hero-popular {
	margin-top: 1.15rem;
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: .5rem;
}
.eo-hero-popular-label {
	font-size: .85rem;
	color: var(--eo-muted);
	font-weight: 600;
	margin-right: .15rem;
}
.eo-pill {
	display: inline-block;
	background: color-mix(in srgb, var(--eo-primary) 10%, #fff);
	color: var(--eo-primary);
	border-radius: 999px;
	padding: .35rem .9rem;
	font-size: .82rem;
	font-weight: 600;
}
.eo-pill:hover { background: color-mix(in srgb, var(--eo-primary) 18%, #fff); text-decoration: none; }

@media (max-width: 700px) {
	.eo-hero { padding: 2rem 0 3.5rem; min-height: 0; }
	.eo-hero-search-card { padding: 1.25rem 1.25rem 1.1rem; margin-top: .5rem; }
	.eo-hero-field { flex: 1 1 100%; }
	.eo-hero-submit { width: 100%; }
	/* Only the keyword input (+ submit) shows on mobile — the English
	   level/country selects are still real, working filters on the full
	   archive page, just not worth the vertical space in a small hero
	   card on a small screen. */
	.eo-hero-field:not(.eo-hero-field-keyword) { display: none; }
}

/* -----------------------------------------------------------------------
   Sections
----------------------------------------------------------------------- */
.eo-section { padding: 2.75rem 0; }
.eo-section:nth-of-type(even) { background: var(--eo-surface); }

.eo-section-head {
	display: flex;
	align-items: baseline;
	justify-content: space-between;
	gap: 1rem;
	margin-bottom: 1.25rem;
}
.eo-section-head h2 { font-size: 1.4rem; }
.eo-section-head .eo-see-all { font-size: .9rem; font-weight: 600; white-space: nowrap; }

/* -----------------------------------------------------------------------
   Opportunity cards
----------------------------------------------------------------------- */
/* 3 per row by design request, not auto-fill's "however many fit" —
   collapses to 2 then 1 at the breakpoints below rather than trying to
   keep 3 cramped columns on a narrow screen. */
.eo-card-grid {
	display: grid;
	grid-template-columns: repeat(3, 1fr);
	gap: 1.25rem;
}
@media (max-width: 900px) {
	.eo-card-grid { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 600px) {
	.eo-card-grid { grid-template-columns: 1fr; }
}

/* The whole card is the link (readme.md §41 UI review: "cards should be
   clickable, not the title") — .eo-card is an <a>, not an <article>, so
   it needs its own text-decoration/color reset; nothing inside it is a
   nested link any more. */
.eo-card {
	background: var(--eo-surface);
	border: 1px solid var(--eo-border);
	border-radius: 14px;
	padding: 1.2rem;
	display: flex;
	flex-direction: column;
	gap: .4rem;
	box-shadow: 0 1px 2px rgba(15,23,42,.05);
	transition: box-shadow .15s ease, transform .15s ease;
	color: inherit;
	text-decoration: none;
}
.eo-card:hover { box-shadow: 0 12px 26px rgba(15,23,42,.1); transform: translateY(-2px); text-decoration: none; }
.eo-section:nth-of-type(even) .eo-card { background: var(--eo-bg); }

.eo-card-eyebrow {
	font-size: .74rem;
	text-transform: uppercase;
	letter-spacing: .04em;
	color: var(--eo-muted);
	font-weight: 600;
}
.eo-card-eyebrow .eo-featured-tag { color: var(--eo-accent); }

.eo-card h3 { font-size: 1.02rem; margin: 0; color: var(--eo-ink); }
.eo-card:hover h3 { color: var(--eo-primary); }

.eo-card-header { display: flex; align-items: flex-start; gap: .6rem; }
.eo-card-header-text { min-width: 0; } /* lets the title/org text wrap instead of pushing the logo out */

.eo-card-logo {
	width: 40px;
	height: 40px;
	border-radius: 8px;
	object-fit: contain;
	background: var(--eo-bg);
	border: 1px solid var(--eo-border);
	flex-shrink: 0;
}
.eo-card-logo-placeholder {
	display: flex;
	align-items: center;
	justify-content: center;
	font-weight: 700;
	font-size: 1.1rem;
	color: var(--eo-primary);
	background: color-mix(in srgb, var(--eo-primary) 12%, var(--eo-surface));
	text-transform: uppercase;
}

.eo-card-org { font-size: .87rem; color: var(--eo-muted); }
.eo-card-location {
	font-size: .85rem;
	color: var(--eo-primary);
	display: flex;
	align-items: center;
	gap: .3rem;
	margin-top: .1rem;
}
.eo-card-salary { font-size: .87rem; font-weight: 600; color: var(--eo-ink); }

.eo-card-meta {
	font-size: .78rem;
	color: var(--eo-muted);
	margin-top: auto;
	padding-top: .5rem;
	display: flex;
	flex-wrap: wrap;
	gap: .4rem;
}
.eo-card-meta span {
	background: var(--eo-bg);
	border-radius: 999px;
	padding: .2rem .65rem;
}
.eo-section:nth-of-type(even) .eo-card-meta span { background: var(--eo-surface); }

/* -----------------------------------------------------------------------
   List-row card variant — same .eo-card markup/data, just reflowed
   horizontally (readme.md §41 UI review: "Latest Jobs... full width row
   ...like a standard job search portal"). Reused for both the homepage
   Latest Jobs section and the archive split-view's left-hand list —
   deliberately styled with CSS `order` on the *existing* card markup
   rather than a second, parallel card template, so both places always
   render identical real data with zero duplicated PHP.
----------------------------------------------------------------------- */
.eo-card-list { display: flex; flex-direction: column; gap: .75rem; }
/* Admin-configurable (Homepage Settings — "Latest Jobs layout") — same
   .eo-card--row cards, just laid out 2-per-line instead of full-width. */
.eo-card-list--2col { display: grid; grid-template-columns: repeat(2, 1fr); gap: .75rem 1.25rem; }
@media (max-width: 700px) {
	.eo-card-list--2col { grid-template-columns: 1fr; }
}
.eo-card--row {
	flex-direction: row;
	align-items: center;
	flex-wrap: wrap;
	gap: .4rem 1.5rem;
	padding: 1rem 1.25rem;
}
.eo-card--row:hover { transform: none; } /* the translateY lift reads oddly on a full-width row; the shadow alone still signals hover */
.eo-card--row .eo-card-header { order: 1; flex: 1 1 280px; min-width: 0; }
.eo-card--row .eo-card-salary,
.eo-card--row .eo-card-meta { order: 2; flex-shrink: 0; }
.eo-card--row .eo-card-meta { flex-direction: column; align-items: flex-end; margin-top: 0; padding-top: 0; gap: .3rem; }
.eo-card--row .eo-card-eyebrow { order: 3; flex-basis: 100%; }

@media (max-width: 700px) {
	/* Kept flex-direction:row (with wrap) rather than switching to
	   column — column would reinterpret every child's desktop flex-basis
	   (set to control *width* above) as a *height* instead once the main
	   axis flips, which is exactly what made the "Latest Jobs" cards
	   overlap and stretch on mobile (🔴 real bug found live — same shape
	   already found and fixed for .eo-split-list/.eo-split-detail).
	   header and salary each force their own full-width line
	   (flex-basis:100%); the eyebrow tag and the meta dates share the
	   trailing line and right-align together as a group, rather than the
	   eyebrow spanning its own full-width row as before. */
	.eo-card--row { align-items: flex-start; justify-content: flex-end; }
	.eo-card--row .eo-card-header { order: 1; flex: 1 1 100%; }
	.eo-card--row .eo-card-salary { order: 2; flex: 1 1 100%; }
	.eo-card--row .eo-card-eyebrow,
	.eo-card--row .eo-card-meta {
		order: 3;
		flex: 0 1 auto;
	}
	.eo-card--row .eo-card-meta { flex-direction: row; align-items: center; flex-wrap: wrap; margin-top: 0; padding-top: 0; }
}

.eo-verified-badge {
	display: inline-flex;
	align-items: center;
	gap: .2rem;
	color: var(--eo-success);
	font-size: .78rem;
	font-weight: 600;
}

/* -----------------------------------------------------------------------
   Featured Opportunities carousel (front-page.php, "featured_opportunities"
   section only — every other opportunities section keeps the plain grid)
----------------------------------------------------------------------- */
/* Horizontal padding reserves a real gutter for the arrows outside the
   card row itself (not overlapping card content — a direct fix after
   the cards-as-links change made overlapping arrows sit visually
   "inside" the first/last card). */
.eo-carousel-wrap { position: relative; padding: 0 48px; }

.eo-card-carousel {
	display: flex;
	gap: 1.25rem;
	overflow-x: auto;
	scroll-snap-type: x mandatory;
	padding: .25rem .25rem .5rem;
	scrollbar-width: none; /* Firefox */
	-ms-overflow-style: none; /* old Edge/IE */
}
.eo-card-carousel::-webkit-scrollbar { display: none; height: 0; } /* Chrome/Safari — scrolling itself (touch/trackpad/arrow buttons) still works */

.eo-card-carousel .eo-card {
	flex: 0 0 calc((100% - 2.5rem) / 3);
	min-width: 260px;
	scroll-snap-align: start;
}
@media (max-width: 900px) {
	.eo-card-carousel .eo-card { flex-basis: calc((100% - 1.25rem) / 2); }
}
@media (max-width: 600px) {
	.eo-card-carousel .eo-card { flex-basis: 85%; }
}

.eo-carousel-btn {
	position: absolute;
	top: 50%;
	transform: translateY(-50%);
	z-index: 5;
	width: 40px;
	height: 40px;
	border-radius: 999px;
	border: 1px solid var(--eo-border);
	background: #fff;
	color: var(--eo-ink);
	display: flex;
	align-items: center;
	justify-content: center;
	cursor: pointer;
	box-shadow: 0 6px 16px rgba(15,23,42,.12);
}
.eo-carousel-btn:hover { background: var(--eo-bg); }
.eo-carousel-prev { left: 0; }
.eo-carousel-next { right: 0; }
@media (max-width: 700px) {
	.eo-carousel-btn { display: none; }
	.eo-carousel-wrap { padding: 0; }
}

/* -----------------------------------------------------------------------
   Employer cards
----------------------------------------------------------------------- */
.eo-employer-card {
	background: var(--eo-surface);
	border: 1px solid var(--eo-border);
	border-radius: var(--eo-radius);
	padding: 1.1rem;
	display: flex;
	flex-direction: column;
	gap: .35rem;
}
.eo-section:nth-of-type(even) .eo-employer-card { background: var(--eo-bg); }
.eo-employer-card h3 { font-size: 1rem; }
.eo-employer-card p { font-size: .87rem; color: var(--eo-muted); margin: 0; }

/* -----------------------------------------------------------------------
   Article cards
----------------------------------------------------------------------- */
.eo-article-card { background: var(--eo-surface); border: 1px solid var(--eo-border); border-radius: var(--eo-radius); overflow: hidden; display: flex; flex-direction: column; }
.eo-section:nth-of-type(even) .eo-article-card { background: var(--eo-bg); }
.eo-article-card img { width: 100%; height: 150px; object-fit: cover; }
.eo-article-card-body { padding: 1rem; display: flex; flex-direction: column; gap: .4rem; flex: 1; }
.eo-article-card h3 { font-size: .98rem; }
.eo-article-card p { font-size: .87rem; color: var(--eo-muted); margin: 0; }

/* -----------------------------------------------------------------------
   Newsletter — was a flat solid-colour box with a bare, border-less email
   input; redesigned to match the hero's gradient treatment with a real
   icon badge and a single rounded "pill" input+button group instead.
----------------------------------------------------------------------- */
.eo-newsletter {
	background: linear-gradient(135deg, var(--eo-primary) 0%, var(--eo-primary-dark) 100%);
	color: #fff;
	border-radius: var(--eo-radius);
	padding: 3rem 2rem;
	text-align: center;
}
.eo-newsletter-icon {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 56px;
	height: 56px;
	border-radius: 50%;
	background: rgba(255,255,255,.16);
	margin-bottom: 1.1rem;
}
.eo-newsletter-icon svg { width: 26px; height: 26px; stroke: #fff; fill: none; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
.eo-newsletter h2 { color: #fff; margin-bottom: .4rem; }
.eo-newsletter p { color: rgba(255,255,255,.85); max-width: 480px; margin: 0 auto 1.6rem; }
.eo-newsletter-form {
	display: flex;
	gap: 0;
	justify-content: center;
	max-width: 460px;
	margin: 0 auto;
	background: #fff;
	border-radius: 999px;
	padding: .3rem;
	box-shadow: 0 14px 30px rgba(15,23,42,.25);
}
.eo-newsletter-form input[type=email] {
	flex: 1 1 auto;
	min-width: 0;
	border: none;
	background: transparent;
	padding: .7rem 1rem;
	color: var(--eo-ink);
	border-radius: 999px;
}
.eo-newsletter-form input[type=email]:focus { outline: 2px solid var(--eo-primary); outline-offset: -2px; }
.eo-newsletter-form button {
	flex-shrink: 0;
	background: var(--eo-accent);
	color: #fff;
	border: none;
	border-radius: 999px;
	padding: .7rem 1.5rem;
	font-weight: 700;
	cursor: pointer;
	transition: background .15s ease;
}
.eo-newsletter-form button:hover { background: var(--eo-primary-dark); }
.eo-newsletter-notice { margin-top: 1rem; font-size: .88rem; font-weight: 600; }
@media (max-width: 480px) {
	.eo-newsletter { padding: 2.25rem 1.25rem; }
	.eo-newsletter-form { flex-direction: column; background: none; box-shadow: none; padding: 0; gap: .6rem; }
	.eo-newsletter-form input[type=email] { background: #fff; box-shadow: 0 6px 16px rgba(15,23,42,.2); }
	.eo-newsletter-form button { width: 100%; }
}

/* -----------------------------------------------------------------------
   Employer/Candidate CTA banner (Homepage Settings — fully admin-editable,
   readme.md §41 UI review, between Featured Opportunities and Latest Jobs)
----------------------------------------------------------------------- */
.eo-cta-grid {
	display: grid;
	grid-template-columns: repeat(2, 1fr);
	gap: 1.25rem;
}
@media (max-width: 700px) {
	.eo-cta-grid { grid-template-columns: 1fr; }
}
.eo-cta-card {
	position: relative;
	border-radius: 16px;
	overflow: hidden;
	min-height: 220px;
	display: flex;
	align-items: flex-end;
	background: linear-gradient(135deg, var(--eo-primary) 0%, var(--eo-primary-dark) 100%);
	background-size: cover;
	background-position: center;
}
/* Tint present whether or not an image is set — keeps the card body's
   white text readable over a photo, and adds a touch of depth over the
   plain gradient fallback so it doesn't look flat next to the photo one. */
.eo-cta-card::before {
	content: "";
	position: absolute;
	inset: 0;
	background: linear-gradient(180deg, rgba(15,23,42,.15) 0%, rgba(15,23,42,.72) 100%);
}
.eo-cta-card-body { position: relative; z-index: 1; padding: 1.75rem; color: #fff; }
.eo-cta-card-body h3 { color: #fff; font-size: 1.3rem; margin-bottom: .4rem; }
.eo-cta-card-body p { color: rgba(255,255,255,.88); margin: 0 0 1rem; max-width: 420px; }
.eo-cta-card-body .eo-btn { background: #fff; color: var(--eo-primary-dark); }
.eo-cta-card-body .eo-btn:hover { background: rgba(255,255,255,.85); color: var(--eo-primary-dark); }

/* -----------------------------------------------------------------------
   Breadcrumbs (readme.md §37) — markup rendered by EO\SEO\Breadcrumbs::render()
----------------------------------------------------------------------- */
.eo-breadcrumbs { margin: 1.5rem 0 1.25rem; font-size: .85rem; color: var(--eo-muted, #666); }
.eo-breadcrumbs ol { display: flex; flex-wrap: wrap; align-items: center; gap: .35rem; list-style: none; margin: 0; padding: 0; }
.eo-breadcrumbs li { display: flex; align-items: center; gap: .35rem; }
.eo-breadcrumbs li:not(:last-child)::after { content: "/"; opacity: .5; }
.eo-breadcrumbs a { color: inherit; text-decoration: none; }
.eo-breadcrumbs a:hover { text-decoration: underline; }
.eo-breadcrumbs [aria-current="page"] { font-weight: 600; }

/* -----------------------------------------------------------------------
   Archive / search page
----------------------------------------------------------------------- */
.eo-archive-head { padding: 2rem 0 1rem; }
.eo-archive-filters {
	display: flex;
	flex-wrap: wrap;
	gap: .6rem;
	align-items: center;
	background: var(--eo-surface);
	border: 1px solid var(--eo-border);
	border-radius: var(--eo-radius);
	padding: 1rem;
	margin-bottom: 1.5rem;
}
.eo-archive-filters input[type=search] { flex: 1 1 200px; }
/* On desktop these two wrapper divs are invisible to layout — their
   fields flow directly into .eo-archive-filters' own flex row, identical
   to before this markup was split out. Only on mobile (below) do they
   become real containers: one always-visible row (keyword + filter
   toggle + submit) and one collapsible group behind that toggle
   (readme.md §41 UI review: "creative ways to reduce the form fields
   available in mobile... filters toggled by a filter icon"). */
.eo-archive-filters-primary,
.eo-archive-filters-extra { display: contents; }
.eo-archive-filters-toggle { display: none; }
/* Search stays right next to the keyword field in the DOM (so it's
   always visible on mobile, not stranded inside the collapsible group),
   but visually belongs at the end of the row on desktop, matching the
   original single-row layout this was split out of. */
.eo-archive-filters-primary .eo-btn { order: 10; }
/* Compact by request (readme.md §41 UI review: "too large... make the
   fields and their texts/placeholders smaller") — a scoped override
   rather than shrinking every input/select sitewide. */
.eo-archive-filters input,
.eo-archive-filters select {
	padding: .4rem .6rem;
	font-size: .85rem;
	border-radius: 8px;
}
.eo-archive-filters input::placeholder { font-size: .85rem; }
.eo-archive-filters select { padding-right: 1.8rem; background-size: 16px; }
.eo-archive-filters label { font-size: .85rem; }
.eo-archive-filters .eo-btn { padding: .45rem .9rem; font-size: .85rem; }
.eo-archive-results-count { color: var(--eo-muted); font-size: .9rem; margin-bottom: 1rem; }

@media (max-width: 700px) {
	.eo-archive-filters { flex-direction: column; align-items: stretch; padding: .75rem; }
	.eo-archive-filters-primary {
		display: flex;
		gap: .5rem;
		align-items: center;
	}
	.eo-archive-filters-primary input[type=search],
	#eo-archive-q {
		flex: 1 1 0 !important;
		min-width: 0 !important;
		width: auto !important;
	}
	/* 🔴 Real bug found live: with the "Filters" text label included, the
	   toggle button + Search button together didn't fit next to the
	   keyword input at real phone widths — Search ended up positioned
	   ~3px past the viewport's right edge (confirmed via a computed
	   getBoundingClientRect() probe), effectively invisible. Icon-only
	   here (real text label kept for screen readers via the button's own
	   aria-label) frees enough width for all three to fit on one line. */
	.eo-archive-filters-toggle {
		display: inline-flex;
		align-items: center;
		justify-content: center;
		flex-shrink: 0;
		width: 38px;
		height: 38px;
		padding: 0;
		border: 1px solid var(--eo-border);
		border-radius: 8px;
		background: #fff;
		color: var(--eo-body);
		cursor: pointer;
	}
	.eo-archive-filters-toggle-label { display: none; }
	.eo-archive-filters-toggle .eo-icon { width: 17px; height: 17px; }
	.eo-archive-filters-toggle[aria-expanded="true"] { border-color: var(--eo-primary); color: var(--eo-primary); }
	.eo-archive-filters-primary .eo-btn { flex-shrink: 0; padding: .5rem .8rem; }
	/* Real, collapsible container on mobile only — display:contents above
	   (desktop) is overridden back to a real box here so hiding/showing
	   it actually works. */
	.eo-archive-filters-extra {
		display: none;
		flex-direction: column;
		gap: .5rem;
		margin-top: .65rem;
		padding-top: .65rem;
		border-top: 1px solid var(--eo-border);
	}
	.eo-archive-filters-extra.is-open { display: flex; }
}

/* -----------------------------------------------------------------------
   Archive split view (archive-eo_opportunity.php + assets/js/archive-split.js)
   — readme.md §41 UI review: a scrollable list on the left, a detail
   panel on the right that loads via AJAX, each scrolling independently.
----------------------------------------------------------------------- */
.eo-split-view {
	display: flex;
	align-items: flex-start;
	gap: 1.5rem;
	margin-bottom: 2rem;
}
.eo-split-list {
	/* Admin-configurable (Dashboard\Settings\Controller's General tab,
	   "Archive list width (%)" — readme.md §41 UI review, e.g. 30 for a
	   30/70 split or 60 for 60/40) via the --eo-split-list-pct custom
	   property set inline on #eo-split-view (archive-eo_opportunity.php).
	   flex-shrink:0 — a *fixed* share of the row, not a starting point
	   flexbox is free to renegotiate; .eo-split-detail (flex:1 1 0) fills
	   whatever's left. Subtracting a bit less than half the row gap keeps
	   the two panes visually balanced around the configured ratio. */
	flex: 0 0 calc(var(--eo-split-list-pct, 40) * 1% - .75rem);
	max-width: none;
	/* 🔴 Real bug found live: without this, .eo-split-list's default flex
	   min-width (`auto`, i.e. its own content's intrinsic minimum) fought
	   .eo-split-detail's — once the detail panel's real content loaded
	   (in particular .eo-detail-facts' CSS grid, whose own minimum
	   content width is real and non-trivial), flexbox protected the
	   *detail* panel's larger minimum at the list's expense, crushing it
	   down to a sliver with text wrapping character-by-character. Both
	   panes need min-width:0 so the explicit flex-basis/max-width values
	   above actually govern the layout instead of an unpredictable
	   content-driven tug-of-war between the two. */
	min-width: 0;
	display: flex;
	flex-direction: column;
	gap: .6rem;
	overflow-y: auto;
	padding-right: .4rem;
	/* Real fallback height for the brief window before archive-split.js
	   sets a precise, viewport-aware value (see its own comment) — never
	   left unbounded, so the layout doesn't jump once JS runs. */
	max-height: 88vh;
	/* Scrolling stays fully functional (wheel/touch/keyboard) — only the
	   visible scrollbar track/thumb is hidden, on the two engines that
	   support doing that without JS. */
	scrollbar-width: none; /* Firefox */
	-ms-overflow-style: none; /* legacy Edge */
}
.eo-split-list::-webkit-scrollbar { display: none; /* Chrome/Safari/new Edge */ }
/* A scanning list benefits from tighter cards than the homepage's own
   showcase grid — .eo-card--row looked visibly compressed at this pane's
   narrower width (found live), so the list reverted to plain vertical
   .eo-card, just denser.

   Background is its own branding-configurable token (--eo-archive-list-bg,
   Branding settings — falls back to the ordinary card surface colour when
   unset) rather than sharing .eo-card's plain --eo-surface, so the list
   pane can be visually distinguished from the detail pane beside it.

   border-right is reserved (transparent) at the same width an active
   card uses below, so selecting a card doesn't shift its width/content by
   changing how much border it has. */
.eo-split-item {
	padding: .9rem 1rem;
	gap: .3rem;
	background: var(--eo-archive-list-bg, var(--eo-surface));
	border-right: 4px solid transparent;
}
.eo-split-item .eo-card-header { gap: .5rem; }
.eo-split-item .eo-card-logo { width: 34px; height: 34px; }
.eo-split-detail {
	/* 🔴 Real bug found live: `flex: 1 1 auto` — with no `width` set,
	   flex-basis:auto resolves from the item's own CONTENT size, not
	   "fill remaining space". Once real content loaded (long description
	   text), that content-derived basis dominated the shrink
	   calculation and the panel kept ~90% of the row's width regardless
	   of min-width:0, crushing .eo-split-list to a sliver next to it.
	   flex-basis:0 is the standard fix for "grow to fill whatever's left,
	   full stop, ignore my own content size" — confirmed via a live
	   computed-style probe (list width was 83px, detail 1033px, on a
	   1140px-wide row) before this change. */
	flex: 1 1 0;
	min-width: 0;
	overflow-y: auto;
	max-height: 88vh;
	background: var(--eo-surface);
	border: 1px solid var(--eo-border);
	border-radius: 14px;
	padding: 1.85rem 2rem;
}
.eo-split-item { cursor: pointer; }
/* A thicker right-edge accent instead of a full highlight border/glow —
   the other three sides keep their ordinary .eo-card border, only the
   reserved border-right (transparent when inactive, set above) picks up
   the primary colour, plus a faint tint so the active row still reads
   clearly at a glance without outlining the whole card. */
.eo-split-item.is-active {
	border-right-color: var(--eo-primary);
	background: color-mix(in srgb, var(--eo-primary) 6%, var(--eo-archive-list-bg, var(--eo-surface)));
}
.eo-split-sentinel { height: 1px; }
.eo-split-status { text-align: center; color: var(--eo-muted); font-size: .85rem; padding: .5rem 0; }
.eo-split-detail-placeholder { color: var(--eo-muted); text-align: center; padding: 3.5rem 1rem; }
/* Continuous scroll replaces pagination on this page (readme.md §41 UI
   review) — hidden by default via CSS rather than only via JS after the
   fact, so it never even flashes visible before archive-split.js runs.
   #eo-pagination is this page's own ID, not the shared .eo-pagination
   class other pages (employers directory, category archive) still use
   real pagination on — this rule can't affect them. The real markup and
   links stay in the DOM regardless (search-engine-crawlable, and
   archive-split.js un-hides it as a working fallback on the rare browser
   without IntersectionObserver support). */
#eo-pagination { display: none; }

@media (max-width: 900px) {
	.eo-split-view { flex-direction: column; }
	/* 🔴 Real bug found live: this reset max-width/width but never the
	   `flex` shorthand itself, so .eo-split-list kept its desktop
	   `flex: 0 0 calc(var(--eo-split-list-pct) * 1% - .75rem)` — a
	   flex-basis meant to control *width* in a row layout. Once
	   .eo-split-view flips to `flex-direction: column` on mobile, the
	   main axis is vertical, so that same flex-basis got reinterpreted
	   as a *height* instead: a percentage against an undefined container
	   height resolves unpredictably, which is what produced "the list
	   isn't contained in one container, it overlaps beyond the footer."
	   `flex: 1 1 auto` makes it a normal auto-height block in column
	   mode, sized by its own content like any other stacked element. */
	.eo-split-list, .eo-split-detail { flex: 1 1 auto; max-height: none; overflow-y: visible; max-width: none; width: 100%; }
	/* archive-split.js only intercepts row clicks for the AJAX detail
	   panel above this breakpoint — below it, a full single-listing page
	   is the right pattern on a small screen, so the panel (and its
	   placeholder text) never shows here at all. */
	.eo-split-detail { display: none; }
}

/* -----------------------------------------------------------------------
   Detail panel content (assets/js/archive-split.js's own JS template —
   the list side reuses the existing .eo-card markup/CSS, but the panel's
   content has no PHP-rendered equivalent to inherit classes from)
----------------------------------------------------------------------- */
.eo-detail-loading, .eo-detail-error { text-align: center; color: var(--eo-muted); padding: 3rem 1rem; }
.eo-detail-eyebrow {
	font-size: .74rem;
	text-transform: uppercase;
	letter-spacing: .04em;
	color: var(--eo-muted);
	font-weight: 600;
	margin-bottom: .5rem;
}
.eo-detail-header { display: flex; gap: 1rem; align-items: flex-start; margin-bottom: 1rem; }
.eo-detail-logo { width: 56px; height: 56px; border-radius: 10px; object-fit: contain; background: var(--eo-bg); border: 1px solid var(--eo-border); flex-shrink: 0; }
.eo-detail-logo-placeholder {
	display: flex; align-items: center; justify-content: center;
	font-weight: 700; font-size: 1.4rem; color: var(--eo-primary);
	background: color-mix(in srgb, var(--eo-primary) 12%, var(--eo-surface));
	text-transform: uppercase;
}
.eo-detail-title { font-size: 1.4rem; margin: 0 0 .3rem; }
.eo-detail-org { color: var(--eo-muted); font-size: .95rem; display: flex; align-items: center; gap: .3rem; flex-wrap: wrap; }
.eo-detail-location { display: flex; align-items: center; gap: .3rem; color: var(--eo-primary); font-size: .9rem; margin-top: .3rem; }
.eo-detail-actions { display: flex; align-items: center; gap: .75rem; margin: 1.25rem 0; flex-wrap: wrap; }
.eo-detail-icon-btn {
	display: inline-flex; align-items: center; justify-content: center;
	width: 40px; height: 40px; border-radius: 999px;
	border: 1px solid var(--eo-border); background: #fff; color: var(--eo-body); cursor: pointer;
}
.eo-detail-icon-btn:hover { background: var(--eo-bg); }
.eo-detail-facts {
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
	gap: 1rem 1.5rem;
	padding: 1.25rem 0;
	margin-bottom: 1.25rem;
	border-top: 1px solid var(--eo-border);
	border-bottom: 1px solid var(--eo-border);
}
.eo-detail-fact-label { display: block; font-size: .78rem; color: var(--eo-muted); margin-bottom: .15rem; }
.eo-detail-fact-value { font-weight: 600; color: var(--eo-ink); }
.eo-detail-description { line-height: 1.7; overflow-wrap: break-word; }
.eo-detail-description a { overflow-wrap: break-word; }
.eo-detail-description p { margin: 0 0 1em; }
.eo-detail-view-full { display: block; margin-top: 1.5rem; font-size: .88rem; }

/* Shown under an imported listing's description when it's sourced from
   an API/feed that only ever supplies a snippet (Adzuna's search API is
   the clearest example — its own docs say so) — makes clear the text
   above isn't the whole posting, rather than letting a paragraph that
   just stops mid-sentence read as a content bug. */
.eo-detail-excerpt-note {
	margin-top: 1rem;
	padding: .7rem 1rem;
	background: var(--eo-bg);
	border: 1px solid var(--eo-border);
	border-radius: 10px;
	font-size: .85rem;
	color: var(--eo-muted);
}
.eo-detail-excerpt-note a { margin-left: .3rem; font-weight: 600; }

/* -----------------------------------------------------------------------
   Single opportunity page (single-eo_opportunity.php) — deliberately
   reuses the .eo-detail-* classes above so it looks like the same
   surface as the archive's AJAX detail panel, just at full-page width
   instead of a side panel (readme.md §41 UI review: "consistent").
----------------------------------------------------------------------- */
/* Widened from a single centered column (readme.md §41 UI review — "expand
   the page... sidebar with related postings and a job filter" on the
   left, article on the right). */
.eo-opportunity-page { max-width: var(--eo-max-width); margin: 2rem auto; padding: 0 1.25rem; }
.eo-opportunity-layout { display: flex; align-items: flex-start; gap: 2rem; }
.eo-opportunity-sidebar { flex: 0 0 280px; display: flex; flex-direction: column; gap: 1.5rem; }
.eo-opportunity-sidebar-block {
	background: var(--eo-surface);
	border: 1px solid var(--eo-border);
	border-radius: 14px;
	padding: 1.25rem;
}
.eo-opportunity-sidebar-block h2 { font-size: 1rem; margin-bottom: .85rem; }
.eo-opportunity-sidebar-block .eo-card-list { gap: .6rem; }
/* Same branding-configurable background as the archive split view's list
   pane (--eo-archive-list-bg) — these related-postings cards are the same
   "compact job listing" element wherever it appears, so it reads as one
   consistent list style, not two different card backgrounds by accident. */
.eo-opportunity-sidebar-block .eo-card { padding: .75rem .85rem; background: var(--eo-archive-list-bg, var(--eo-surface)); }
.eo-opportunity-mini-filter { display: flex; flex-direction: column; gap: .6rem; }
.eo-opportunity-mini-filter .eo-btn { width: 100%; }

/* Real back-link, styled as a small pill and pinned to the top-right of
   the panel (readme.md §41 UI review) rather than a plain text line
   floating above it. */
.eo-opportunity-panel {
	position: relative;
	background: var(--eo-surface);
	border: 1px solid var(--eo-border);
	border-radius: 14px;
	padding: 2rem 2.25rem;
}
.eo-opportunity-back {
	position: absolute;
	top: 1.5rem;
	right: 1.75rem;
	display: inline-flex;
	align-items: center;
	gap: .3rem;
	font-size: .82rem;
	font-weight: 600;
	color: var(--eo-body);
	background: var(--eo-bg);
	border: 1px solid var(--eo-border);
	border-radius: 999px;
	padding: .4rem .9rem;
}
.eo-opportunity-back:hover { background: var(--eo-border); text-decoration: none; }

@media (max-width: 900px) {
	.eo-opportunity-layout { flex-direction: column-reverse; }
	.eo-opportunity-sidebar { flex: 1 1 auto; width: 100%; }
	.eo-opportunity-back { position: static; display: inline-flex; margin-bottom: 1rem; }
}
.eo-opportunity-panel .eo-detail-title { font-size: 1.7rem; }
.eo-opportunity-panel h2 { font-size: 1.2rem; margin-top: 1.75rem; }
.eo-opportunity-missing { text-align: center; padding: 4rem 1rem; }
.eo-opportunity-missing .eo-btn { margin-top: 1rem; }
.eo-opportunity-skills { margin-bottom: 1.25rem; }
.eo-skill-tag {
	display: inline-block;
	background: var(--eo-bg);
	border: 1px solid var(--eo-border);
	border-radius: 6px;
	padding: .2rem .6rem;
	margin: 0 .3rem .3rem 0;
	font-size: .82rem;
	color: var(--eo-body);
}
.eo-opportunity-report { margin-top: 1.75rem; font-size: .9rem; }
.eo-opportunity-report summary { cursor: pointer; font-weight: 600; }
.eo-opportunity-report form {
	display: flex;
	flex-direction: column;
	gap: .6rem;
	max-width: 420px;
	margin-top: .75rem;
}

.eo-pagination {
	display: flex;
	flex-wrap: wrap;
	gap: .4rem;
	margin-top: 2rem;
}
.eo-pagination a, .eo-pagination span {
	display: inline-block;
	min-width: 2.2rem;
	text-align: center;
	padding: .4rem .55rem;
	border: 1px solid var(--eo-border);
	border-radius: 6px;
	font-size: .88rem;
	color: var(--eo-body);
}
.eo-pagination a:hover { border-color: var(--eo-primary); color: var(--eo-primary); text-decoration: none; }
.eo-pagination .current { background: var(--eo-primary); color: #fff; border-color: var(--eo-primary); font-weight: 600; }

/* -----------------------------------------------------------------------
   Footer
----------------------------------------------------------------------- */
.eo-site-footer {
	background: var(--eo-ink);
	color: #cbd5e1;
	padding: 2.5rem 0 1.5rem;
	margin-top: 3rem;
	font-size: .88rem;
}
.eo-footer-cols {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
	gap: 1.5rem;
	margin-bottom: 2rem;
}
.eo-footer-cols h4 { color: #fff; font-size: .82rem; text-transform: uppercase; letter-spacing: .04em; margin-bottom: .75rem; }
.eo-footer-cols ul { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: .4rem; }
.eo-footer-cols a { color: #cbd5e1; }
.eo-footer-cols a:hover { color: #fff; }
.eo-footer-bottom {
	border-top: 1px solid rgba(255,255,255,.1);
	padding-top: 1.25rem;
	color: #94a3b8;
	display: flex;
	justify-content: space-between;
	align-items: center;
	flex-wrap: wrap;
	gap: .5rem;
}
.eo-footer-powered-by a { color: #94a3b8; }
.eo-footer-powered-by a:hover { color: #fff; }

/* -----------------------------------------------------------------------
   Generic WP page/post content (index.php's fallback template) — a
   readable line length for long-form pages (legal pages, blog posts)
   rather than the raw full site-width column.
----------------------------------------------------------------------- */
.eo-container > article { max-width: 760px; margin-left: auto; margin-right: auto; }
.eo-container > article h2 { margin-top: 2rem; }
.eo-container > article h3 { margin-top: 1.5rem; }
.eo-container > article ul, .eo-container > article ol { padding-left: 1.4rem; }
.eo-container > article li { margin-bottom: .4rem; }
.eo-container > article p { margin-bottom: 1rem; line-height: 1.7; }

/* -----------------------------------------------------------------------
   Auth pages — login.php, candidate-register.php, employer-register.php.
   One shared visual language across all three (same card, same field/
   button/divider shapes) so moving between "log in" and either "sign up"
   never feels like a different, less-finished part of the site — this
   was previously the one flow still rendering the plugin's bare-bones
   fallback markup (inline styles, no header/footer chrome parity) even
   with the rest of the theme fully built out.
----------------------------------------------------------------------- */
.eo-auth-page {
	background: linear-gradient(180deg, var(--eo-bg) 0%, #eef2ff 100%);
	padding: 3rem 0 4rem;
	min-height: 60vh;
}
.eo-auth-wrap {
	max-width: 440px;
	margin: 0 auto;
	padding: 0 1.25rem;
}
.eo-auth-wrap--wide { max-width: 500px; }

.eo-auth-card {
	background: var(--eo-surface);
	border: 1px solid var(--eo-border);
	border-radius: 16px;
	padding: 2.25rem 2rem;
	box-shadow: 0 20px 45px rgba(15,23,42,.09);
}
@media (max-width: 480px) {
	.eo-auth-card { padding: 1.75rem 1.25rem; border-radius: 12px; }
}

.eo-auth-head { text-align: center; margin-bottom: 1.75rem; }
.eo-auth-icon {
	width: 52px;
	height: 52px;
	border-radius: 999px;
	background: color-mix(in srgb, var(--eo-primary) 12%, #fff);
	color: var(--eo-primary);
	display: flex;
	align-items: center;
	justify-content: center;
	margin: 0 auto .9rem;
}
.eo-auth-icon svg { width: 26px; height: 26px; }
.eo-auth-head h1 { font-size: 1.4rem; margin-bottom: .3rem; }
.eo-auth-head p { color: var(--eo-muted); font-size: .92rem; margin: 0; }

.eo-auth-form { display: flex; flex-direction: column; gap: 1.05rem; }
.eo-auth-field { display: flex; flex-direction: column; gap: .35rem; }
.eo-auth-field label { font-size: .86rem; font-weight: 600; color: var(--eo-ink); }
.eo-auth-field input { width: 100%; padding: .7rem .85rem; }
.eo-auth-field-row { display: grid; grid-template-columns: 1fr 1fr; gap: .85rem; }
@media (max-width: 480px) { .eo-auth-field-row { grid-template-columns: 1fr; } }

.eo-auth-row-between { display: flex; align-items: center; justify-content: space-between; font-size: .86rem; }
.eo-auth-check { display: flex; align-items: flex-start; gap: .5rem; font-size: .86rem; color: var(--eo-body); line-height: 1.4; }
.eo-auth-check input { margin-top: .2rem; flex-shrink: 0; }

.eo-auth-submit { width: 100%; text-align: center; padding: .8rem 1rem; font-size: .98rem; }

.eo-auth-divider {
	display: flex;
	align-items: center;
	gap: .75rem;
	margin: 1.4rem 0;
	color: var(--eo-muted);
	font-size: .82rem;
	text-transform: uppercase;
	letter-spacing: .04em;
}
.eo-auth-divider::before, .eo-auth-divider::after { content: ""; flex: 1; height: 1px; background: var(--eo-border); }

.eo-auth-google {
	display: flex;
	align-items: center;
	justify-content: center;
	gap: .6rem;
	width: 100%;
	padding: .68rem 1rem;
	border: 1px solid var(--eo-border);
	border-radius: var(--eo-radius);
	background: #fff;
	color: var(--eo-ink);
	font-size: .92rem;
	font-weight: 600;
	cursor: pointer;
	transition: border-color .15s ease, box-shadow .15s ease;
}
.eo-auth-google:hover { border-color: color-mix(in srgb, var(--eo-primary) 40%, var(--eo-border)); box-shadow: 0 4px 12px rgba(15,23,42,.08); text-decoration: none; color: var(--eo-ink); }
.eo-auth-google svg { flex-shrink: 0; }

.eo-auth-foot { text-align: center; margin-top: 1.6rem; font-size: .88rem; color: var(--eo-muted); }
.eo-auth-foot a { font-weight: 600; }
.eo-auth-switch { text-align: center; margin-top: .6rem; font-size: .84rem; color: var(--eo-muted); }

.eo-auth-notice {
	border-radius: 10px;
	padding: .75rem 1rem;
	font-size: .88rem;
	margin-bottom: 1.25rem;
}
.eo-auth-notice-error { background: #fef2f2; color: #b91c1c; border: 1px solid #fecaca; }
.eo-auth-notice-success { background: #f0fdf4; color: #15803d; border: 1px solid #bbf7d0; }
