/* ============================================================
   NetraClos design system, hand coded. v1.0 (2026-07-26)
   Scoped under .ncx so nothing leaks into the Porto header,
   menu or footer while the rest of the site is still Porto.
   Palette is shared with NetraClouds on purpose.
   ============================================================ */

.ncx {
	--clos-navy: #16265C;
	--clos-navy-deep: #0E1A40;
	--clos-g1: #F4772E;
	--clos-g2: #ED3A5F;
	--clos-g3: #C81E1E;
	--clos-ink: #1B2440;
	--clos-body: #4A5570;
	--clos-line: #E4E8F0;
	--clos-tint: #F6F8FC;
	--clos-grad: linear-gradient(100deg, var(--clos-g1) 0%, var(--clos-g2) 52%, var(--clos-g3) 100%);
	--clos-wrap: 1200px;

	/* NOTE: --ncx-sb (scrollbar width) is deliberately NOT declared here.
	   The template script sets it on :root, and a local declaration would
	   shadow it. Usage sites read it as var(--ncx-sb, 0px). */

	color: var(--clos-body);
	font-size: 16px;
	line-height: 1.7;
}

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

.ncx h1, .ncx h2, .ncx h3, .ncx h4 {
	color: var(--clos-ink);
	line-height: 1.18;
	margin: 0;
	font-weight: 700;
	letter-spacing: -0.01em;
}
.ncx p { margin: 0 0 16px; }
.ncx p:last-child { margin-bottom: 0; }
.ncx img { max-width: 100%; height: auto; display: block; }
.ncx a { text-decoration: none; }

.ncx-wrap {
	max-width: var(--clos-wrap);
	margin: 0 auto;
	padding: 0 24px;
	width: 100%;
}

/* full bleed out of whatever container Porto puts us in */
.ncx-bleed {
	width: calc(100vw - var(--ncx-sb, 0px));
	margin-left: calc(50% - 50vw + (var(--ncx-sb, 0px) / 2));
	margin-right: calc(50% - 50vw + (var(--ncx-sb, 0px) / 2));
}

/* ---- section rhythm: equal spacing everywhere ---- */
.ncx-sec { padding: 84px 0; }
.ncx-sec--tint { background: var(--clos-tint); }
.ncx-sec--navy { background: var(--clos-navy); }
.ncx-sec--navy h2,
.ncx-sec--navy h3 { color: #fff; }
.ncx-sec--navy p { color: rgba(255,255,255,.82); }

/* ---- shared bits ---- */
.ncx-eyebrow {
	display: inline-block;
	font-size: 12px;
	font-weight: 700;
	letter-spacing: .16em;
	text-transform: uppercase;
	margin-bottom: 14px;
	background: var(--clos-grad);
	-webkit-background-clip: text;
	background-clip: text;
	color: transparent;
}
.ncx-sec--navy .ncx-eyebrow {
	background: none;
	-webkit-text-fill-color: currentColor;
	color: #FF9B6A;
}

.ncx-underline { position: relative; padding-bottom: 16px; }
.ncx-underline::after {
	content: "";
	position: absolute;
	left: 0; bottom: 0;
	width: 68px; height: 4px;
	border-radius: 3px;
	background: var(--clos-grad);
}
.ncx-center { text-align: center; }
.ncx-center .ncx-underline::after { left: 50%; transform: translateX(-50%); }

.ncx-head { max-width: 760px; margin: 0 auto 52px; }
.ncx-head h2 { font-size: clamp(28px, 3.4vw, 40px); }
.ncx-head p { margin-top: 18px; font-size: 17px; }

/* ---- buttons ---- */
.ncx-btn {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: 10px;
	padding: 15px 32px;
	border-radius: 6px;
	font-weight: 700;
	font-size: 15px;
	letter-spacing: .01em;
	border: 2px solid transparent;
	transition: background .25s ease, color .25s ease, border-color .25s ease, transform .18s ease;
	cursor: pointer;
}
.ncx-btn--grad { background: var(--clos-grad); color: #fff; }
.ncx-btn--grad:hover { background: var(--clos-navy); color: #fff; transform: translateY(-2px); }
.ncx-btn--ghost { border-color: rgba(255,255,255,.6); color: #fff; background: transparent; }
.ncx-btn--ghost:hover { background: #fff; color: var(--clos-navy); border-color: #fff; }
.ncx-btn--outline { border-color: var(--clos-navy); color: var(--clos-navy); background: transparent; }
.ncx-btn--outline:hover { background: var(--clos-navy); color: #fff; }

/* ============ hero ============ */
.ncx-hero {
	position: relative;
	min-height: 620px;
	display: flex;
	align-items: center;
	background: var(--clos-navy-deep) var(--ncx-hero-img, none) center/cover no-repeat;
	padding: 96px 0;
}
.ncx-hero::before {
	content: "";
	position: absolute; inset: 0;
	background: linear-gradient(96deg, rgba(10,20,52,.94) 0%, rgba(14,26,64,.86) 42%, rgba(14,26,64,.42) 100%);
}
.ncx-hero .ncx-wrap { position: relative; z-index: 2; }
.ncx-hero-inner { max-width: 720px; }
.ncx-hero h1 {
	color: #fff;
	font-size: clamp(32px, 4.6vw, 54px);
	line-height: 1.1;
	margin-bottom: 22px;
}
.ncx-hero h1 .ncx-hl {
	background: var(--clos-grad);
	-webkit-background-clip: text;
	background-clip: text;
	color: transparent;
}
.ncx-hero p {
	color: rgba(255,255,255,.88);
	font-size: 18px;
	max-width: 620px;
	margin-bottom: 32px;
}
.ncx-hero-ctas { display: flex; flex-wrap: wrap; gap: 14px; }

/* ============ stats ============ */
.ncx-stats {
	display: grid;
	grid-template-columns: repeat(3, 1fr);
	gap: 0;
	background: #fff;
	border: 1px solid var(--clos-line);
	border-radius: 10px;
	overflow: hidden;
	box-shadow: 0 18px 46px rgba(22,38,92,.10);
	margin-top: -62px;
	position: relative;
	z-index: 5;
}
.ncx-stat { padding: 34px 26px; text-align: center; border-right: 1px solid var(--clos-line); }
.ncx-stat:last-child { border-right: 0; }
.ncx-stat-n {
	font-size: clamp(32px, 4vw, 44px);
	font-weight: 800;
	line-height: 1;
	background: var(--clos-grad);
	-webkit-background-clip: text;
	background-clip: text;
	color: transparent;
}
.ncx-stat-l {
	margin-top: 10px;
	font-size: 12px;
	font-weight: 700;
	letter-spacing: .14em;
	text-transform: uppercase;
	color: var(--clos-ink);
}

/* ============ service cards ============ */
.ncx-grid3 { display: grid; grid-template-columns: repeat(3, 1fr); gap: 26px; }
.ncx-grid4 { display: grid; grid-template-columns: repeat(4, 1fr); gap: 22px; }

.ncx-card {
	background: #fff;
	border: 1px solid var(--clos-line);
	border-radius: 10px;
	overflow: hidden;
	display: flex;
	flex-direction: column;
	transition: transform .25s ease, box-shadow .25s ease, border-color .25s ease;
}
.ncx-card:hover {
	transform: translateY(-5px);
	box-shadow: 0 20px 44px rgba(22,38,92,.14);
	border-color: transparent;
}
.ncx-card-img { position: relative; aspect-ratio: 11 / 7; overflow: hidden; background: var(--clos-tint); }
.ncx-card-img img { width: 100%; height: 100%; object-fit: cover; transition: transform .5s ease; }
.ncx-card:hover .ncx-card-img img { transform: scale(1.05); }
.ncx-card-body { padding: 24px 24px 26px; flex: 1; display: flex; flex-direction: column; }
.ncx-card h3 { font-size: 19px; margin-bottom: 10px; }
.ncx-card p { font-size: 15px; flex: 1; }
.ncx-card-more {
	margin-top: 16px;
	font-weight: 700;
	font-size: 14px;
	color: var(--clos-g2);
	display: inline-flex;
	align-items: center;
	gap: 7px;
}
.ncx-card-more::after { content: "\203A"; font-size: 19px; line-height: 1; transition: transform .2s ease; }
.ncx-card:hover .ncx-card-more::after { transform: translateX(4px); }

/* ============ split ============ */
.ncx-split {
	display: grid;
	grid-template-columns: 1fr 1fr;
	gap: 60px;
	align-items: center;
}
.ncx-split h2 { font-size: clamp(26px, 3.1vw, 36px); }
.ncx-split-img img { border-radius: 12px; box-shadow: 0 22px 52px rgba(22,38,92,.18); }
.ncx-split--rev .ncx-split-img { order: -1; }

.ncx-checks { list-style: none; padding: 0; margin: 24px 0 0; }
.ncx-checks li {
	position: relative;
	padding-left: 34px;
	margin-bottom: 13px;
	font-size: 15.5px;
}
.ncx-checks li::before {
	content: "";
	position: absolute;
	left: 0; top: 5px;
	width: 20px; height: 20px;
	border-radius: 50%;
	background: var(--clos-grad);
}
.ncx-checks li::after {
	content: "";
	position: absolute;
	left: 7px; top: 10px;
	width: 5px; height: 9px;
	border: solid #fff;
	border-width: 0 2px 2px 0;
	transform: rotate(45deg);
}
.ncx-sec--navy .ncx-checks li { color: rgba(255,255,255,.86); }

/* feature pills */
.ncx-pills { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 26px; }
.ncx-pill {
	font-size: 13.5px;
	font-weight: 600;
	padding: 8px 16px;
	border-radius: 40px;
	background: rgba(255,255,255,.09);
	border: 1px solid rgba(255,255,255,.2);
	color: rgba(255,255,255,.92);
}

/* ============ sector tiles ============ */
.ncx-tile {
	position: relative;
	border-radius: 10px;
	overflow: hidden;
	min-height: 250px;
	display: flex;
	align-items: flex-end;
}
.ncx-tile img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; transition: transform .5s ease; }
.ncx-tile::after {
	content: "";
	position: absolute; inset: 0;
	background: linear-gradient(to top, rgba(11,20,50,.92) 8%, rgba(11,20,50,.28) 62%, rgba(11,20,50,.06) 100%);
}
.ncx-tile:hover img { transform: scale(1.06); }
.ncx-tile-body { position: relative; z-index: 2; padding: 24px; }
.ncx-tile h3 { color: #fff; font-size: 18px; margin-bottom: 6px; }
.ncx-tile p { color: rgba(255,255,255,.8); font-size: 14px; margin: 0; }

/* ============ cta band ============ */
.ncx-cta { background: var(--clos-navy); padding: 66px 0; }
.ncx-cta-in {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 34px;
	flex-wrap: wrap;
}
.ncx-cta h2 { color: #fff; font-size: clamp(24px, 2.8vw, 32px); }
.ncx-cta p { color: rgba(255,255,255,.8); margin-top: 10px; }
.ncx-cta-btns { display: flex; gap: 14px; flex-wrap: wrap; }

/* ============ responsive ============ */
@media (max-width: 1024px) {
	.ncx-grid3 { grid-template-columns: repeat(2, 1fr); }
	.ncx-grid4 { grid-template-columns: repeat(2, 1fr); }
	.ncx-split { grid-template-columns: 1fr; gap: 38px; }
	.ncx-split--rev .ncx-split-img { order: 0; }
	.ncx-sec { padding: 68px 0; }
}

@media (max-width: 700px) {
	.ncx-grid3, .ncx-grid4 { grid-template-columns: 1fr; }
	.ncx-hero { min-height: 0; padding: 72px 0; }
	.ncx-stats { grid-template-columns: 1fr; margin-top: -34px; }
	.ncx-stat { border-right: 0; border-bottom: 1px solid var(--clos-line); padding: 26px 20px; }
	.ncx-stat:last-child { border-bottom: 0; }
	.ncx-sec { padding: 56px 0; }
	.ncx-head { margin-bottom: 38px; }
	.ncx-hero-ctas .ncx-btn,
	.ncx-cta-btns .ncx-btn { flex: 1 1 100%; }
	.ncx-cta-in { flex-direction: column; align-items: flex-start; }
}

@media (prefers-reduced-motion: reduce) {
	.ncx * { transition: none !important; animation: none !important; }
}

/* ============================================================
   v1.1 (2026-07-26) hero slider, 4 slides
   Owner asked for slides in the front banner, at least 4.
   Each slide carries its own background, cross faded.
   ============================================================ */

/* background layers sit under the wash, content sits above both */
.ncx-hero-bgs { position: absolute; inset: 0; z-index: 0; }
.ncx-hero-bg {
	position: absolute;
	inset: 0;
	background-image: var(--img);
	background-size: cover;
	background-position: center;
	opacity: 0;
	transition: opacity .9s ease;
}
.ncx-hero-bg.on { opacity: 1; }
.ncx-hero::before { z-index: 1; }
.ncx-hero .ncx-wrap { z-index: 2; }

/* slides stack in one grid cell, so the hero is as tall as the tallest slide
   and nothing jumps when they change */
.ncx-hero-slides { display: grid; }
.ncx-slide {
	grid-area: 1 / 1;
	opacity: 0;
	visibility: hidden;
	transform: translateY(12px);
	transition: opacity .55s ease, transform .55s ease, visibility .55s;
}
.ncx-slide.on { opacity: 1; visibility: visible; transform: none; }

/* the heading is an h1 on slide 1 only, the rest are divs styled to match,
   so the page keeps exactly one h1 */
.ncx-slide h1,
.ncx-slide .ncx-slide-h {
	color: #fff;
	font-size: clamp(32px, 4.6vw, 54px);
	line-height: 1.1;
	font-weight: 700;
	letter-spacing: -0.01em;
	margin: 0 0 22px;
}
.ncx-slide .ncx-hl {
	background: var(--clos-grad);
	-webkit-background-clip: text;
	background-clip: text;
	color: transparent;
}

.ncx-dots {
	display: flex;
	gap: 10px;
	margin: 4px 0 30px;
	padding: 0;
	list-style: none;
}
.ncx-dot {
	width: 34px;
	height: 4px;
	padding: 0;
	border: 0;
	border-radius: 3px;
	background: rgba(255,255,255,.34);
	cursor: pointer;
	transition: background .25s ease, width .25s ease;
}
.ncx-dot:hover { background: rgba(255,255,255,.6); }
.ncx-dot.on { background: var(--clos-grad); width: 54px; }
.ncx-dot:focus-visible { outline: 2px solid #fff; outline-offset: 4px; }

@media (max-width: 700px) {
	.ncx-dot { width: 26px; }
	.ncx-dot.on { width: 40px; }
	.ncx-dots { margin-bottom: 24px; }
}

/* no cross fade or auto advance for anyone who asked for less motion */
@media (prefers-reduced-motion: reduce) {
	.ncx-hero-bg, .ncx-slide { transition: none; }
}

/* ============================================================
   v1.2 (2026-07-26) Porto paints every <button> with its own
   orange (rgb(241,86,5)), which beat the .ncx-dot rule and made
   all four dots look active. Take it back explicitly.
   ============================================================ */
.ncx .ncx-dots .ncx-dot {
	background-color: rgba(255,255,255,.34) !important;
	background-image: none !important;
	box-shadow: none !important;
	border: 0 !important;
	border-radius: 3px !important;
	min-width: 0 !important;
	min-height: 0 !important;
	line-height: 0 !important;
}
.ncx .ncx-dots .ncx-dot:hover { background-color: rgba(255,255,255,.62) !important; }
.ncx .ncx-dots .ncx-dot.on {
	background-color: transparent !important;
	background-image: var(--clos-grad) !important;
}

/* ============================================================
   v1.3 (2026-07-26) delivery steps.
   Owner: NetraClos does project design, hardware procurement,
   installation and commissioning. Managed IT is NetraClouds.
   ============================================================ */
.ncx-steps {
	display: grid;
	grid-template-columns: repeat(4, 1fr);
	gap: 22px;
	margin-top: 44px;
}
.ncx-step {
	background: rgba(255,255,255,.06);
	border: 1px solid rgba(255,255,255,.14);
	border-radius: 10px;
	padding: 26px 22px 24px;
}
.ncx-step-n {
	font-size: 13px;
	font-weight: 800;
	letter-spacing: .14em;
	background: var(--clos-grad);
	-webkit-background-clip: text;
	background-clip: text;
	color: transparent;
	display: block;
	margin-bottom: 12px;
}
.ncx-step h3 { color: #fff; font-size: 17px; margin-bottom: 8px; }
.ncx-step p { color: rgba(255,255,255,.76); font-size: 14.5px; margin: 0; }

.ncx-note {
	margin-top: 34px;
	padding: 18px 22px;
	border-left: 3px solid var(--clos-g2);
	background: rgba(255,255,255,.05);
	border-radius: 0 8px 8px 0;
	font-size: 15px;
	color: rgba(255,255,255,.84);
}
.ncx-note a { color: #FF9B6A; text-decoration: underline; }

@media (max-width: 1024px) { .ncx-steps { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 620px)  { .ncx-steps { grid-template-columns: 1fr; } }

/* ============================================================
   v1.4 (2026-07-26) owner: slider markers as small circular dots
   instead of the wide pills. Needs the same !important as v1.2,
   since Porto also sets button geometry.
   ============================================================ */
.ncx .ncx-dots { gap: 12px; align-items: center; }

.ncx .ncx-dots .ncx-dot {
	width: 10px !important;
	height: 10px !important;
	border-radius: 50% !important;
	transition: background-color .25s ease, box-shadow .25s ease;
}
.ncx .ncx-dots .ncx-dot.on {
	width: 11px !important;
	height: 11px !important;
	box-shadow: 0 0 0 4px rgba(255,255,255,.16);
}

@media (max-width: 700px) {
	.ncx .ncx-dots { gap: 10px; }
	.ncx .ncx-dots .ncx-dot    { width: 9px !important;  height: 9px !important; }
	.ncx .ncx-dots .ncx-dot.on { width: 10px !important; height: 10px !important; }
}

/* ============================================================
   v1.5 (2026-07-26) owner: use the netraclouds.com colour scheme
   throughout, and no gradient on the banner text.
   Values below are lifted verbatim from netraclouds nc-design.css
   so the two sites match. Do not "improve" them.
   ============================================================ */
.ncx {
	--clos-navy: #16265C;   /* --nc-navy */
	--clos-ink: #0A1A30;    /* --nc-ink */
	--clos-body: #3D4C66;   /* --nc-body */
	--clos-muted: #7A8AA6;  /* --nc-muted */
	--clos-line: #E3E9F4;   /* --nc-line */
	--clos-tint: #F4F7FB;   /* --nc-bg-alt */
	--clos-accent: #E11D48; /* --nc-accent */
	--clos-accent-deep: #BE123C;
	--clos-black: #111318;
	--clos-grad: linear-gradient(135deg, #F4772E 0%, #ED3A5F 45%, #C81E1E 100%);
	--clos-radius: 14px;
	--clos-wrap: 1320px;
}

/* netraclouds headings are navy at weight 800, not near black at 700 */
.ncx h1, .ncx h2, .ncx h3, .ncx h4 { color: var(--clos-navy); font-weight: 800; line-height: 1.22; }
.ncx-sec--navy h2, .ncx-sec--navy h3, .ncx-hero h1 { color: #fff; }

/* match the netraclouds corner radius */
.ncx-card, .ncx-tile, .ncx-stats, .ncx-step { border-radius: var(--clos-radius); }
.ncx-split-img img { border-radius: var(--clos-radius); }

/* OWNER: no gradient on banner text. Headline stays plain white. */
.ncx-hero h1 .ncx-hl,
.ncx-slide .ncx-hl,
.ncx-slide h1 .ncx-hl {
	background: none !important;
	-webkit-background-clip: border-box !important;
	background-clip: border-box !important;
	-webkit-text-fill-color: #fff !important;
	color: #fff !important;
}

/* ============================================================
   v1.6 (2026-07-26) voice section: WebRTC + SMB + call centre,
   and a 10th service card, so the card grid must handle a last
   row that is not full. Flex wrap centres the orphan; CSS grid
   would leave it stranded on the left.
   ============================================================ */
.ncx-grid3 {
	display: flex;
	flex-wrap: wrap;
	justify-content: center;
	gap: 26px;
}
.ncx-grid3 > * {
	flex: 1 1 320px;
	max-width: 420px;
}

.ncx-feat {
	display: grid;
	grid-template-columns: repeat(3, 1fr);
	gap: 30px;
	align-items: start;
}
.ncx-feat-col {
	background: rgba(255,255,255,.06);
	border: 1px solid rgba(255,255,255,.14);
	border-radius: var(--clos-radius);
	padding: 30px 26px 32px;
}
.ncx-feat-col h3 { color: #fff; font-size: 19px; margin-bottom: 12px; }
.ncx-feat-col p { color: rgba(255,255,255,.78); font-size: 15px; }
.ncx-feat-col .ncx-checks { margin-top: 18px; }
.ncx-feat-col .ncx-checks li { font-size: 14.5px; color: rgba(255,255,255,.86); margin-bottom: 11px; }

.ncx-feat-img { margin-top: 40px; }
.ncx-feat-img img {
	width: 100%;
	border-radius: var(--clos-radius);
	box-shadow: 0 22px 52px rgba(0,0,0,.34);
}

@media (max-width: 1024px) { .ncx-feat { grid-template-columns: 1fr; gap: 22px; } }

/* ============================================================
   v1.7 (2026-07-26) the chosen slide 1 headline is long. At the
   old 54px it ran to four lines and pushed the body copy below
   the fold. Wider measure + smaller cap = two lines.
   ============================================================ */
.ncx-hero-inner { max-width: 880px; }
.ncx-hero { min-height: 660px; }

.ncx-slide h1,
.ncx-slide .ncx-slide-h {
	font-size: clamp(30px, 3.6vw, 46px);
	line-height: 1.14;
	margin-bottom: 20px;
}
.ncx-hero p { font-size: 17.5px; max-width: 660px; }

@media (max-width: 700px) {
	.ncx-slide h1,
	.ncx-slide .ncx-slide-h { font-size: clamp(26px, 7vw, 34px); }
	.ncx-hero { min-height: 0; }
}

/* ============================================================
   v1.8 (2026-07-26) Porto's header eats ~230px before the hero
   even starts, which pushed the CTAs off a laptop screen.
   Tighten the hero until we hand code a leaner header.
   ============================================================ */
.ncx-hero { min-height: 0; padding: 62px 0 56px; }
.ncx-hero p { margin-bottom: 24px; }
.ncx-dots { margin: 2px 0 22px; }

/* v1.9: the stats card overlaps the hero by -62px, so the hero needs
   enough bottom padding for that overlap to land in empty space
   instead of on top of the CTA buttons. */
.ncx-hero { padding: 62px 0 104px; }
@media (max-width: 700px) { .ncx-hero { padding: 48px 0 72px; } }

/* ============================================================
   v2.0 (2026-07-26) OWNER: no colour outside the brand palette.
   Audit found six invented values, all introduced by me:
     #FF9B6A  light orange, eyebrows on navy + the sister company link
     #0E1A40  a "deeper navy" that is not in the palette
     #1B2440 #4A5570 #E4E8F0 #F6F8FC  the original v1.0 tokens
     rgba(11,20,50) rgba(14,26,64) rgba(10,20,52)  overlay approximations
   Everything below is navy #16265C or ink #0A1A30, the brand blues.
   On navy backgrounds brand blue would be unreadable, so those use
   the brand gradient or white, which are still palette colours.
   ============================================================ */
.ncx {
	--clos-navy-deep: #0A1A30;   /* was #0E1A40 */
	--clos-ink: #0A1A30;         /* was #1B2440 */
	--clos-body: #3D4C66;        /* was #4A5570 */
	--clos-line: #E3E9F4;        /* was #E4E8F0 */
	--clos-tint: #F4F7FB;        /* was #F6F8FC */
}

/* eyebrow on navy: brand gradient, not the invented orange */
.ncx-sec--navy .ncx-eyebrow {
	background: var(--clos-grad);
	-webkit-background-clip: text;
	background-clip: text;
	-webkit-text-fill-color: transparent;
	color: transparent;
}

/* sister company link: white with a clear underline, gradient on hover */
.ncx-note { border-left-color: var(--clos-g2); }
.ncx-note a {
	color: #fff;
	text-decoration: underline;
	text-underline-offset: 3px;
	text-decoration-thickness: 2px;
	text-decoration-color: var(--clos-g2);
}
.ncx-note a:hover { text-decoration-color: #fff; }

/* hero wash: ink to navy, both brand blues */
.ncx-hero::before {
	background: linear-gradient(96deg,
		rgba(10,26,48,.94) 0%,
		rgba(22,38,92,.86) 42%,
		rgba(22,38,92,.42) 100%);
}

/* sector tile scrim: brand ink */
.ncx-tile::after {
	background: linear-gradient(to top,
		rgba(10,26,48,.92) 8%,
		rgba(10,26,48,.30) 62%,
		rgba(10,26,48,.06) 100%);
}

/* ============================================================
   v2.1 (2026-07-26) OWNER: take the blue from the netraclouds
   front page. Measured on the live site, not assumed:

     h2                     #14224F   (nc-design v2.16 override)
     h2 + p, section lead   #5D6C86
     h3                     #16265C   (--nc-navy)
     alt section background #F4F7FB
     footer gradient        #0A1A30 -> #14264A
     footer body text       #C9D4E8
     footer tagline         #DCE5F4
     footer muted           #9FB1CE

   The token is #16265C but netraclouds paints h2 #14224F, which is
   why the two sites did not match. Copy what renders, not the token.
   ============================================================ */
.ncx h2 { color: #14224F; letter-spacing: -0.4px; }
.ncx h1 { letter-spacing: -0.6px; }
.ncx h3 { color: #16265C; letter-spacing: -0.15px; font-weight: 700; }
.ncx-head p,
.ncx h2 + p { color: #5D6C86; }

/* dark sections keep white headings */
.ncx-sec--navy h2,
.ncx-sec--navy h3,
.ncx-cta h2,
.ncx-hero h1,
.ncx-feat-col h3,
.ncx-step h3,
.ncx-tile h3 { color: #fff; }
.ncx-sec--navy .ncx-head p { color: rgba(255,255,255,.82); }

/* ============================================================
   v3.0 (2026-07-26) HAND CODED HEADER AND FOOTER.
   Replaces Porto's chrome, which was 230px tall, carried the last
   off palette greys, and forced the hero to be squeezed.
   Footer structure and colours mirror netraclouds nc-footer.
   ============================================================ */

.ncxh-skip {
	position: absolute; left: -9999px; top: 0; z-index: 200;
	background: #fff; color: var(--clos-navy); padding: 12px 20px; font-weight: 700;
}
.ncxh-skip:focus { left: 12px; top: 12px; }

/* ---- thin contact bar ---- */
.ncxh-top { background: #0A1A30; color: #C9D4E8; font-size: 13px; }
.ncxh-wrap { max-width: 1320px; margin: 0 auto; padding: 0 24px; }
.ncxh-top .ncxh-wrap {
	display: flex; justify-content: flex-end; align-items: center; gap: 26px; height: 40px;
}
.ncxh-t-item { display: inline-flex; align-items: center; gap: 8px; color: #C9D4E8; }
.ncxh-t-item:hover { color: #fff; }
.ncxh-t-item svg { opacity: .75; }

/* ---- main bar ---- */
.ncxh {
	position: sticky; top: 0; z-index: 120;
	background: #fff; border-bottom: 1px solid var(--clos-line);
	transition: box-shadow .2s ease;
}
.ncxh.is-stuck { box-shadow: 0 6px 24px rgba(10,26,48,.10); }
.ncxh-bar { display: flex; align-items: center; justify-content: space-between; gap: 32px; height: 78px; }
.ncxh-logo img { width: 176px; height: auto; display: block; }

.ncxh-nav { display: flex; align-items: center; gap: 30px; }
.ncxh-menu { display: flex; align-items: center; gap: 28px; list-style: none; margin: 0; padding: 0; }
.ncxh-menu li { position: relative; }
.ncxh-menu > li > a {
	color: var(--clos-navy); font-weight: 600; font-size: 15px;
	padding: 28px 0; display: inline-block;
}
.ncxh-menu > li > a:hover,
.ncxh-menu > li.current-menu-item > a { color: var(--clos-accent); }

/* submenus */
.ncxh-menu .sub-menu {
	position: absolute; top: 100%; left: 0; min-width: 250px;
	background: #fff; border: 1px solid var(--clos-line); border-radius: 10px;
	box-shadow: 0 18px 44px rgba(10,26,48,.14);
	padding: 10px 0; margin: 0; list-style: none;
	opacity: 0; visibility: hidden; transform: translateY(8px);
	transition: opacity .18s ease, transform .18s ease, visibility .18s;
}
.ncxh-menu li:hover > .sub-menu,
.ncxh-menu li:focus-within > .sub-menu { opacity: 1; visibility: visible; transform: none; }
.ncxh-menu .sub-menu a { display: block; padding: 10px 20px; color: var(--clos-body); font-size: 15px; }
.ncxh-menu .sub-menu a:hover { color: var(--clos-accent); background: var(--clos-tint); }

.ncxh-cta {
	background: var(--clos-grad); color: #fff; font-weight: 700; font-size: 15px;
	padding: 13px 26px; border-radius: 6px; white-space: nowrap;
	transition: background .25s ease;
}
.ncxh-cta:hover { background: var(--clos-navy); }

.ncxh-burger { display: none; background: none; border: 0; padding: 10px; cursor: pointer; }
.ncxh-burger span {
	display: block; width: 24px; height: 2px; background: var(--clos-navy);
	margin: 5px 0; transition: transform .22s ease, opacity .22s ease;
}
.ncxh.nav-open .ncxh-burger span:nth-child(1) { transform: translateY(7px) rotate(45deg); }
.ncxh.nav-open .ncxh-burger span:nth-child(2) { opacity: 0; }
.ncxh.nav-open .ncxh-burger span:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }

@media (max-width: 1199px) {
	.ncxh-burger { display: block; }
	.ncxh-bar { height: 66px; }
	.ncxh-logo img { width: 190px; }
	.ncxh-nav {
		position: absolute; top: 100%; left: 0; right: 0;
		background: #fff; border-bottom: 1px solid var(--clos-line);
		flex-direction: column; align-items: stretch; gap: 0;
		max-height: 0; overflow: hidden; transition: max-height .3s ease;
		box-shadow: 0 18px 40px rgba(10,26,48,.12);
	}
	.ncxh.nav-open .ncxh-nav { max-height: 80vh; overflow-y: auto; }
	.ncxh-menu { flex-direction: column; align-items: stretch; gap: 0; padding: 6px 24px 0; }
	.ncxh-menu > li > a { padding: 14px 0; border-bottom: 1px solid var(--clos-line); width: 100%; }
	.ncxh-menu .sub-menu {
		position: static; opacity: 1; visibility: visible; transform: none;
		box-shadow: none; border: 0; padding: 0 0 0 14px; min-width: 0;
	}
	.ncxh-cta { margin: 16px 24px 22px; text-align: center; }
	.ncxh-top .ncxh-wrap { justify-content: center; gap: 18px; font-size: 13px; }
}
@media (max-width: 520px) { .ncxh-t-item:first-child { display: none; } }

/* ============ footer ============ */
.ncxf {
	background: linear-gradient(115deg, #0A1A30, #14264A);
	color: #C9D4E8;
	font-size: 14px;
}
.ncxf a { color: #C9D4E8; }
.ncxf a:hover { color: var(--clos-accent); }
.ncxf-wrap { max-width: 1320px; margin: 0 auto; padding: 0 24px; }
.ncxf-grid {
	display: grid;
	grid-template-columns: 1.5fr 1fr 1fr 1.2fr;
	gap: 36px;
	padding: 58px 0 30px;
}
.ncxf-logo img { width: 210px; height: auto; }
.ncxf-tag { font-size: 13.5px; line-height: 1.8; margin-top: 16px; color: #DCE5F4; max-width: 340px; }
.ncxf-office { margin-top: 18px; font-size: 13.5px; line-height: 1.65; }
.ncxf-office b { color: #fff; display: block; margin-bottom: 3px; }

.ncxf-hd {
	font-size: 12px; letter-spacing: 1.6px; text-transform: uppercase; font-weight: 700;
	color: #fff; border-bottom: 2px solid var(--clos-accent);
	display: inline-block; padding-bottom: 5px; margin-bottom: 16px;
}
.ncxf ul { margin: 0; padding: 0; }
.ncxf li { list-style: none; padding: 5px 0; }
.ncxf p { margin: 0; font-size: 13.5px; line-height: 1.7; }

.ncxf-btn {
	display: inline-block; background: var(--clos-grad); color: #fff !important;
	font-weight: 700; font-size: 14px; padding: 12px 22px; border-radius: 6px;
}
.ncxf-btn:hover { background: #fff; color: var(--clos-navy) !important; }
.ncxf-phone { color: var(--clos-accent); font-weight: 700; font-size: 17px; display: inline-block; margin-top: 14px; }
.ncxf-hours { color: #9FB1CE; font-size: 12.5px; margin-top: 10px; line-height: 1.8; }

.ncxf-a11y {
	max-width: 1320px; margin: 0 auto;
	padding: 16px clamp(16px, 2.4vw, 24px) 0;
	color: #9FB1CE; font-size: 13px; line-height: 1.6;
}
.ncxf-a11y a { color: #C9D4E8; text-decoration: underline; text-underline-offset: 2px; }
.ncxf-a11y a:hover { color: #F4772E; }

.ncxf-bottom { border-top: 1px solid rgba(255,255,255,.12); margin-top: 22px; font-size: 13px; }
.ncxf-bottom-in { display: flex; align-items: center; justify-content: space-between; padding: 16px 24px; }
.ncxf-socials { display: flex; gap: 12px; }
.ncxf-socials a {
	width: 32px; height: 32px; border-radius: 50%;
	display: inline-flex; align-items: center; justify-content: center;
	border: 1px solid rgba(255,255,255,.22);
}
.ncxf-socials a:hover { background: var(--clos-accent); border-color: var(--clos-accent); color: #fff; }

@media (max-width: 1024px) { .ncxf-grid { grid-template-columns: 1fr 1fr; } }
@media (max-width: 640px) {
	.ncxf-grid { grid-template-columns: 1fr; gap: 28px; }
	.ncxf-bottom-in { flex-direction: column; gap: 14px; text-align: center; }
}

/* ============================================================
   v3.1 (2026-07-26) BASE. Stripping every theme stylesheet also
   removed the font stack and the CSS reset, so the page fell back
   to Times New Roman with underlined links. When the page owns the
   whole document it has to own the base styles too.
   ============================================================ */
:root {
	--ncx-font: 'Poppins', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto,
	            'Helvetica Neue', Arial, sans-serif;
}

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

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

body.ncx-page {
	margin: 0;
	font-family: var(--ncx-font);
	font-size: 16px;
	line-height: 1.7;
	color: #3D4C66;
	background: #fff;
	-webkit-font-smoothing: antialiased;
	-moz-osx-font-smoothing: grayscale;
	overflow-x: hidden;
}

body.ncx-page h1,
body.ncx-page h2,
body.ncx-page h3,
body.ncx-page h4,
body.ncx-page h5,
body.ncx-page h6 { font-family: var(--ncx-font); margin: 0; }

body.ncx-page p { margin: 0 0 16px; }
body.ncx-page a { color: inherit; text-decoration: none; }
body.ncx-page img { max-width: 100%; height: auto; border: 0; }
body.ncx-page ul, body.ncx-page ol { margin: 0; padding: 0; }
body.ncx-page button { font-family: inherit; }

/* the design system inherits the base font */
.ncx { font-family: var(--ncx-font); }

/* visible focus, since the theme's focus styles went with it */
body.ncx-page a:focus-visible,
body.ncx-page button:focus-visible {
	outline: 3px solid var(--clos-accent);
	outline-offset: 3px;
}

/* ============================================================
   v3.2 (2026-07-26) THE TOKENS WERE TRAPPED IN .ncx.

   nc-clos.css declared every --clos-* token on `.ncx`, which was
   fine while the page lived inside Porto's chrome. Now the header
   and footer are hand coded and sit OUTSIDE .ncx, so every
   var(--clos-*) in them resolved to nothing:
     .ncxh-cta lost its gradient and rendered as plain text
     .ncxh-burger lost `background: none` and showed a stray orange box
   Promote the tokens to :root so the whole document can use them.
   ============================================================ */
:root {
	--clos-navy: #16265C;
	--clos-navy-deep: #0A1A30;
	--clos-ink: #0A1A30;
	--clos-body: #3D4C66;
	--clos-muted: #7A8AA6;
	--clos-line: #E3E9F4;
	--clos-tint: #F4F7FB;
	--clos-accent: #E11D48;
	--clos-accent-deep: #BE123C;
	--clos-black: #111318;
	--clos-g1: #F4772E;
	--clos-g2: #ED3A5F;
	--clos-g3: #C81E1E;
	--clos-grad: linear-gradient(135deg, #F4772E 0%, #ED3A5F 45%, #C81E1E 100%);
	--clos-radius: 14px;
	--clos-wrap: 1320px;
}

/* the burger is desktop-hidden; beat any inherited button styling */
.ncxh .ncxh-burger {
	display: none;
	background: none;
	background-color: transparent;
	background-image: none;
	border: 0;
	box-shadow: none;
	border-radius: 0;
}
@media (max-width: 1199px) { .ncxh .ncxh-burger { display: block; } }

/* CTA needs to win over any stray button rule too */
.ncxh .ncxh-cta {
	background-image: var(--clos-grad);
	background-color: transparent;
	color: #fff;
}
.ncxh .ncxh-cta:hover {
	background-image: none;
	background-color: var(--clos-navy);
	color: #fff;
}

/* v3.3: `.ncxf a` (0,1,1) outranks `.ncxf-phone` (0,1,0), so the phone
   number rendered in body colour instead of the accent. Same specificity
   trap as the ghost button earlier. */
.ncxf a.ncxf-phone { color: var(--clos-accent); }
.ncxf a.ncxf-phone:hover { color: #fff; }
.ncxf a.ncxf-btn { color: #fff; }
.ncxf a.ncxf-btn:hover { color: var(--clos-navy); }

/* ============================================================
   v3.4 (2026-07-26) OWNER: the big blue block in the middle goes,
   the owner's own voice platform becomes the centre of the story,
   and every service gets treated separately.

   Sections now alternate white and #F4F7FB like netraclouds,
   with the CTA band as the only dark block on the page.
   ============================================================ */

/* the "How we work" steps are on light now, not navy */
.ncx-steps-sec .ncx-step {
	background: #fff;
	border: 1px solid var(--clos-line);
	box-shadow: 0 10px 26px rgba(22,38,92,.06);
}
.ncx-steps-sec .ncx-step h3 { color: var(--clos-navy); }
.ncx-steps-sec .ncx-step p { color: var(--clos-body); }
.ncx-steps-sec .ncx-note {
	background: #fff;
	border-left: 3px solid var(--clos-g2);
	color: var(--clos-body);
	box-shadow: 0 10px 26px rgba(22,38,92,.06);
}
.ncx-steps-sec .ncx-note a { color: var(--clos-navy); text-decoration-color: var(--clos-g2); }
.ncx-steps-sec .ncx-note a:hover { color: var(--clos-accent); }

/* ---- the voice centrepiece ---- */
.ncx-voice {
	background:
		radial-gradient(1200px 420px at 50% 0%, rgba(237,58,95,.07), transparent 70%),
		#fff;
	border-top: 1px solid var(--clos-line);
	border-bottom: 1px solid var(--clos-line);
}
.ncx-voice-head { max-width: 760px; margin: 0 auto 40px; text-align: center; }
.ncx-voice-head h2 { font-size: clamp(30px, 3.8vw, 44px); }
.ncx-voice-head .ncx-underline::after { left: 50%; transform: translateX(-50%); }
.ncx-voice-head p { margin-top: 18px; font-size: 17px; color: #5D6C86; }

.ncx-voice-hero { margin: 0 auto 44px; max-width: 1040px; }
.ncx-voice-hero img {
	width: 100%;
	border-radius: var(--clos-radius);
	box-shadow: 0 26px 60px rgba(22,38,92,.18);
}

/* feature columns are light cards now, not panels on navy */
.ncx-voice .ncx-feat-col {
	background: #fff;
	border: 1px solid var(--clos-line);
	box-shadow: 0 10px 30px rgba(22,38,92,.07);
}
.ncx-voice .ncx-feat-col h3 { color: var(--clos-navy); }
.ncx-voice .ncx-feat-col p { color: var(--clos-body); }
.ncx-voice .ncx-feat-col .ncx-checks li { color: var(--clos-body); }

/* focus blocks: give the image real presence */
.ncx-split-img img { width: 100%; }

@media (max-width: 700px) {
	.ncx-voice-hero { margin-bottom: 30px; }
}

/* v3.5: AI voice makes a fourth column. auto-fit so it is 4 across on
   wide screens, 2x2 on tablets and stacked on phones, without the
   cards getting squeezed. */
.ncx-feat { grid-template-columns: repeat(auto-fit, minmax(258px, 1fr)); }

/* the AI column is the newest capability, give it a quiet highlight */
.ncx-voice .ncx-feat-col--ai {
	border-color: rgba(237,58,95,.34);
	box-shadow: 0 12px 34px rgba(237,58,95,.12);
	position: relative;
}
.ncx-voice .ncx-feat-col--ai::before {
	content: "";
	position: absolute; inset: 0 0 auto 0; height: 3px;
	border-radius: var(--clos-radius) var(--clos-radius) 0 0;
	background: var(--clos-grad);
}
@media (max-width: 1024px) { .ncx-feat { grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); } }

/* v3.6: the footer services list now carries all eleven services, so it
   runs in two columns on desktop rather than towering over the others. */
.ncxf-services { columns: 2; column-gap: 26px; }
.ncxf-services li { break-inside: avoid; }
@media (max-width: 1024px) { .ncxf-services { columns: 2; } }
@media (max-width: 480px)  { .ncxf-services { columns: 1; } }

/* v3.7: with eleven services in two columns, the 1fr cell was too narrow
   and every label wrapped to three lines. Give Services the room. */
.ncxf-grid { grid-template-columns: 1.35fr 1.75fr 0.95fr 1.25fr; }
.ncxf-services { column-gap: 30px; }
.ncxf-services li { padding: 4px 0; line-height: 1.5; }

@media (max-width: 1024px) {
	.ncxf-grid { grid-template-columns: 1fr 1fr; }
	.ncxf-services { columns: 1; }
}
@media (max-width: 640px) { .ncxf-grid { grid-template-columns: 1fr; } }

/* ============================================================
   v3.8 (2026-07-26) MEGA MENU. First one is Hospitality IT.
   Hover opens on desktop, click/keyboard opens everywhere, which
   is what makes it usable on touch and with a screen reader.
   ============================================================ */
.ncxh-menu > li.has-mega { position: static; }
.ncxh-caret { margin-left: 6px; transition: transform .2s ease; opacity: .7; }
.ncxh-menu > li.has-mega:hover > a .ncxh-caret,
.ncxh-menu > li.has-mega.open > a .ncxh-caret { transform: rotate(180deg); }

.ncxh-mega {
	position: absolute;
	left: 0; right: 0; top: 100%;
	background: #fff;
	border-top: 1px solid var(--clos-line);
	border-bottom: 1px solid var(--clos-line);
	box-shadow: 0 24px 48px rgba(10,26,48,.14);
	opacity: 0; visibility: hidden; transform: translateY(8px);
	transition: opacity .2s ease, transform .2s ease, visibility .2s;
	z-index: 130;
}
.ncxh-menu > li.has-mega:hover > .ncxh-mega,
.ncxh-menu > li.has-mega:focus-within > .ncxh-mega,
.ncxh-menu > li.has-mega.open > .ncxh-mega {
	opacity: 1; visibility: visible; transform: none;
}

.ncxh-mega-in {
	max-width: 1320px;
	margin: 0 auto;
	padding: 30px 24px 34px;
	display: grid;
	grid-template-columns: 320px 1fr;
	gap: 38px;
}

/* the promo tile */
.ncxh-mega-lead { display: block; border-radius: var(--clos-radius); overflow: hidden; background: var(--clos-tint); }
.ncxh-mega-lead img { width: 100%; height: 150px; object-fit: cover; display: block; }
.ncxh-mega-lead-body { display: block; padding: 16px 18px 18px; }
.ncxh-mega-lead-body strong { display: block; color: var(--clos-navy); font-size: 16px; margin-bottom: 6px; }
.ncxh-mega-lead-body span { display: block; color: var(--clos-body); font-size: 14px; line-height: 1.5; }
.ncxh-mega-lead:hover .ncxh-mega-lead-body strong { color: var(--clos-accent); }

/* the link grid */
.ncxh-mega-list {
	list-style: none; margin: 0; padding: 0;
	display: grid; grid-template-columns: repeat(2, 1fr); gap: 4px 26px;
}
.ncxh-mega-list a {
	display: block; padding: 12px 14px; border-radius: 10px;
	transition: background .18s ease;
}
.ncxh-mega-list a:hover { background: var(--clos-tint); }
.ncxh-mega-list strong {
	display: block; color: var(--clos-navy); font-size: 16px; font-weight: 600;
	margin-bottom: 3px;
}
.ncxh-mega-list a:hover strong { color: var(--clos-accent); }
.ncxh-mega-list span { display: block; color: var(--clos-body); font-size: 14px; line-height: 1.5; }

@media (max-width: 1199px) {
	.ncxh-menu > li.has-mega { position: relative; }
	.ncxh-mega {
		position: static; opacity: 1; visibility: visible; transform: none;
		box-shadow: none; border: 0;
		max-height: 0; overflow: hidden; transition: max-height .3s ease;
	}
	.ncxh-menu > li.has-mega.open > .ncxh-mega { max-height: 1400px; }
	.ncxh-menu > li.has-mega:hover > .ncxh-mega { max-height: 0; }
	.ncxh-menu > li.has-mega.open:hover > .ncxh-mega { max-height: 1400px; }
	.ncxh-mega-in { grid-template-columns: 1fr; gap: 16px; padding: 6px 0 14px; }
	.ncxh-mega-lead { display: none; }
	.ncxh-mega-list { grid-template-columns: 1fr; }
	.ncxh-mega-list a { padding: 10px 0; }
}

/* v3.9: the mega panel would not open. The rule matched and won on
   specificity, but `visibility` in a transition is a discrete property
   and kept computing to hidden. Drop visibility entirely and gate the
   panel on opacity + pointer-events, which are continuous and reliable. */
.ncxh-mega {
	visibility: visible;
	opacity: 0;
	pointer-events: none;
	transform: translateY(8px);
	transition: opacity .2s ease, transform .2s ease;
}
.ncxh-menu > li.has-mega:hover > .ncxh-mega,
.ncxh-menu > li.has-mega:focus-within > .ncxh-mega,
.ncxh-menu > li.has-mega.open > .ncxh-mega {
	visibility: visible;
	opacity: 1;
	pointer-events: auto;
	transform: none;
}
@media (max-width: 1199px) {
	.ncxh-mega { opacity: 1; pointer-events: auto; transform: none; max-height: 0; }
	.ncxh-menu > li.has-mega.open > .ncxh-mega { max-height: 1400px; }
	.ncxh-menu > li.has-mega:hover > .ncxh-mega { max-height: 0; }
	.ncxh-menu > li.has-mega.open:hover > .ncxh-mega { max-height: 1400px; }
}

/* v3.10: pointer-events and visibility from the open rule applied, but
   opacity stayed 0, so an earlier declaration is still winning it.
   Forcing just this one property rather than restructuring the cascade. */
.ncxh-menu > li.has-mega:hover > .ncxh-mega,
.ncxh-menu > li.has-mega:focus-within > .ncxh-mega,
.ncxh-menu > li.has-mega.open > .ncxh-mega { opacity: 1 !important; }

/* ============================================================
   v4.0 (2026-07-26) OWNER: the mega panel must start where the logo
   starts and end where the Contact Us button ends, not bleed the full
   viewport. The header wrap is max-width 1320 with 24px padding, so the
   content box is 1272 at most. Match that exactly and the panel lines
   up with the logo on the left and the CTA on the right at every width.
   ============================================================ */
@media (min-width: 1200px) {
	.ncxh-mega {
		left: 50%;
		right: auto;
		width: min(1272px, calc(100vw - 48px));
		transform: translateX(-50%) translateY(8px);
		margin-top: 6px;
		border: 1px solid var(--clos-line);
		border-radius: var(--clos-radius);
		box-shadow: 0 26px 54px rgba(10,26,48,.16);
		overflow: hidden;
	}
	.ncxh-menu > li.has-mega:hover > .ncxh-mega,
	.ncxh-menu > li.has-mega:focus-within > .ncxh-mega,
	.ncxh-menu > li.has-mega.open > .ncxh-mega {
		transform: translateX(-50%);
	}

	/* the panel is already the right width, so the inner wrap only pads */
	.ncxh-mega-in {
		max-width: none;
		margin: 0;
		padding: 28px 28px 30px;
	}

	/* narrower laptops: drop the promo tile before the links get cramped */
	@media (max-width: 1180px) {
		.ncxh-mega-in { grid-template-columns: 260px 1fr; gap: 26px; }
	}
	@media (max-width: 1080px) {
		.ncxh-mega-in { grid-template-columns: 1fr; }
		.ncxh-mega-lead { display: none; }
	}
}

/* the promo tile image was rendering blank: give it a real aspect box
   rather than a fixed height that the object-fit had nothing to fill */
.ncxh-mega-lead img {
	width: 100%;
	aspect-ratio: 16 / 9;
	height: auto;
	object-fit: cover;
	display: block;
}

/* v4.1: the panel sat 8px proud on each side because 100vw counts the
   scrollbar. --ncx-sb is already measured for the hero full bleed, so
   subtract it here too and the edges land exactly on the logo and CTA. */
@media (min-width: 1200px) {
	.ncxh-mega {
		width: min(1272px, calc(100vw - 48px - var(--ncx-sb, 0px)));
	}
}

/* ============================================================
   v5.0 (2026-07-26) BLOG on the NC design system.
   home.php and single.php replace Porto for the blog, so the 82
   posts now share the hand coded header, footer and type.
   ============================================================ */
.ncxb-hero { padding: 56px 0 30px; }
.ncxb-hero h1 { font-size: clamp(30px, 4vw, 46px); }
.ncxb-hero p { margin-top: 18px; font-size: 17px; color: #5D6C86; max-width: 640px; }

/* topic chips */
.ncxb-filters { display: flex; flex-wrap: wrap; gap: 10px; padding: 6px 0 4px; }
.ncxb-chip {
	display: inline-flex; align-items: center; gap: 7px;
	padding: 8px 16px; border-radius: 40px;
	border: 1px solid var(--clos-line); background: #fff;
	color: var(--clos-navy); font-size: 13.5px; font-weight: 600;
	transition: border-color .2s ease, color .2s ease, background .2s ease;
}
.ncxb-chip span { color: var(--clos-muted); font-weight: 600; font-size: 12px; }
.ncxb-chip:hover { border-color: var(--clos-accent); color: var(--clos-accent); }
.ncxb-chip.is-on { background: var(--clos-navy); border-color: var(--clos-navy); color: #fff; }
.ncxb-chip.is-on span { color: rgba(255,255,255,.7); }

.ncxb-list { padding-top: 30px; }

/* cards */
.ncxb-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 28px; }
.ncxb-card {
	display: flex; flex-direction: column;
	background: #fff; border: 1px solid var(--clos-line);
	border-radius: var(--clos-radius); overflow: hidden;
	transition: transform .25s ease, box-shadow .25s ease;
}
.ncxb-card:hover { transform: translateY(-5px); box-shadow: 0 20px 44px rgba(22,38,92,.14); }
.ncxb-card-img { aspect-ratio: 16 / 10; overflow: hidden; background: var(--clos-tint); }
.ncxb-card-img img { width: 100%; height: 100%; object-fit: cover; transition: transform .5s ease; }
.ncxb-card:hover .ncxb-card-img img { transform: scale(1.05); }
.ncxb-card-body { padding: 22px 22px 24px; flex: 1; display: flex; flex-direction: column; }
.ncxb-card h3 { font-size: 18px; line-height: 1.35; margin-bottom: 10px; color: var(--clos-navy); }
.ncxb-card p { font-size: 14.5px; color: var(--clos-body); flex: 1; }

.ncxb-cat {
	display: inline-block; font-size: 11.5px; font-weight: 700;
	letter-spacing: .1em; text-transform: uppercase;
	color: var(--clos-accent); margin-bottom: 10px;
}
.ncxb-meta { font-size: 13px; color: var(--clos-muted); margin-top: 14px; display: block; }

/* the lead post gets the full width, image beside the words */
.ncxb-lead-wrap { margin-bottom: 34px; }
.ncxb-card--lead { display: grid; grid-template-columns: 1.15fr 1fr; }
.ncxb-card--lead .ncxb-card-img { aspect-ratio: auto; height: 100%; min-height: 320px; }
.ncxb-card--lead .ncxb-card-body { padding: 34px 36px 36px; justify-content: center; }
.ncxb-card--lead h3 { font-size: clamp(22px, 2.4vw, 30px); }
.ncxb-card--lead p { font-size: 16px; }

/* pagination */
.ncxb-pager { display: flex; justify-content: center; gap: 8px; margin-top: 44px; }
.ncxb-pager .page-numbers {
	min-width: 40px; height: 40px; padding: 0 12px;
	display: inline-flex; align-items: center; justify-content: center;
	border: 1px solid var(--clos-line); border-radius: 8px;
	color: var(--clos-navy); font-weight: 600; font-size: 14px;
}
.ncxb-pager .page-numbers:hover { border-color: var(--clos-accent); color: var(--clos-accent); }
.ncxb-pager .page-numbers.current { background: var(--clos-navy); border-color: var(--clos-navy); color: #fff; }

/* ---- single post ---- */
.ncxb-measure { max-width: 760px; margin: 0 auto; }
.ncxb-single-head { padding: 54px 0 24px; text-align: center; }
.ncxb-single-head h1 { font-size: clamp(28px, 4vw, 44px); line-height: 1.2; }
.ncxb-single-head .ncxb-meta { margin-top: 16px; }
.ncxb-hero-img { max-width: 1000px; margin: 0 auto 40px; }
.ncxb-hero-img img { width: 100%; border-radius: var(--clos-radius); box-shadow: 0 22px 52px rgba(22,38,92,.16); }

/* article body: readable measure and real vertical rhythm */
.ncxb-prose { padding-bottom: 60px; font-size: 17px; line-height: 1.8; color: var(--clos-body); }
.ncxb-prose h2 { font-size: clamp(23px, 2.6vw, 30px); margin: 44px 0 14px; }
.ncxb-prose h3 { font-size: 20px; margin: 32px 0 10px; }
.ncxb-prose p { margin: 0 0 20px; }
.ncxb-prose ul, .ncxb-prose ol { margin: 0 0 22px; padding-left: 22px; }
.ncxb-prose li { margin-bottom: 9px; }
.ncxb-prose a { color: var(--clos-navy); text-decoration: underline; text-underline-offset: 3px; text-decoration-color: var(--clos-g2); }
.ncxb-prose a:hover { color: var(--clos-accent); }
.ncxb-prose img { border-radius: 10px; margin: 12px 0 26px; }
.ncxb-prose figure { margin: 26px 0; }
.ncxb-prose figcaption { font-size: 13.5px; color: var(--clos-muted); margin-top: 8px; text-align: center; }
.ncxb-prose blockquote {
	margin: 28px 0; padding: 4px 0 4px 22px;
	border-left: 3px solid var(--clos-g2); color: var(--clos-navy); font-size: 18px;
}
.ncxb-prose table { width: 100%; border-collapse: collapse; margin: 26px 0; font-size: 15px; display: block; overflow-x: auto; }
.ncxb-prose th, .ncxb-prose td { border: 1px solid var(--clos-line); padding: 10px 12px; text-align: left; }
.ncxb-prose th { background: var(--clos-tint); color: var(--clos-navy); font-weight: 700; }

@media (max-width: 1024px) {
	.ncxb-grid { grid-template-columns: repeat(2, 1fr); }
	.ncxb-card--lead { grid-template-columns: 1fr; }
	.ncxb-card--lead .ncxb-card-img { min-height: 0; aspect-ratio: 16 / 9; }
	.ncxb-card--lead .ncxb-card-body { padding: 26px; }
}
@media (max-width: 640px) {
	.ncxb-grid { grid-template-columns: 1fr; }
	.ncxb-prose { font-size: 16.5px; }
}

/* v5.1: hand coded table of contents, only rendered on posts with 8+
   headings. Replaces the ez-toc plugin, which injected into every post
   and whose stylesheet was being stripped, so it rendered unstyled. */
.ncxb-toc {
	background: var(--clos-tint);
	border: 1px solid var(--clos-line);
	border-left: 3px solid var(--clos-g2);
	border-radius: 0 var(--clos-radius) var(--clos-radius) 0;
	padding: 22px 26px 24px;
	margin: 0 0 36px;
}
.ncxb-toc-hd {
	font-size: 12px; font-weight: 700; letter-spacing: .12em;
	text-transform: uppercase; color: var(--clos-navy); margin-bottom: 12px;
}
.ncxb-toc ol { margin: 0; padding-left: 20px; columns: 2; column-gap: 30px; }
.ncxb-toc li { margin-bottom: 7px; font-size: 14.5px; break-inside: avoid; }
.ncxb-toc a { color: var(--clos-body); text-decoration: none; }
.ncxb-toc a:hover { color: var(--clos-accent); text-decoration: underline; text-underline-offset: 3px; }

/* jumping to a heading must clear the sticky header */
.ncxb-prose h2[id] { scroll-margin-top: 100px; }

@media (max-width: 700px) { .ncxb-toc ol { columns: 1; } }

/* v4.2: four mega menus plus Home, Blog and Contact is a lot of nav.
   Tighten the spacing and type as the viewport narrows so the bar does
   not collide with the logo before the mobile breakpoint takes over. */
@media (min-width: 1200px) {
	.ncxh-menu { gap: 24px; }
	.ncxh-menu > li > a { font-size: 15px; }
	.ncxh-nav { gap: 24px; }
}
@media (min-width: 1200px) and (max-width: 1420px) {
	.ncxh-menu { gap: 16px; }
	.ncxh-menu > li > a { font-size: 14px; }
	.ncxh-logo img { width: 176px; }
	.ncxh-cta { padding: 12px 18px; font-size: 14px; }
	.ncxh-nav { gap: 16px; }
}
@media (min-width: 1200px) and (max-width: 1240px) {
	.ncxh-menu { gap: 12px; }
	.ncxh-menu > li > a { font-size: 13px; }
	.ncxh-logo img { width: 176px; }
	.ncxh-caret { margin-left: 3px; }
}

/* v4.3: nav labels were wrapping to two lines with four mega menus in the
   bar, and the promo tile <img> painted blank despite loading correctly.
   Nowrap the labels; render the tile image as a background instead. */
.ncxh-menu > li > a { white-space: nowrap; }

.ncxh-mega-lead-img {
	display: block;
	width: 100%;
	aspect-ratio: 16 / 9;
	background-image: var(--tile);
	background-size: cover;
	background-position: center;
	background-color: var(--clos-line);
}

/* ============================================================
   v5.3 (2026-07-26) OWNER: every blog post gets a banner in brand
   navy, with the heading sitting on it, transparent, left aligned.
   The featured image goes behind the navy wash rather than sitting
   as a separate block below the title.
   ============================================================ */
.ncxb-banner {
	position: relative;
	background-color: var(--clos-ink);
	background-image: var(--banner, none);
	background-size: cover;
	background-position: center;
	padding: 78px 0 72px;
	overflow: hidden;
}

/* navy wash: heavy on the left where the words are, lighter on the
   right so the photograph still reads */
.ncxb-banner::before {
	content: "";
	position: absolute;
	inset: 0;
	background: linear-gradient(96deg,
		rgba(10,26,48,.95) 0%,
		rgba(22,38,92,.88) 46%,
		rgba(22,38,92,.55) 100%);
}
.ncxb-banner > .ncx-wrap { position: relative; z-index: 2; }

.ncxb-banner-in { max-width: 800px; text-align: left; }

.ncxb-banner .ncxb-cat {
	color: #fff;
	background: rgba(255,255,255,.14);
	border: 1px solid rgba(255,255,255,.24);
	padding: 5px 13px;
	border-radius: 40px;
	margin-bottom: 16px;
}
.ncxb-banner .ncxb-cat:hover { background: var(--clos-accent); border-color: var(--clos-accent); }

.ncxb-banner h1 {
	color: #fff;
	font-size: clamp(28px, 3.9vw, 46px);
	line-height: 1.16;
	margin: 0;
}
.ncxb-banner .ncxb-meta { color: rgba(255,255,255,.72); margin-top: 18px; }

/* the tagline keeps the gradient, it reads well on navy */
.ncxb-banner .ncxb-strap { margin-bottom: 12px; }

/* the article itself starts below the banner */
.ncxb-single .ncxb-prose { padding-top: 52px; }

@media (max-width: 700px) {
	.ncxb-banner { padding: 54px 0 50px; }
	.ncxb-banner::before {
		background: linear-gradient(180deg, rgba(10,26,48,.92) 0%, rgba(22,38,92,.9) 100%);
	}
}

/* v5.4: the featured images have the post title baked into them, so with
   the banner showing the image behind the real heading the title printed
   twice. Blur the background layer until the burned in text reads as
   texture, and deepen the navy. Proper fix is new imagery. */
.ncxb-banner { background-image: none; }
.ncxb-banner::after {
	content: "";
	position: absolute;
	inset: -30px;
	background-image: var(--banner, none);
	background-size: cover;
	background-position: center;
	filter: blur(14px) saturate(.5);
	z-index: 0;
}
.ncxb-banner::before {
	z-index: 1;
	background: linear-gradient(96deg,
		rgba(10,26,48,.97) 0%,
		rgba(16,30,70,.93) 46%,
		rgba(22,38,92,.80) 100%);
}
.ncxb-banner > .ncx-wrap { z-index: 2; }

/* the tagline needs to clear the category chip, not sit beside it */
.ncxb-banner .ncxb-cat { display: inline-block; }
.ncxb-banner .ncxb-strap { display: block; clear: both; margin-top: 4px; }

/* v5.5: the brand gradient runs orange to deep red, and its dark end is
   nearly invisible on navy. On the banner, run the gradient across the
   bright end only so the tagline stays legible. */
.ncxb-banner .ncxb-strap {
	font-size: clamp(15px, 1.7vw, 19px);
	letter-spacing: .01em;
	margin-bottom: 14px;
	background: linear-gradient(100deg, #F4772E 0%, #FF6B7A 55%, #FF8A5B 100%);
	-webkit-background-clip: text;
	background-clip: text;
	-webkit-text-fill-color: transparent;
}

/* v5.6: the owner wants the post's own image visible in the banner, not
   a flat navy block. Drop the heavy blur and weight the navy wash to the
   left, where the words are, so the photograph reads on the right. */
.ncxb-banner::after {
	filter: blur(2px) saturate(.85);
	inset: -12px;
}
.ncxb-banner::before {
	background: linear-gradient(96deg,
		rgba(10,26,48,.94) 0%,
		rgba(12,28,60,.86) 30%,
		rgba(18,34,78,.58) 62%,
		rgba(22,38,92,.30) 100%);
}
@media (max-width: 820px) {
	/* on a narrow screen the text crosses the whole width, so the wash
	   has to cover the whole width too */
	.ncxb-banner::before {
		background: linear-gradient(180deg, rgba(10,26,48,.90) 0%, rgba(18,34,78,.86) 100%);
	}
}

/* v5.7: card titles use the same split as the single post. The topic is
   the heading, the question sits under it in muted type, so the 22 long
   two part titles stop overflowing their cards. */
.ncxb-card-strap {
	display: block;
	font-size: 13.5px;
	line-height: 1.5;
	color: var(--clos-muted);
	margin: -4px 0 10px;
}

/* ============================================================
   v6.0 (2026-07-26) blog reading experience.
   Applied against UX guidance: line length 65-75 characters,
   consistent modular type scale, graceful truncation.
   ============================================================ */

/* measure in ch, not px, so it self corrects with the font size.
   760px at 17px was running past 80 characters per line. */
.ncxb-measure { max-width: 68ch; }

/* lede: the opening paragraph carries the reader in */
.ncxb-prose > p:first-of-type {
	font-size: 1.125em;
	line-height: 1.7;
	color: var(--clos-ink);
}

/* modular scale, so headings stop competing with each other */
.ncxb-prose h2 {
	font-size: clamp(22px, 2.4vw, 28px);
	margin: 46px 0 12px;
	line-height: 1.3;
}
.ncxb-prose h3 {
	font-size: clamp(18px, 1.9vw, 20px);
	margin: 30px 0 8px;
	line-height: 1.35;
	color: var(--clos-navy);
}
/* a heading immediately after another needs less gap */
.ncxb-prose h2 + h3 { margin-top: 16px; }
/* first heading should not push the lede away */
.ncxb-prose > h2:first-child { margin-top: 0; }

/* lists read better with a little air */
.ncxb-prose li { margin-bottom: 10px; padding-left: 2px; }
.ncxb-prose li::marker { color: var(--clos-g2); }

/* tables: readable on a phone without breaking the measure */
.ncxb-prose table { font-size: 14.5px; }
.ncxb-prose th { white-space: nowrap; }
.ncxb-prose td { vertical-align: top; }

/* cards: clamp so every card in a row is the same height and
   long titles degrade gracefully instead of overflowing */
.ncxb-card h3 {
	display: -webkit-box;
	-webkit-line-clamp: 2;
	-webkit-box-orient: vertical;
	overflow: hidden;
}
.ncxb-card p {
	display: -webkit-box;
	-webkit-line-clamp: 3;
	-webkit-box-orient: vertical;
	overflow: hidden;
}
.ncxb-card-strap {
	display: -webkit-box;
	-webkit-line-clamp: 2;
	-webkit-box-orient: vertical;
	overflow: hidden;
}
.ncxb-card--lead h3 { -webkit-line-clamp: 3; }
.ncxb-card--lead p  { -webkit-line-clamp: 4; }

/* respect reduced motion on the card lift */
@media (prefers-reduced-motion: reduce) {
	.ncxb-card, .ncxb-card:hover { transform: none; transition: none; }
	.ncxb-card-img img { transition: none; }
}

/* v6.1: underlines off in the table of contents and article body.
   The TOC read as a wall of underlined blue, which is noise, not
   affordance. Links stay identifiable by colour, and only reveal an
   underline on hover and focus where it signals interaction. */
.ncxb-toc a,
.ncxb-toc a:link,
.ncxb-toc a:visited {
	text-decoration: none;
	border-bottom: 0;
}
.ncxb-toc a:hover,
.ncxb-toc a:focus-visible {
	color: var(--clos-accent);
	text-decoration: underline;
	text-underline-offset: 3px;
}
.ncxb-toc li::marker { color: var(--clos-muted); }

/* article body: no underline at rest, underline on hover so the link
   is still discoverable without shouting */
.ncxb-prose a,
.ncxb-prose a:link,
.ncxb-prose a:visited {
	text-decoration: none;
	color: var(--clos-navy);
	font-weight: 600;
	box-shadow: inset 0 -2px 0 rgba(237,58,95,.28);
}
.ncxb-prose a:hover,
.ncxb-prose a:focus-visible {
	color: var(--clos-accent);
	box-shadow: inset 0 -2px 0 var(--clos-accent);
}

/* the category chip in the banner is a link, it should not underline */
.ncxb-banner .ncxb-cat,
.ncxb-cat { text-decoration: none; }

/* cards are links, nothing inside them should underline */
.ncxb-card, .ncxb-card * { text-decoration: none; }

/* v6.2: two faults visible on screen.
   1. headings sat almost touching the paragraph below, because the
      paragraph carries no top margin and the h2 only had 12px below.
   2. the measure was rendering ~85 characters per line. The 68ch rule
      lost to the earlier `.ncxb-measure { max-width: 760px }`, so state
      it with the same specificity it has to beat, in ch and capped. */
.ncxb-prose .ncxb-measure,
.ncxb-measure.ncxb-prose,
.ncxb-measure {
	max-width: min(68ch, 100%);
}

/* breathing room under every heading */
.ncxb-prose h2 + p,
.ncxb-prose h2 + ul,
.ncxb-prose h2 + ol,
.ncxb-prose h2 + figure,
.ncxb-prose h2 + table { margin-top: 14px; }

.ncxb-prose h3 + p,
.ncxb-prose h3 + ul,
.ncxb-prose h3 + ol { margin-top: 10px; }

/* and space above a heading that follows body copy, so sections read
   as sections rather than one continuous block */
.ncxb-prose p + h2,
.ncxb-prose ul + h2,
.ncxb-prose ol + h2,
.ncxb-prose table + h2,
.ncxb-prose figure + h2 { margin-top: 52px; }

.ncxb-prose p + h3,
.ncxb-prose ul + h3,
.ncxb-prose ol + h3 { margin-top: 34px; }

/* the banner heading has its own measure, keep it wider than body copy */
.ncxb-banner .ncxb-banner-in { max-width: 800px; }

/* v6.3: no underline in the table of contents in ANY state. The earlier
   rule still underlined on hover and focus. Colour alone carries the
   hover, and focus-visible keeps a ring so keyboard users are not lost. */
.ncxb-toc a,
.ncxb-toc a:link,
.ncxb-toc a:visited,
.ncxb-toc a:hover,
.ncxb-toc a:active,
.ncxb-toc a:focus,
.ncxb-toc a:focus-visible,
.ncxb-toc li a,
.ncxb-toc ol a {
	text-decoration: none !important;
	text-underline-offset: 0;
	border-bottom: 0 !important;
	box-shadow: none !important;
}
.ncxb-toc a:hover { color: var(--clos-accent); }
.ncxb-toc a:focus-visible {
	outline: 2px solid var(--clos-accent);
	outline-offset: 3px;
	border-radius: 3px;
}

/* v6.4: the measure kept rendering ~85 characters per line. Two earlier
   attempts lost the cascade, so state it once, decisively. 68ch on the
   prose itself, since that is the element the ch unit should resolve
   against. Target is 65-75 characters. */
.ncxb-prose {
	max-width: 68ch !important;
	margin-left: auto;
	margin-right: auto;
}
/* the banner heading is not body copy, it keeps its own wider measure */
.ncxb-banner .ncxb-banner-in { max-width: 800px !important; }

/* v6.5: gradient service line above each hero slide heading. The brand
   gradient ends in deep red, which disappears on navy, so the hero uses
   the bright end of the ramp, same treatment as the blog banner. */
.ncx-slide-eyebrow {
	display: block;
	font-size: clamp(13px, 1.35vw, 16px);
	font-weight: 700;
	letter-spacing: .12em;
	text-transform: uppercase;
	margin-bottom: 14px;
	background: linear-gradient(100deg, #F4772E 0%, #FF6B7A 55%, #FF8A5B 100%);
	-webkit-background-clip: text;
	background-clip: text;
	-webkit-text-fill-color: transparent;
	color: transparent;
}
@media (max-width: 700px) { .ncx-slide-eyebrow { margin-bottom: 10px; letter-spacing: .1em; } }

/* ── v6.6 ── slide eyebrow, long labels on narrow screens ─────────────
   'Video Conferencing System for Meeting Rooms' runs 501px, so it wraps
   below roughly 420px. Left alone it drops a single orphan word onto the
   second line above a large heading. Balance the break and tighten the
   tracking a little so the two lines read as one label.                */
@media (max-width: 600px) {
	.ncx-slide-eyebrow {
		text-wrap: balance;
		letter-spacing: 1.4px;
		line-height: 1.45;
	}
}

/* ══ v7.0 ══ service pages ════════════════════════════════════════════
   Banner matches the blog treatment the owner approved: the page's own
   image behind a navy wash, heading left aligned on a transparent
   background, gradient reserved for the eyebrow above it.

   Note: no loading="lazy" on the banner image. Inside an overflow:hidden
   container it never enters the viewport as far as the loader is
   concerned and the image silently never loads. That has now bitten this
   build twice.                                                          */

.ncxs-banner {
	position: relative;
	overflow: hidden;
	background: var(--clos-navy, #16265C);
	isolation: isolate;
}

.ncxs-banner-img {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	object-fit: cover;
	z-index: 0;
}

/* navy wash, heavier on the left so the copy always has contrast under it */
.ncxs-banner::after {
	content: '';
	position: absolute;
	inset: 0;
	z-index: 1;
	background: linear-gradient( 100deg,
		rgba( 10, 26, 48, .95 ) 0%,
		rgba( 16, 38, 92, .88 ) 45%,
		rgba( 22, 46, 105, .72 ) 100% );
}

.ncxs-banner-in {
	position: relative;
	z-index: 2;
	padding: clamp( 64px, 9vw, 118px ) 0 clamp( 56px, 8vw, 96px );
}

.ncxs-banner-in h1 {
	color: #fff;
	margin: 0 0 18px;
	max-width: 17ch;
	font-size: clamp( 32px, 4.4vw, 54px );
	line-height: 1.1;
	letter-spacing: -.5px;
}

.ncxs-banner-in p {
	color: rgba( 255, 255, 255, .88 );
	max-width: 62ch;
	margin: 0;
	font-size: clamp( 16px, 1.35vw, 18px );
	line-height: 1.65;
}

/* readable measure for body copy, same as the blog single */
.ncxs-measure {
	max-width: 820px;
}

.ncxs-measure h3 {
	margin: 34px 0 10px;
}

.ncxs-measure h3:first-of-type {
	margin-top: 0;
}

@media (max-width: 700px) {
	.ncxs-banner-in h1 { max-width: none; }
}

/* v7.0a  the site wide brand sheet loads after this one and flattens
   heading margins, so the banner h1 needs to state its own spacing
   explicitly. Same specificity trap that caught the ghost button and the
   footer phone link earlier in this build.                              */
.ncx .ncxs-banner-in h1 { margin: 0 0 20px !important; }
.ncx .ncxs-banner-in .ncx-slide-eyebrow { display: block; margin-bottom: 14px; }

/* v7.0b  the first wash was built against a dark high contrast hero and was
   effectively opaque over the owner's own photography, which is lighter and
   softer. Pulled back so the building is actually visible, with a readable
   scrim kept under the copy on the left where the text sits.             */
.ncx .ncxs-banner::after {
	background: linear-gradient( 100deg,
		rgba( 10, 26, 48, .86 ) 0%,
		rgba( 13, 32, 74, .68 ) 42%,
		rgba( 20, 44, 100, .44 ) 100% );
}

/* ══ v7.1 ══ interface polish and consistency ═════════════════════════
   Buttons were 15px/32px padding at 15px text, roughly 56px tall, which
   reads heavy next to the type. Brought down to about 46px on desktop.

   46px is deliberate rather than as small as it could go: the accessible
   minimum for a touch target is 44px, so this is the smallest the control
   can get and still be comfortable to tap. On narrow screens it is pinned
   back to 44px minimum, because that is where thumbs are, not mice.      */

.ncx .ncx-btn {
	padding: 12px 26px;
	font-size: 14.5px;
	border-radius: 8px;
	border-width: 1.5px;
	line-height: 1.35;
	transition: background .22s ease, color .22s ease,
	            border-color .22s ease, transform .16s ease,
	            box-shadow .22s ease;
}

/* the two CTA pairs sit next to each other, so they need the same rhythm */
.ncx .ncx-cta-btns,
.ncx .ncx-hero-ctas {
	gap: 12px;
}

/* one lift value everywhere instead of a different nudge per component */
.ncx .ncx-btn:hover {
	transform: translateY(-2px);
}

.ncx .ncx-btn:active {
	transform: translateY(0);
}

/* header call to action matches the body buttons rather than out sizing them */
.ncxh-cta {
	padding: 11px 22px;
	font-size: 15px;
	border-radius: 8px;
}

/* Focus has to stay obvious. Never remove the ring, only make it fit the
   brand: navy on light surfaces, white where the background is navy.     */
.ncx .ncx-btn:focus-visible,
.ncxh-cta:focus-visible {
	outline: 2px solid var(--clos-navy, #16265C);
	outline-offset: 3px;
}

.ncx-cta .ncx-btn:focus-visible,
.ncxs-banner .ncx-btn:focus-visible {
	outline-color: #fff;
}

/* Touch: keep the comfortable target back on small screens, and let the
   buttons go full width so they are easy to hit rather than clever.      */
@media (max-width: 640px) {
	.ncx .ncx-btn {
		min-height: 44px;
		padding: 12px 22px;
		width: 100%;
	}

	.ncx .ncx-cta-btns,
	.ncx .ncx-hero-ctas {
		flex-direction: column;
		align-items: stretch;
		width: 100%;
	}
}

/* Respect the system setting. Anyone who has asked for less motion gets
   the state changes without the movement.                                */
@media (prefers-reduced-motion: reduce) {
	.ncx *,
	.ncxh *,
	.ncxf * {
		animation-duration: .01ms !important;
		animation-iteration-count: 1 !important;
		transition-duration: .01ms !important;
		scroll-behavior: auto !important;
	}

	.ncx .ncx-btn:hover,
	.ncx .ncx-card:hover,
	.ncx .ncx-tile:hover {
		transform: none;
	}
}

/* ══ v7.2 ══ second image on service pages ═══════════════════════════
   Paired with the point it illustrates rather than dropped in as
   decoration. Image and copy share a row on desktop and stack on
   narrow screens, image first so it still leads.

   aspect-ratio holds the space before the file arrives, so the section
   does not jump as it loads. No lazy attribute: see the note at v7.0. */

.ncxs-split {
	display: grid;
	grid-template-columns: 1.05fr 1fr;
	gap: clamp( 28px, 4vw, 56px );
	align-items: center;
}

.ncxs-split-img {
	border-radius: 14px;
	overflow: hidden;
	box-shadow: 0 18px 40px rgba( 10, 26, 48, .13 );
}

.ncxs-split-img img {
	display: block;
	width: 100%;
	height: auto;
	aspect-ratio: 1400 / 900;
	object-fit: cover;
}

.ncxs-split-body h2 { margin-top: 0; }
.ncxs-split-body p  { margin-bottom: 0; }

/* alternate the image side down the page so a run of these does not
   read as the same block repeated */
.ncxs-split-sec:nth-of-type(even) .ncxs-split-img { order: 2; }

@media (max-width: 860px) {
	.ncxs-split { grid-template-columns: 1fr; gap: 24px; }
	.ncxs-split-sec:nth-of-type(even) .ncxs-split-img { order: 0; }
}

/* v7.2a  nth-of-type counts position among ALL sibling sections, not among
   the split sections, so both landed on the same side. An explicit modifier
   is what actually expresses the intent here.                             */
.ncxs-split-sec--flip .ncxs-split-img { order: 2; }
@media (max-width: 860px) {
	.ncxs-split-sec--flip .ncxs-split-img { order: 0; }
}

/* v7.2b  the nth-of-type rule from v7.2 was still matching both sections and
   pinning them right. Order is now controlled only by the explicit modifier:
   default image left, flipped image right.                                */
.ncx .ncxs-split-sec .ncxs-split-img { order: 0; }
.ncx .ncxs-split-sec--flip .ncxs-split-img { order: 2; }
@media (max-width: 860px) {
	.ncx .ncxs-split-sec .ncxs-split-img,
	.ncx .ncxs-split-sec--flip .ncxs-split-img { order: 0; }
}

/* ══ v7.3 ══ blog search ══════════════════════════════════════════════
   Grouping by technology made browsing better and finding worse, so both
   are needed. Filtering runs over an index of every published post rather
   than only what is on the page, and never reloads.                     */

.ncxb-search { margin: 0 0 18px; }

.ncxb-search input[type=search] {
	width: 100%;
	max-width: 460px;
	padding: 12px 16px;
	font: inherit;
	font-size: 15px;
	color: var(--clos-navy, #16265C);
	background: #fff;
	border: 1.5px solid var(--clos-line, #E2E8F2);
	border-radius: 8px;
	transition: border-color .2s ease, box-shadow .2s ease;
}

.ncxb-search input[type=search]::placeholder { color: #93A0B5; }

.ncxb-search input[type=search]:focus {
	outline: none;
	border-color: var(--clos-navy, #16265C);
	box-shadow: 0 0 0 3px rgba( 22, 38, 92, .12 );
}

.ncxb-search input[type=search]:focus-visible {
	outline: 2px solid var(--clos-navy, #16265C);
	outline-offset: 2px;
}

.ncxb-count {
	margin: 8px 0 0;
	min-height: 20px;
	font-size: 14px;
	color: #5D6C86;
}

.ncxb-empty {
	padding: 40px 0 8px;
	font-size: 17px;
	color: #5D6C86;
}

@media (max-width: 600px) {
	.ncxb-search input[type=search] { max-width: none; }
}

/* v7.3a  Porto's screen-reader-text helper does not exist here, so the label
   rendered inline and looked accidental. Keeping it visible is the better
   answer anyway: a real label beats a placeholder, which disappears the
   moment somebody starts typing.                                          */
.ncxb-search label {
	display: block;
	margin: 0 0 8px;
	font-size: 13px;
	font-weight: 700;
	letter-spacing: .08em;
	text-transform: uppercase;
	color: #5D6C86;
}

/* ══ v7.4 ══ mega menu headings ═══════════════════════════════════════
   These were Poppins 700 with body leading of 1.7 and no tracking, so a
   two line item like High Rise and Multi Residential drifted apart and
   read soft. The site sets headings at 800 with negative tracking and
   tight leading; the menu now follows the same rule instead of looking
   like bold body text.                                                  */

.ncxh-mega-list a strong,
.ncxh-mega-lead-body strong {
	font-weight: 600;
	letter-spacing: -.2px;
	line-height: 1.28;
	display: block;
	margin-bottom: 4px;
	color: var(--clos-navy, #16265C);
}

.ncxh-mega-lead-body strong {
	font-size: 18px; font-weight: 700;
	letter-spacing: -.3px;
}

/* the supporting line underneath is body copy, so it keeps body leading
   but drops back in weight and colour so the heading leads clearly */
.ncxh-mega-list a span,
.ncxh-mega-lead-body span {
	font-weight: 400;
	line-height: 1.5;
	color: #5D6C86;
}

/* v7.5  the lead tile picture follows the hovered item, so the panel
   previews where you are about to go. Crossfaded rather than snapped,
   and held still for anyone who has asked for reduced motion.          */
.ncxh-mega-lead-img {
	transition: background-image .28s ease, opacity .28s ease;
}
@media (prefers-reduced-motion: reduce) {
	.ncxh-mega-lead-img { transition: none; }
}

/* v7.6  the intro pairs with the first image so a picture appears directly
   under the banner rather than after a full width block of text. Copy sits
   left, image right, stacking image first on narrow screens. */
.ncxs-split-img--right { order: 2; }
@media (max-width: 860px) { .ncxs-split-img--right { order: 0; } }

/* ══ v7.7 ══ how we deliver, on brand navy ═══════════════════════════
   The delivery sequence is the same on every service page, so it reads
   as a band across the middle of the page rather than another tinted
   section. Navy separates it from the content either side.             */

.ncx .ncx-deliver-sec {
	background: linear-gradient( 160deg, #0A1A30 0%, #16265C 55%, #12203F 100% );
	color: rgba( 255, 255, 255, .88 );
}

.ncx .ncx-deliver-sec h2,
.ncx .ncx-deliver-sec h3 { color: #fff; }

.ncx .ncx-deliver-sec .ncx-head p,
.ncx .ncx-deliver-sec .ncx-step p { color: rgba( 255, 255, 255, .78 ); }

/* the underline rule under the heading needs to show on navy */
.ncx .ncx-deliver-sec h2.ncx-underline::after { background: var( --clos-grad ); }

.ncx .ncx-deliver-sec .ncx-step {
	background: rgba( 255, 255, 255, .05 );
	border: 1px solid rgba( 255, 255, 255, .12 );
	border-radius: 14px;
	padding: 26px 24px 24px;
}

.ncx .ncx-deliver-sec .ncx-step-n {
	background: var( --clos-grad );
	color: #fff;
	box-shadow: 0 6px 18px rgba( 0, 0, 0, .28 );
}

/* v7.7a  the step number was a gradient clipped to the text. Overriding its
   background turned it into a full width bar. It is now an explicit badge,
   which is what it looked like it was all along.                         */
.ncx .ncx-deliver-sec .ncx-step-n {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 40px;
	height: 40px;
	flex: 0 0 40px;
	border-radius: 50%;
	font-size: 17px;
	font-weight: 800;
	line-height: 1;
	margin-bottom: 14px;
	-webkit-text-fill-color: #fff;
	-webkit-background-clip: border-box;
	background-clip: border-box;
}

/* v7.7b  solid dark navy, no gradient anywhere in this band. The step
   number is a plain white disc with navy figures: no orange, and it
   reads at a glance rather than competing with the headings.           */
.ncx .ncx-deliver-sec {
	background: #0A1A30;
	background-image: none;
}
.ncx .ncx-deliver-sec .ncx-step-n {
	background: #fff;
	background-image: none;
	color: var( --clos-navy, #16265C );
	-webkit-text-fill-color: var( --clos-navy, #16265C );
	box-shadow: none;
}
.ncx .ncx-deliver-sec h2.ncx-underline::after { background: #fff; opacity: .35; }
.ncx .ncx-deliver-sec .ncx-eyebrow {
	background: none;
	-webkit-text-fill-color: rgba( 255, 255, 255, .72 );
	color: rgba( 255, 255, 255, .72 );
}

/* v7.7c  back to the brand navy rather than the near black. Still solid,
   still no gradient, but it is now the same navy used across the site. */
.ncx .ncx-deliver-sec { background: var( --clos-navy, #16265C ); background-image: none; }

/* v7.7d  a step darker than the brand navy without going near black.
   Sits between #16265C and #0A1A30. */
.ncx .ncx-deliver-sec { background: #12204A; background-image: none; }

/* v7.8  the closing ask now lives inside the delivery band, so it needs a
   separator rather than its own background. Same row layout as the old
   standalone call to action, stacking on narrow screens. */
.ncxs-close {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: space-between;
	gap: 22px;
	margin-top: clamp( 36px, 5vw, 60px );
	padding-top: clamp( 30px, 4vw, 46px );
	border-top: 1px solid rgba( 255, 255, 255, .16 );
}
.ncxs-close h2 { color: #fff; margin: 0 0 8px; }
.ncxs-close p  { color: rgba( 255, 255, 255, .78 ); margin: 0; max-width: 52ch; }
@media (max-width: 760px) {
	.ncxs-close { flex-direction: column; align-items: stretch; }
}

/* v7.8a  the band carries two jobs now, so it was running tall. Tightened
   throughout: less section padding, a smaller heading, shorter step cards
   and a narrower gap before the closing ask.                            */
.ncx .ncx-deliver-sec {
	padding-top: clamp( 44px, 5vw, 66px );
	padding-bottom: clamp( 44px, 5vw, 66px );
}
.ncx .ncx-deliver-sec .ncx-head { margin-bottom: clamp( 26px, 3vw, 38px ); }
.ncx .ncx-deliver-sec .ncx-head h2 {
	font-size: clamp( 24px, 2.5vw, 32px );
	max-width: 22ch;
	margin-left: auto;
	margin-right: auto;
}
.ncx .ncx-deliver-sec .ncx-head p { font-size: 15px; max-width: 62ch; margin-left: auto; margin-right: auto; }
.ncx .ncx-deliver-sec .ncx-step { padding: 20px 18px 18px; }
.ncx .ncx-deliver-sec .ncx-step h3 { font-size: 17px; margin-bottom: 6px; }
.ncx .ncx-deliver-sec .ncx-step p  { font-size: 14px; line-height: 1.55; }
.ncx .ncx-deliver-sec .ncx-step-n {
	width: 32px; height: 32px; flex: 0 0 32px; font-size: 15px; margin-bottom: 10px;
}
.ncx .ncxs-close {
	margin-top: clamp( 26px, 3vw, 38px );
	padding-top: clamp( 22px, 2.6vw, 32px );
}
.ncx .ncxs-close h2 { font-size: clamp( 21px, 2.1vw, 26px ); }
.ncx .ncxs-close p  { font-size: 15px; }

/* v7.9  Our Partners. Logos sit on white tiles at a common height so that
   wildly different source artwork reads as one row. Muted by default and
   full colour on hover, so the strip supports the page rather than
   shouting over the closing ask above it. */
.ncxp-partners { background: #F4F7FB; }
.ncxp-logos {
	list-style: none;
	margin: 0;
	padding: 0;
	display: grid;
	grid-template-columns: repeat( auto-fit, minmax( 150px, 1fr ) );
	gap: 14px;
}
.ncxp-logos li {
	display: flex;
	align-items: center;
	justify-content: center;
	background: #fff;
	border: 1px solid var( --clos-line, #E2E8F2 );
	border-radius: 12px;
	padding: 18px 16px;
	min-height: 88px;
}
.ncxp-logos img {
	max-width: 100%;
	height: auto;
	max-height: 42px;
	width: auto;
	object-fit: contain;
	filter: grayscale( 1 );
	opacity: .68;
	transition: filter .22s ease, opacity .22s ease;
}
.ncxp-logos li:hover img { filter: grayscale( 0 ); opacity: 1; }
@media (prefers-reduced-motion: reduce) { .ncxp-logos img { transition: none; } }

/* v7.9a  partners as a moving strip, matching netraclouds. The track holds
   the list twice so the loop has no seam, and translating half its width
   returns it exactly to the start. Paused on hover and held still for
   anyone who has asked for reduced motion. */
.ncxp-partners { background: #F4F7FB; }
.ncxp-partners .ncx-head { margin-bottom: 28px; }
.ncxp-marquee { overflow: hidden; width: 100%; -webkit-mask-image: linear-gradient( 90deg, transparent, #000 8%, #000 92%, transparent ); mask-image: linear-gradient( 90deg, transparent, #000 8%, #000 92%, transparent ); }
.ncxp-track { display: flex; align-items: center; width: max-content; animation: ncxp-scroll linear infinite; animation-duration: calc( var( --ncx-n, 13 ) * 3.2s ); }
.ncxp-marquee:hover .ncxp-track { animation-play-state: paused; }
@keyframes ncxp-scroll { from { transform: translateX( 0 ); } to { transform: translateX( -50% ); } }
.ncxp-box { flex: 0 0 auto; display: flex; align-items: center; justify-content: center; padding: 0 30px; }
.ncxp-box img { height: 40px; width: auto; max-width: 150px; object-fit: contain; filter: grayscale( 1 ); opacity: .62; transition: filter .22s ease, opacity .22s ease; }
.ncxp-box:hover img { filter: grayscale( 0 ); opacity: 1; }
@media (prefers-reduced-motion: reduce) {
	.ncxp-track { animation: none; }
	.ncxp-box img { transition: none; }
}

/* v7.9b  the phone button was a ghost style built for light backgrounds, so
   on the navy closing band it was dark text on a dark field. White outline
   and white text where it sits on navy. */
.ncx .ncxs-close .ncx-btn--outline {
	border-color: rgba( 255, 255, 255, .55 );
	color: #fff;
}
.ncx .ncxs-close .ncx-btn--outline:hover {
	background: rgba( 255, 255, 255, .1 );
	border-color: #fff;
	color: #fff;
}

/* v7.9c  logos in full colour and smaller. The muted treatment was making
   them read as an afterthought; at this size they sit in the strip without
   competing with the section above. */
.ncxp-box { padding: 0 22px; }
.ncxp-box img {
	height: 28px;
	max-width: 112px;
	filter: none;
	opacity: 1;
}
.ncxp-box:hover img { filter: none; opacity: 1; transform: scale( 1.06 ); }
.ncxp-box img { transition: transform .2s ease; }
@media (prefers-reduced-motion: reduce) { .ncxp-box:hover img { transform: none; } }
@media (max-width: 700px) { .ncxp-box { padding: 0 16px; } .ncxp-box img { height: 24px; max-width: 96px; } }

/* v7.9d  body.ncx-page img sets height:auto at (0,1,2), which outranked
   .ncxp-box img at (0,1,1), so the logo sizing was being ignored while the
   colour and opacity applied. Two classes plus the element wins cleanly
   without reaching for !important. */
.ncx .ncxp-box img { height: 28px; width: auto; max-width: 112px; }
@media (max-width: 700px) { .ncx .ncxp-box img { height: 24px; max-width: 96px; } }

/* v7.9e  smaller again, and no plate behind them. The logo files now carry
   their alpha channel, so they sit directly on the section colour instead
   of on a white rectangle. */
.ncx .ncxp-box img { height: 22px; max-width: 92px; }
.ncxp-box { padding: 0 20px; }
@media (max-width: 700px) { .ncx .ncxp-box img { height: 19px; max-width: 78px; } .ncxp-box { padding: 0 14px; } }

/* v7.9f  a step back up from 22px. Still well short of the plated version,
   but readable at a glance rather than needing a squint. */
.ncx .ncxp-box img { height: 30px; max-width: 124px; }
.ncxp-box { padding: 0 26px; }
@media (max-width: 700px) { .ncx .ncxp-box img { height: 25px; max-width: 104px; } .ncxp-box { padding: 0 16px; } }

/* v7.9g  the earlier rules were written as .ncx .ncxp-box img, which only
   matched inside the .ncx wrapper. On the homepage the partners strip sits
   outside it, so the logos fell back to their natural 320px width and the
   strip looked like it was repeating. Anchoring on body.ncx-page instead
   matches everywhere and still outranks body.ncx-page img. */
body.ncx-page .ncxp-box img {
	height: 30px;
	width: auto;
	max-width: 124px;
	object-fit: contain;
}
@media (max-width: 700px) {
	body.ncx-page .ncxp-box img { height: 25px; max-width: 104px; }
}

/* v7.9h  a marquee only looks seamless while one copy of the list is wider
   than the viewport. At 1636px against a 1920px screen you could see a full
   copy plus the start of the next, which reads as duplicated logos. Even
   box widths push one copy past 2500px, so only one copy is ever on screen
   and the loop stays invisible. */
.ncxp-box {
	min-width: 170px;
	padding: 0 24px;
	box-sizing: content-box;
}
@media (max-width: 700px) { .ncxp-box { min-width: 110px; padding: 0 14px; } }

/* v7.9i  another step up in logo size. Box width rises with it so one copy
   of the list stays wider than the viewport and the loop stays seamless. */
body.ncx-page .ncxp-box img { height: 38px; max-width: 158px; }
.ncxp-box { min-width: 190px; padding: 0 26px; }
@media (max-width: 700px) {
	body.ncx-page .ncxp-box img { height: 30px; max-width: 120px; }
	.ncxp-box { min-width: 120px; padding: 0 14px; }
}

/* v7.9j  the partners strip inherited the site wide 84px top/bottom section
   padding, which is sized for content heavier than a one line heading and
   a marquee. Cut it down so the band reads as a strip, not another full
   size section. */
.ncx .ncxp-partners { padding: 40px 0; }
.ncx .ncxp-partners .ncx-head { margin-bottom: 18px; }
@media (max-width: 700px) { .ncx .ncxp-partners { padding: 30px 0; } }

/* v7.9k  .ncx .ncxp-partners does not match on the homepage, the same gap
   that broke the logo sizing earlier: the partners include sits outside
   the .ncx wrapper there. body.ncx-page matches on every page regardless
   of where the include lands, and still outranks the plain .ncx-sec rule. */
body.ncx-page .ncxp-partners { padding: 40px 0; }
body.ncx-page .ncxp-partners .ncx-head { margin-bottom: 18px; }
@media (max-width: 700px) { body.ncx-page .ncxp-partners { padding: 30px 0; } }

/* v7.7e  the number badges lost all brand colour when the orange and the
   gradient were pulled off the band background. This restores a touch of
   the brand gradient on the badge itself only, a small accent rather than
   a wash across the whole section, which stays solid navy. */
.ncx .ncx-deliver-sec .ncx-step-n {
	background: var( --clos-grad );
	background-image: var( --clos-grad );
	color: #fff;
	-webkit-text-fill-color: #fff;
	box-shadow: 0 6px 16px rgba( 0, 0, 0, .3 );
}

/* v7.7f  the eyebrow above 'One team from design through commissioning'
   was flattened to muted white when the navy band went in, which dropped
   the brand gradient every other eyebrow on the site carries. Restored: the
   gradient clip-text treatment reads fine against dark navy. */
.ncx .ncx-deliver-sec .ncx-eyebrow {
	background: var( --clos-grad );
	-webkit-background-clip: text;
	background-clip: text;
	-webkit-text-fill-color: transparent;
	color: transparent;
}

/* v7.7g  the underline bar between the heading and the paragraph had two
   competing rules at identical specificity: one setting it to the brand
   gradient, one forcing it to plain white, added later and winning by
   cascade order alone. This settles it on the gradient for good. */
.ncx .ncx-deliver-sec h2.ncx-underline::after {
	background: var( --clos-grad );
	opacity: 1;
}

/* ══ v8.0 ══ homepage 'How We Work' on navy ══════════════════════════
   Scoped to .ncx-steps-sec only, which after the v7.7 rename is used
   solely by the homepage. The service page delivery band is a separate
   class (.ncx-deliver-sec) and cannot be affected by this.

   Headings default to navy text sitewide, which would be invisible here,
   so heading and body colours are set explicitly. The STEP 0X labels and
   the eyebrow already carry the brand gradient as text fill from their
   base rules and need no change; they read fine on dark navy as is. */

.ncx .ncx-steps-sec {
	background: #12204A;
	background-image: none;
}

.ncx .ncx-steps-sec h2,
.ncx .ncx-steps-sec h3 { color: #fff; }

.ncx .ncx-steps-sec .ncx-head p { color: rgba( 255, 255, 255, .78 ); }

.ncx .ncx-steps-sec h2.ncx-underline::after {
	background: var( --clos-grad );
	opacity: 1;
}

.ncx .ncx-steps-sec .ncx-step {
	background: rgba( 255, 255, 255, .05 );
	border: 1px solid rgba( 255, 255, 255, .12 );
	box-shadow: none;
}

.ncx .ncx-steps-sec .ncx-step p { color: rgba( 255, 255, 255, .76 ); }

/* ══ v8.1 ══ contact form on the design system ═══════════════════════
   WPForms ships neutral grey defaults. Restyled to the brand: navy
   labels, brand focus ring, gradient submit matching every other button. */
body.ncx-page .wpforms-container { margin: 8px 0 0; }
body.ncx-page .wpforms-field label.wpforms-field-label {
	color: var( --clos-navy, #16265C );
	font-weight: 700;
	font-size: 14.5px;
	margin-bottom: 6px;
}
body.ncx-page .wpforms-field input[type=text],
body.ncx-page .wpforms-field input[type=email],
body.ncx-page .wpforms-field input[type=tel],
body.ncx-page .wpforms-field textarea {
	width: 100%;
	max-width: 640px;
	padding: 12px 16px;
	font: inherit;
	font-size: 15px;
	color: var( --clos-navy, #16265C );
	background: #fff;
	border: 1.5px solid var( --clos-line, #E2E8F2 );
	border-radius: 8px;
	transition: border-color .2s ease, box-shadow .2s ease;
}
body.ncx-page .wpforms-field input:focus,
body.ncx-page .wpforms-field textarea:focus {
	outline: none;
	border-color: var( --clos-navy, #16265C );
	box-shadow: 0 0 0 3px rgba( 22, 38, 92, .12 );
}
body.ncx-page .wpforms-submit,
body.ncx-page button[type=submit].wpforms-submit {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	padding: 12px 26px;
	font: inherit;
	font-size: 14.5px;
	font-weight: 700;
	color: #fff;
	background: var( --clos-grad );
	border: 0;
	border-radius: 8px;
	cursor: pointer;
	transition: transform .16s ease, box-shadow .22s ease;
}
body.ncx-page .wpforms-submit:hover { transform: translateY( -2px ); }
body.ncx-page .wpforms-submit:focus-visible { outline: 2px solid var( --clos-navy, #16265C ); outline-offset: 3px; }
body.ncx-page .wpforms-field { margin-bottom: 18px; }
body.ncx-page label.wpforms-error { color: #C81E1E; font-size: 13.5px; margin-top: 4px; }
@media (prefers-reduced-motion: reduce) { body.ncx-page .wpforms-submit:hover { transform: none; } }

/* ══ v8.2 ══ FAQ accordion + touch target fixes from the skill audit ══ */
.ncxs-qa { border-bottom: 1px solid var( --clos-line, #E2E8F2 ); }
.ncxs-qa summary {
	cursor: pointer;
	list-style: none;
	position: relative;
	padding: 16px 40px 16px 0;
	font-weight: 700;
	font-size: 16.5px;
	color: var( --clos-navy, #16265C );
	min-height: 44px;                      /* touch target */
	display: flex; align-items: center;
}
.ncxs-qa summary::-webkit-details-marker { display: none; }
.ncxs-qa summary::after {
	content: '+'; position: absolute; right: 4px;
	font-size: 22px; font-weight: 400; color: #5D6C86;
	transition: transform .2s ease;
}
.ncxs-qa[open] summary::after { transform: rotate( 45deg ); }
.ncxs-qa summary:focus-visible { outline: 2px solid var( --clos-navy ); outline-offset: 2px; }
.ncxs-qa p { margin: 0 0 18px; color: #3D4C66; }
@media (prefers-reduced-motion: reduce) { .ncxs-qa summary::after { transition: none; } }

/* carousel dots were 10px tap targets. Visual size unchanged; the hit
   area grows to 44px via padding on the button itself. */
.ncx .ncx-dot { position: relative; padding: 17px; box-sizing: content-box; background-clip: content-box; }

/* footer + topbar links: comfortable touch rows on small screens */
@media (max-width: 700px) {
	.ncxf a, .ncxh-top a { display: inline-block; padding: 9px 0; }
}

/* nav-state-active: the section you are in stays marked in the header */
.ncxh-menu > li.is-here > a { color: var( --clos-g1, #F4772E ); }
.ncxh-menu > li.is-here > a::after {
	content: ''; position: absolute; left: 0; right: 0; bottom: -6px;
	height: 2px; background: var( --clos-grad );
}
.ncxh-menu > li.is-here { position: relative; }

/* v8.2a  the active underline anchored to the li and rendered as a floating
   bar below the header. Anchor it to the link itself, sized to the text. */
.ncxh-menu > li.is-here > a { position: relative; }
.ncxh-menu > li.is-here > a::after {
	content: ''; position: absolute; left: 0; right: 14px; bottom: 2px;
	height: 2px; background: var( --clos-grad ); border-radius: 2px;
}
.ncxh-menu > li.is-here:not(.has-mega) > a::after { right: 0; }

/* ══ v8.3 ══ footer accessibility note alignment ═════════════════════
   A later paragraph rule overrode margin auto on .ncxf-a11y, so the note
   lost its centering and hugged the viewport edge while the columns above
   sat centered in their wrap. Re-stated with enough specificity to hold,
   using the same wrap width as the rest of the footer. */
.ncxf p.ncxf-a11y,
body.ncx-page .ncxf p.ncxf-a11y {
	max-width: var( --clos-wrap, 1320px );
	margin: 0 auto;
	padding: 16px clamp( 16px, 2.4vw, 24px ) 0;
}

/* The logo is a brand asset, not filler: it must never be flex-shrunk to
   make room for the nav. Without this the bar quietly squashed a 200px
   logo down to ~178px whenever the row ran a few pixels over budget.    */
.ncxh-logo { flex-shrink: 0; }

/* The universal washroom components image is an annotated diagram: its
   callout labels sit hard against the top and bottom edges. The default
   1400/900 split slot crops about 20% vertically, which decapitates the
   ADO label and cuts off Push To Open. This one image keeps its own
   ratio so the whole annotated frame survives.                          */
.ncxs-split-img img[src*="clos-washroom-components"] {
	aspect-ratio: 1402 / 1122;
}

/* Every underlined heading gets a consistent 30px of air beneath it.
   This has to out-specify "body.ncx-page h1..h6 { margin-bottom: 0 }"
   further up the file, so the selector is body scoped rather than a
   bare .ncx-underline, which the reset would otherwise win against.   */
body.ncx-page .ncx-underline,
.ncx .ncx-underline,
.ncx-underline {
	margin-bottom: 30px;
}

/* Headings run in title case: every word starts with a capital. This is a
   display transform only, so the underlying markup keeps its original
   sentence case for search engines and screen readers. Acronyms such as
   IT and VOIP are untouched, since capitalize only raises the first
   letter of a word and never lowercases the rest.                       */
body.ncx-page h1,
body.ncx-page h2,
body.ncx-page h3,
body.ncx-page h4,
body.ncx-page h5,
body.ncx-page h6 {
	text-transform: capitalize;
}

/* Accessible door operator diagrams. Both carry dimension callouts that run
   right to the frame edge, so the default 1400/900 split slot clips them:
   17% off the sides of the mounting heights drawing and 7% off the spec
   sheet. Each keeps its native ratio so no measurement is lost.          */
.ncxs-split-img img[src*="accessible-door-operator-mounting-heights"] {
	aspect-ratio: 1717 / 916;
}
.ncxs-split-img img[src*="automatic-door-operator-activation-options"] {
	aspect-ratio: 1622 / 970;
}

/* Access control diagrams. Both carry their headline text hard against the
   left edge and a dashboard against the right, so the 1400/900 split slot
   clipped 7% and 11% off the sides. Native ratios keep both readable.    */
.ncxs-split-img img[src*="door-status-monitoring-access-control"] {
	aspect-ratio: 1622 / 970;
}
.ncxs-split-img img[src*="access-control-scheduling-software"] {
	aspect-ratio: 1662 / 946;
}

/* Garage and vehicle access diagrams. Headline and feature list sit at the
   left edge, phone panel at the right, so the 1400/900 slot clipped ~7%
   off both sides. Native ratios keep the full composition.               */
.ncxs-split-img img[src*="parking-garage-access-control"] {
	aspect-ratio: 1620 / 971;
}
.ncxs-split-img img[src*="vehicle-access-control-anti-tailgating"] {
	aspect-ratio: 1622 / 970;
}

/* The hotel common door graphic carries its headline and the 201-205 lock
   row in a right hand panel, so the 1400/900 slot clipped 16% off the
   sides and cut the last room off. Native ratio keeps the panel whole.  */
.ncxs-split-img img[src*="hotel-common-door-access-control"] {
	aspect-ratio: 1707 / 921;
}

/* v8.3: the header logo read small against the 78px bar (176px wide is a
   32px tall mark; netraclouds runs its mark at 46px). Sized up toward
   parity, stepping down where the nav gets tight, and matched in the 66px
   mobile bar. File order beats the earlier equal-specificity rules. */
.ncxh-logo img { width: 248px; }
@media (min-width: 1200px) and (max-width: 1420px) { .ncxh-logo img { width: 208px; } }
@media (min-width: 1200px) and (max-width: 1240px) { .ncxh-logo img { width: 200px; } }
@media (max-width: 1199px) { .ncxh-logo img { width: 216px; } }
@media (max-width: 480px) { .ncxh-logo img { width: 188px; } }

/* Card grids inside owner supplied service sections. The card component is
   the one from the home page; these rules only handle the case where a card
   carries its own short list, and keep the grid breathing under the section
   text rather than butting straight against it.                          */
.ncxs-cards { margin-top: 34px; }
.ncxs-cards .ncx-card { display: flex; }
.ncxs-cards .ncx-card-body { padding: 26px 24px 28px; }
.ncxs-cards .ncx-card-body h3 { margin-bottom: 10px; }
.ncx-checks--tight { margin-top: 14px; }
.ncx-checks--tight li { font-size: 14px; margin-bottom: 7px; }

/* A steps band sitting inside a normal section needs its own top gap; the
   delivery band gets this from the section head above it.                */
.ncx-sec .ncx-steps { margin-top: 34px; }

/* The step component was written for the dark delivery band, so its heading
   and copy are white. Used inside an ordinary light section that renders as
   white on white: numbers visible, words gone. Restore body colours unless
   the step really is on the dark band.                                    */
.ncx-sec:not(.ncx-deliver-sec):not(.ncx-steps-sec) .ncx-step h3 {
	color: var(--clos-navy, #16265C);
}
.ncx-sec:not(.ncx-deliver-sec):not(.ncx-steps-sec) .ncx-step p {
	color: #5D6C86;
}

/* v8.4: AODA contrast. The muted grey #7A8AA6 measures 3.5:1 on white and
   is used for 12-13.5px meta text (chips, dates, captions, TOC markers),
   which needs 4.5:1. #5D6E8C measures 5.2:1 and keeps the same cool cast.
   Netraclouds carries the same token and should get the same value for
   parity. Both definition scopes overridden; file order wins. */
:root { --clos-muted: #5D6E8C; }
.ncx { --clos-muted: #5D6E8C; }

/* v8.5: AODA button contrast (owner approved 2026-07-30). White button
   text on the brand gradient measured 2.8:1 at the orange end; buttons
   now carry the same orange to red journey two shades deeper, 5.7:1 at
   every stop. Decorative gradients (underlines, marquee, hero accents)
   keep the original bright run. Hover states already resolve to navy or
   white and were fine. Netraclouds should mirror this for parity. */
:root { --clos-grad-btn: linear-gradient(100deg, #B3400E 0%, #BE2F45 52%, #C81E1E 100%); }
.ncx-btn--grad, .ncxh-cta, .ncxh .ncxh-cta, .ncxf a.ncxf-btn, .ncxf-btn { background: var(--clos-grad-btn); }

/* v8.6: the All Services page was bare heading and bullet lists through
   the generic template. Rebuilt as linked cards per technology group;
   the page id gets the full wrap because cards need the band, not the
   820px prose measure. */
.page-id-20532 .ncxs-measure { max-width: var( --clos-wrap, 1320px ); }
.ncxsv-group { margin-bottom: 14px; }
.ncxsv-grid { display: grid; grid-template-columns: repeat( 3, 1fr ); gap: 18px; margin: 22px 0 40px; }
.ncxsv-card { display: block; padding: 20px 22px; border: 1px solid var( --clos-line ); border-radius: var( --clos-radius ); background: #fff; text-decoration: none; transition: box-shadow .2s ease, transform .2s ease; }
.ncxsv-card strong { display: block; color: var( --clos-navy ); font-size: 16.5px; margin-bottom: 6px; }
.ncxsv-card span { display: block; color: var( --clos-body ); font-size: 14.5px; line-height: 1.55; }
.ncxsv-card:hover { box-shadow: 0 10px 26px rgba( 10, 26, 48, .10 ); transform: translateY( -2px ); }
.ncxsv-card:hover strong { color: var( --clos-accent ); }
.ncxsv-card:focus-visible { outline: 3px solid var( --clos-accent ); outline-offset: 2px; }
@media (prefers-reduced-motion: reduce) { .ncxsv-card { transition: none; } .ncxsv-card:hover { transform: none; } }
@media (max-width: 980px) { .ncxsv-grid { grid-template-columns: repeat( 2, 1fr ); } }
@media (max-width: 620px) { .ncxsv-grid { grid-template-columns: 1fr; } }

/* v8.6.1: wpautop injects p and br between the service cards and each
   injected p becomes an empty grid cell, scattering the layout. Dissolve
   anything wpautop adds inside the grid; the a.ncxsv-card children lay
   out directly on the grid again. */
.ncxsv-grid > p { display: contents; }
.ncxsv-grid br { display: none; }

/* v8.7: two header faults the owner hit on /boardrooms/ at zoomed widths.
   1. The is-here active rule (v-earlier, L2580) set position:relative on
      the li, beating the has-mega position:static at equal specificity by
      file order, so the ACTIVE menu item anchored its mega panel to the li
      and the panel ran past the right edge of the screen. The underline
      anchors to the a, not the li, so the li can stay static.
   2. With Home in the menu and the larger logo, the 1200 to 1420 range
      overflowed and pushed Contact Us off screen. Tightened until the row
      fits at 1200 with everything visible. */
.ncxh-menu > li.is-here.has-mega { position: static; }
@media (min-width: 1200px) and (max-width: 1420px) {
	.ncxh-logo img { width: 176px; }
	.ncxh-bar { gap: 20px; }
	.ncxh-menu { gap: 12px; }
	.ncxh-menu > li > a { font-size: 13.5px; }
	.ncxh-nav { gap: 14px; }
	.ncxh-cta { padding: 11px 14px; font-size: 13.5px; }
}
@media (min-width: 1200px) and (max-width: 1240px) {
	.ncxh-logo img { width: 160px; }
	.ncxh-menu { gap: 9px; }
	.ncxh-menu > li > a { font-size: 13px; }
}

/* v8.8: Our Partners page logo grids (one per technology group) plus the
   AODA leftovers. Stat numbers were gradient text at 2.79:1 where large
   text needs 3:1; the deep button gradient reads 5.7:1 and keeps the
   brand journey. Navy-section eyebrows were gradient text whose red end
   read 2.5:1 on navy; solid brand orange reads 5.1:1 there. */
.ncxpp-logos { display: grid; grid-template-columns: repeat( auto-fill, minmax( 150px, 1fr ) ); gap: 14px; margin: 18px 0 34px; }
.ncxpp-logos > p { display: contents; }
.ncxpp-logos br { display: none; }
.ncxpp-logos img { width: 100%; height: auto; border: 1px solid var( --clos-line ); border-radius: 10px; background: #fff; padding: 10px 16px; box-sizing: border-box; }
.ncx-stat-n { background: var( --clos-grad-btn ); -webkit-background-clip: text; background-clip: text; }
.ncx-sec--navy .ncx-eyebrow { background: none; -webkit-background-clip: border-box; background-clip: border-box; color: var( --clos-g1, #F4772E ); -webkit-text-fill-color: var( --clos-g1, #F4772E ); }

/* v8.9: owner wants the four VOIP feature tiles the same length. The
   base .ncx-feat grid aligns items start, so each card stopped at its
   own content. Stretch them in the voice section so all four match the
   tallest. */
.ncx-voice .ncx-feat { align-items: stretch; }

/* ============================================================
   v9.0: design-skills polish pass (Emil Kowalski + taste-skill +
   impeccable, owner-approved 2026-07-31). Brand, layout and copy are
   locked; this layer touches only how the interface RESPONDS.
   Principles applied: custom easing curves (built-ins are too weak),
   press feedback on every pressable, stronger ease-out on enter
   transitions, slow elegant image settles, touch devices excluded
   from hover lifts. The global reduced-motion killswitch above
   already covers everything added here.
   ============================================================ */
:root {
	--ease-out-strong: cubic-bezier(0.23, 1, 0.32, 1);
	--ease-in-out-strong: cubic-bezier(0.77, 0, 0.175, 1);
}

/* every pressable acknowledges the press (Emil: the UI is listening) */
.ncx-btn:active, .ncxh-cta:active, .ncxf-btn:active,
.ncxb-chip:active, .ncxsv-card:active, .ncxsv-card:active strong {
	transform: scale(0.98);
}
.ncx-btn {
	transition: background .25s ease, color .25s ease, border-color .25s ease,
		transform .16s var(--ease-out-strong), box-shadow .22s var(--ease-out-strong);
}
.ncxh-cta, .ncxf-btn, .ncxb-chip {
	transition: background .22s ease, color .22s ease, border-color .22s ease,
		transform .16s var(--ease-out-strong);
}

/* menus enter with intent: same distance, stronger curve */
.ncxh-mega {
	transition: opacity .18s var(--ease-out-strong),
		transform .18s var(--ease-out-strong), visibility .18s;
}
.ncxh-menu .sub-menu {
	transition: opacity .16s var(--ease-out-strong),
		transform .16s var(--ease-out-strong), visibility .16s;
}
.ncxh-caret { transition: transform .2s var(--ease-out-strong); }

/* cards lift with a confident settle, images drift slower than the card */
.ncx-card, .ncxb-card, .ncxsv-card {
	transition: transform .22s var(--ease-out-strong),
		box-shadow .3s ease, border-color .25s ease;
}
.ncx-card-img img, .ncx-tile img, .ncxb-card-img img {
	transition: transform .7s var(--ease-out-strong);
}
.ncxsv-card:hover { transform: translateY(-2px); }

/* touch devices get taps, not hover physics */
@media (hover: none) {
	.ncx-card:hover, .ncxb-card:hover, .ncxsv-card:hover,
	.ncx-btn--grad:hover { transform: none; }
}

/* v9.1: craft floor (best of Emil + taste + impeccable, round two).
   Every rule is progressive enhancement; nothing here can break a
   browser that ignores it. */

/* brand-tinted text selection */
::selection { background: var(--clos-navy, #16265C); color: #fff; }

/* anchor jumps land below the sticky header instead of under it */
h2[id], h3[id], section[id], .ncxs-qa[id] { scroll-margin-top: 100px; }
@media (prefers-reduced-motion: no-preference) { html { scroll-behavior: smooth; } }

/* headings never strand a single word on their own line */
h1, h2, h3 { text-wrap: balance; }

/* stat digits align like instruments, not prose */
.ncx-stat-n, .ncx-step-n { font-variant-numeric: tabular-nums; }

/* native form controls carry the brand */
input, select, textarea { accent-color: var(--clos-accent, #E11D48); }

/* one focus language everywhere custom rules do not already speak */
:where(a, button, input, select, textarea, summary):focus-visible {
	outline: 3px solid var(--clos-accent, #E11D48);
	outline-offset: 2px;
}

/* entrance reveal: cards rise 12px and settle as they enter view.
   Gated behind .ncx-reveal-on, which ONLY the footer script sets after
   confirming IntersectionObserver exists, so no JS means no hiding.
   The global reduced-motion killswitch collapses it to instant. */
.ncx-reveal-on .ncx-card,
.ncx-reveal-on .ncx-tile,
.ncx-reveal-on .ncxsv-card,
.ncx-reveal-on .ncx-feat-col {
	opacity: 0;
	transform: translateY(12px);
	transition: opacity .5s var(--ease-out-strong), transform .5s var(--ease-out-strong);
}
.ncx-reveal-on .ncx-card.is-in,
.ncx-reveal-on .ncx-tile.is-in,
.ncx-reveal-on .ncxsv-card.is-in,
.ncx-reveal-on .ncx-feat-col.is-in {
	opacity: 1;
	transform: none;
}
/* short cascade inside a grid: 60ms steps, capped at four */
.ncx-reveal-on .is-in:nth-child(2) { transition-delay: .06s; }
.ncx-reveal-on .is-in:nth-child(3) { transition-delay: .12s; }
.ncx-reveal-on .is-in:nth-child(4) { transition-delay: .18s; }
@media (prefers-reduced-motion: reduce) {
	.ncx-reveal-on .ncx-card, .ncx-reveal-on .ncx-tile,
	.ncx-reveal-on .ncxsv-card, .ncx-reveal-on .ncx-feat-col {
		opacity: 1; transform: none; transition: none;
	}
}

/* v9.2: entrance reveal, second architecture. The v9.1 class-gated
   approach above is retired (nothing sets .ncx-reveal-on any more);
   its rules are inert. This version is fail-open by construction:
   elements are never hidden by default. The footer script adds
   .ncx-anim-in as an element enters the viewport, which plays a
   one-shot rise; with no JS, no observer, or any failure at all,
   content simply sits visible. Global reduced-motion killswitch
   already covers animation: none !important. */
@keyframes ncx-rise {
	from { opacity: 0; transform: translateY(12px); }
}
.ncx-anim-in { animation: ncx-rise .55s var(--ease-out-strong) both; }
.ncx-anim-in:nth-child(2) { animation-delay: .07s; }
.ncx-anim-in:nth-child(3) { animation-delay: .14s; }
.ncx-anim-in:nth-child(4) { animation-delay: .21s; }
@media (prefers-reduced-motion: reduce) { .ncx-anim-in { animation: none; } }

/* v9.3: entrance reveal RETIRED (owner: pages felt slow to load; the
   rise animation delayed perceived content arrival, and the server was
   measured fast at 0.14-0.30s TTFB). Press feedback, easing curves and
   the craft floor stay. .ncx-anim-in is now inert. */
.ncx-anim-in { animation: none; }

/* v9.4: Services page banner (owner 2026-08-01): eyebrow + title
   centred, title in caps. */
.page-id-20532 .ncxs-banner-in .ncx-wrap { text-align: center; }
.page-id-20532 .ncxs-banner h1 { text-transform: uppercase; letter-spacing: .03em; }
.page-id-20532 .ncxs-banner h1 { margin-left: auto; margin-right: auto; }
/* the base banner h1 margin carries !important (L1865); match it */
.page-id-20532 .ncx .ncxs-banner-in h1 { margin: 0 auto 20px !important; }

/* v9.5: extend the centred caps banner to every simple title banner
   (page.php pages: Services, About, Careers, Case Studies, Our
   Partners, Contact, Privacy, Accessibility). Service-template pages
   keep their designed left-aligned heroes. */
.page-template-default .ncxs-banner-in .ncx-wrap { text-align: center; }
.page-template-default .ncxs-banner h1 { text-transform: uppercase; letter-spacing: .03em; }
.page-template-default .ncx .ncxs-banner-in h1 { margin: 0 auto 20px !important; }

/* ============================================================
   v9.6  AODA audit fixes (2026-08-01)
   1) Gradient clip text failed contrast at the red end on navy:
      deliver-sec eyebrow (small text) 2.75:1, hero highlight word
      2.95:1 against #0E1A40. Hero/slider highlight now ends at g2
      (4.33:1, passes large-text 3:1); the deliver eyebrow goes solid
      g1 (5.1:1), same treatment .ncx-sec--navy eyebrows already got.
   2) Marquee pause control: hover-pause was mouse only. Small text
      button, hidden under reduced motion where the track never moves.
   ============================================================ */
.ncx-hero h1 .ncx-hl,
.ncx-slide .ncx-hl {
	background: linear-gradient(100deg, var(--clos-g1) 0%, var(--clos-g2) 100%);
	-webkit-background-clip: text;
	background-clip: text;
}
.ncx .ncx-deliver-sec .ncx-eyebrow {
	background: none;
	-webkit-background-clip: border-box;
	background-clip: border-box;
	color: var(--clos-g1, #F4772E);
	-webkit-text-fill-color: var(--clos-g1, #F4772E);
}
.ncxp-pause {
	display: block;
	margin: 10px auto 0;
	background: none;
	border: 0;
	padding: 4px 8px;
	color: #5D6E8C;
	font: inherit;
	font-size: 13px;
	text-decoration: underline;
	cursor: pointer;
}
.ncxp-pause:hover { color: #16265C; }
.ncxp-pause:focus-visible { outline: 2px solid #E11D48; outline-offset: 3px; }
.ncxp-marquee.paused .ncxp-track { animation-play-state: paused; }
@media (prefers-reduced-motion: reduce) { .ncxp-pause { display: none; } }

/* v9.6 addendum: the field label rule never set display, so the MESSAGE
   textarea label rendered inline beside the box instead of above it. */
body.ncx-page .wpforms-field label.wpforms-field-label { display: block; }


/* ============================================================
   v9.7  contact form checkbox group (owner 2026-08-02: "not in
   very great shape"). WPForms renders a default bulleted list
   inside a bare fieldset border: bullets next to checkboxes, no
   gap before the label text, one long column. Restyled as a
   responsive grid of selectable cards; the whole card toggles
   via the label, the native checkbox stays visible, checked and
   keyboard states are obvious.
   ============================================================ */
body.ncx-page .wpforms-field-payment-checkbox fieldset {
	border: 0;
	padding: 0;
	margin: 0;
	min-width: 0;
}
body.ncx-page .wpforms-field-payment-checkbox legend.wpforms-field-label {
	display: block;
	padding: 0;
	margin: 0 0 10px;
	color: var(--clos-navy, #16265C);
	font-weight: 700;
	font-size: 14.5px;
}
body.ncx-page .wpforms-field-payment-checkbox ul {
	list-style: none;
	margin: 0;
	padding: 0;
	display: grid;
	grid-template-columns: repeat(3, 1fr);
	gap: 10px;
}
@media (max-width: 900px) {
	body.ncx-page .wpforms-field-payment-checkbox ul { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 560px) {
	body.ncx-page .wpforms-field-payment-checkbox ul { grid-template-columns: 1fr; }
}
body.ncx-page .wpforms-field-payment-checkbox li {
	position: relative;
	margin: 0;
	display: flex;
}
body.ncx-page .wpforms-field-payment-checkbox li input[type=checkbox] {
	position: absolute;
	left: 14px;
	top: 50%;
	transform: translateY(-50%);
	width: 18px;
	height: 18px;
	margin: 0;
	accent-color: var(--clos-accent, #E11D48);
}
body.ncx-page .wpforms-field-payment-checkbox li label.wpforms-field-label-inline {
	display: block;
	width: 100%;
	margin: 0;
	padding: 12px 14px 12px 44px;
	border: 1.5px solid var(--clos-line, #E4E8F0);
	border-radius: 8px;
	background: #fff;
	color: var(--clos-ink, #1B2440);
	font-size: 14.5px;
	font-weight: 600;
	line-height: 1.35;
	cursor: pointer;
	transition: border-color .15s ease, background .15s ease;
}
body.ncx-page .wpforms-field-payment-checkbox li:hover label.wpforms-field-label-inline {
	border-color: #B9C6DB;
}
body.ncx-page .wpforms-field-payment-checkbox li:has(input:checked) label.wpforms-field-label-inline {
	border-color: var(--clos-accent, #E11D48);
	background: #FDF2F5;
}
body.ncx-page .wpforms-field-payment-checkbox li:focus-within label.wpforms-field-label-inline {
	outline: 2px solid var(--clos-accent, #E11D48);
	outline-offset: 2px;
}
@media (prefers-reduced-motion: reduce) {
	body.ncx-page .wpforms-field-payment-checkbox li label.wpforms-field-label-inline { transition: none; }
}


/* ============================================================
   v9.8  header overflow (owner 2026-08-02: Contact button not
   visible at normal zoom). Measured: logo 248 + menu 1058 at
   28px gaps + CTA 129 + bar gaps needs ~1550px of viewport, but
   the burger only takes over below 1200px. Everything between
   1200 and ~1550 clipped the CTA off the right edge, and larger
   screens up to ~1720 were borderline. Two compression bands so
   the bar fits its wrap at every width above the burger point.
   ============================================================ */
@media (min-width: 1200px) and (max-width: 1719px) {
	.ncxh-bar { gap: 20px; }
	.ncxh-logo img { width: 156px; }
	.ncxh-nav { gap: 18px; }
	.ncxh-menu { gap: 18px; }
	.ncxh-menu > li > a { font-size: 14px; }
	.ncxh .ncxh-cta { padding: 12px 20px; font-size: 14px; }
}
@media (min-width: 1200px) and (max-width: 1339px) {
	.ncxh-bar { gap: 14px; }
	.ncxh-logo img { width: 140px; }
	.ncxh-nav { gap: 12px; }
	.ncxh-menu { gap: 12px; }
	.ncxh-menu > li > a { font-size: 13.5px; }
	.ncxh .ncxh-cta { padding: 11px 16px; font-size: 13.5px; }
	.ncxh .ncx-wrap { padding: 0 16px; }
}

/* v9.9  cloud page diagram slots: owner wants the artwork sitting directly
   on the page, not in a photo card. These two images carry a pure white
   background matching their sections, so the card chrome (radius, drop
   shadow) is what was reading as edges. Scoped by filename so photo slots
   elsewhere keep their card look. */
.ncxs-split-img:has(img[src*="clos-cloudsites"]),
.ncxs-split-img:has(img[src*="clos-cloudbridge"]) {
	border-radius: 0;
	box-shadow: none;
	overflow: visible;
	background: none;
}

/* v9.9a  owner: uniform navy tint on the two cloud diagrams. A flat tint
   meets the white section at a line, so the slots get their rounded corners
   back (still no drop shadow) and read as deliberate panels. */
.ncxs-split-img:has(img[src*="clos-cloudsites"]),
.ncxs-split-img:has(img[src*="clos-cloudbridge"]) {
	border-radius: 14px;
	overflow: hidden;
}

/* ══ v10.0 ══ active nav underline sits under its label ══════════════
   Owner: with a mega panel open the header read as a stack of stray
   horizontal rules. Measured live at 1920px on the Surveillance Cameras
   page: the label's glyphs end at y84.25, the orange indicator ran
   y110.75-112.75, the header hairline sits at y119 and the panel's top
   border at y124. So the indicator floated 26.5px under the word it is
   supposed to mark, then landed 6px above the header border - three
   lines inside 15px, with a void above them.

   The indicator is sized to the text (left 0 / right 14px to clear the
   caret), so this is an underline-the-label pattern, not a full width
   tab indicator. Convention for an underline is a 4-8px offset from the
   glyphs; a tab indicator is instead flush at 0. The old `bottom: 2px`
   was measured off the link box, and that box carries 28px of vertical
   padding to fill the 78px bar, so nearly all of the padding fell into
   the gap.

   28px padding - 20px offset - 2px rule leaves the rule 6px clear of
   the line box, 8.5px below the glyphs.

   Desktop only. Below 1200px these same links are drawer rows with
   14px padding and their own border-bottom, where a 20px offset would
   ride up over the text. */
@media (min-width: 1200px) {
	.ncxh-menu > li.is-here > a::after { bottom: 20px; }
}

/* ══ v10.1 ══ three body sections have to alternate ══════════════════
   Every service page now carries a third body image (the template's
   img4 slot), and with three of them two faults became obvious that
   two sections had been hiding.

   Measured on /telecommunication/ at 1920px before this rule:
     section 1  image RIGHT  593px
     section 2  image RIGHT  593px   <- same side twice
     section 3  image LEFT   623px   <- wider than the other two

   Both come from the same place. The grid is 1.05fr 1fr, so track one
   is the wider one and belongs to the text; the image belongs in the
   narrower track two. Section 2 carries --flip and was ordered to
   track two like section 1, and section 3 (image first in the markup,
   no modifier) fell into track one and picked up the text width.

   Fixed by intent rather than by another order tweak: the image always
   takes the narrower track, and the side alternates by mirroring the
   tracks on the flipped section. Result is right, left, right with all
   three images the same width.

   Desktop only. Under 861px the grid collapses to one column and the
   existing rules stack these, so ordering must not be touched there.
   The owner-supplied `sections` entries render as .ncx-sec rather than
   .ncxs-split-sec and are deliberately out of scope here. */
@media (min-width: 861px) {
	/* second section: image left, and the tracks mirror so it stays narrow */
	.ncx .ncxs-split-sec--flip .ncxs-split { grid-template-columns: 1fr 1.05fr; }
	.ncx .ncxs-split-sec--flip .ncxs-split-img  { order: 0; }
	.ncx .ncxs-split-sec--flip .ncxs-split-body { order: 2; }

	/* third section: no modifier and image first in the markup, so send it
	   back to the narrow track and match section one */
	.ncx .ncxs-split-sec:not(.ncxs-split-sec--flip)
		.ncxs-split-img:not(.ncxs-split-img--right) { order: 2; }
}

/* v10.2  the owner supplied panels are composed graphics, not photos:
   each carries labelled callouts and a footer card, so the 1400/900 body
   crop would shave the margin the artwork was drawn with. Same treatment
   already given to clos-washroom-components above: state the source ratio
   and let the whole frame survive. All are 1536x1024. */
.ncxs-split-img img[src*="cabling-pathways-containment"],
.ncxs-split-img img[src*="workstation-floor-boxes-poke-throughs"],
.ncxs-split-img img[src*="garage-door-access-reader-car-window"],
.ncxs-split-img img[src*="hotel-guest-room-lock-installation"],
.ncxs-split-img img[src*="commercial-alarm-motion-detector-selection"],
.ncxs-split-img img[src*="video-intercom-panel-replacement"],
.ncxs-split-img img[src*="office-fit-out-phased-floor-handover"],
.ncxs-split-img img[src*="high-rise-common-area-access"],
.ncxs-split-img img[src*="smb-single-supplier-cameras"],
/* the two panels already on the alarm page are the same 1536x1024 composed
   artwork and were still being cropped 3.6% by the default, which left them
   14px shorter than the one beside them. Same rule, same page, one height. */
.ncxs-split-img img[src*="commercial-alarm-system-control-panel"],
.ncxs-split-img img[src*="alarm-verification-touchscreen-panel"] {
	aspect-ratio: 1536 / 1024;
}

/* v10.3  the camera page coverage panel is composed artwork too: camera
   callouts round the roofline and a five step footer row. It is 1717x916,
   wider than the 1400/900 body crop, so cover would shave the footer off.
   State the source ratio and keep the whole frame. */
.ncxs-split-img img[src*="cctv-camera-coverage-design-commercial-building"] {
	aspect-ratio: 1717 / 916;
}
