/* Philentia Design System v1.0 — tokens
 * Copyright (c) 2026, IT Business Dominicana (ITBD)
 *
 * The single source of truth for colour, type, spacing, radius, elevation and
 * motion. Nothing else in the product should contain a hex value.
 *
 * ---------------------------------------------------------------------------
 * Fill colours and text colours are not the same tokens
 * ---------------------------------------------------------------------------
 * The brand palette was specified alongside a WCAG 2.1 AA requirement, and
 * three of its colours cannot carry text on white at AA. Measured, not
 * assumed — contrast ratio against #FFFFFF:
 *
 *     --philentia-blue-600  #0164C9   5.74:1   ok as text and as a button fill
 *     --impact-green-600    #3DA124   3.32:1   FAILS as text; fill only
 *     --impact-green-700    #0D7420   5.97:1   ok as text
 *     --warning-500         #F79009   2.35:1   FAILS as text; fill only
 *     --warning-700         #B54708   5.43:1   ok as text
 *     --danger-600          #D92D20   4.83:1   ok as text and as a button fill
 *     --neutral-500         #98A2B3   2.58:1   FAILS as text; borders and icons
 *     --growth-lime-500     #7CCF2C   1.94:1   accent fill only, never text
 *
 * WCAG 2.2 also asks for 3:1 on *non-text* contrast (SC 1.4.11): the visual
 * boundary that identifies a control. The specified `#D0D5DD` input border is
 * 1.47:1 against white and fails it — an empty text input has no affordance
 * other than its box, so the box is not decoration. `--border-control` exists
 * for that: `#8A93A3` is the lightest neutral in this family that clears 3:1.
 * `--border` stays light, because a card edge or a table rule *is* decoration
 * and 1.4.11 does not reach it.
 *
 * So every semantic role has a `-fill` and a `-text` token and they are
 * deliberately different values. Using `--success-fill` for a label is the
 * mistake this split exists to make visible, and green-on-white success text
 * at 3.32:1 is exactly the failure an accessibility audit returns.
 *
 * White text on a filled control is judged against the fill, which is why
 * `--success-fill` is allowed to carry white (3.32:1 fails AA there too, so
 * the success button uses `--success-fill-strong`).
 */

:root {
	/* -------------------------------------------------------------------
	 * Brand — blue: technology, navigation, finance, trust
	 * ------------------------------------------------------------------- */
	--philentia-navy: #063078;
	--philentia-blue-700: #0147a4;
	--philentia-blue-600: #0164c9;
	--philentia-blue-500: #038bef;
	--philentia-blue-200: #89cdfa;
	--philentia-blue-100: #d0ecfb;
	--philentia-blue-50: #f1f9fe;

	/* Brand — green: mission, people, outcomes, impact */
	--impact-green-700: #0d7420;
	--impact-green-600: #3da124;
	--growth-lime-500: #7ccf2c;

	/* The product's primary. Everything interactive resolves to this. */
	--brand-primary: var(--philentia-blue-600);
	--brand-primary-hover: var(--philentia-blue-700);
	--brand-primary-active: var(--philentia-navy);

	/* -------------------------------------------------------------------
	 * Neutrals
	 * ------------------------------------------------------------------- */
	--neutral-950: #101828;
	--neutral-900: #1d2939;
	--neutral-800: #344054;
	--neutral-700: #475467;
	--neutral-600: #667085;
	--neutral-500: #98a2b3;
	--neutral-400: #b3bac5;
	--neutral-300: #d0d5dd;
	--neutral-200: #eaecf0;
	--neutral-100: #f2f4f7;
	--neutral-50: #f9fafb;
	--white: #ffffff;

	/* -------------------------------------------------------------------
	 * Surfaces and text
	 * ------------------------------------------------------------------- */
	--surface: var(--white);
	--surface-secondary: var(--neutral-50);
	--surface-tertiary: var(--neutral-100);
	--surface-inverse: var(--philentia-navy);

	--text-primary: var(--neutral-950);
	--text-secondary: var(--neutral-700);
	--text-muted: var(--neutral-600); /* 4.96:1 — the lightest text allowed */
	--text-on-fill: var(--white);
	--text-link: var(--philentia-blue-600);

	--border: var(--neutral-200); /* decorative: card edges, table rules */
	--border-strong: var(--neutral-300);
	/* Interactive boundaries — input, select, textarea, checkbox, secondary
	 * button. 3.1:1 on white, so the control is identifiable (SC 1.4.11). */
	--border-control: #8a93a3;
	--border-focus: var(--brand-primary);

	/* -------------------------------------------------------------------
	 * Semantic — each role is a fill, a text colour and a tint background
	 * ------------------------------------------------------------------- */
	--success-fill: var(--impact-green-600);
	--success-fill-strong: var(--impact-green-700); /* white text needs this */
	--success-text: var(--impact-green-700);
	--success-bg: #ecfdf3;
	--success-border: #abefc6;

	--warning-fill: #f79009;
	--warning-fill-strong: #b54708;
	--warning-text: #b54708;
	--warning-bg: #fffaeb;
	--warning-border: #fedf89;

	--danger-fill: #d92d20;
	--danger-fill-strong: #b42318;
	--danger-text: #b42318;
	--danger-bg: #fef3f2;
	--danger-border: #fecdca;

	--info-fill: var(--philentia-blue-500);
	--info-fill-strong: var(--philentia-blue-700);
	--info-text: var(--philentia-blue-700);
	--info-bg: #eff8ff;
	--info-border: var(--philentia-blue-200);

	/* Neutral / not-applicable. A jurisdiction we do not support is grey on
	 * purpose: it must not read as either a pass or a failure. */
	/* The manual gives #667085 on #F2F4F7 for the neutral state. That is
	 * 4.51:1 — it clears 4.5:1 by 0.01, which is not a margin, it is a
	 * rounding error. Neutral 700 is the same hue at 6.98:1. */
	--muted-fill: var(--neutral-400);
	--muted-text: var(--neutral-700);
	--muted-bg: var(--neutral-100);
	--muted-border: var(--neutral-300);

	/* -------------------------------------------------------------------
	 * Gradients
	 * ------------------------------------------------------------------- */
	--gradient-brand: linear-gradient(
		135deg,
		var(--philentia-navy) 0%,
		var(--philentia-blue-600) 50%,
		var(--philentia-blue-500) 100%
	);
	--gradient-impact: linear-gradient(
		135deg,
		var(--impact-green-700) 0%,
		var(--impact-green-600) 55%,
		var(--growth-lime-500) 100%
	);
	/* Blue into green: the two halves of the product meeting. Reserved for
	 * fundraising progress, where money becomes outcome. */
	--gradient-progress: linear-gradient(
		90deg,
		var(--philentia-blue-600) 0%,
		var(--impact-green-600) 100%
	);
	--gradient-ai: linear-gradient(
		135deg,
		var(--philentia-blue-700) 0%,
		var(--philentia-blue-500) 100%
	);

	/* -------------------------------------------------------------------
	 * Type
	 * ------------------------------------------------------------------- */
	--font-ui: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
		"Helvetica Neue", Arial, sans-serif;
	--font-brand: "Montserrat", var(--font-ui);
	--font-mono: "JetBrains Mono", ui-monospace, SFMono-Regular, Menlo, monospace;
	/* Money and identifiers line up in columns only with tabular figures. A
	 * ledger where the decimal point moves per row is unreadable. */
	--font-numeric: var(--font-ui);

	--text-display-xl: 3rem; /* 48 / 56 / 700 */
	--text-display: 2.5rem; /* 40 / 48 / 700 */
	--text-h1: 2rem; /* 32 / 40 / 700 */
	--text-h2: 1.75rem; /* 28 / 36 / 700 */
	--text-h3: 1.5rem; /* 24 / 32 / 600 */
	--text-h4: 1.25rem; /* 20 / 28 / 600 */
	--text-body-lg: 1rem; /* 16 / 24 / 400 */
	--text-body: 0.875rem; /* 14 / 20 / 400 */
	--text-body-sm: 0.8125rem; /* 13 / 18 / 400 */
	--text-caption: 0.75rem; /* 12 / 16 / 500 */

	--leading-tight: 1.2;
	--leading-snug: 1.4;
	--leading-normal: 1.5;
	--leading-relaxed: 1.65;

	--weight-regular: 400;
	--weight-medium: 500;
	--weight-semibold: 600;
	--weight-bold: 700;

	/* -------------------------------------------------------------------
	 * Space — 4px base
	 * ------------------------------------------------------------------- */
	--space-1: 4px;
	--space-2: 8px;
	--space-3: 12px;
	--space-4: 16px;
	--space-5: 20px;
	--space-6: 24px;
	--space-8: 32px;
	--space-10: 40px;
	--space-12: 48px;
	--space-16: 64px;
	--space-20: 80px;
	--space-24: 96px;

	/* -------------------------------------------------------------------
	 * Radius
	 * ------------------------------------------------------------------- */
	--radius-xs: 4px;
	--radius-sm: 6px;
	--radius-md: 8px; /* inputs, buttons */
	--radius-lg: 12px; /* cards */
	--radius-xl: 16px; /* modals, KPI cards */
	--radius-2xl: 20px;
	--radius-full: 9999px; /* avatars, badges */

	/* -------------------------------------------------------------------
	 * Elevation — the 3D belongs to the logo, not to the application
	 * ------------------------------------------------------------------- */
	--shadow-xs: 0 1px 2px rgba(16, 24, 40, 0.05);
	--shadow-sm: 0 1px 3px rgba(16, 24, 40, 0.08),
		0 1px 2px rgba(16, 24, 40, 0.04);
	--shadow-md: 0 4px 12px rgba(16, 24, 40, 0.08);
	--shadow-lg: 0 12px 30px rgba(16, 24, 40, 0.1);
	--focus-ring: 0 0 0 3px rgba(1, 100, 201, 0.12);
	--focus-ring-danger: 0 0 0 3px rgba(217, 45, 32, 0.12);

	/* -------------------------------------------------------------------
	 * Layout
	 * ------------------------------------------------------------------- */
	--sidebar-width: 260px;
	--sidebar-collapsed: 72px;
	--topbar-height: 64px;
	--control-height: 44px; /* buttons and controls */
	--control-height-sm: 36px; /* dense tables only */
	/* WCAG 2.2 SC 2.5.8 (AA) asks for 24x24 CSS px; 44x44 is SC 2.5.5, which
	 * is AAA. The brand manual asks for 44 "where possible", so 44 is the
	 * default and 24 is the floor nothing may go under. */
	--touch-target-min: 24px;
	--touch-target-comfortable: 44px;
	--content-max: 1440px;
	--rail-width: 360px; /* optional right rail: activity, quick detail, AI */

	/* -------------------------------------------------------------------
	 * Motion
	 * ------------------------------------------------------------------- */
	--ease-out: cubic-bezier(0.16, 1, 0.3, 1);
	--duration-fast: 150ms;
	--duration-base: 200ms;
	--duration-slow: 250ms;
	/* Per interaction, because "150-250ms" is not one number: a press that
	 * takes as long as a drawer feels broken. */
	--duration-hover: 140ms;
	--duration-press: 100ms;
	--duration-drawer: 220ms;
	--duration-toast: 200ms;
	--duration-progress: 320ms;
	--duration-skeleton: 1400ms;

	/* Breakpoints. Declared for documentation and for JS that has to agree
	 * with the CSS; a media query cannot read a custom property. */
	--bp-sm: 640px;
	--bp-md: 768px;
	--bp-lg: 1024px;
	--bp-xl: 1280px;
	--bp-2xl: 1536px;

	/* -------------------------------------------------------------------
	 * Functional domains (§32). One family, not a rainbow.
	 * ------------------------------------------------------------------- */
	--domain-core: var(--philentia-blue-600);
	--domain-finance: var(--philentia-navy);
	--domain-fundraising: var(--impact-green-600);
	--domain-campaigns: var(--philentia-blue-500);
	--domain-grants: var(--philentia-blue-700);
	--domain-programs: var(--philentia-blue-600);
	--domain-impact: var(--impact-green-600);
	--domain-compliance: var(--philentia-navy);
	--domain-sites: var(--philentia-blue-500);

	/* Charts. Four series before anything repeats; a fifth category is a sign
	 * the chart should be a table. */
	--chart-actual: var(--philentia-blue-600);
	--chart-target: var(--philentia-blue-200);
	--chart-positive: var(--impact-green-600);
	--chart-negative: var(--danger-fill);
	--chart-neutral: var(--neutral-400);
	--chart-grid: var(--neutral-200);
}

/* ---------------------------------------------------------------------------
 * Dark mode (§47) — prepared, not yet the default.
 *
 * Frappe switches themes with `data-theme` on <html>; `prefers-color-scheme`
 * is honoured only when the user has not chosen. Both are handled, and the
 * explicit choice always wins over the system.
 * --------------------------------------------------------------------------- */
@media (prefers-color-scheme: dark) {
	:root:not([data-theme="light"]) {
		--surface: #101828;
		--surface-secondary: #0b1220;
		--surface-tertiary: #1d2939;
		--surface-inverse: #0b1220;

		--text-primary: #f2f4f7;
		--text-secondary: #d0d5dd;
		--text-muted: #98a2b3;
		--text-link: var(--philentia-blue-200);

		--border: #344054;
		--border-strong: #475467;

		/* Saturated brand colour on a dark ground reads as glare. The blue is
		 * lifted, not brightened, so it stays the same colour. */
		--brand-primary: var(--philentia-blue-500);
		--brand-primary-hover: var(--philentia-blue-200);

		--success-text: #7ccf2c;
		--warning-text: #fedf89;
		--danger-text: #fecdca;
		--info-text: var(--philentia-blue-200);

		--success-bg: rgba(61, 161, 36, 0.14);
		--warning-bg: rgba(247, 144, 9, 0.14);
		--danger-bg: rgba(217, 45, 32, 0.14);
		--info-bg: rgba(3, 139, 239, 0.14);
		--muted-bg: rgba(152, 162, 179, 0.12);

		--shadow-xs: 0 1px 2px rgba(0, 0, 0, 0.4);
		--shadow-sm: 0 1px 3px rgba(0, 0, 0, 0.45);
		--shadow-md: 0 4px 12px rgba(0, 0, 0, 0.5);
		--shadow-lg: 0 12px 30px rgba(0, 0, 0, 0.55);
	}
}

:root[data-theme="dark"] {
	--surface: #101828;
	--surface-secondary: #0b1220;
	--surface-tertiary: #1d2939;
	--surface-inverse: #0b1220;

	--text-primary: #f2f4f7;
	--text-secondary: #d0d5dd;
	--text-muted: #98a2b3;
	--text-link: var(--philentia-blue-200);

	--border: #344054;
	--border-strong: #475467;

	--brand-primary: var(--philentia-blue-500);
	--brand-primary-hover: var(--philentia-blue-200);

	--success-text: #7ccf2c;
	--warning-text: #fedf89;
	--danger-text: #fecdca;
	--info-text: var(--philentia-blue-200);

	--success-bg: rgba(61, 161, 36, 0.14);
	--warning-bg: rgba(247, 144, 9, 0.14);
	--danger-bg: rgba(217, 45, 32, 0.14);
	--info-bg: rgba(3, 139, 239, 0.14);
	--muted-bg: rgba(152, 162, 179, 0.12);

	--shadow-xs: 0 1px 2px rgba(0, 0, 0, 0.4);
	--shadow-sm: 0 1px 3px rgba(0, 0, 0, 0.45);
	--shadow-md: 0 4px 12px rgba(0, 0, 0, 0.5);
	--shadow-lg: 0 12px 30px rgba(0, 0, 0, 0.55);
}

/* ---------------------------------------------------------------------------
 * Motion preference. 150–250ms is comfortable; for somebody who gets motion
 * sick it is not, and this is part of AA.
 * --------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
	:root {
		--duration-fast: 0ms;
		--duration-base: 0ms;
		--duration-slow: 0ms;
	}
}
