/**
 * DishaOnline — Design System : Tokens, Reset, Typography, Utilities
 * Layer 1 of 3. Loaded on every page. Keep lean.
 *
 * @package DishaOnline
 */

/* =========================================================
   1. DESIGN TOKENS
   ========================================================= */
/**
 * Metrics-matched fallback for Noto Sans Devanagari.
 *
 * WHY THIS EXISTS
 * ---------------
 * The local Devanagari fallbacks render ~5% wider than Noto Sans Devanagari.
 * On the homepage that pushed the hero heading onto a third line, so when the
 * web font finished loading the heading collapsed 120px -> 80px and dragged
 * every section above the fold upward. Measured cost: 0.097 CLS on a 390px
 * viewport -- almost the entire 0.1 "good" budget, spent before the visitor
 * had done anything.
 *
 * size-adjust scales the fallback down so it occupies the same width as the
 * real font, making the swap visually near-invisible. The percentage is the
 * measured width ratio (692 / 725) of the two faces at identical size.
 *
 * This is a pure progressive enhancement: browsers without size-adjust
 * support simply ignore the descriptor and get today's behaviour.
 */
@font-face {
	font-family: "Noto Devanagari Fallback";
	/*
	 * MUST be a range. A @font-face with no font-weight defaults to 400, so a
	 * weight-800 heading finds no match and skips straight past this face to
	 * the next family -- which is exactly the reflow we are trying to prevent.
	 * The same applies to font-style.
	 */
	font-weight: 100 900;
	font-style: normal;
	font-display: swap;
	/*
	 * One real Devanagari-capable face per platform, most-specific first.
	 * If a name is absent the browser moves on; if none match, the face stays
	 * unloaded and the next entry in the stack is used, exactly as before.
	 */
	src: local("Nirmala UI"),            /* Windows 8+            */
	     local("Mangal"),                /* Windows (legacy)      */
	     local("Kohinoor Devanagari"),   /* macOS / iOS           */
	     local("Devanagari Sangam MN"),  /* macOS / iOS (older)   */
	     local("Noto Sans Devanagari"),  /* Android / ChromeOS    */
	     local("Lohit Devanagari"),      /* Linux (Fedora/RHEL)   */
	     local("Samyak Devanagari"),     /* Linux                 */
	     local("DejaVu Sans"),           /* Linux (Debian family) */
	     local("Liberation Sans"),       /* Linux                 */
	     local("Arial");                 /* last resort           */
	/*
	 * 95.5% is the measured Noto-to-fallback width ratio for the widest and
	 * most common fallbacks (system-ui / DejaVu measured 95.4%). Narrower
	 * faces such as Liberation Sans sit at ~98.7%, so for those the correction
	 * slightly overshoots — still far better than the uncorrected ~5% jump.
	 */
	size-adjust: 95.5%;
	ascent-override: 105%;
	descent-override: 28%;
	line-gap-override: 0%;
}

:root {
	/* Brand — Deep Navy (authority/trust) */
	--dio-navy-900: #08172E;
	--dio-navy-800: #0C2246;
	--dio-navy-700: #0F2A57;
	--dio-navy-600: #17427F;
	--dio-navy-500: #1E56A0;
	--dio-navy-300: #7FA3CE;
	--dio-navy-200: #C7D8EE;
	/* Large decorative numeral: still clears 3:1 against the page background. */
	--dio-ghost-figure: #6B8FBF;
	--dio-navy-100: #E8EFF9;
	--dio-navy-50:  #F3F7FC;

	/* Accent — Saffron (action/highlight, used sparingly) */
	--dio-saffron-700: #A85708;
	--dio-saffron-600: #B45C08;
	--dio-saffron-500: #E07A17;
	/* Accessible saffron for TEXT: 4.5:1+ on both white and navy-900. */
	--dio-saffron-text: #B25A00;
	--dio-saffron-text-dark: #F59B3C;
	--dio-saffron-100: #FDF1E3;

	/* Semantic */
	--dio-success-700: #12603C;
	--dio-success-500: #157F4E;
	--dio-success-50:  #E9F6EF;
	--dio-warning-700: #8A5A00;
	--dio-warning-500: #B87A08;
	--dio-warning-50:  #FDF4E3;
	--dio-danger-700:  #98221E;
	--dio-danger-500:  #C22E29;
	--dio-danger-50:   #FBECEB;
	--dio-info-700:    var(--dio-navy-600);
	--dio-info-50:     var(--dio-navy-100);

	/* Neutrals */
	--dio-white:   #FFFFFF;
	--dio-bg:      #F6F8FB;
	--dio-surface: #FFFFFF;
	--dio-surface-2: #F1F4F9;
	--dio-border:  #DFE4EC;
	--dio-border-strong: #C6CEDB;
	--dio-text:    #1B2432;
	--dio-text-2:  #3D4859;
	--dio-muted:   #5C6779;
	--dio-heading: #0F1725;

	/* Typography */
	--dio-font-hi: "Noto Sans Devanagari", "Noto Devanagari Fallback", "Nirmala UI", "Mangal", system-ui, sans-serif;
	--dio-font-en: "Inter", system-ui, -apple-system, "Segoe UI", Roboto, Arial, sans-serif;
	--dio-font-serif: "Noto Serif Devanagari", "Noto Serif", Georgia, serif;
	--dio-font-body: var(--dio-font-hi), var(--dio-font-en);
	--dio-font-mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;

	/* Modest, readable type scale (fluid) */
	--dio-fs-xs:  0.8125rem;  /* 13px */
	--dio-fs-sm:  0.875rem;   /* 14px */
	--dio-fs-base: 1rem;      /* 16px */
	--dio-fs-md:  1.0625rem;  /* 17px */
	--dio-fs-lg:  clamp(1.125rem, 1.05rem + 0.35vw, 1.25rem);
	--dio-fs-xl:  clamp(1.25rem, 1.15rem + 0.5vw, 1.5rem);
	--dio-fs-2xl: clamp(1.5rem, 1.32rem + 0.85vw, 1.9rem);
	--dio-fs-3xl: clamp(1.75rem, 1.45rem + 1.4vw, 2.45rem);
	--dio-fs-4xl: clamp(2rem, 1.6rem + 2vw, 3rem);

	--dio-lh-tight: 1.28;
	--dio-lh-snug: 1.45;
	--dio-lh-body: 1.75;   /* Devanagari needs generous leading */
	--dio-lh-loose: 1.9;

	/* Spacing (4px base) */
	--dio-s1: 0.25rem;
	--dio-s2: 0.5rem;
	--dio-s3: 0.75rem;
	--dio-s4: 1rem;
	--dio-s5: 1.25rem;
	--dio-s6: 1.5rem;
	--dio-s8: 2rem;
	--dio-s10: 2.5rem;
	--dio-s12: 3rem;
	--dio-s16: 4rem;
	--dio-section: clamp(2.25rem, 1.5rem + 3vw, 4rem);

	/* Radius — restrained, editorial */
	--dio-r-sm: 4px;
	--dio-r: 8px;
	--dio-r-lg: 12px;
	--dio-r-pill: 999px;

	/* Elevation — subtle only */
	--dio-shadow-xs: 0 1px 2px rgba(11, 27, 51, 0.06);
	--dio-shadow-sm: 0 1px 3px rgba(11, 27, 51, 0.08), 0 1px 2px rgba(11, 27, 51, 0.04);
	--dio-shadow-md: 0 4px 14px rgba(11, 27, 51, 0.08);

	/* Layout */
	--dio-container: 1220px;
	--dio-container-narrow: 760px;
	--dio-gutter: clamp(1rem, 0.6rem + 1.6vw, 2rem);
	--dio-header-h: 64px;

	/*
	 * Height of the WordPress admin bar, as an offset every sticky/fixed
	 * element can subtract.
	 *
	 * Zero for logged-out visitors. The `body.admin-bar` rules further down
	 * raise it to the real value, which core itself varies by viewport:
	 * 32px on wide screens, 46px at 782px and below (where the bar grows and
	 * switches to position:fixed).
	 */
	--dio-adminbar-h: 0px;

	/* Motion */
	--dio-t-fast: 120ms ease;
	--dio-t: 180ms ease;

	--dio-focus: 0 0 0 3px rgba(30, 86, 160, 0.35);
	--dio-z-header: 100;
	--dio-z-overlay: 200;
}

/* Optional dark mode — opt-in only, never forced (see §52). */
html[data-dio-theme="dark"] {
	--dio-bg: #0C121C;
	--dio-surface: #131B28;
	--dio-surface-2: #18222F;
	--dio-border: #26303F;
	--dio-border-strong: #33405233;
	--dio-text: #E4E9F1;
	--dio-text-2: #C3CBD8;
	--dio-muted: #98A3B4;
	--dio-heading: #F2F5FA;
	--dio-navy-200: #22374F;
	--dio-ghost-figure: #456A90;
	--dio-navy-100: #16263F;
	--dio-navy-50: #121C2B;
	--dio-saffron-100: #2A1D0C;
	--dio-success-50: #10241A;
	--dio-warning-50: #241C0B;
	--dio-danger-50: #2A1414;
	--dio-white: #131B28;
	--dio-shadow-sm: 0 1px 3px rgba(0, 0, 0, 0.5);
	--dio-shadow-md: 0 4px 14px rgba(0, 0, 0, 0.45);
}

/* =========================================================
   2. RESET / NORMALISE (light touch — GP handles the rest)
   ========================================================= */
*,
*::before,
*::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }

@media (prefers-reduced-motion: reduce) {
	html { scroll-behavior: auto; }
	*, *::before, *::after {
		animation-duration: 0.001ms !important;
		animation-iteration-count: 1 !important;
		transition-duration: 0.001ms !important;
		scroll-behavior: auto !important;
	}
}

body.dio {
	background-color: var(--dio-bg);
	color: var(--dio-text);
	font-family: var(--dio-font-body);
	font-size: var(--dio-fs-md);
	line-height: var(--dio-lh-body);
	overflow-x: hidden; /* guarantee: no horizontal overflow on mobile */
	-webkit-font-smoothing: antialiased;
	text-rendering: optimizeLegibility;
}

img, svg, video, iframe { max-width: 100%; height: auto; }
img { display: block; }

/* =========================================================
   3. TYPOGRAPHY
   ========================================================= */
/*
 * IMPORTANT — these element defaults are wrapped in :where() so they carry
 * ZERO specificity.
 *
 * Previously they were written as `.dio h1, .dio h2, ...` (specificity 0,1,1).
 * That beat every single-class component rule such as `.dio-hero__title`
 * (0,1,0), so headings on dark backgrounds silently reverted to the dark
 * body colour and became unreadable. :where() makes these pure defaults that
 * any component class overrides naturally, which is what a base layer should
 * do. Do not remove the :where() wrappers.
 */
:where(.dio) :is(h1, h2, h3, h4, h5, h6) {
	font-family: var(--dio-font-body);
	color: var(--dio-heading);
	line-height: var(--dio-lh-tight);
	font-weight: 700;
	letter-spacing: -0.005em;
	margin: 0 0 var(--dio-s4);
	overflow-wrap: break-word;
}
:where(.dio) h1 { font-size: var(--dio-fs-3xl); }
:where(.dio) h2 { font-size: var(--dio-fs-2xl); }
:where(.dio) h3 { font-size: var(--dio-fs-xl); }
:where(.dio) h4 { font-size: var(--dio-fs-lg); }
:where(.dio) :is(h5, h6) { font-size: var(--dio-fs-base); }
:where(.dio) p { margin: 0 0 var(--dio-s5); }
:where(.dio) a { color: var(--dio-navy-600); text-decoration-thickness: 1px; text-underline-offset: 2px; }
:where(.dio) a:hover { color: var(--dio-navy-500); }

.dio :is(a, button, input, select, textarea, summary, [tabindex]):focus-visible {
	outline: 2px solid var(--dio-navy-500);
	outline-offset: 2px;
	border-radius: var(--dio-r-sm);
}

/*
 * Latin runs inside Hindi copy get Inter metrics for even colour.
 *
 * MUST use [lang|="en"], never :lang(en).
 *
 * :lang() matches by INHERITED language, and WordPress ships <html lang="en-US">
 * on a default install. That made this rule match every element on the page, so
 * all Hindi copy silently rendered in the Latin stack (Inter) instead of Noto
 * Sans Devanagari — the Devanagari glyphs then came from an arbitrary system
 * fallback, which is what caused the hero heading to reflow by a whole line
 * when the real font loaded.
 *
 * The attribute selector matches only elements explicitly marked up as English,
 * which is the actual intent: <span lang="en">PAN</span> inside a Hindi
 * sentence. Sites that genuinely run in English are unaffected, because the
 * body stack already falls through to Inter for Latin text.
 */
.dio [lang|="en"], .dio .en { font-family: var(--dio-font-en); }

/* =========================================================
   4. LAYOUT PRIMITIVES
   ========================================================= */
.dio-container {
	width: 100%;
	max-width: var(--dio-container);
	margin-inline: auto;
	padding-inline: var(--dio-gutter);
}
.dio-container--narrow { max-width: var(--dio-container-narrow); }

.dio-section { padding-block: var(--dio-section); }
.dio-section--tight { padding-block: clamp(1.5rem, 1rem + 2vw, 2.5rem); }
.dio-section--alt { background: var(--dio-surface); border-block: 1px solid var(--dio-border); }

.dio-grid { display: grid; gap: var(--dio-s5); }
.dio-grid--2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.dio-grid--3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.dio-grid--4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.dio-grid--auto { grid-template-columns: repeat(auto-fill, minmax(min(260px, 100%), 1fr)); }

.dio-stack > * + * { margin-top: var(--dio-s4); }
.dio-cluster { display: flex; flex-wrap: wrap; gap: var(--dio-s2); align-items: center; }

/* Content column + sidebar */
.dio-with-sidebar {
	display: grid;
	gap: var(--dio-s8);
	grid-template-columns: minmax(0, 1fr);
	align-items: start;
}

@media (min-width: 1025px) {
	.dio-with-sidebar { grid-template-columns: minmax(0, 1fr) 330px; gap: var(--dio-s10); }
	.dio-with-sidebar--left { grid-template-columns: 330px minmax(0, 1fr); }
	/*
	 * Sticky sidebar.
	 *
	 * `position: sticky` only travels inside its own containing block, and
	 * the containing block here is the <aside> grid item — NOT the row. The
	 * grid sets `align-items: start`, which shrink-wraps that item to the
	 * height of its widgets (~1350px against a 4000px article), so the
	 * sticky element filled its parent completely and had zero room to
	 * move. It was declared sticky and scrolled away like static content.
	 *
	 * `align-self: stretch` gives the aside the full row height, which is
	 * what sticky needs to travel through.
	 */
	.dio-with-sidebar > .dio-sidebar { align-self: stretch; }

	.dio-sidebar-sticky {
		position: sticky;
		top: calc(var(--dio-adminbar-h) + var(--dio-header-h) + var(--dio-s4));

		/*
		 * A sidebar taller than the viewport would pin with its lower
		 * widgets permanently off-screen and unreachable, since the page
		 * scroll no longer moves it. Cap it to the visible area and let it
		 * scroll internally; `overscroll-behavior` stops that inner scroll
		 * from chaining to the page when it bottoms out.
		 *
		 * Short sidebars are unaffected — the max-height never engages.
		 */
		max-height: calc(100vh - var(--dio-adminbar-h) - var(--dio-header-h) - var(--dio-s8));
		overflow-y: auto;
		overscroll-behavior: contain;
		scrollbar-width: thin;
	}

	/*
	 * Reserve the scrollbar gutter so a focus ring on a widget link is never
	 * clipped by the overflow container.
	 */
	.dio-sidebar-sticky { padding-inline-end: 2px; margin-inline-end: -2px; }

	/*
	 * Customizer sidebar position (Appearance > Customize > DishaOnline >
	 * लेआउट). `order` moves the aside without touching template markup, so the
	 * DOM order stays content-first for screen readers and keyboard users.
	 */
	.dio-sidebar-left .dio-with-sidebar { grid-template-columns: 330px minmax(0, 1fr); }
	.dio-sidebar-left .dio-with-sidebar > .dio-content-col { order: 2; }
	.dio-sidebar-left .dio-with-sidebar > .dio-sidebar { order: 1; }
	.dio-sidebar-none .dio-with-sidebar { grid-template-columns: minmax(0, 1fr); }
	.dio-sidebar-none .dio-with-sidebar > .dio-sidebar { display: none; }
}

/* Responsive grid collapse — deliberate, per breakpoint (§53) */
@media (max-width: 1024px) {
	.dio-grid--4 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
	.dio-grid--3 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 640px) {
	.dio-grid--2,
	.dio-grid--3,
	.dio-grid--4 { grid-template-columns: minmax(0, 1fr); }
}

/* =========================================================
   5. SECTION HEADINGS
   ========================================================= */
.dio-section-head {
	display: flex;
	align-items: flex-end;
	justify-content: space-between;
	gap: var(--dio-s4);
	margin-bottom: var(--dio-s6);
	padding-bottom: var(--dio-s3);
	border-bottom: 1px solid var(--dio-border);
}
.dio-section-head__title {
	margin: 0;
	font-size: var(--dio-fs-xl);
	display: flex;
	align-items: center;
	gap: var(--dio-s3);
}
.dio-section-head__title::before {
	content: "";
	width: 4px;
	height: 1.15em;
	border-radius: 2px;
	background: var(--dio-saffron-500);
	flex: none;
}
.dio-section-head__sub {
	margin: var(--dio-s1) 0 0;
	font-size: var(--dio-fs-sm);
	color: var(--dio-muted);
	line-height: var(--dio-lh-snug);
}
.dio-section-head__link {
	font-size: var(--dio-fs-sm);
	font-weight: 600;
	white-space: nowrap;
	text-decoration: none;
	color: var(--dio-navy-600);
}
.dio-section-head__link:hover { text-decoration: underline; }
@media (max-width: 480px) {
	.dio-section-head { flex-direction: column; align-items: flex-start; gap: var(--dio-s2); }
}

/* =========================================================
   6. UTILITIES / ACCESSIBILITY
   ========================================================= */
.dio-sr-only {
	position: absolute !important;
	width: 1px; height: 1px;
	padding: 0; margin: -1px;
	overflow: hidden;
	clip: rect(0, 0, 0, 0);
	white-space: nowrap; border: 0;
}
.dio-skip-link {
	position: absolute;
	left: -9999px;
	top: 0;
	z-index: 999;
	background: var(--dio-navy-700);
	color: #fff;
	padding: var(--dio-s3) var(--dio-s5);
	border-radius: 0 0 var(--dio-r) 0;
	font-weight: 600;
}
.dio-skip-link:focus { left: 0; color: #fff; }

.dio-muted { color: var(--dio-muted); }
.dio-small { font-size: var(--dio-fs-sm); }
.dio-nowrap { white-space: nowrap; }
.dio-mt-0 { margin-top: 0 !important; }
.dio-mb-0 { margin-bottom: 0 !important; }
.dio-hide { display: none !important; }
@media (max-width: 768px)  { .dio-hide-mobile { display: none !important; } }
@media (min-width: 769px)  { .dio-hide-desktop { display: none !important; } }

/* Text clamping for card titles/excerpts */
.dio-clamp-2, .dio-clamp-3 {
	display: -webkit-box;
	-webkit-box-orient: vertical;
	overflow: hidden;
}
.dio-clamp-2 { -webkit-line-clamp: 2; line-clamp: 2; }
.dio-clamp-3 { -webkit-line-clamp: 3; line-clamp: 3; }

/* Print */
@media print {
	.dio-site-header, .dio-site-footer, .dio-sidebar, .dio-ad, .dio-share, .dio-toc { display: none !important; }
	.dio { background: #fff; }
}

/* ------------------------------------------------- WordPress admin bar.
 *
 * When an editor is logged in, core pins #wpadminbar to the top of the
 * viewport with z-index 99999 — far above anything a theme should use. The
 * sticky site header was positioned at top:0, so as soon as the page
 * scrolled the admin bar sat on top of it and cut off the logo and the
 * first row of navigation. The theme had no admin-bar handling at all.
 *
 * Rather than patch each component, the bar's height is published as
 * --dio-adminbar-h and every sticky/fixed element offsets by it. Logged-out
 * visitors keep 0px, so their layout is completely unchanged.
 *
 * The breakpoint below mirrors WordPress core (wp-includes/css/admin-bar.css):
 * at 782px and under the bar becomes 46px tall and switches to fixed, which
 * is why the offset has to change with it.
 */
body.admin-bar {
	--dio-adminbar-h: 32px;
}

@media screen and (max-width: 782px) {
	body.admin-bar {
		--dio-adminbar-h: 46px;
	}
}

/*
 * Below 600px core UNPINS the admin bar — it scrolls away with the page
 * (position: absolute), so nothing needs an offset any more. Keeping one
 * would leave a permanent 46px gap under the header.
 */
@media screen and (max-width: 600px) {
	body.admin-bar {
		--dio-adminbar-h: 0px;
	}
}
