/*
 * Reader appearance controls: text size, content width, colour scheme.
 *
 * Dark mode keys off a single attribute, data-lpf-dark="1", which the inline
 * head script sets after resolving "automatic" against prefers-color-scheme.
 * Doing the resolution in JS rather than CSS means every dark rule is written
 * once instead of duplicated inside a media query.
 *
 * Colour works by redefining the theme's design tokens. Both the theme CSS and
 * the 120KB customiser stylesheet read from var(--lpf-*), so most of the site
 * follows automatically. The handful of selectors that hardcode a white
 * background, or that custom.css pins with !important, are listed explicitly.
 */

/* ============================================================ text size */

:root {
	--lpf-read-scale: 1;
}

html[data-lpf-text="small"]    { --lpf-read-scale: 0.9375; }
html[data-lpf-text="standard"] { --lpf-read-scale: 1; }
html[data-lpf-text="large"]    { --lpf-read-scale: 1.1875; }

/* The theme sizes everything in px, so the scale is applied directly to the
   elements a reader reads rather than inherited from the root. !important is
   needed because custom.css pins these sizes. */
html[data-lpf-text] .entry-content,
html[data-lpf-text] .entry-content p,
html[data-lpf-text] .entry-content li,
html[data-lpf-text] .entry-content td,
html[data-lpf-text] .entry-content th {
	font-size: calc( 16px * var( --lpf-read-scale ) ) !important;
}

html[data-lpf-text] .entry-content h2 { font-size: calc( 26px * var( --lpf-read-scale ) ) !important; }
html[data-lpf-text] .entry-content h3 { font-size: calc( 19px * var( --lpf-read-scale ) ) !important; }
html[data-lpf-text] .entry-content h4 { font-size: calc( 17px * var( --lpf-read-scale ) ) !important; }

html[data-lpf-text] .entry-content pre,
html[data-lpf-text] .entry-content code {
	font-size: calc( 14px * var( --lpf-read-scale ) ) !important;
}

/* ================================================================ width */

/*
 * Width.
 *
 * Standard layout is max-width 1290px, so below that the container already
 * fills the viewport and there is nothing to widen. Applying a vw-based cap
 * there makes the content NARROWER than standard, which is what an earlier
 * version did on phones and on small laptops.
 *
 * Wide therefore only engages once 95vw actually exceeds 1290px, which happens
 * at about 1360px. min() keeps it one rule: 95vw while that is the smaller
 * number, capped at 1560px on large displays.
 *
 * Two different jobs inside that:
 *  - Inner containers hold the readable column and widen.
 *  - #content.site-content is the outer wrapper. The theme caps it at 1290px,
 *    which is what actually limited the post column since a child cannot
 *    exceed its parent. On pages carrying .lpf-has-band custom.css sets it to
 *    none so the coloured sections reach the viewport edges, so it is only
 *    capped where there are no bands.
 */

@media ( min-width: 1360px ) {

	html[data-lpf-width="wide"] .container,
	html[data-lpf-width="wide"] .site-header .container,
	html[data-lpf-width="wide"] .main-navigation .container,
	html[data-lpf-width="wide"] #content.site-content > .container,
	html[data-lpf-width="wide"] body.lpf-has-band #content.site-content > .container,
	html[data-lpf-width="wide"] .content-sidebar-wrap,
	html[data-lpf-width="wide"] footer.site-footer-new .footer-container {
		max-width: min( 1560px, 95vw ) !important;
	}

	html[data-lpf-width="wide"] body:not( .lpf-has-band ) .site-content,
	html[data-lpf-width="wide"] body:not( .lpf-has-band ) #content.site-content {
		max-width: min( 1560px, 95vw ) !important;
	}

	/* Full-bleed pages keep their edge-to-edge bands. */
	html[data-lpf-width="wide"] body.lpf-has-band #content.site-content {
		max-width: none !important;
	}
}

/*
 * Width on small screens.
 *
 * Below 1360px the container already fills the viewport, so there is no extra
 * width to take. Capping it at a vw value made the column NARROWER, which is
 * why the desktop rule is gated above.
 *
 * What IS available on a phone is the gutters. On a 375px screen the text
 * column loses 54px to padding: 12px each side on .container and 15px each
 * side on .entry-content, nesting to 27px per edge. Trimming those to 14px per
 * edge hands roughly 26px back to the text, which is about 8% more line length
 * and clearly visible when reading.
 *
 * Vertical padding is untouched; only the left and right are narrowed.
 */

@media ( max-width: 1359px ) {

	html[data-lpf-width="wide"] .container,
	html[data-lpf-width="wide"] .site-header .container,
	html[data-lpf-width="wide"] .main-navigation .container,
	html[data-lpf-width="wide"] #content.site-content > .container,
	html[data-lpf-width="wide"] footer.site-footer-new .footer-container {
		padding-left: 8px !important;
		padding-right: 8px !important;
	}

	html[data-lpf-width="wide"] .entry-content,
	html[data-lpf-width="wide"] .entry-summary {
		padding-left: 6px !important;
		padding-right: 6px !important;
	}

	html[data-lpf-width="wide"] .page article.page {
		padding-left: 12px !important;
		padding-right: 12px !important;
	}

	/* Code blocks and tables gain the most from the extra room. */
	html[data-lpf-width="wide"] .entry-content pre {
		padding-left: 12px !important;
		padding-right: 12px !important;
	}
}

/* ================================================================ colour */

html[data-lpf-dark="1"],
html[data-lpf-dark="1"][data-lpf-dark="1"] {
	color-scheme: dark;

	--lpf-surface:           #141d28;
	--lpf-surface-2:         #1a2633;
	--lpf-surface-3:         #21303e;
	--lpf-ground:            #0d151d;
	--lpf-ink:               #f3f7fb;
	--lpf-body:              #d6dfe8;
	--lpf-muted:             #bcc8d4;
	--lpf-faint:             #97a5b3;
	--lpf-line:              #2c3b4a;
	--lpf-line-soft:         #243342;
	--lpf-accent-tint:       #10312e;
	--lpf-accent-strong:     #38dcc8;
	--lpf-accent-strong-rgb: 56, 220, 200;
	--lpf-accent-mid:        #2dd4bf;
	--lpf-code-bg:           #22303f;
	--lpf-code-bar:          #2e4055;
	--lpf-code-inline-bg:    #27384a;
	--lpf-shadow-rgb:        0, 0, 0;
}

/*
 * Surfaces that hardcode white. Tokens cannot reach these, so each is listed.
 *
 * The list was rebuilt after stripping CSS comments from the source sheets: an
 * earlier scan matched comment text into the selector and silently missed
 * .site-wrapper, .post and .single article.post, which is why the article
 * column stayed white while the sidebar went dark.
 */
html[data-lpf-dark="1"] body,
html[data-lpf-dark="1"] .site-wrapper,
html[data-lpf-dark="1"] .post,
html[data-lpf-dark="1"] .single article.post,
html[data-lpf-dark="1"] .page article.page,
html[data-lpf-dark="1"] .content-area,
html[data-lpf-dark="1"] .widget-area,
html[data-lpf-dark="1"] .widget,
html[data-lpf-dark="1"] .widget_categories,
html[data-lpf-dark="1"] .tabbed-widget,
html[data-lpf-dark="1"] .posts-grid article,
html[data-lpf-dark="1"] .related-post-item,
html[data-lpf-dark="1"] .post-navigation-optimized .nav-item,
html[data-lpf-dark="1"] .pagination a,
html[data-lpf-dark="1"] .pagination span,
html[data-lpf-dark="1"] .author-bio-box,
html[data-lpf-dark="1"] .lpf-sm-cat,
html[data-lpf-dark="1"] .single .entry-content table,
html[data-lpf-dark="1"] .lpf-table-wrap {
	background-color: var( --lpf-surface ) !important;
	background-image: none !important;
	color: var( --lpf-body );
}

/* This one is a gradient that starts white, so the image has to go too. */
html[data-lpf-dark="1"] .lpf-author-card {
	background: var( --lpf-surface-2 ) !important;
}

/* Form fields, including the white-on-focus state. */
html[data-lpf-dark="1"] input[type="text"],
html[data-lpf-dark="1"] input[type="email"],
html[data-lpf-dark="1"] input[type="search"],
html[data-lpf-dark="1"] textarea,
html[data-lpf-dark="1"] select,
html[data-lpf-dark="1"] .wpcf7-form input[type="text"]:focus,
html[data-lpf-dark="1"] .wpcf7-form input[type="email"]:focus,
html[data-lpf-dark="1"] .wpcf7-form textarea:focus {
	background-color: var( --lpf-surface-2 ) !important;
	color: var( --lpf-ink ) !important;
	border-color: var( --lpf-line ) !important;
}

html[data-lpf-dark="1"] .tab-nav button.active {
	background-color: var( --lpf-surface-2 ) !important;
	color: var( --lpf-ink ) !important;
}

/*
 * Type. custom.css pins several of these with !important, so they are restated
 * here at higher specificity rather than left to lose the cascade.
 */
html[data-lpf-dark="1"] .single .entry-title,
html[data-lpf-dark="1"] .page .entry-title,
html[data-lpf-dark="1"] .entry-title,
html[data-lpf-dark="1"] .entry-title a,
html[data-lpf-dark="1"] .widget-title,
html[data-lpf-dark="1"] h1,
html[data-lpf-dark="1"] h2,
html[data-lpf-dark="1"] h4,
html[data-lpf-dark="1"] h5,
html[data-lpf-dark="1"] h6 {
	color: var( --lpf-ink ) !important;
}

html[data-lpf-dark="1"] .single .entry-content,
html[data-lpf-dark="1"] .page .entry-content,
html[data-lpf-dark="1"] .entry-content,
html[data-lpf-dark="1"] .entry-content p,
html[data-lpf-dark="1"] .entry-content li,
html[data-lpf-dark="1"] .entry-content td,
html[data-lpf-dark="1"] .entry-content th,
html[data-lpf-dark="1"] .entry-content strong,
html[data-lpf-dark="1"] .entry-summary,
html[data-lpf-dark="1"] .entry-meta,
html[data-lpf-dark="1"] .entry-meta a,
html[data-lpf-dark="1"] .post-excerpt {
	color: var( --lpf-body ) !important;
}

/* Section headings keep the accent, brightened so it reads on dark. */
html[data-lpf-dark="1"] .single .entry-content h3,
html[data-lpf-dark="1"] .page .entry-content h3,
html[data-lpf-dark="1"] .entry-content a,
html[data-lpf-dark="1"] .single .entry-content a {
	color: var( --lpf-accent-strong ) !important;
}

/* Borders and dividers. */
html[data-lpf-dark="1"] .widget,
html[data-lpf-dark="1"] .posts-grid article,
html[data-lpf-dark="1"] .related-post-item,
html[data-lpf-dark="1"] .author-bio-box,
html[data-lpf-dark="1"] .lpf-table-wrap,
html[data-lpf-dark="1"] .post-navigation-optimized .nav-item {
	border-color: var( --lpf-line ) !important;
}

/* Screenshots on a white canvas glare against a dark page. */
html[data-lpf-dark="1"] .entry-content img:not( [src*=".svg"] ) {
	filter: brightness( 0.9 );
}


/*
 * Belt and braces. custom.css pins content headings with chains like
 * ".single .entry-content h3 { color: ... !important }". These mirror those
 * chains with the dark attribute in front so the dark palette always wins,
 * whatever order the stylesheets load in.
 */
html[data-lpf-dark="1"] .single .entry-content,
html[data-lpf-dark="1"] .single .entry-content > p,
html[data-lpf-dark="1"] .single .entry-content > p:first-of-type,
html[data-lpf-dark="1"] .page .entry-content,
html[data-lpf-dark="1"] .page .entry-content > p,
html[data-lpf-dark="1"] .page .entry-content > p:first-of-type,
html[data-lpf-dark="1"] .single .entry-content ul,
html[data-lpf-dark="1"] .single .entry-content ol,
html[data-lpf-dark="1"] .single .entry-content blockquote {
	color: var( --lpf-body ) !important;
}

html[data-lpf-dark="1"] .single .entry-content h2,
html[data-lpf-dark="1"] .page .entry-content h2,
html[data-lpf-dark="1"] .single .entry-content h4,
html[data-lpf-dark="1"] .single .entry-content h5,
html[data-lpf-dark="1"] .single .entry-header .entry-title,
html[data-lpf-dark="1"] .page .entry-header .entry-title {
	color: var( --lpf-ink ) !important;
}

html[data-lpf-dark="1"] .single .entry-content h3,
html[data-lpf-dark="1"] .page .entry-content h3,
html[data-lpf-dark="1"] .single .entry-content a,
html[data-lpf-dark="1"] .page .entry-content a {
	color: var( --lpf-accent-strong ) !important;
}

/* Nothing in the content area should inherit a dimmed opacity. */
html[data-lpf-dark="1"] .content-area,
html[data-lpf-dark="1"] .entry-header,
html[data-lpf-dark="1"] .entry-content {
	opacity: 1 !important;
	filter: none;
}

/*
 * Code blocks.
 *
 * In light mode a dark block on a white page reads clearly on its own. In dark
 * mode that no longer works, so the block is lifted ABOVE the page surface and
 * given a border and a shadow. background-color only, never the shorthand:
 * custom.css draws the terminal dots with a background-image and the shorthand
 * would erase them.
 */
html[data-lpf-dark="1"] .single .entry-content pre,
html[data-lpf-dark="1"] .page .entry-content pre,
html[data-lpf-dark="1"] .entry-content pre {
	/* background-color only. custom.css paints the terminal dots and the title
	   bar with background-image, and the shorthand would wipe both. */
	background-color: var( --lpf-code-bg ) !important;
	border: 1px solid #3a4d63 !important;
	border-left: 4px solid var( --lpf-accent-bright, #2dd4bf ) !important;
	box-shadow: 0 10px 28px -8px rgba( 0, 0, 0, 0.7 ) !important;
}

html[data-lpf-dark="1"] .entry-content pre code,
html[data-lpf-dark="1"] .single .entry-content pre code {
	background: transparent !important;
	/* The <pre> already draws the frame. Anything that gives inline code a
	   border must be cancelled here or a <pre><code> block renders two. */
	border: 0 !important;
	padding: 0 !important;
	color: #e6f1fa !important;
}

/* Inline code needs to separate from body copy without shouting.
 *
 * Scoped to :not(pre) > code deliberately. Most posts on the site use a bare
 * <pre>, but seven wrap the contents in <code>, and an unscoped rule here puts
 * a second border inside the terminal frame on every block in them. */
html[data-lpf-dark="1"] .single .entry-content :not( pre ) > code,
html[data-lpf-dark="1"] .page .entry-content :not( pre ) > code {
	background-color: var( --lpf-code-inline-bg ) !important;
	color: #7ff0dd !important;
	border: 1px solid #35485d;
}

/* The table wrapper is a panel too, so lift it the same way. */
html[data-lpf-dark="1"] .lpf-table-wrap {
	border-color: #35485d !important;
	box-shadow: 0 6px 20px rgba( 0, 0, 0, 0.35 ) !important;
}

html[data-lpf-dark="1"] .lpf-table-wrap thead th {
	background: #26374a !important;
	color: #eaf2fa !important;
}

/* ================================================== the panel itself */

.lpf-appear-toggle {
	position: fixed;
	right: 30px;
	bottom: 96px; /* clear of #back-to-top at bottom 30px */
	z-index: 9998;
	display: inline-flex;
	align-items: center;
	gap: 8px;
	padding: 10px 15px;
	font: 600 14px/1 'Roboto', system-ui, sans-serif;
	color: #eaf2fa;
	background: #0f1b29;
	border: 1px solid #2b4058;
	border-radius: 999px;
	cursor: pointer;
	box-shadow: 0 4px 14px rgba( 0, 0, 0, 0.3 );
	-webkit-font-smoothing: antialiased;
}

.lpf-appear-toggle:hover,
.lpf-appear-toggle:focus-visible {
	border-color: #2dd4bf;
	outline: none;
}

.lpf-appear-panel {
	position: fixed;
	right: 30px;
	bottom: 148px;
	z-index: 9999;
	width: 258px;
	padding: 16px 20px 20px;
	background: #16283a;
	border: 1px solid #2b4058;
	border-radius: 12px;
	box-shadow: 0 12px 34px rgba( 0, 0, 0, 0.45 );
	color: #eaf2fa;
	font-family: 'Roboto', system-ui, sans-serif;
	-webkit-font-smoothing: antialiased;
}

.lpf-appear-panel[hidden] {
	display: none;
}

.lpf-appear-head {
	display: flex;
	align-items: center;
	justify-content: space-between;
	margin: 0 0 12px;
}

.lpf-appear-panel h2 {
	margin: 0;
	padding: 0;
	font-size: 15px;
	font-weight: 700;
	color: #fff;
	border: 0;
}

.lpf-appear-hide {
	background: #1e3247;
	border: 1px solid #2b4058;
	border-radius: 5px;
	color: #a9bacb;
	font: 500 12px/1 'Roboto', system-ui, sans-serif;
	padding: 5px 9px;
	cursor: pointer;
}

.lpf-appear-hide:hover {
	color: #fff;
}

.lpf-appear-group {
	margin-top: 14px;
	padding-top: 12px;
	border-top: 1px solid #2b4058;
}

.lpf-appear-group:first-of-type {
	margin-top: 0;
	padding-top: 0;
	border-top: 0;
}

.lpf-appear-group fieldset {
	margin: 0;
	padding: 0;
	border: 0;
}

.lpf-appear-group legend {
	padding: 0 0 6px;
	font-size: 12px;
	letter-spacing: 0.06em;
	text-transform: uppercase;
	color: #93a7bb;
}

.lpf-appear-opt {
	display: flex;
	align-items: center;
	gap: 10px;
	padding: 5px 0;
	font-size: 14px;
	color: #eaf2fa;
	cursor: pointer;
}

.lpf-appear-opt input {
	accent-color: #2dd4bf;
	width: 16px;
	height: 16px;
	margin: 0;
	cursor: pointer;
}

/*
 * Never taller than the space available. A landscape phone is around 375px
 * high, and the panel is roughly 340px, so without this it runs off the top.
 */
.lpf-appear-panel {
	max-height: calc( 100vh - 180px );
	overflow-y: auto;
	overscroll-behavior: contain;
}

@media ( max-width: 600px ) {

	.lpf-appear-panel {
		right: 12px;
		left: 12px;
		width: auto;
		bottom: 116px;
		max-height: calc( 100vh - 160px );
	}

	/*
	 * Stacked ABOVE #back-to-top, not beside it. responsive-fixes.css moves
	 * that button to bottom 20px / right 15px at 42px square, so it occupies
	 * up to 62px from the bottom. Anchoring the toggle at 72px leaves a clear
	 * gap; an earlier attempt at 24px put the two on top of each other.
	 */
	.lpf-appear-toggle {
		right: 12px;
		bottom: 72px;
		padding: 9px 13px;
		font-size: 13px;
	}
}

/* Short viewports, mostly phones held sideways. */
@media ( max-height: 520px ) {

	.lpf-appear-panel {
		bottom: 116px;
		max-height: calc( 100vh - 140px );
	}
}

@media print {

	.lpf-appear-toggle,
	.lpf-appear-panel {
		display: none;
	}
}

/*
 * The About page "Work with me" button. In dark mode the generic
 * ".page .entry-content a" rule above outranks the button's own colour and
 * paints its label teal on a teal fill. Pin the dark-surface button pair here,
 * with the dark attribute in front so it wins whatever custom.css says.
 */
html[data-lpf-dark="1"] .page .entry-content .lpf-about-cta-primary {
	background: var( --lpf-btn-on-dark ) !important;
	color: var( --lpf-btn-on-dark-ink ) !important;
}

html[data-lpf-dark="1"] .page .entry-content .lpf-about-cta-primary:hover {
	color: var( --lpf-btn-on-dark-ink ) !important;
	box-shadow: 0 10px 22px -8px rgba( var( --lpf-accent-strong-rgb ), 0.45 );
}

/* ===== dark: Home nav highlight =====
   The "Home" tab is styled by a first-child selector in
   custom-drupal-style.css as a full bright gradient fill
   (--lpf-accent-mid to --lpf-accent-strong). In light mode those tokens
   are muted teals and the pill looks intentional; in dark mode they jump
   to #2dd4bf/#38dcc8, and the fill reads as a stray highlighter block
   against the rest of the nav's dark chrome. Bring it in line with how
   every other current/hover nav item is styled here: the same chrome
   background, with an accent edge and accent text to keep Home marked
   as current without the glare. */
/* Same treatment for every nav item's active state: Home, DevOps, Linux,
   Kubernetes, Terraform, Monitoring Tools, About me all get this when that
   section is the current page.

   !important and the extra body.home selector are both deliberate. The
   customizer stylesheet (uploads/lpf-css/custom.css) loads after this file
   and carries its own rule for Home specifically -- `body.home ... 
   li:first-child > a`, independent of the .current-menu-item class -- plus
   !important variants at the 769px breakpoint for the header's always-dark
   chrome bar. Neither checks the reader's dark/light choice, so the plain
   .current-menu-item override above missed Home's path entirely: every
   other section picked up the fix, Home kept its bright pill. */
html[data-lpf-dark="1"] body.home .main-navigation #primary-menu > li:first-child > a,
html[data-lpf-dark="1"] .main-navigation #primary-menu > li.current-menu-item > a,
html[data-lpf-dark="1"] .main-navigation #primary-menu > li.current_page_item > a,
html[data-lpf-dark="1"] .main-navigation #primary-menu > li.current-menu-ancestor > a,
html[data-lpf-dark="1"] .main-navigation #primary-menu > li.current_page_ancestor > a,
html[data-lpf-dark="1"] .main-navigation #primary-menu > li.current-category-ancestor > a {
	background: var(--lpf-chrome) !important;
	box-shadow: inset 3px 0 0 0 var(--lpf-accent-strong) !important;
	color: var(--lpf-accent-strong) !important;
}

/* The mobile hamburger button's open ("X") state used the same bright
   accent-fill square as the old nav pill. Match it to the nav highlight
   above: dark chrome fill with an accent border, not a solid accent block.
   custom.css sets this unscoped too, so !important again. */
html[data-lpf-dark="1"] .menu-toggle-btn.is-open {
	background: var(--lpf-chrome) !important;
	border-color: var(--lpf-accent-strong) !important;
}
