/* ==========================================================================
   base.css — self-hosted faces, light reset, typography, focus states.
   Consumes tokens.css. Defines no raw values of its own.
   ========================================================================== */

/* ------------------------------------------------------------------ fonts */
/* Self-hosted per CLAUDE.md — no Google Fonts CDN. SIL OFL 1.1, licence text
   bundled at assets/fonts/OFL.txt. font-display: swap so text paints on the
   fallback rather than waiting.

   600 and 700 were added 2026-09-09. The system had only 400 and 500, which is why
   every heading read as large body copy: Poppins at 500 has no authority at display
   size. Weight contrast is doing the work a second typeface would normally do, since
   the family itself is locked. */

@font-face {
	font-family: "Poppins";
	font-style: normal;
	font-weight: 400;
	font-display: swap;
	src: url("../fonts/poppins-400-latin.woff2") format("woff2");
	unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
		U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191,
		U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
	font-family: "Poppins";
	font-style: normal;
	font-weight: 400;
	font-display: swap;
	src: url("../fonts/poppins-400-latin-ext.woff2") format("woff2");
	unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF,
		U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020,
		U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
	font-family: "Poppins";
	font-style: normal;
	font-weight: 500;
	font-display: swap;
	src: url("../fonts/poppins-500-latin.woff2") format("woff2");
	unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
		U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191,
		U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
	font-family: "Poppins";
	font-style: normal;
	font-weight: 500;
	font-display: swap;
	src: url("../fonts/poppins-500-latin-ext.woff2") format("woff2");
	unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF,
		U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020,
		U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
	font-family: "Poppins";
	font-style: normal;
	font-weight: 600;
	font-display: swap;
	src: url("../fonts/poppins-600-latin.woff2") format("woff2");
	unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
		U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191,
		U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
	font-family: "Poppins";
	font-style: normal;
	font-weight: 600;
	font-display: swap;
	src: url("../fonts/poppins-600-latin-ext.woff2") format("woff2");
	unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF,
		U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020,
		U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
	font-family: "Poppins";
	font-style: normal;
	font-weight: 700;
	font-display: swap;
	src: url("../fonts/poppins-700-latin.woff2") format("woff2");
	unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
		U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191,
		U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
	font-family: "Poppins";
	font-style: normal;
	font-weight: 700;
	font-display: swap;
	src: url("../fonts/poppins-700-latin-ext.woff2") format("woff2");
	unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF,
		U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020,
		U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}


/* ------------------------------------------------------------------ reset */
/* Deliberately small. The parent theme and Elementor both ship their own resets
   and fighting them is a losing game; this only covers what the design depends on. */

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

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

/* ------------------------------------------------------------- typography */

body {
	font-family: var(--font-body);
	font-size: var(--text-body-lg);
	font-weight: var(--font-weight-regular);
	line-height: var(--text-body-lg-lh);
	color: var(--color-text-body);
	background-color: var(--color-surface-page);
	-webkit-font-smoothing: antialiased;
	-moz-osx-font-smoothing: grayscale;
}

h1,
h2,
h3,
h4 {
	font-family: var(--font-heading);
	font-weight: var(--font-weight-semibold);
	color: var(--color-text-heading);
	margin: 0;
	/* Headlines here are short and set large. Balance stops a two-line headline
	   leaving one orphaned word, which the old 60px h2 did constantly:
	   "Why GNT / Associates?". */
	text-wrap: balance;
}

p {
	margin: 0;
	max-width: var(--measure);
}

/* THE THIRD UPSTREAM RULE THAT TAKES AN ELEMENT OFF YOU.
   CLAUDE.md names two; this is a third. hello-elementor/assets/css/reset.css carries
   `a{color:#c36}` -- a magenta -- so ANY link this stylesheet does not colour renders
   in it. Measured across all fifteen pages on 2026-09-10: sixteen links fell through,
   fifteen of them the header logo anchor (an image, so invisible) and one the phone
   number on /contact/, which was rendering magenta in the middle of a paragraph.

   Scoped to unclassed links inside <main> rather than a bare `a`, deliberately. A bare
   rule would also underline the nav, which relies on reset.css's text-decoration:none
   and loads before us; and every button, nav item and footer link already carries a
   class, so this cannot reach them. It does catch anything the client adds later in an
   Elementor text widget, which is where the next one would have come from.

   The underline is not decoration. #0000CD against the #0a1f33 body ink is 1.508:1,
   far below the 3:1 that WCAG 1.4.1 requires before colour alone may distinguish a
   link, so the underline is what actually makes it a link. */
#gnt-main a:not( [class] ) {
	color: var(--color-brand-primary);
	text-decoration: underline;
	text-decoration-thickness: 1px;
	text-underline-offset: 0.2em;
}

/* Prose links only. Buttons must not pick this up, which is why it is scoped
   rather than set on a bare `a`. */
.gnt-prose a,
.gnt-footer__about a {
	color: currentcolor;
	text-decoration-thickness: 1px;
	text-underline-offset: 0.2em;
}

/* --------------------------------------------------------------- skip link */
/* Visible only on focus. The header is three tiers plus a six-item nav, which is a
   lot to tab through on every page. */

.gnt-skip-link {
	position: absolute;
	left: var(--space-4);
	top: var(--space-4);
	z-index: 999;
	padding: var(--space-3) var(--space-5);
	font-family: var(--font-body);
	font-size: var(--text-body);
	font-weight: var(--font-weight-semibold);
	color: var(--color-text-inverse);
	background-color: var(--blue-600);
	border-radius: var(--radius-sm);
	transform: translateY(-200%);
}

.gnt-skip-link:focus { transform: translateY(0); }

/* ------------------------------------------------------------ focus states */
/* CLAUDE.md quality floor: visible keyboard focus, unannounced.
   :focus-visible only, so a mouse click does not leave a ring behind. */

:focus-visible {
	outline: 3px solid var(--color-state-focus);
	outline-offset: 3px;
	border-radius: var(--border-width-thin);
}

/* NOTE, 2026-09-09: hello-elementor/assets/css/reset.css carries
   button,input,select,textarea:focus-visible{box-shadow:0 0 0 4px #fff;outline:2px solid #000}
   at 0,1,1, which beats the bare :focus-visible above at 0,1,0. So native form controls
   on light surfaces focus with its black ring rather than ours. Left alone on purpose:
   black on white is 21:1 and its white box-shadow survives a coloured ground, so
   overriding it would be a preference, not a fix. The rule below is 0,2,0 and still
   wins on dark surfaces, which is the case that actually matters. Elementor's button
   renders an <a>, not a <button>, so it is unaffected. See docs/ENVIRONMENT.md. */

/* #004afc on the brand navy is 1.87:1, so every dark ground inverts to white. */
.gnt-section--dark :focus-visible,
.gnt-hero :focus-visible,
.gnt-cta :focus-visible,
.gnt-footer :focus-visible {
	outline-color: var(--color-state-focus-inverse);
}

/* --------------------------------------------------------------- motion */

/* !important is load-bearing here and a higher-specificity selector will not do.
   Page builders emit transition and animation declarations INLINE, into the element's
   style attribute. Divi did it under #et-boc .et-l .et_pb_module; Elementor does it
   on .elementor-element and in its per-post stylesheets under
   wp-content/uploads/elementor/css/. Inline styles cannot be beaten by specificity at
   all, only by !important.

   Tried first, under Divi: #et-boc .et-l * and body.et-db * — both lose to the style
   attribute. That is why this rule reaches for the universal selector rather than
   naming a builder, and it is why it survived the move to Elementor unchanged.

   Honouring prefers-reduced-motion is a hard accessibility requirement, so this is
   the one place the escape hatch is correct. */
@media (prefers-reduced-motion: reduce) {
	*,
	*::before,
	*::after {
		animation-duration: 0.01ms !important;   /* stylelint-disable-line declaration-no-important */
		animation-iteration-count: 1 !important; /* stylelint-disable-line declaration-no-important */
		transition-duration: 0.01ms !important;  /* stylelint-disable-line declaration-no-important */
		scroll-behavior: auto !important;        /* stylelint-disable-line declaration-no-important */
	}
}
