/*
 * layout.css — header, primary nav + mega menu, mobile drawer, footer,
 * grid system. Component visuals (buttons, cards) live in components.css;
 * this file is strictly about positioning and structure.
 */

/* ---------------------------------------------------------------
 * Grid
 * ------------------------------------------------------------- */
.grid { display: grid; gap: var(--space-m); }
.grid--2 { grid-template-columns: repeat(2, 1fr); }
.grid--3 { grid-template-columns: repeat(3, 1fr); }
.grid--4 { grid-template-columns: repeat(4, 1fr); }
.grid--auto { grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); }
@media (max-width: 980px) {
	.grid--3, .grid--4 { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 640px) {
	.grid--2, .grid--3, .grid--4 { grid-template-columns: 1fr; }
}

.split {
	display: grid;
	grid-template-columns: 1.1fr 0.9fr;
	gap: var(--space-xl);
	align-items: center;
}
.split--reverse { grid-template-columns: 0.9fr 1.1fr; }
.split--reverse > :first-child { order: 2; }
@media (max-width: 900px) {
	.split, .split--reverse { grid-template-columns: 1fr; }
	.split--reverse > :first-child { order: 0; }
}

/* ---------------------------------------------------------------
 * Site header
 * ------------------------------------------------------------- */
.site-header {
	position: sticky;
	top: 0;
	z-index: 100;
	height: var(--header-h);
	display: flex;
	align-items: center;
	background: rgba(var(--brand-rgb), 0);
	backdrop-filter: blur(0px);
	transition: height var(--dur-base) var(--ease), background-color var(--dur-base) var(--ease), box-shadow var(--dur-base) var(--ease), backdrop-filter var(--dur-base) var(--ease);
}
.site-header::after {
	content: "";
	position: absolute;
	inset: 0;
	background: var(--surface);
	opacity: 0;
	transition: opacity var(--dur-base) var(--ease);
	z-index: -1;
	border-bottom: 1px solid transparent;
}
.site-header.is-scrolled {
	height: calc(var(--header-h) - 14px);
	box-shadow: var(--shadow-s);
}
.site-header.is-scrolled::after {
	opacity: .92;
	backdrop-filter: blur(14px);
	border-bottom-color: var(--border);
}
.site-header__inner {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: var(--space-m);
	width: 100%;
}
.logo { display: inline-flex; align-items: center; }
.logo img {
	display: block;
	height: 34px;
	width: auto;
	transition: filter var(--dur-base) var(--ease);
}

/*
 * logo.png carries a black wordmark, and every template opens with a
 * dark band — .hero and .page-header are both --navy — under a header
 * that is transparent until you scroll. Left alone the wordmark simply
 * disappears there.
 *
 * brightness(0) invert(1) flattens the whole lockup to solid white,
 * which reads as an intentional monochrome treatment rather than a
 * broken asset; the full-colour logo returns the moment the header
 * gains its own background. Drop a pre-made light asset in as
 * logo-light.png and this can be swapped for a <picture> instead.
 */
/* .site-header:not(.is-scrolled) .logo--image img,
.site-footer .logo--image img {
	filter: brightness(0) invert(1);
} */

/* Scrolled header and drawer both sit on --surface, which is dark in
   dark mode — so the inversion has to persist there too. */
[data-theme="dark"] .site-header .logo--image img,
[data-theme="dark"] .mobile-drawer .logo--image img {
	filter: brightness(0) invert(1);
}
@media (prefers-color-scheme: dark) {
	:root:not([data-theme="light"]) .site-header .logo--image img,
	:root:not([data-theme="light"]) .mobile-drawer .logo--image img {
		filter: brightness(0) invert(1);
	}
}

/* ---------------------------------------------------------------
 * Primary nav + mega menu
 * ------------------------------------------------------------- */
.primary-nav { display: flex; }
.primary-nav .menu {
	display: flex;
	align-items: center;
	gap: var(--space-2xs);
}
.primary-nav .menu-item { position: relative; }
.primary-nav .menu-link {
	display: flex;
	align-items: center;
	gap: 0.35em;
	padding: 0.6em 0.9em;
	font-size: var(--text-s);
	font-weight: 500;
	color: var(--ink-soft);
	border-radius: var(--radius-full);
	transition: color var(--dur-fast) var(--ease), background-color var(--dur-fast) var(--ease);
}
.primary-nav .menu-link:hover,
.primary-nav .current-menu-item > .menu-link { color: var(--brand-text); background: var(--brand-light); }
.menu-link__caret { width: 14px; height: 14px; transition: transform var(--dur-fast) var(--ease); }
.menu-item--parent:hover .menu-link__caret { transform: rotate(180deg); }

/*
 * The panel sits 6px below the trigger. That gap belongs to neither
 * element, so crossing it drops :hover and the menu closes under the
 * cursor. This bridges it — but only while the item is already open,
 * so it can never be what opens the menu in the first place.
 */
.menu-item--parent:hover::after,
.menu-item--parent:focus-within::after {
	content: "";
	position: absolute;
	left: 0;
	right: 0;
	top: 100%;
	height: 16px;
}

.primary-nav .sub-menu {
	position: absolute;
	top: 100%;
	left: 0;
	min-width: 240px;
	background: var(--surface);
	border: 1px solid var(--border);
	border-radius: var(--radius-m);
	box-shadow: var(--shadow-l);
	padding: var(--space-2xs);
	opacity: 0;
	visibility: hidden;
	transform: translateY(6px);
	transition: opacity var(--dur-fast) var(--ease-out), transform var(--dur-fast) var(--ease-out), visibility var(--dur-fast);
}
.menu-item--parent:not(.menu-item--mega):hover > .sub-menu,
.menu-item--parent:not(.menu-item--mega):focus-within > .sub-menu {
	opacity: 1; visibility: visible; pointer-events: auto; transform: translateY(8px);
}
/*
 * Only top-level dropdowns are switched off while closed. Scoping by
 * direct descent deliberately excludes the list nested inside the mega
 * panel, which instead inherits pointer-events from .mega-panel — none
 * while closed, auto once open. Setting pointer-events:auto on that
 * nested list directly would let it opt back in through its own closed
 * parent, leaving an invisible 920x400 hit target over the hero.
 */
.primary-nav .menu > .menu-item > .sub-menu { pointer-events: none; }

.primary-nav .sub-menu .menu-link { border-radius: var(--radius-s); padding: 0.65em 0.85em; }

.primary-nav .mega-panel {
	position: absolute;
	top: 100%;
	left: 50%;
	transform: translate(-50%, 6px);
	width: min(920px, 88vw);
	background: var(--surface);
	border: 1px solid var(--border);
	border-radius: var(--radius-l);
	box-shadow: var(--shadow-l);
	padding: var(--space-m);
	display: grid;
	grid-template-columns: 220px 1fr;
	gap: var(--space-m);
	opacity: 0;
	visibility: hidden;
	pointer-events: none;
	transition: opacity var(--dur-fast) var(--ease-out), transform var(--dur-fast) var(--ease-out), visibility var(--dur-fast);
}
.primary-nav .menu-item--mega:hover .mega-panel,
.primary-nav .menu-item--mega:focus-within .mega-panel {
	opacity: 1; visibility: visible; pointer-events: auto; transform: translate(-50%, 10px);
}
.mega-panel__promo {
	background: var(--surface-alt);
	border-radius: var(--radius-m);
	padding: var(--space-m);
	display: flex;
	flex-direction: column;
	justify-content: space-between;
	gap: var(--space-m);
}
/* Every other eyebrow on the site is IBM Plex Mono; this one was the
   only one set in the body face, which broke the convention. */
.mega-panel__eyebrow { font-family: var(--font-mono); font-size: .6875rem; font-weight: 500; color: var(--brand-text); text-transform: uppercase; letter-spacing: .14em; }
.mega-panel__text { font-size: var(--text-s); }
.mega-panel__link { display: inline-flex; align-items: center; gap: .4em; font-weight: 600; color: var(--brand-text); font-size: var(--text-s); }
.mega-panel__link .icon { width: 16px; height: 16px; transition: transform var(--dur-fast) var(--ease-out); }
.mega-panel__link:hover .icon { transform: translate(3px, -3px); }
.mega-panel__groups { align-content: start; }
.mega-panel__groups .sub-menu {
	/* The walker emits one <ul> holding all the service <li>s — a grid
	   on the wrapper here would only ever see that single child, so the
	   2-column layout has to live on the list itself via multi-column
	   flow, which distributes the <li> children directly. */
	position: static; opacity: 1; visibility: visible; transform: none;
	background: none; border: 0; box-shadow: none; padding: 0;
	display: block;
	columns: 2;
	column-gap: var(--space-m);
}
.mega-panel__groups .sub-menu .menu-item {
	break-inside: avoid;
}
.mega-panel__groups .sub-menu .menu-link {
	padding-block: 0.55em;
}

/* ---------------------------------------------------------------
 * Header actions + mobile menu toggle
 * ------------------------------------------------------------- */
.site-header__actions { display: flex; align-items: center; gap: var(--space-xs); }
/* Element-qualified so this beats .btn's own `display: inline-flex`
   (components.css loads after layout.css, and .header-cta plus .btn
   share the same class-selector specificity, so source order would
   otherwise let .btn win and show the button below the breakpoint). */
a.header-cta { display: none; }
@media (min-width: 1081px) { a.header-cta { display: inline-flex; } }

.menu-toggle {
	display: none;
	width: 42px; height: 42px;
	align-items: center;
	justify-content: center;
	border-radius: var(--radius-s);
	color: var(--ink);
}
.menu-toggle .icon { width: 22px; height: 22px; }
.menu-toggle .icon-close { display: none; }
html.nav-open .menu-toggle .icon-menu { display: none; }
html.nav-open .menu-toggle .icon-close { display: block; }
@media (max-width: 1080px) {
	.primary-nav { display: none; }
	.menu-toggle { display: inline-flex; }
}

/* ---------------------------------------------------------------
 * Mobile drawer
 * ------------------------------------------------------------- */
.mobile-drawer {
	position: fixed;
	inset: 0;
	z-index: 200;
	visibility: hidden;
}
.mobile-drawer__backdrop {
	position: absolute; inset: 0;
	background: rgba(6, 13, 24, .55);
	opacity: 0;
	transition: opacity var(--dur-base) var(--ease);
}
.mobile-drawer__panel {
	position: absolute;
	top: 0; right: 0; bottom: 0;
	width: min(380px, 86vw);
	background: var(--surface);
	padding: var(--space-m);
	overflow-y: auto;
	transform: translateX(100%);
	transition: transform var(--dur-base) var(--ease-out);
	display: flex;
	flex-direction: column;
	gap: var(--space-m);
}
html.nav-open .mobile-drawer { visibility: visible; }
html.nav-open .mobile-drawer__backdrop { opacity: 1; }
html.nav-open .mobile-drawer__panel { transform: translateX(0); }
html.nav-open { overflow: hidden; }

.mobile-drawer__head { display: flex; align-items: center; justify-content: space-between; }
.mobile-drawer__close { width: 40px; height: 40px; display: inline-flex; align-items: center; justify-content: center; border-radius: var(--radius-s); background: var(--surface-alt); }
.mobile-drawer__close .icon { width: 20px; height: 20px; }

.mobile-menu { display: flex; flex-direction: column; }
.mobile-menu .menu-item { border-bottom: 1px solid var(--border-soft); }
.mobile-menu .menu-link { display: flex; align-items: center; justify-content: space-between; padding: .95em 0.1em; font-size: var(--text-l); font-weight: 600; border-radius: 0; }
.mobile-menu .sub-menu { display: none; padding-bottom: var(--space-xs); }
.mobile-menu .menu-item--parent.is-expanded .sub-menu { display: block; }
.mobile-menu .menu-item--parent.is-expanded .menu-link__caret { transform: rotate(180deg); }
.mobile-menu .sub-menu .menu-link { font-size: var(--text-m); font-weight: 500; color: var(--muted); padding-left: var(--space-s); }

/* ---------------------------------------------------------------
 * Mega panel inside the mobile drawer.
 *
 * The walker emits identical markup for both menus, so tapping
 * "Services" in the drawer was opening the desktop mega panel — which
 * is position:absolute, 920px wide and anchored to the viewport centre,
 * so it landed entirely off-screen.
 *
 * Inside the drawer it is stripped back to a plain stacked list and
 * gated by the same .is-expanded class the accordion already toggles.
 * These rules sit after the .mobile-menu block above so they win on
 * source order rather than needing extra specificity.
 * ------------------------------------------------------------- */
.mobile-menu .mega-panel {
	display: none;
	position: static;
	width: auto;
	min-width: 0;
	transform: none;
	opacity: 1;
	visibility: visible;
	pointer-events: auto;
	background: none;
	border: 0;
	border-radius: 0;
	box-shadow: none;
	backdrop-filter: none;
	-webkit-backdrop-filter: none;
	padding: 0 0 var(--space-xs);
	grid-template-columns: 1fr;
	gap: 0;
}
.mobile-menu .menu-item--parent.is-expanded .mega-panel { display: block; }

/* The promo card is a desktop affordance — in a narrow drawer it just
   pushes the actual service links below the fold. */
.mobile-menu .mega-panel__promo { display: none; }

/* One column here: two would give each link about 140px and wrap most
   of the service names. */
.mobile-menu .mega-panel__groups .sub-menu {
	columns: 1;
	display: flex;
	flex-direction: column;
	gap: 0;
	padding: 0;
	background: none;
	border: 0;
	box-shadow: none;
}
.mobile-menu .mega-panel__groups .menu-item { border-bottom: 0; }
.mobile-menu .mega-panel__groups .menu-link {
	font-size: var(--text-m);
	font-weight: 500;
	color: var(--muted);
	padding: .55em 0 .55em var(--space-s);
}
.mobile-menu .mega-panel__groups .menu-link:hover { color: var(--brand-text); }

.mobile-drawer__foot { margin-top: auto; display: flex; flex-direction: column; gap: var(--space-s); padding-top: var(--space-m); border-top: 1px solid var(--border-soft); }
.mobile-drawer__socials { display: flex; gap: var(--space-2xs); }

/* ---------------------------------------------------------------
 * Footer
 * ------------------------------------------------------------- */
.site-footer {
	background: var(--navy);
	color: rgba(255,255,255,.7);
	padding-top: var(--space-xl);
	position: relative;
	overflow: hidden;
}
.site-footer a { color: rgba(255,255,255,.7); transition: color var(--dur-fast) var(--ease); }
.site-footer a:hover { color: #fff; }
.site-footer h4 {
	color: #fff;
	font-family: var(--font-mono);
	font-size: .6875rem;
	font-weight: 500;
	text-transform: uppercase;
	letter-spacing: .14em;
	margin-bottom: var(--space-s);
}

/* Services gets the widest track because it carries thirteen links in
   two sub-columns; everything else is sized to its longest label so no
   link has to wrap. */
.footer-grid {
	display: grid;
	grid-template-columns: 1fr 2.1fr 0.85fr 0.85fr 1fr;
	gap: var(--space-m) var(--space-l);
	padding-bottom: var(--space-l);
	border-bottom: 1px solid var(--navy-line);
}
@media (max-width: 1100px) {
	.footer-grid { grid-template-columns: 1.2fr 2fr 1fr; }
}
@media (max-width: 820px) {
	.footer-grid { grid-template-columns: repeat(2, 1fr); }
	.footer-col--services { grid-column: 1 / -1; }
}
@media (max-width: 560px) {
	.footer-grid { grid-template-columns: 1fr; }
	/* Services keeps two columns even here: the short labels fit ~160px
	   comfortably, and collapsing to one stacks thirteen rows and adds
	   about 250px to the footer on a phone. */
}

/* On navy. Without an explicit colour the base p rule applied --muted
   (#5A6B80), which is 3.18:1 here; this matches the other footer copy. */
.footer-brand__desc { max-width: 320px; margin-top: var(--space-s); font-size: var(--text-s); color: rgba(255,255,255,.7); }
.footer-brand__socials { display: flex; gap: var(--space-2xs); margin-top: var(--space-m); }

/* Belt and braces on the bullets: the reset in base.css keys off
   ul[class], and these lists only carry a class because items_wrap adds
   one — stating it here means a future markup change can't bring the
   bullets back. */
.footer-col ul {
	list-style: none;
	padding: 0;
	margin: 0;
	display: flex;
	flex-direction: column;
	gap: 6px;
}
.footer-col li { margin: 0; }
.footer-col a {
	font-size: var(--text-s);
	line-height: 1.45;
	display: inline-block;
}

/* The services list runs to 13 links — flowing it into two columns
   keeps this column roughly the same height as its neighbors instead
   of towering over Company/Legal. */
.footer-col--services ul {
	display: block;
	columns: 2;
	column-gap: var(--space-l);
}
.footer-col--services li {
	break-inside: avoid;
	margin-bottom: var(--space-2xs);
}

.footer-contact li { display: flex; align-items: flex-start; gap: .6em; font-size: var(--text-s); margin-bottom: var(--space-2xs); }
.footer-contact .icon { width: 17px; height: 17px; flex-shrink: 0; margin-top: 0.2em; color: var(--brand-on-dark); }

.footer-bottom {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: var(--space-s);
	padding-block: var(--space-m);
	font-size: var(--text-xs);
	flex-wrap: wrap;
}
.footer-bottom__legal { display: flex; gap: var(--space-s); flex-wrap: wrap; }

.footer-glow {
	position: absolute;
	top: -120px; right: -120px;
	width: 420px; height: 420px;
	background: radial-gradient(circle, rgba(var(--brand-rgb),.35), transparent 70%);
	filter: blur(20px);
	pointer-events: none;
}

/* ---------------------------------------------------------------
 * WhatsApp float
 * ------------------------------------------------------------- */
.whatsapp-float {
	position: fixed;
	right: var(--space-m);
	bottom: var(--space-m);
	z-index: 90;
	width: 58px; height: 58px;
	display: inline-flex; align-items: center; justify-content: center;
	background: #25D366;
	border-radius: 50%;
	box-shadow: var(--shadow-l);
	color: #fff;
}
.whatsapp-float__icon { width: 28px; height: 28px; }
