/**
 * Colour schema: deep navy #14315B.
 *
 * theme.css is bundled through Vite and dist/ is committed, so the tokens are
 * overridden here instead of edited there. Loaded after the bundle, and the
 * same selectors are used so every theme state stays in step: the explicit
 * light and dark choices, and the default state that stamps neither.
 *
 * #14315B is 12.96:1 on white and 1.45:1 on a dark ground, so it is the light
 * theme's primary and the brand surface everywhere -- but dark mode takes a
 * lighter tint of the same hue (215 degrees) for anything that has to be read.
 */

[data-theme='light'] {
	--em-primary: #14315B;
	--em-primary-dark: #0F2545;
	--em-on-primary: #FFFFFF;
	--em-brand: #14315B;
	--em-accent: #B45309;
	--em-success: #0F7A52;
	--em-warning: #B45309;
	--em-bg-dark: #F7F8FA;
	--em-bg-2: #E9EDF3;
	--em-bg-card: #FFFFFF;
	--em-border: #A8B4C4;
	--em-text: #0C1220;
	--em-muted: #5A6676;
	--em-header-bg: rgba(247, 248, 250, 0.85);
	--em-glass-border: rgba(12, 18, 32, 0.08);
	--em-code-bg: #0A101A;
	--em-code-text: #E8EDF5;
}

[data-theme='dark'],
body:not([data-theme]) {
	--em-primary: #79A4E2;
	--em-primary-dark: #6093DC;
	--em-on-primary: #0A101A;
	--em-brand: #14315B;
	--em-accent: #F5A524;
	--em-success: #6FC8A8;
	--em-warning: #F5A524;
	--em-bg-dark: #0A101A;
	--em-bg-2: #0F1827;
	--em-bg-card: #14213A;
	--em-border: #2C3F5E;
	--em-text: #E8EDF5;
	--em-muted: #98A6BC;
	--em-header-bg: rgba(10, 16, 26, 0.75);
	--em-glass-border: rgba(152, 166, 188, 0.14);
	--em-code-bg: #070C14;
	--em-code-text: #E8EDF5;
}

/* Hero glows and the newsletter halo were tuned to an older accent. */
.em-hero-glow-1 {
	background: radial-gradient(circle, rgba(121, 164, 226, 0.16) 0%, transparent 70%);
}

.em-hero-glow-2 {
	background: radial-gradient(circle, rgba(245, 165, 36, 0.10) 0%, transparent 70%);
}

.em-newsletter {
	box-shadow: 0 0 40px rgba(20, 49, 91, 0.25);
}

.em-badge[style*="rgba(14,165,233"],
.em-badge[style*="rgba(14, 165, 233"] {
	background: rgba(121, 164, 226, 0.14) !important;
}

/* ---------- contrast fixes on top of the theme's components ---------- */

/* A fill cannot carry white text in both themes: white on the dark navy reads
   at 12.96:1, white on the light tint at 1.9:1. Each theme names the colour
   that actually works on its own fill. */
.em-btn-primary {
	color: var(--em-on-primary);
	background: var(--em-primary);
	box-shadow: 0 10px 30px rgba(20, 49, 91, 0.30);
}

.em-btn-primary:hover,
.em-btn-primary:focus-visible {
	background: var(--em-primary-dark);
	color: var(--em-on-primary);
}

/* The active pill was white on a gradient that ended in an indigo left over
   from an older palette. White reads at 1.9:1 on the light tint this theme
   uses in dark mode, so the label was invisible. It now takes the same fill
   and label pair as the primary button: 7.46:1 dark, 12.96:1 light. */
.em-pill.is-active {
	color: var(--em-on-primary);
	background: var(--em-primary);
	border-color: transparent;
}

.em-pill:hover,
.em-pill:focus-visible {
	color: var(--em-text);
	border-color: var(--em-primary);
}

.em-pill.is-active:hover,
.em-pill.is-active:focus-visible {
	color: var(--em-on-primary);
	background: var(--em-primary-dark);
}

:where(a, button, input, select, textarea, [tabindex]):focus-visible {
	outline: 2px solid var(--em-primary);
	outline-offset: 2px;
}

/* ---------- links ---------- */

/* WordPress's global styles underline every link. Removed here. */
a,
a:where(:not(.wp-element-button)) {
	text-decoration: none;
}

/* Inside prose that leaves a problem: the link colour sits only 1.44:1 from
   the body text in the light theme and 2.17:1 in the dark one, well under the
   3:1 that lets colour carry the distinction alone. So content links keep a
   weight difference, and the underline returns on hover and keyboard focus --
   findable while reading, quiet while not. */
.em-post-content a:not(.em-btn):not(.em-cs-anchor),
.em-cs-content a:not(.em-btn),
.em-cs-callout a {
	font-weight: 600;
	color: var(--em-primary);
	text-underline-offset: 3px;
	text-decoration-thickness: 1px;
}

.em-post-content a:not(.em-btn):not(.em-cs-anchor):hover,
.em-post-content a:not(.em-btn):not(.em-cs-anchor):focus-visible,
.em-cs-content a:not(.em-btn):hover,
.em-cs-content a:not(.em-btn):focus-visible,
.em-cs-callout a:hover,
.em-cs-callout a:focus-visible {
	text-decoration: underline;
}

/* Code inside a link should not inherit the link weight. */
.em-post-content a code,
.em-cs-content a code {
	font-weight: 400;
}

/* ---------- no gradients ---------- */

/* custom.css paints nine things with two-colour gradients, several still
   ending in an indigo from an older palette. They are flattened here rather
   than edited there: that file is bundled through Vite with dist/ committed.
 *
 * Anything clipped to text also needs text-fill-color reset, or removing the
 * gradient leaves the text transparent -- invisible rather than plain. */
.em-logo-text-gradient,
.em-gradient-blue,
.em-stats-item-num,
.em-404-title {
	background: none;
	-webkit-background-clip: border-box;
	background-clip: border-box;
	-webkit-text-fill-color: currentColor;
}

.em-logo-text-gradient {
	color: var(--em-text);
}

.em-gradient-blue,
.em-404-title {
	color: var(--em-primary);
}

.em-stats-item-num {
	color: var(--em-text);
}

.em-gradient-orange {
	background: none;
	-webkit-background-clip: border-box;
	background-clip: border-box;
	-webkit-text-fill-color: currentColor;
	color: var(--em-accent);
}

#em-reading-progress,
.em-progress-bar,
.em-page-link.current,
.em-btn-accent {
	background: var(--em-primary);
}

.em-progress-bar.em-accent-fill,
.em-btn-accent {
	background: var(--em-accent);
}

.em-btn-accent {
	color: var(--em-on-primary);
}

.em-section-label::before {
	background: var(--em-primary);
}

/* The hero wash and the section heroes were dark-to-dark fades; flat surfaces
   read the same and stay honest to the palette. */
.em-hero {
	background: var(--em-bg-dark);
}

.em-archive-hero,
.em-page-hero {
	background: var(--em-bg-2);
}

/* The newsletter used a gradient ring drawn with a mask. A plain border does
   the same job without one. */
.em-newsletter::before {
	display: none;
}

.em-newsletter {
	border: 1px solid var(--em-border);
	box-shadow: none;
}

/* ---------- category tiles ---------- */

/* The tile printed the slug as a badge and the name under it, so every tile
   read "BACKEND" then "Backend". The colour already carries the identity, so
   the badge is a dot and the name is said once. */
.em-cat-tile-name {
	display: flex;
	align-items: center;
	gap: 0.55rem;
	font-size: 1.02rem;
	line-height: 1.3;
}

.em-cat-tile-dot {
	width: 9px;
	height: 9px;
	border-radius: 50%;
	flex: 0 0 auto;
}

.em-cat-tile {
	gap: 0.4rem;
}

.em-cat-tile-count {
	font-family: 'JetBrains Mono', ui-monospace, monospace;
	font-size: 0.72rem;
	letter-spacing: 0.04em;
	text-transform: uppercase;
	color: var(--em-muted);
}

/* ---------- back to top ---------- */

/* Was a 3rem circle carrying a solid triangle and a heavy drop shadow. An
   arrow says "up" without needing to be decoded, and the button sits quietly
   until hovered. */
.em-back-top {
	width: 2.75rem;
	height: 2.75rem;
	color: var(--em-muted);
	box-shadow: none;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	transition:
		opacity 0.2s ease,
		visibility 0.2s ease,
		transform 0.2s ease,
		color 0.15s ease,
		border-color 0.15s ease;
}

.em-back-top:hover,
.em-back-top:focus-visible {
	color: var(--em-primary);
	border-color: var(--em-primary);
}

@media (max-width: 560px) {
	.em-back-top {
		right: 1rem;
		bottom: 1rem;
		width: 2.5rem;
		height: 2.5rem;
	}
}

@media (prefers-reduced-motion: reduce) {
	.em-back-top {
		transition: opacity 0.2s ease, visibility 0.2s ease;
		transform: none;
	}
}

/* ---------- icons ---------- */
/* Site-wide: icons appear on the home page, the cheat sheets, the series
   index and its cards. Keeping them in the home stylesheet meant a page that
   used them without loading it rendered them unstyled. */
.em-icon {
	flex: 0 0 auto;
	vertical-align: middle;
}

/* Section labels: the icon carries the section's identity so the eye can
   tell them apart while scrolling, without another heading level. */
.em-section-label {
	display: inline-flex;
	align-items: center;
	gap: 0.45rem;
}

.em-section-label .em-icon {
	color: var(--em-primary);
}

.em-btn .em-icon {
	margin-inline-start: 0.1rem;
}

.em-btn-outline .em-icon {
	margin-inline-start: 0;
	margin-inline-end: 0.15rem;
}

.em-newsletter-label {
	margin-bottom: 0.5rem;
}


/* ---------- section headings ---------- */

/* One definition, site-wide. This lived in both the home and cheat sheet
   stylesheets with different margins, and whichever loaded last decided the
   spacing -- which is not a decision, it is an accident.
 *
 * The heading, its one-line note and the cards that follow were each adding
 * their own margin, stacking to nearly 3rem of air under the heading. The
 * gap is set once, here. */
.em-section-head {
	display: flex;
	align-items: flex-end;
	justify-content: space-between;
	gap: 1rem;
	flex-wrap: wrap;
	margin-bottom: 0.6rem;
}

.em-section-head h2 {
	margin: 0;
}

.em-section-head .em-btn {
	flex: 0 0 auto;
}

.em-home-cs-note {
	max-width: 62ch;
	margin: 0 0 1.4rem;
	font-size: 0.95rem;
}

/* ---------- mobile menu: a nested list that reads as nested ----------
 * The mobile panel uses WordPress's own walker, so a dropdown comes through
 * as <ul class="sub-menu"> -- correctly nested, but no rule ever matched it.
 * Every anchor got the same size, weight and hairline, so six topics under
 * "Tutorials" read as six more top-level destinations.
 */
.em-mobile-nav-list .sub-menu {
	margin: 0 0 0 0.85rem;
	padding: 0;
	list-style: none;
	border-left: 1px solid var(--em-border);
	border-bottom: 1px solid var(--em-border);
}

.em-mobile-nav-list .sub-menu a {
	padding: 0.5rem 0 0.5rem 0.9rem;
	font-size: 0.97rem;
	font-weight: 500;
	color: var(--em-muted);
	border-bottom: 0;
}

.em-mobile-nav-list .sub-menu li:first-child a {
	padding-top: 0.7rem;
}

.em-mobile-nav-list .sub-menu li:last-child a {
	padding-bottom: 0.7rem;
}

/* The parent keeps its own weight but drops the rule the list below repeats. */
.em-mobile-nav-list > li.menu-item-has-children > a {
	border-bottom: 0;
}

/* Comment form trap: present for anything filling every field it finds, out
   of the tab order and off the screen for everyone else. */
.em-comment-trap {
	position: absolute !important;
	left: -9999px !important;
	width: 1px !important;
	height: 1px !important;
	overflow: hidden !important;
}
