/**
 * Oyolloo Elements — frontend styles
 *
 * Only the things Elementor's controls cannot express. Everything achievable
 * through the editor is left in the editor so the client can change it.
 *
 * Selectors target Elementor element IDs, which are fixed by the template data
 * (oyohdr / oyoftr prefixes), so they survive edits to template settings.
 *
 * Several comments below give the row range a band's background was cut from —
 * "rows [435, 512] of backdrop-a.png" and the like. Those source plates are not
 * shipped with the plugin, because nothing serves them; they live beside the
 * Figma renders in the project's audit folder, `_project-audit/audit/design-src/`.
 * design/ here holds only what a page actually requests.
 *
 * @package OyollooElements
 * @since   1.0.0
 */

/* The design's type is Arial MT Pro, which cannot be served: the licensed file
   carries fsType 0x0004 (Monotype, "Preview & Print embedding only"), so web
   embedding is not granted. Arimo is metric-compatible and openly licensed
   (SIL OFL), so it takes its place without moving a single glyph. It arrives
   from Google Fonts, enqueued by the Elementor kit, whose four global
   typography groups now name it directly. */

:root {
	--oyo-bg: #000204;
	--oyo-surface: #12151f;
	--oyo-surface-alt: #11172b;
	--oyo-text: #ffffff;
	--oyo-text-muted: #a3a3a3;
	--oyo-hairline: rgba(255, 255, 255, 0.1);
	--oyo-blue: #1ca8f8;
	--oyo-violet: #696bff;
	/* The page bands take their gutter from Elementor, which rewrites it per
	   breakpoint. This is for the markup that is ours rather than Elementor's,
	   so it has to carry the same three steps itself. */
	--oyo-gutter: 100px;
	/* Figma's canvas is 1600 wide and every band is padded 100px, so the design's
	   content column is exactly 1400. */
	--oyo-content: 1400px;
}

@media (max-width: 1024px) {
	:root { --oyo-gutter: 40px; }
}

@media (max-width: 767px) {
	:root { --oyo-gutter: 20px; }
}

/* -------------------------------------------------------
   Content column

   Past 1600px the column has to stay 1400 rather than grow
   with the viewport, or the whole composition — line breaks,
   card proportions, the gap rhythm — stops matching Figma.
   The surplus goes into the gutter instead.

   Elementor derives a container's horizontal padding from
   `--padding-left` / `--padding-right`, which it rewrites per
   breakpoint. Folding those into max() keeps whatever the
   editor set for the current breakpoint and only adds the
   overflow, so the responsive gutters need no duplicate here.

   Top-level containers only: `> .e-con` under a document root.
   Nested containers keep their own padding untouched.
------------------------------------------------------- */
.elementor > .e-con {
	--padding-inline-start: max(var(--padding-left), (100% - var(--oyo-content)) / 2);
	--padding-inline-end: max(var(--padding-right), (100% - var(--oyo-content)) / 2);
}

/* A band whose artwork has to reach the viewport edge opts out here and takes
   the gutter inside its own widget instead, so the picture is full width while
   the words stay in the 1400 column. `oyo-ihero` does the same thing further
   down; this is the class version, for the widgets that carry a whole band. */
.elementor > .e-con.oyo-bleed {
	--padding-inline-start: 0px;
	--padding-inline-end: 0px;
}

/* -------------------------------------------------------
   Page shell

   hello-elementor's reset.css also sets `body { background }`.
   It has equal specificity and loads after this file, so it
   would win on order alone — `html body` settles it without
   depending on enqueue order or !important.
------------------------------------------------------- */
html body {
	background-color: var(--oyo-bg);
}

/* hello-elementor underlines every link in its reset, which reaches Elementor's
   button widget because that renders an <a>. A pill with an underline through
   it is not a button in any design, here or elsewhere. */
.elementor .elementor-button {
	text-decoration: none;
}

/* -------------------------------------------------------
   Header — sticky translucent bar

   Figma: padding 16px 100px 0, backdrop-filter blur(10px).
   Elementor has no backdrop-filter control, so it lives here.
------------------------------------------------------- */
/* The header floats over the page rather than sitting above it:
   in the design (node 314:10) the nav and the hero share one
   418px Earth plate, with the nav on top of the image. The
   location wrapper is targeted rather than the container itself
   because Elementor sets `position: relative` on containers with
   a selector this file cannot outrank.

   Every page's first section therefore carries enough top
   padding to clear the header.

   STICKY ON EVERY WIDTH — client, 02 Oct 2026.

   This was `absolute`, so above 1024 the bar scrolled away with
   the hero it is drawn on and only the drawer breakpoint pinned
   it (the S2 note further down). The client scrolled the desktop
   site and found no bar. Figma is static and cannot settle this
   either way, so it is a decision, not a measurement: the bar
   stays.

   `fixed` is the only line that changes. Both values are out of
   flow, so nothing reflows and the first section's top padding
   still does its job. The S2 block below now restates what it
   inherits; it is left there because it carries why the drawer
   breakpoint needed this first. */
.elementor-location-header {
	position: fixed;
	top: 0;
	right: 0;
	left: 0;
	z-index: 100;
}

/* A fixed bar hides whatever an in-page link jumps to, so the
   scroll port keeps a header's worth of padding. scroll-padding
   on the scroller covers every anchor at once — #contact from
   "Book a demo", #content from the skip link — where a
   scroll-margin per target would have to be kept in step with
   each new id.

   Measured on the live site, tallest page per width: 122 above
   1240 (careers and company; home, tech and products are 116),
   90.02 from 1025 to 1240 and at the tablet tier, 82.05 below
   768. Rounded up to clear the taller pages with 2px to spare. */
html {
	scroll-padding-top: 124px;
}

@media screen and (max-width: 1240px) {
	html {
		scroll-padding-top: 92px;
	}
}

@media screen and (max-width: 767px) {
	html {
		scroll-padding-top: 84px;
	}
}

.admin-bar .elementor-location-header {
	top: 32px;
}

@media screen and (max-width: 782px) {
	.admin-bar .elementor-location-header {
		top: 46px;
	}
}

.elementor-element-oyohdr1 {
	z-index: 100;
}

/* The blur lives on a pseudo-element, not on the header itself.
   backdrop-filter (like transform and filter) makes an element
   the containing block for its position:fixed descendants — with
   it on the header, the mobile drawer resolved against the header
   box instead of the viewport and came out 144px tall.

   OFF AT THE TOP OF THE PAGE, ON ONCE SCROLLED — client, 02 Oct 2026.

   Figma does declare it: the header component #570:2977 carries
   BACKGROUND_BLUR radius 20. But that frame's fills are empty, and
   Figma paints no background blur through a frame with no fill, so
   the design renders crisp. CSS backdrop-filter has no such rule —
   it filters the backdrop whether or not the element is painted —
   so the bar was blurring a 116px band of the hero at rest, and its
   hard bottom edge drew a line across the full width. On Recruitment
   and Tech, where the earth's bright limb sits right on that edge,
   detail below the line measured 20x and 16x what was left above it.
   That band is what the client boxed.

   So: no blur while the page is at the top, which is the state every
   screenshot and every capture shows, and the blur back once the bar
   has something other than its own hero underneath. The threshold is
   the bar's own height, read from the element in nav-menu.js so it
   follows the breakpoints rather than hard-coding 116.

   The resting rule names no backdrop-filter at all, rather than
   blur(0), so at rest there is provably no backdrop root and no
   compositing to round colours differently. opacity carries the
   fade, because none -> blur(10px) is not an interpolable pair. */
.elementor-element-oyohdr1::before {
	content: "";
	position: absolute;
	inset: 0;
	z-index: -1;
	opacity: 0;
	pointer-events: none;
}

/* The transition is declared here and not on the resting rule on purpose, so
   it runs one way. A transition is taken from the state being moved TO: with
   it on the resting rule the blur would fade in and then, on the way back up,
   try to fade out while backdrop-filter — which has no interpolable pair with
   none — had already been dropped in the first frame, so the blur vanished and
   an invisible box faded after it. Declared here it fades in and cuts out, and
   the cut lands on the frame the filter leaves anyway. */
.elementor-element-oyohdr1.oyo-scrolled::before {
	-webkit-backdrop-filter: blur(10px);
	backdrop-filter: blur(10px);
	/* A scrim, not just the blur. Blurring a bright picture leaves a bright
	   picture. Measured off the pinned bar on live, worst non-ink pixel behind
	   a label, blur on and no scrim:

	     industry cards, white cloud   rgb(230,239,243)   1.46:1
	     careers photo, white facade   rgb(227,224,227)   1.30:1
	     recruitment band              rgb(174,173,176)   1.31:1

	   #C7C6CA at 20px regular is 4.5:1 text under WCAG 2.2, not 3:1, so those
	   labels were gone. Composited over the brightest of them this alpha
	   measures 9.01:1 (0.70 would already clear it at 5.35; the margin is
	   there because brighter art may yet be added). Over the darkest sky the
	   site has, rgb(6,6,9), it resolves to rgb(1,3,5) — so it darkens the bar
	   without drawing a visible band across the hero.

	   Figma has no scrolled state to copy, so the colour is taken from the
	   site's own language: the footer plate is rgba(0,0,0,0.9) and the contact
	   card is #000204. */
	background-color: rgba(0, 2, 4, 0.85);
	opacity: 1;
	transition: opacity 240ms ease;
}

@media screen and (prefers-reduced-motion: reduce) {
	.elementor-element-oyohdr1.oyo-scrolled::before {
		transition: none;
	}
}


/* -------------------------------------------------------
   Between the burger and the full desktop bar

   Figma draws this header at 1600 and at 440 and nothing in
   between. At 1600 the five nav items measure 650.73 wide
   (Figma 655 — the 4.27 is the Arimo substitution, 2.21 of
   it in "Book A Demo"), and the desktop tier asks for a
   333px logo inside 100px padding with a 24px minimum gap.
   That is 1007.73 of content, so it stops fitting below a
   1207.73 viewport, and the bar wrapped onto two lines from
   1025 up to 1207 — the band where the burger has not taken
   over yet. It wrapped before this round too; the new labels
   are 9px narrower and still did not clear it.

   Rather than invent a third set of numbers for a width the
   design never drew, this hands the band the tier that is
   already defined one step down: the 40px padding and
   226.5px logo Elementor writes for <=1024. At 1025 that
   needs 901.23 of 945, so it holds across the whole band,
   and 1240 leaves 32px of slack above the 1207.73 the
   desktop tier needs.

   Four classes, because Elementor's per-document sheet is
   printed after this file and wins every tie at three.
   ------------------------------------------------------- */
@media screen and (min-width: 1025px) and (max-width: 1240px) {
	.elementor .elementor-element.elementor-element-oyohdr1.e-con {
		--padding-left: 40px;
		--padding-right: 40px;
	}

	.elementor .elementor-element.elementor-element-oyohdrlogo.elementor-widget img {
		width: 226.5px;
	}
}


/* -------------------------------------------------------
   Mobile / tablet menu — bar toggle and slide-in drawer

   Figma: the header band #374:1788 and the Menu frame #409:7,
   both drawn 440 wide.

   The toggle's fill, border width, radius and colour are the
   widget's own Toggle Button controls. What it has no control
   for is the box's size and the glyph, which are here. Figma
   draws the box 32x32 with a 1px OUTSIDE stroke, so the box as
   rendered is 34x34 — measured on the frame render, where the
   border lands on columns 387 and 420 and rows 29 and 62, not
   on 388/419. A border-box 34 carrying Elementor's 1px border
   reproduces that, and the -1px right margin puts the stroke's
   outer edge where Figma puts it, 1px past the 20px gutter.
   (Elementor's own margin on the toggle is `0 auto`, which in
   this space-between row would split the free space and pull
   the toggle off the right edge, so it is restated here.)

   Markup relied on (verified in the DOM):

     .elementor-menu-toggle            gets .elementor-active
     .elementor-menu-toggle + nav.elementor-nav-menu--dropdown

   The three bars are drawn with two pseudo-elements — the
   middle bar is a box-shadow on ::before — so no extra
   markup is needed and the a11y attributes stay untouched.
   --oyo-burger keeps the bars off `color`, which the border
   reads too: open, Figma turns the X white (#409:43) and
   leaves the box's stroke grey.
------------------------------------------------------- */
@media screen and (max-width: 1024px) {

	/* --- toggle ------------------------------------------------ */
	.elementor .elementor-element.elementor-element-oyohdrnav div.elementor-menu-toggle {
		--oyo-burger: currentColor;
		position: relative;
		z-index: 1000;
		box-sizing: border-box;
		width: 34px;
		height: 34px;
		padding: 0;
		margin: 0 -1px 0 auto;
	}

	/* Elementor's own open/close glyphs. */
	.elementor-element-oyohdrnav .elementor-menu-toggle i,
	.elementor-element-oyohdrnav .elementor-menu-toggle svg {
		display: none;
	}

	/* #374:1866-68 are three 16px lines at weight 1.5 with round
	   caps, 7px apart. A round cap adds half the weight beyond each
	   end, so the drawn bar is 17.5 long with a 0.75 radius. The
	   pseudo-elements resolve against the padding box, which the
	   1px border already insets, so 50%/50% is the design's centre
	   at (404, 46). */
	.elementor-element-oyohdrnav .elementor-menu-toggle::before,
	.elementor-element-oyohdrnav .elementor-menu-toggle::after {
		content: "";
		position: absolute;
		left: 50%;
		top: 50%;
		width: 17.5px;
		height: 1.5px;
		margin-left: -8.75px;
		margin-top: -0.75px;
		border-radius: 0.75px;
		background: var(--oyo-burger);
		transition:
			transform 0.32s cubic-bezier(0.4, 0, 0.2, 1),
			box-shadow 0.18s linear,
			width 0.32s cubic-bezier(0.4, 0, 0.2, 1);
	}

	/* Top bar, plus the middle bar as a shadow 7px below it. */
	.elementor-element-oyohdrnav .elementor-menu-toggle::before {
		transform: translateY(-7px);
		box-shadow: 0 7px 0 var(--oyo-burger);
	}

	.elementor-element-oyohdrnav .elementor-menu-toggle::after {
		transform: translateY(7px);
	}

	/* Open: middle bar drops out, the outer two cross. #409:42's X
	   is 12x12, so each stroke is that square's diagonal, 12√2. */
	/* The box keeps its grey stroke while the X goes white, and it
	   has to be pinned: clicking leaves the button focused, and the
	   widget's Toggle hover/focus colour would otherwise repaint the
	   border along with the glyph. That rule is (0,5,1) — the same
	   weight as the obvious selector here — so this one carries the
	   widget's own .elementor-widget as a sixth class to outrank it
	   rather than tie and lose on order. */
	.elementor .elementor-element.elementor-element-oyohdrnav.elementor-widget div.elementor-menu-toggle.elementor-active {
		--oyo-burger: #ffffff;
		color: #cccccc;
	}

	.elementor-element-oyohdrnav .elementor-menu-toggle.elementor-active::before,
	.elementor-element-oyohdrnav .elementor-menu-toggle.elementor-active::after {
		width: 16.9706px;
		margin-left: -8.4853px;
	}

	.elementor-element-oyohdrnav .elementor-menu-toggle.elementor-active::before {
		transform: rotate(45deg);
		box-shadow: 0 0 0 transparent;
	}

	.elementor-element-oyohdrnav .elementor-menu-toggle.elementor-active::after {
		transform: rotate(-45deg);
	}

	/* --- drawer ------------------------------------------------ */
	.elementor-element-oyohdrnav .elementor-menu-toggle + .elementor-nav-menu--dropdown {
		position: fixed;
		top: 0;
		right: 0;
		bottom: auto;
		left: auto;
		z-index: 999;
		width: min(320px, 82vw);

		/* top + bottom + an implied height over-constrains the box:
		   the browser resolved a 890px height anchored to the bottom
		   and left a sliver uncovered at the top. An explicit height
		   is unambiguous. dvh tracks mobile browser chrome; vh is the
		   fallback for engines without it. */
		height: 100vh;
		height: 100dvh;

		/* Elementor spaces the dropdown off the toggle with a
		   margin; on a fixed panel that just pushes it 10px down
		   the screen. */
		margin: 0;
		padding: 104px 28px 40px;
		overflow-y: auto;

		/* #409:7's fill. The widget's Dropdown section styles the
		   items' background but has no control for the panel's own,
		   and Elementor's base sheet paints it #fff, so this has to
		   be here. */
		background-color: #000104;
		-webkit-backdrop-filter: blur(10px);
		backdrop-filter: blur(10px);
		border-left: 1px solid rgba(158, 159, 255, 0.25);
		box-shadow: -24px 0 60px rgba(0, 0, 0, 0.6);

		/* Neutralise Elementor's max-height animation and drive
		   the motion from transform instead. */
		max-height: none !important;
		display: block !important;

		visibility: hidden;
		transform: translateX(100%);
		transition:
			transform 0.38s cubic-bezier(0.4, 0, 0.2, 1),
			visibility 0.38s;
	}

	.elementor-element-oyohdrnav .elementor-menu-toggle.elementor-active + .elementor-nav-menu--dropdown {
		visibility: visible;
		transform: translateX(0);
	}

	/* Elementor paints dropdown items on a light surface with a
	   grey active pill. Reset all four states onto the dark panel.

	   `border: 0` matters twice over: Elementor's own dropdown rule
	   carries `border-inline-start: 8px solid transparent`, which
	   would hold the labels 8px in from the panel's padding, and it
	   draws a divider under every item but the last. #409:45 spaces
	   its five labels with a 32px gap and no rule between them.
	   The vertical padding is the widget's own control (16px), so
	   the items land on the design's 64px pitch. */
	.elementor-element-oyohdrnav .elementor-nav-menu--dropdown a.elementor-item,
	.elementor-element-oyohdrnav .elementor-nav-menu--dropdown a.elementor-item:hover,
	.elementor-element-oyohdrnav .elementor-nav-menu--dropdown a.elementor-item:focus,
	.elementor-element-oyohdrnav .elementor-nav-menu--dropdown a.elementor-item.elementor-item-active,
	.elementor-element-oyohdrnav .elementor-nav-menu--dropdown a.elementor-item.highlighted {
		background-color: transparent;
		border: 0;
		color: #c7c6ca;
	}

	.elementor-element-oyohdrnav .elementor-nav-menu--dropdown a.elementor-item.elementor-item-active {
		color: #c7c6ca;
	}

	.elementor-element-oyohdrnav .elementor-nav-menu--dropdown a.elementor-item:hover,
	.elementor-element-oyohdrnav .elementor-nav-menu--dropdown a.elementor-item:focus {
		color: #1ca8f8;
	}

	/* Items fan in behind the panel once it has started moving. */
	.elementor-element-oyohdrnav .elementor-nav-menu--dropdown li {
		opacity: 0;
		transform: translateX(18px);
		transition:
			opacity 0.3s ease,
			transform 0.3s ease;
	}

	.elementor-element-oyohdrnav .elementor-menu-toggle.elementor-active + .elementor-nav-menu--dropdown li {
		opacity: 1;
		transform: none;
	}

	.elementor-element-oyohdrnav .elementor-menu-toggle.elementor-active + .elementor-nav-menu--dropdown li:nth-child(1) { transition-delay: 0.12s; }
	.elementor-element-oyohdrnav .elementor-menu-toggle.elementor-active + .elementor-nav-menu--dropdown li:nth-child(2) { transition-delay: 0.17s; }
	.elementor-element-oyohdrnav .elementor-menu-toggle.elementor-active + .elementor-nav-menu--dropdown li:nth-child(3) { transition-delay: 0.22s; }
	.elementor-element-oyohdrnav .elementor-menu-toggle.elementor-active + .elementor-nav-menu--dropdown li:nth-child(4) { transition-delay: 0.27s; }
	.elementor-element-oyohdrnav .elementor-menu-toggle.elementor-active + .elementor-nav-menu--dropdown li:nth-child(5) { transition-delay: 0.32s; }
}

/* -------------------------------------------------------
   The drawer at the width it was drawn

   #409:7 is a full-width panel, not a right-hand sheet: 440
   wide from y=0, filled #000104 under the home hero's
   starfield plate. That plate is not stretched — the fill's
   imageTransform windows source columns 0.302..0.642 and rows
   -0.854..0.747, so the window opens above the image and only
   the part from source row 0 down shows, landing flush with
   the panel's bottom across 46.666% of its height. The slice
   is design/home/menu-plate-e66e94.webp; rebuilt from the
   transform it reads 0.27/255 against Figma's own render of
   the frame, worst pixel 10.7.

   74px of top padding puts the first label's text at y=90,
   where #409:46 sits: the widget's Vertical Padding control
   gives each item 16 above and below its 32px line, so the
   five labels land on the design's 64px pitch — 90, 154, 218,
   282, 346 — and #409:45's own 288px height falls out of it.

   The logo and the toggle are lifted over the panel and the
   band's top padding goes 16 -> 30, which is exactly the
   difference between the header's logo (#374:1789 at y=16)
   and the drawer's (#409:24 at y=30). One logo that moves,
   rather than a second copy of it inside the panel.

   768-1024 keeps the narrower right-hand sheet: the design
   file says nothing about a tablet drawer, and a full-screen
   panel there would be a change with nothing behind it.
------------------------------------------------------- */
@media screen and (max-width: 767px) {
	.elementor-element-oyohdrnav .elementor-menu-toggle + .elementor-nav-menu--dropdown {
		left: 0;
		right: 0;
		width: auto;

		/* #449:2910 is 440 x 654, but an artboard height is not a viewport:
		   on a real 800-tall phone a 654 panel leaves the page showing
		   underneath. WebDeveloperArif's call, 22 Sep — the panel covers the
		   screen and the plate hangs off the bottom instead. dvh tracks
		   mobile browser chrome; vh is the fallback for engines without it.

		   The logo stays at y16 and belongs to the header, which draws over
		   this panel. #449:2922 puts the nav at y92 — but that 92 is where
		   the design's 32-tall *text row* begins, and our <a> carries its own
		   16px of padding above its text. Setting padding-top to 92 put every
		   label 18px low against the frame (ink at 120 where the export has
		   it at 102). The panel's padding is therefore 92 less the <a>'s own
		   lead-in, which is the 74 it always was. */
		height: 100vh;
		height: 100dvh;
		padding: 74px 20px 40px;
		border-left: 0;
		box-shadow: none;
		-webkit-backdrop-filter: none;
		backdrop-filter: none;
		/* #460:3200 is 440 x 573. With the panel now the height of the
		   screen it is anchored to the foot rather than the head, so the
		   earth sits on the bottom edge and the flat #000104 fills whatever
		   is left above it. */
		background-image: url(../../design/plates/plate-drawer.webp);
		background-repeat: no-repeat;
		background-position: center bottom;
		background-size: 100% 573px;
	}

	.elementor-element-oyohdrnav .elementor-nav-menu--dropdown a.elementor-item {
		text-align: left;
	}

	/* The 18/09 drawer dropped its logo to y30 on open, so the header grew to
	   match. #449:2910 puts it back at y16 — the same place the closed header
	   has it — so the header must not move at all now. */

	.elementor-element-oyohdrlogo {
		position: relative;
		z-index: 1000;
	}
}

/* Someone who asked for less motion gets the drawer without
   the slide, and without the staggered items. */
@media screen and (max-width: 1024px) and (prefers-reduced-motion: reduce) {
	.elementor-element-oyohdrnav .elementor-menu-toggle::before,
	.elementor-element-oyohdrnav .elementor-menu-toggle::after,
	.elementor-element-oyohdrnav .elementor-menu-toggle + .elementor-nav-menu--dropdown,
	.elementor-element-oyohdrnav .elementor-nav-menu--dropdown li {
		transition: none;
	}

	.elementor-element-oyohdrnav .elementor-nav-menu--dropdown li {
		opacity: 1;
		transform: none;
	}
}

/* -------------------------------------------------------
   Footer — rounded top, violet wash, gradient hairline

   Figma node 314:286: fills are a violet gradient
   (rgba(158,159,255,.05) -> transparent) layered over
   rgba(0,0,0,.9); stroke is a 2px violet gradient; radius
   is 32px 32px 0 0.

   The base colour and the radius are set on the Elementor
   container so the client can edit them — and because
   Elementor's generated selector
   (.elementor-31 .elementor-element.elementor-element-x)
   outranks anything reasonable this file can write.
   Only the two layered gradients live here, both inheriting
   the radius so they follow whatever Elementor sets.
------------------------------------------------------- */
/* Figma pairs the last band with the footer inside an auto-layout column whose
   `gap` is -23px, so the footer's 32px top corners ride over the band above
   rather than sitting below it.

   That pairing is per page, not global. Home's #314:219, products' #314:890 and
   tech's #314:1353 each hold a band *and* the footer, so the overlap applies.
   The company page's #314:457 holds the footer alone — a lone child has no gap
   to collapse — and its Industries band keeps its full foot. Pulling the footer
   up there buried the last 5px of that band's corner-bracket frame, which sits
   only 18px above the band's bottom edge.

   So the overlap belongs to the three bands that own it. Set through Elementor's
   own --margin-bottom, which it reads into margin-block-end. */
.elementor .elementor-element.elementor-element-oyocfsec,
.elementor .elementor-element.oyo-band,
.elementor .elementor-element.elementor-element-oycrctasec {
	--margin-bottom: -23px;
}

/* The mobile frames deepen that overlap on the three pages whose closing band
   is the CTA: #392:6081, #392:6080 and #392:6079 all pair it with the footer at
   gap -30. Home keeps -23 — #374:3336 pairs the contact form with the footer,
   and that column still reads -23 on the 440 frame. */
@media (max-width: 767px) {
	.elementor .elementor-element.oyo-band,
	.elementor .elementor-element.elementor-element-oycrctasec {
		--margin-bottom: -30px;
	}
}

.elementor-element-oyoftr1 {
	position: relative;
	isolation: isolate;
}

/* The 2px gradient stroke. A gradient border needs the
   mask trick; Elementor only offers solid borders. */
.elementor-element-oyoftr1::before {
	content: "";
	position: absolute;
	inset: 0;
	z-index: 0;
	padding: 2px;
	border-radius: inherit;
	background: linear-gradient(
		180deg,
		rgba(158, 159, 255, 0.4) 0%,
		rgba(158, 159, 255, 0) 92%
	);
	-webkit-mask:
		linear-gradient(#000 0 0) content-box,
		linear-gradient(#000 0 0);
	mask:
		linear-gradient(#000 0 0) content-box,
		linear-gradient(#000 0 0);
	-webkit-mask-composite: xor;
	mask-composite: exclude;
	pointer-events: none;
}

/* The violet wash sitting on top of the base colour. */
.elementor-element-oyoftr1::after {
	content: "";
	position: absolute;
	inset: 0;
	z-index: -1;
	border-radius: inherit;
	background: linear-gradient(
		180deg,
		rgba(158, 159, 255, 0.05) 0%,
		rgba(158, 159, 255, 0) 100%
	);
	pointer-events: none;
}

/* Keep footer content above both pseudo-elements. */
.elementor-element-oyoftr1 > * {
	position: relative;
	z-index: 1;
}

/* -------------------------------------------------------
   Footer link lists

   Figma renders these as bulleted lists (node 314:304 /
   314:309, listSpacing 20). Elementor's nav-menu has no
   list-marker control, so the bullet is drawn here.
------------------------------------------------------- */
/* The bullet goes on the li, never on .elementor-item::before —
   that pseudo-element is Elementor's menu pointer (absolutely
   positioned, painted with the pointer colour), so content put
   there renders as a blue bar instead of a bullet.
   Scoped to --main so the hidden dropdown copy of the same menu
   is not decorated as well. */
.elementor-element-oyoftrnav1 .elementor-nav-menu--main > ul > li,
.elementor-element-oyoftrnav2 .elementor-nav-menu--main > ul > li {
	display: flex;
	align-items: center;
	gap: 0;
}

/* PUT BACK ON CLIENT INSTRUCTION, 30 Sep 2026 — annotation 4 of
   "stupot68 changes.pdf" boxes the Menu column and asks for it to match, and the
   render inside that box is bulleted. They came out on 17 Sep and they go back
   in now; the note that removed them said "say the word and the indent comes
   back on its own", and this is that word.

   Nothing here is guessed. The 30/09 PDF is vector, so it was rendered at 8x and
   12x and the marks measured directly. Three Quick-links rows agree to a
   hundredth, and they agree with what was measured off Figma back in September:

     diameter    4.00px                  (Sep: "a 4px mark")
     ink from    list box + 9.97         (Sep: 713.019 against an origin of 703)
     ink to      list box + 13.88
     centre      list box + 11.93        — which a 24px box centres at 12.00
     text origin list box + 24.00
     centre y    cap-height centre + 0.12, i.e. 0.06 off the line-box centre,
                 so align-items:center on the li is right to within a tenth
     colour      rgb(163,163,163), sampled off the render — the list text's own
                 colour, so currentColor carries the #FFFFFF hover with it

   Figma's side of it is a text-node property, not a drawn shape: 449:300 and
   449:305 carry lineTypes UNORDERED with indent 1 and listSpacing 20, and the
   mobile frames 449:2058 / 449:2063 carry the same, so this is not breakpointed.

   The bullet goes on the li, never on .elementor-item::before — that
   pseudo-element is Elementor's menu pointer (absolutely positioned, painted
   with the pointer colour), so content put there renders as a blue bar instead
   of a bullet. Scoped to --main so the hidden dropdown copy is not decorated.

   Drawn as a box rather than set as "\2022" so the mark is exactly 4.00px on
   any font stack: Arimo is a substitute for Arial MT Pro, and its bullet glyph
   is not a measurement we control. */
.elementor-element-oyoftrnav1 .elementor-nav-menu--main > ul > li::before,
.elementor-element-oyoftrnav2 .elementor-nav-menu--main > ul > li::before {
	content: "";
	/* 10 + 4 + 10 = the 24px track, with the mark's ink landing at 10..14 and
	   the text starting at 24. The radius is 50% of a 4x4 box, so it is a
	   circle rather than an ellipse of some wider track. */
	flex: 0 0 4px;
	width: 4px;
	height: 4px;
	margin-left: 10px;
	margin-right: 10px;
	border-radius: 50%;
	/* Stated, not currentColor. The #A3A3A3 is set by the widget on
	   a.elementor-item; the li only inherits the container's near-black, which
	   painted the mark rgb(43,43,44) on a rgb(6,6,9) background - there, but
	   invisible. Figma gives the mark the list text's own colour, sampled off
	   the 30/09 render at rgb(163,163,163). It does not follow the link hover:
	   Figma draws no hover for it, and the mark lives on the li, outside the
	   anchor the hover belongs to. */
	background-color: #a3a3a3;
}

/* -------------------------------------------------------
   Footer nav menus

   Elementor's nav-menu is built for horizontal bars; in a
   vertical footer column the inherited centring and item
   padding fight the design.
------------------------------------------------------- */
.elementor-element-oyoftrnav1 .elementor-nav-menu--main .elementor-item,
.elementor-element-oyoftrnav2 .elementor-nav-menu--main .elementor-item {
	padding-left: 0;
	padding-right: 0;
	justify-content: flex-start;
}

/* -------------------------------------------------------
   Footer social marks

   Each mark is Figma's own SVG uploaded as a custom icon, and
   each carries that node's frame as its viewBox: facebook 26
   (314:339 draws a 10 x 19 glyph inside it), X 19 (314:343),
   Instagram 19 (314:346), LinkedIn 21 (314:353). Elementor's
   widget has one Size control, so all four render at 18 and
   only X and Instagram are right.

   Size the SVG, not the anchor: the widget derives both the
   44px ring and the row's line box from the anchor's font-size,
   so raising that grew the bottom bar from 93 to 97. The glyphs
   are already correct inside their square viewBoxes, so the box
   is all that has to change. Targeted by repeater item because
   a custom SVG leaves the network suffix of
   .elementor-social-icon- empty.
------------------------------------------------------- */
.elementor .elementor-widget.elementor-element-oyoftrsocial a.elementor-repeater-item-oyos1 svg {
	width: 26px;
	height: 26px;
}

.elementor .elementor-widget.elementor-element-oyoftrsocial a.elementor-repeater-item-oyos4 svg {
	width: 21px;
	height: 21px;
}

/* The rings and their grid items are inline-block, so the row box
   reserves a baseline descender under them and the bottom bar came
   out 97 against Figma's 93. Aligning the items to the top removes
   the gap without changing the 44px ring. */
.elementor .elementor-widget.elementor-element-oyoftrsocial .elementor-grid-item {
	vertical-align: top;
}

/* -------------------------------------------------------
   Footer contact rows

   Figma 314:313 / 314:322 / 314:328 are horizontal frames with
   gap 20 between a 24.32px icon and its label, so the label box
   opens 44.32px right of the icon box. Elementor puts the
   indent on the icon's padding-right but leaves the span wider
   than the glyph, which pushed the label to 50.39.

   The .elementor-widget on the selector is deliberate: the
   per-document sheet is enqueued during render and beats this
   file at equal specificity.
------------------------------------------------------- */
.elementor .elementor-widget.elementor-element-oyoftricons .elementor-icon-list-icon {
	box-sizing: border-box;
	width: 44.32px;
	padding-right: 20px;
}

.elementor .elementor-widget.elementor-element-oyoftricons .elementor-icon-list-icon svg {
	/* flex-basis, not width: the span is a flex container and the SVG is
	   a replaced flex item, so an author width still leaves it free to
	   resolve against its intrinsic ratio - it was landing at 18.23. */
	flex: 0 0 24.32px;
	width: 24.32px;
	height: 24.32px;
}

/* -------------------------------------------------------
   Responsive

   Padding, direction and type scale live on the Elementor
   widgets' own responsive controls so the client can edit
   them. Only the gradient-border radius is repeated here,
   because ::before inherits it and the border is CSS-only.
------------------------------------------------------- */
/* Nothing here — the footer's mobile radius is an Elementor
   responsive control, and both pseudo-elements inherit it. */

/* ==========================================================================
   Home — Product Feature Section (Figma #314:44)
   Only what Elementor has no control for: backdrop-filter, a three-layer
   background, `flex: 1 1 0` sizing, and the two overflow-cropped images.

   Every selector is scoped under `.elementor` (0-3-0 / 0-3-1) on purpose.
   Elementor's base rules `.e-con.e-flex { flex: var(--flex-*) }` and
   `.elementor img { height: auto; max-width: 100%; border-radius: 0 }` sit at
   0-2-0 / 0-1-1, and its per-widget sheets are enqueued during render, so
   nothing here may depend on load order.
   ========================================================================== */

/* #314:44 carries four fills, one of them hidden. Two properties of Figma's fill
   arrays govern every band in this file. First, the array is bottom-first while
   CSS paints background-image top-first, so a Figma fill list transfers reversed.
   Second, a fill may carry visible:false, and Figma then does not paint it at
   all: #314:44's fourth fill is an opaque #000209 to #01043D gradient that is
   switched off, and most of the bands below hide a spare copy of the Earth plate
   the same way. Reading those hidden entries as live is what makes these stacks
   look impossible - an opaque gradient sitting on top of everything. Each visible
   image is this section's own crop, stretched to the box exactly as the design
   does with scaleMode STRETCH / backgroundSize 100% 100%. */
.elementor .elementor-element.elementor-element-oyopfsec {
	/* Decomposed back into four layers from the single baked export this rule used
	   to carry. That export flattened the starfield in at full strength, but Figma
	   composites the plate at opacity 0.30 over the page's #000204, and a baked file
	   cannot be corrected afterwards: a scrim laid over it would darken the Earth
	   sliver and the gradient with it. Layered, the 0.30 is exact - the plate at full
	   strength under a solid rgba(0, 2, 4, 0.7) gives 0.7B + 0.3S, the same blend
	   Figma performs. The Earth sliver is fill 1's crop, rows [435, 512] of
	   backdrop-a.png, landing on the top (1 - 0.8494119) / 1.3586426 = 11.084% of
	   the band. Composing these layers previously agreed with the baked export to
	   mean 1.36 / RMS 2.50 of 255, so the 0.30 is the only thing that changes. */
	background-color: var(--oyo-bg);
	background-image:
		linear-gradient(180deg, rgba(0, 2, 4, 0) 0%, rgba(0, 2, 4, 0.84) 15.7327%, rgba(0, 2, 4, 0) 100%),
		url(../../design/home/bg-pf-earth-6db38c.webp),
		linear-gradient(rgba(0, 2, 4, 0.7), rgba(0, 2, 4, 0.7)),
		url(../../design/home/bg-pf-b-51cc05.webp);
	background-size:
		100% 100%,
		100% 11.084%,
		100% 100%,
		100% 100%;
	background-position: center top, center top, center top, center top;
	background-repeat: no-repeat;
}

/* Glass blur — Figma effects on #314:47, #314:72, #314:76/:83, #314:178. */
.elementor .elementor-element.elementor-element-oyopfc1,
.elementor .elementor-element.elementor-element-oyopfc2 {
	-webkit-backdrop-filter: blur(11.25px);
	backdrop-filter: blur(11.25px);
}
.elementor .elementor-element.elementor-element-oyopfc2ab,
.elementor .elementor-element.elementor-element-oyopfc2bb {
	-webkit-backdrop-filter: blur(15px);
	backdrop-filter: blur(15px);
}
.elementor .elementor-element.elementor-element-oyopfnote {
	-webkit-backdrop-filter: blur(10px);
	backdrop-filter: blur(10px);
}

/* Row sizing: #314:47 fills, #314:72 hugs its 708px of fixed children.

   #314:72 is layoutSizingVertical FIXED at 417, not HUG, so this is `height`
   rather than `min-height`: Figma's own render puts its bottom stroke on row
   992 of a card that starts at 576, which is 417 exactly. Its two children are
   FILL, so they take 417 - 2 border - 48 padding = 367 and their contents no
   longer fit the declared 24 padding. Figma squeezes the padding rather than
   growing the card - #314:74 lands 17.5 below the card edge, not 25 - which is
   what centring the content reproduces. Left as min-height the card grew to its
   natural 432.28 and took the whole row 9.28px past the design. */
.elementor .elementor-element.elementor-element-oyopfc1 { flex: 1 1 0; min-width: 0; width: auto; }
.elementor .elementor-element.elementor-element-oyopfc2 { flex: 0 0 auto; width: auto; height: 417px; }
.elementor .elementor-element.elementor-element-oyopfc2a { flex: 0 0 323px; width: auto; justify-content: center; }
.elementor .elementor-element.elementor-element-oyopfc2b { flex: 0 0 321px; width: auto; justify-content: center; }

/* #314:52 fills beside the fixed 271px image 6. */
.elementor .elementor-element.elementor-element-oyopfpills { flex: 1 1 0; min-width: 0; width: auto; }
.elementor .elementor-element.elementor-element-oyopfimg6 { flex: 0 0 271px; width: auto; }
.elementor .elementor-element-oyopfimg6 img {
	display: block;
	width: 271px;
	height: 219px;
	max-width: none;
	object-fit: fill;
	border-radius: 8px;
}

/* Pill rows: 24px icon, text takes the rest. */
.elementor .elementor-element.elementor-element-oyopfp1i,
.elementor .elementor-element.elementor-element-oyopfp2i,
.elementor .elementor-element.elementor-element-oyopfp3i { flex: 0 0 24px; width: auto; align-self: flex-start; }

/* --------------------------------------------------------------------------
   The registered mark in the footer copyright - client, 13 Oct 2026.

   Figma sets that one character apart: 633:2780's characterStyleOverrides
   single out index 17, the mark, and leave every other character on the base
   style. The API does not say what that override carries, so it was measured
   off the design's own render instead:

     design   7 x 8, its top 2px above the cap line
     build    11 tall, sitting on the cap line

   A full-size mark at 16px Arial is about 11 tall, so 8/11 gives 0.73em, and
   putting its foot 5.44px above the baseline puts its top 13.44 above, against
   the design's 13.46.

   Nothing here is a font substitution. The line is Arimo either way, which is
   Arial MT Pro's metric-compatible stand-in and what the whole site uses. The
   difference was only that the mark was drawn full size and on the baseline.
   -------------------------------------------------------------------------- */
.elementor .elementor-element-oyoftrcopy .oyo-reg {
	font-size: 0.73em;
	vertical-align: 0.34em;
}

/* --------------------------------------------------------------------------
   The three bullet marks, drawn from the plugin - client, 13 Oct 2026.

   Figma colours this tick, and sampling its render gives rgb(30,167,248),
   which is the site's own accent. The mark used to come from an SVG in the
   uploads folder, shared by six widgets across two pages, so recolouring it
   meant rewriting that file. That worked, and then the host served the old
   body for a week: Cache-Control on uploads is max-age=604800, and the same
   URL with a cache-busting query came back correct while the plain one did
   not.

   So the mark joins the rest of the design layer instead. It is a plugin
   asset now, like cf-check.svg in the thank-you panel, which means a new URL
   that no cache has an entry for, and one place to change if it changes
   again. The widget's own <img> stays in the markup and is simply not drawn,
   so nothing about the box, the flex basis or the row height moves.
   -------------------------------------------------------------------------- */
.elementor .elementor-element.elementor-element-oyopfp1i,
.elementor .elementor-element.elementor-element-oyopfp2i,
.elementor .elementor-element.elementor-element-oyopfp3i {
	background-image: url(../../design/home/pf-check.svg);
	background-repeat: no-repeat;
	background-position: left top;
	background-size: 24px 24px;
}

.elementor .elementor-element-oyopfp1i img,
.elementor .elementor-element-oyopfp2i img,
.elementor .elementor-element-oyopfp3i img {
	opacity: 0;
}
.elementor .elementor-element.elementor-element-oyopfp1t,
.elementor .elementor-element.elementor-element-oyopfp2t,
.elementor .elementor-element.elementor-element-oyopfp3t { flex: 1 1 0; min-width: 0; width: auto; }

/* #314:78 / #314:85 — 198px plates that crop their oversized child. */
.elementor .elementor-element.elementor-element-oyopfc2aw,
.elementor .elementor-element.elementor-element-oyopfc2bw { flex: 0 0 198px; position: relative; overflow: hidden; }
.elementor .elementor-element.elementor-element-oyopfc2ai,
.elementor .elementor-element.elementor-element-oyopfc2bi { position: absolute; width: auto; }
.elementor .elementor-element.elementor-element-oyopfc2ai { left: -29px; top: -11px; }
.elementor .elementor-element-oyopfc2ai img {
	display: block;
	width: 332px;
	height: 221px;
	max-width: none;
	object-fit: cover;
}
/* The dashboard PNG bakes in its 14.39 / 4.92px drop-shadow bleed, so the
   artwork origin (17, 18) shifts back by that much. */
.elementor .elementor-element.elementor-element-oyopfc2bi { left: 2.61px; top: 13.08px; }
.elementor .elementor-element-oyopfc2bi img {
	display: block;
	width: 483.28px;
	height: 331.78px;
	max-width: none;
}

/* Badge SVGs keep their exported shadow bleed; the negative margins that
   correct for it are Elementor controls, so only the size is set here. */
.elementor .elementor-element.elementor-element-oyopfc2abi,
.elementor .elementor-element.elementor-element-oyopfc2bbi { flex: 0 0 auto; width: auto; }
.elementor .elementor-element-oyopfc2abi img { display: block; width: 188px; height: 60px; max-width: none; }
.elementor .elementor-element-oyopfc2bbi img { display: block; width: 174px; height: 60px; max-width: none; }

@media (max-width: 1024px) {
	.elementor .elementor-element.elementor-element-oyopfc1,
	.elementor .elementor-element.elementor-element-oyopfc2 { flex: 0 0 auto; width: 100%; height: auto; min-height: 0; }
	/* Stacked, the cards are as tall as their content again, so the squeeze the
	   417 imposes at desktop has to be released with it. */
	.elementor .elementor-element.elementor-element-oyopfc2a,
	.elementor .elementor-element.elementor-element-oyopfc2b { justify-content: flex-start; }
	.elementor .elementor-element.elementor-element-oyopfc2a,
	.elementor .elementor-element.elementor-element-oyopfc2b { flex: 1 1 0; min-width: 0; }
}

@media (max-width: 767px) {
	.elementor .elementor-element.elementor-element-oyopfpills,
	.elementor .elementor-element.elementor-element-oyopfimg6,
	.elementor .elementor-element.elementor-element-oyopfc2a,
	.elementor .elementor-element.elementor-element-oyopfc2b { flex: 0 0 auto; width: 100%; }
	.elementor .elementor-element-oyopfimg6 img { width: 100%; height: auto; aspect-ratio: 271 / 219; }
}

/* #314:172 / #314:178 are `hug` in Figma — the pill wraps its own text rather
   than spanning the row. Elementor containers default to `--width: 100%`. */
.elementor .elementor-element.elementor-element-oyopfnote { width: auto; max-width: 100%; }

/* ==========================================================================
   Home — Industries Section (Figma #314:180)
   ========================================================================== */

/* WebDeveloperArif exported this band's background straight out of Figma, so it
   is the designer's own artwork rather than the crop plus gradient this file
   used to compose. The two measured the same — mean 0.37, RMS 0.69 of 255 — and
   the flat export is a quarter of the weight, because baking the near-black
   gradient in leaves far less for the encoder to carry.

   #314:180 and the company page's #314:416 declare identical fills (same
   imageRef, same crop transform, same gradient), so one file serves both. */
.elementor .elementor-element.elementor-element-oycoindsec,
.elementor .elementor-element.elementor-element-oyoindsec {
	position: relative;
	background-image: url(../../design/home/bg-ind-section.webp);
	background-size: 100% 100%;
	background-position: center;
	background-repeat: no-repeat;
}

/* The hairline frame with four violet corner brackets (#314:181) is gone from
   every page. Client, 15 Oct: "sob page theke ei border ta bad jabe".

   The 14/10 file had already dropped it nearly everywhere - home's band is
   633:895, its card Container and nothing else, and so are both mobile bands,
   633:2178 and 633:2309, careers' CV band 633:1776 and home's contact frame
   inside 633:929. The one place it survives in the file is 633:1121 on the
   company page, and that one comes out on the client's word rather than the
   file's. The artwork, design/home/ind-frame.svg, stays in the repo: nothing
   references it now, and putting any of these back is one rule. */

/* The cards are the Industries_Grid widget's own markup now, read from the
   Industry post type, so they are addressed by class rather than by the six
   element ids they used to need across two pages. Each card is one <a>: the
   whole tile is the hit area, and the hover state gets a keyboard equivalent. */
/* The company page's Industries band centres its children, which left the grid
   sizing to content and 5px narrower than the 1400 column. The grid is a band,
   not an item to centre, so it opts out of the parent's alignment. */
.elementor .elementor-widget-oyo-industries-grid {
	width: 100%;
	align-self: stretch;
}

.elementor .oyo-industries {
	display: flex;
	align-items: stretch;
	gap: 24px;
	width: 100%;
}

.elementor .oyo-industry {
	position: relative;
	display: flex;
	flex: 1 1 0;
	min-width: 0;
	flex-direction: column;
	border-radius: 16px;
	background-color: #0e0e10;
	/* #314:187 is a HUG frame with strokesIncludedInLayout: true, so Figma's
	   468 counts the 1px stroke top and bottom. A real border reproduces that
	   and keeps the flex width, because Elementor boxes are border-box. */
	border: 1px solid #2a2a2c;
	text-decoration: none;
	transition:
		background-color 0.28s ease,
		border-color 0.28s ease;
}

.elementor .oyo-industry__media {
	display: block;
	height: 380px;
	overflow: hidden;
	border-radius: 16px 16px 0 0;
}

.elementor .oyo-industry__image {
	display: block;
	width: 100%;
	height: 100%;
	max-width: none;
	border-radius: 0;
	object-fit: cover;
}

.elementor .oyo-industry__foot {
	display: flex;
	flex: 1 1 auto;
	align-items: center;
	justify-content: space-between;
	gap: 16px;
	padding: 24px;
	container-type: inline-size;
}

/* The first card's label is the client's, not the design's: it reads
   "Oil & Gas, Pharma, Data," where Figma has "Oil & Gas". At 32px that is 325px
   on one line, and 186.8 on the wider of the two lines it naturally breaks
   into. The foot gives the title its own width less 88: the two 24px paddings,
   the 16px gap and the 24px arrow. Above roughly 1100 there is room for those
   two lines at the design's 32px; below it there is not, and at 768 the label
   was breaking onto four.

   So the size is read off the card rather than off the viewport, which is why
   the foot is a query container. A viewport formula cannot do this in one
   expression: the section's padding changes at 1024, so 1025 has *less* room
   than 1024 (169 against 208.7) and would need a branch of its own.

   cqw resolves against the container's *content* box, so the 48px of foot
   padding is already gone and only the 16px gap and the 24px arrow have to be
   taken off: 16.27cqw - 6.51px is 0.1713 x (content box - 40), the ratio that
   keeps the wider line inside the room, with five per cent off for slack. It
   reaches 32px by a content box of 237, which is 1024 and everything above
   about 1110, so the design width is untouched. Below 768 the mobile rule
   further down wins, as it did before. */
.elementor .oyo-industry__title {
	font-family: Arimo, sans-serif;
	font-size: clamp(20px, calc(16.27cqw - 6.51px), 32px);
	font-weight: 400;
	line-height: 1.2em;
	letter-spacing: -1.5px;
	color: #e4e2e4;
}

.elementor .oyo-industry__arrow {
	display: block;
	flex: 0 0 24px;
	color: #46464a;
	line-height: 0;
}

.elementor .oyo-industry__arrow svg {
	display: block;
}

/* #314:207 / #314:208 — two blurred #030695 outlines. The design draws them on
   the Clean Energy card alone, which is the hover state shown on one card
   rather than a permanent treatment of the middle one, so every card carries
   them and only hover reveals them. Figma centres a rectangle's stroke, so each
   box is inflated by half the stroke width and its radius grows to match.

   Addressed through the row rather than card by card: Elementor does not render
   _css_classes on containers, and the card ids differ between the two pages.

   `hover: hover` gates it because a tap on a touch device leaves :hover latched
   on the card until something else is tapped — the glow would stick. */
.elementor .oyo-industry::before,
.elementor .oyo-industry::after {
	content: "";
	position: absolute;
	z-index: 2;
	border-style: solid;
	border-color: #030695;
	pointer-events: none;
	opacity: 0;
	transition: opacity 0.28s ease;
}

.elementor .oyo-industry::before {
	inset: -3px -2.66px -2.6px -2.67px;
	border-width: 6px;
	border-radius: 19px;
	filter: blur(10px);
}

.elementor .oyo-industry::after {
	inset: -2px -1.66px -1.93px -1.67px;
	border-width: 4px;
	border-radius: 18px;
	filter: blur(2px);
}

/* `hover: hover` gates it because a tap on a touch device leaves :hover latched
   on the card until something else is tapped — the glow would stick there. */
@media (hover: hover) {
	.elementor .oyo-industry:hover {
		background-color: #191920;
		border-color: #030695;
	}

	.elementor .oyo-industry:hover::before,
	.elementor .oyo-industry:hover::after {
		opacity: 1;
	}
}

/* The keyboard gets the same state, plus a ring of its own: the design's glow
   is a #030695 that all but disappears against the page, so on its own it would
   leave a keyboard user unable to tell which card they are on. */
.elementor .oyo-industry:focus-visible {
	background-color: #191920;
	border-color: #030695;
	outline: 2px solid #9e9fff;
	outline-offset: 4px;
}

.elementor .oyo-industry:focus-visible::before,
.elementor .oyo-industry:focus-visible::after {
	opacity: 1;
}

@media (max-width: 1024px) {
	.elementor .oyo-industry__media { height: 300px; }
}

@media (max-width: 767px) {
	.elementor .oyo-industries { flex-direction: column; }
	.elementor .oyo-industry { flex: 0 0 auto; width: 100%; }
	.elementor .oyo-industry__media { height: 240px; position: relative; }

	/* The 440 frames do not fit the photograph to this box, they clip a bigger
	   one: #449:1944 is 464 x 393 at (-33, 0) and #449:1954 / #449:1966 are
	   448 x 380 at (-25, 0), all inside a 398 x 240 clip. `cover` picks its own
	   zoom and centres, which is a different crop — it scored MAE 63 against the
	   frame on all nine cards.

	   One rule serves all three: card 1's asset is cut a little off the design's
	   own origin (the trap the careers plates used to fall into, before they
	   were re-exported from the clipping frame on 23/09), so fitting it
	   against Figma's render lands on 450 x 381 at (-25, -1), which is also
	   within 2px of what cards 2 and 3 state outright, and measures 5.8 / 3.4 /
	   5.5 live against 26.0 / 13.3 / 9.7 for the design's own 464 x 393 at
	   (-33, 0). Absolute so the oversize never reaches the span's layout.

	   An offline search at step 1 preferred 449 x 380 at (-24, 0) and scored it
	   1.41 / 1.03 / 5.37 — but live it measured 6.3 / 4.0 / 6.3, worse than what
	   is here. The offline model resizes the 898px original with PIL; the browser
	   scales the 768px srcset variant with its own sampler inside a rounded,
	   clipped span at x21. The live number is the one that counts. */
	.elementor .oyo-industry__image {
		position: absolute;
		top: -1px;
		left: -25px;
		width: 450px;
		height: 381px;
	}
	/* The card label is the one place the build came out larger than the design
	   rather than smaller: the mobile frames set 28/33.6 on all nine cards
	   (#374:2536 home, #374:4855 company, #392:6314 careers) against the 32 this
	   widget carries from desktop. Sized the way every other mobile size is -
	   the design value at 440 and above, proportional below, 16px floor - since
	   this widget is ours and has no Elementor typography control. */
	.elementor .oyo-industry__title { font-size: clamp(16px, 6.3636vw, 28px); }
}

/* ==========================================================================
   Home — Contact / Request Early Access Section (Figma #449:216)
   ========================================================================== */

/* Rebuilt 24/09 against the 23/09 file, on the client's note that the band did
   not match Figma and read harder than it should.

   It did not match because the section had been re-layered. What this file
   stacked — one exported plate plus a 0deg wash at 0.43 — was derived from
   #314:220, and that node no longer exists. #449:216 carries four fills of its
   own AND two further background frames as children, #449:217 (2092 wide, so it
   overhangs the section on both sides) and #449:218 (795 tall, top only). Three
   separate scrims, not one.

   Reproducing that stack by hand was tried and abandoned: composited from the
   API's own numbers it scored 16.22 against Figma's render, worse than the
   stale two-layer version's 14.95, because Figma does not paint those fills at
   the opacities it reports — rendering #449:217 alone comes back with an alpha
   of 38..113 where the JSON says the top fill is opaque.

   So the plate is taken from Figma's own rasteriser instead of modelled. The
   section renders as background + content; the content frame #449:219 renders
   separately with alpha, so wherever it is not fully opaque the background is
   solved straight back out of the two:

       bg = (render - content * a) / (1 - a)

   Where the content is fully opaque the background is unrecoverable and also
   invisible; those runs are interpolated across the row so the plate stays
   smooth under stretch. Gutter RMS against Figma's render: 0.000, max channel
   difference 0 — not a fit, an identity.

   Baking that recovered background into a single plate was tried first and
   reverted: the content covers 53% of the render, so 53% of the plate had to be
   invented, and interpolating it across each row left faint horizontal streaks
   wherever our build does not occlude exactly the pixels Figma's did. A plate
   is only honest where something was actually behind it.

   So the artwork layer stays the real starfield export, untouched and with
   nothing invented, and the three scrims are reproduced as gradients over it.
   Their geometry is the file's; only their alphas are fitted, because Figma
   does not paint them at the opacities it reports. Fitted against the recovered
   background over the 42% of the band that is exactly known — the strips where
   the content frame is fully transparent — by grid search:

       wash 0.545   band 0.250   top scrim 0.870

   Gutter RMS against Figma's render, out of 255: the stale single-wash stack
   4.04, Figma's declared opacities 3.95, this 2.58. For reference the previous
   round of this file recorded 3.69 against the 21/09 design. */
.elementor .elementor-element.elementor-element-oyocfsec {
	position: relative;
	background-image:
		/* #449:218, the topmost child, so it is listed first */
		linear-gradient(180deg, rgba(2, 7, 16, 0.87) 0%, rgba(0, 2, 4, 0) 15.73%),
		/* #449:217's band */
		linear-gradient(180deg, rgba(0, 2, 4, 0) 0%, rgba(0, 2, 4, 0.25) 15.73%, rgba(0, 2, 4, 0) 100%),
		/* #449:216's own wash */
		linear-gradient(0deg, rgba(18, 21, 31, 0.545) 0%, rgba(17, 23, 43, 0.545) 97%),
		url(../../design/home/bg-cf-section.webp);
	background-position: center;
	background-size: 100% 100%;
	background-repeat: no-repeat;
}

/* Both overlays sit under the content, as they do in Figma's layer order. */
.elementor .elementor-element.elementor-element-oyocfrow { position: relative; z-index: 1; }

/* #314:224 is primaryAxisSizingMode AUTO - it hugs its content at 560 and does
   NOT match the 731 of the frame beside it. Left to the row's default stretch
   it ran to 731, putting 171px of bare gradient below the last bullet; Figma's
   own render ends the card on row 2515, ours ended on 2688. */
.elementor .elementor-element.elementor-element-oyocfcard { flex: 1 1 0; min-width: 0; width: auto; align-self: flex-start; }
/* #314:249 has no auto-layout: it is a fixed 660x731 box whose children are
   absolutely placed, so the form card does not stretch it. */
.elementor .elementor-element.elementor-element-oyocfframe { flex: 0 0 660px; width: auto; height: 731px; position: relative; }
/* Resolves against the frame's padding box, i.e. the design's (30, 30). */
.elementor .elementor-element.elementor-element-oyocfcard2 { position: absolute; top: 0; right: 0; left: 0; }

/* #314:250 carried the same corner-bracket artwork around the form card. Out
   with the rest of them, 15 Oct; the box keeps its size and its blur. */
.elementor .elementor-element.elementor-element-oyocfcard2 {
	position: relative;
	z-index: 1;
	-webkit-backdrop-filter: blur(11.25px);
	backdrop-filter: blur(11.25px);
}
/* #314:255 centres its children, but the field rows are alignSelf: stretch. */
.elementor .elementor-element.elementor-element-oyocfform { width: 100%; }

/* Bullet rows #314:229 .. #314:244 are primaryAxisSizingMode FIXED at 76, while
   two lines of 38.4 measure 76.8. Figma squeezes rather than grows, the same
   thing #314:72 does with its 417, so the rows are pinned to reproduce it.
   Unpinned the four rows carried +0.81 each and the card closed at 562.9
   instead of 560. Released below the design width, where the text wraps to a
   third line and 76 would clip it. */
.elementor .elementor-element.elementor-element-oyocfb1,
.elementor .elementor-element.elementor-element-oyocfb2,
.elementor .elementor-element.elementor-element-oyocfb3,
.elementor .elementor-element.elementor-element-oyocfb4 { height: 76px; }

/* Bullet rows #314:229 .. #314:244 */
.elementor .elementor-element.elementor-element-oyocfb1i,
.elementor .elementor-element.elementor-element-oyocfb2i,
.elementor .elementor-element.elementor-element-oyocfb3i,
.elementor .elementor-element.elementor-element-oyocfb4i { flex: 0 0 24px; width: auto; align-self: flex-start; }
.elementor .elementor-element.elementor-element-oyocfb1t,
.elementor .elementor-element.elementor-element-oyocfb2t,
.elementor .elementor-element.elementor-element-oyocfb3t,
.elementor .elementor-element.elementor-element-oyocfb4t { flex: 1 1 0; min-width: 0; width: auto; }
/* The mark and the text are separate widgets on a row that tops-aligns both,
   so a 24px tick lands (1.6em - 24px) / 2 above the centre of the first line
   of text: 7.2px at the desktop's 24px type. Figma's own render does exactly
   the same, so this was never drift - the client asked on 14 Oct for the mark
   to sit on the line, which is a change to the design, not a fix to the build.
   The font-size below draws nothing. It is here so the em in the margin
   resolves against the same size the text uses, which keeps the nudge right
   through the fluid clamp at the narrow tier. It has to track post-9.css: 24,
   then 20 below 1025, then clamp(16px, 4.0909vw, 18px) below 768. */
.elementor .elementor-element.elementor-element-oyocfb1i,
.elementor .elementor-element.elementor-element-oyocfb2i,
.elementor .elementor-element.elementor-element-oyocfb3i,
.elementor .elementor-element.elementor-element-oyocfb4i { font-size: 24px; }
.elementor .elementor-element-oyocfb1i img,
.elementor .elementor-element-oyocfb2i img,
.elementor .elementor-element-oyocfb3i img,
.elementor .elementor-element-oyocfb4i img { display: block; width: 24px; height: 24px; max-width: none; margin-top: calc(0.8em - 12px); }

/* --- form fields ------------------------------------------------------------
   Fluent Forms, from 24/09. Pro's form widget carried its spacing, type and
   colours as style controls, and Elementor compiled those into post-9.css - 30
   rules that left with the widget. Every one of them is restated here against
   Fluent's boxes, alongside the rules that always lived in this file.

   The map, for anyone reading this next to an older screenshot:

     .elementor-field-group        ->  .ff-el-group
     the .elementor-col-50 pair    ->  .ff-t-container.oyo-form-row > .ff-t-cell
     label.elementor-field-label   ->  .ff-el-input--label > label
     .elementor-field-textual      ->  .ff-el-form-control
     .elementor-select-wrapper     ->  .ff-el-input--content:has(> select)
     .e-form__buttons > button     ->  .ff_submit_btn_wrapper > .ff-btn-submit

   Fluent's stylesheet is enqueued while the shortcode renders, which is after
   ours, so a tie goes to Fluent. Every rule below is scoped by
   `.elementor .elementor-element-oyocfform`, two classes clear of anything
   Fluent writes.
   -------------------------------------------------------------------------- */

/* Pro's generated sheet spaced the fields with
     .elementor-field-group         { padding: 0 12px; margin-bottom: 32px }
     .elementor-form-fields-wrapper { margin: 0 -12px -32px }
   - a 24px column gutter and a 32px row gap, the negative margins taking the
   gutter back off the outer edges. Fluent has no wrapper to hang the negatives
   on, so the same geometry is stated the other way round: the gap belongs to
   the row, and the last group simply never carries one. */
.elementor .elementor-element-oyocfform .ff-el-group,
.elementor .elementor-element-oyocfform .ff-t-container {
	margin-bottom: 32px;
}

/* `:last-child` is the wrong instrument here: each half of the name row is the
   only child of its own cell, so it would match those two as well and collapse
   the row's gutter. The row is spaced by its container; what it holds is not
   spaced at all. */
.elementor .elementor-element-oyocfform .ff-t-cell > .ff-el-group,
.elementor .elementor-element-oyocfform .ff_submit_btn_wrapper {
	margin-bottom: 0;
}

/* First and last name share a row. Fluent writes `flex-basis: 50%` inline on
   both cells, which no stylesheet can outrank - so the basis is left alone and
   the 24px gutter is taken back out of it by flex-shrink, landing each cell at
   `50% - 12px`. That is the same pair of halves Pro's two `elementor-col-50`
   columns produced. */
.elementor .elementor-element-oyocfform .ff-t-container.oyo-form-row {
	display: flex;
	gap: 24px;
}
.elementor .elementor-element-oyocfform .ff-t-container.oyo-form-row > .ff-t-cell {
	flex: 1 1 0;
	min-width: 0;
	padding: 0;
}

/* #314:257 decomposes as label 24 + gap 4 + line 32 + padding 8 + stroke 1 = 69.
   Figma's group is padding-bottom 8 with a 1px INSIDE stroke, and the stroke
   does NOT eat the last pixel of that padding: #314:257 also carries
   strokesIncludedInLayout: true, and on a hug frame that makes Figma add the
   stroke outside the padding box, exactly as it does on the CTA pill below.
   Reading it as 7 + 1 left every field row at 68, which walked the submit
   button 5px up the card and closed #314:255 at 688 against its declared 693. */
.elementor .elementor-element-oyocfform .ff-el-input--label {
	/* Fluent ships this wrapper as an inline-block, which puts it on a text
	   baseline and leaves the parent's descender space underneath it - about
	   2px per row, invisible on its own and 10px down the card once five rows
	   have each paid it. Pro's label was a block-level <label> with no such
	   line box, so the gap is removed rather than compensated for. */
	display: block;
	margin: 0;
	padding: 0 0 4px;
}
.elementor .elementor-element-oyocfform .ff-el-input--label label {
	color: #ffffff;
	display: block;
	font-family: "Arimo", Sans-serif;
	font-size: 20px;
	font-weight: 400;
	line-height: 1.2em;
	margin: 0;
	padding: 0;
}

/* The design writes the asterisk into the label itself - `First name*`,
   `Email *` - so Fluent's own would be a second one. Five classes, not four:
   Fluent's rule is
     .fluentform .ff-el-input--label.ff-el-is-required.asterisk-right label:after
   at (0,4,2), which is exactly what a four-class rule here would come to, and
   its sheet loads after ours. Naming the wrapper too settles it at (0,5,2). */
.elementor .elementor-element-oyocfform .ff-el-input--label.ff-el-is-required.asterisk-right label::after {
	content: none;
}

.elementor .elementor-element-oyocfform .ff-el-input--content {
	margin: 0;
	padding: 0;
}

.elementor .elementor-element-oyocfform .ff-el-form-control {
	background-color: transparent;
	border: 0;
	border-bottom: 1px solid rgba(204, 204, 204, 0.15);
	border-radius: 0;
	box-shadow: none;
	box-sizing: border-box;
	color: #ffffff;
	font-family: "Arimo", Sans-serif;
	font-size: 20px;
	font-weight: 400;
	/* Fluent sizes its controls with a fixed height, the way Pro's
	   `elementor-size-md` did with a 47px min-height. The design's field box is
	   32px of line plus the 8px that holds the rule, and nothing else. */
	height: auto;
	line-height: 1.6em;
	min-height: 0;
	padding: 0 0 8px;
	width: 100%;
}

.elementor .elementor-element-oyocfform .ff-el-form-control::placeholder {
	color: #cccccc;
	opacity: 0.6;
}

/* #314:277 is a fixed 72px box with no resize grip. Border-box, so the declared
   height carries the 8px of padding and the 1px rule with it: 72 + 8 + 1. That
   puts #314:275 at 109, which is what Figma declares. */
.elementor .elementor-element-oyocfform textarea.ff-el-form-control {
	height: 81px;
	resize: none;
}

/* Country resting state - the placeholder option carries an empty value. */
.elementor .elementor-element-oyocfform select.ff-el-form-control {
	-webkit-appearance: none;
	appearance: none;
	color: #ffffff;
	/* The open list is the browser's widget, not ours. It draws its rows with
	   the control's own `color` - the #ffffff this dark field needs - on its own
	   light sheet, so the country list came out white on white and only the
	   highlighted row was legible. `color-scheme` is what tells the browser to
	   render that widget, its scrollbar and its highlight from the dark side of
	   its palette instead, which is the only lever that reaches the sheet on the
	   engines that own it. */
	color-scheme: dark;
	/* Room for the chevron, which the content box draws rather than the select.
	   Pro's wrapper reserved this with its own background inset. */
	padding-right: 32px;
}
/* And the colours the list paints with where CSS is allowed to paint it, so the
   two engines agree. Same surface and label tokens the rest of the form uses. */
.elementor .elementor-element-oyocfform select.ff-el-form-control option {
	background-color: var(--oyo-state-surface);
	color: var(--oyo-state-label);
}
.elementor .elementor-element-oyocfform select.ff-el-form-control:has(option[value=""]:checked) {
	color: rgba(204, 204, 204, 0.6);
}

/* #314:273. Pro wrapped its select in an element the chevron could hang on, and
   shipped a caret of its own that had to be hidden; Fluent leaves the select
   bare inside the content box and ships no caret, so there is nothing to undo -
   only somewhere to draw. `:has(> select)` reaches exactly the content box that
   holds one, rather than adding a class to all six groups to find one of them. */
.elementor .elementor-element-oyocfform .ff-el-input--content:has(> select) {
	position: relative;
}
.elementor .elementor-element-oyocfform .ff-el-input--content:has(> select)::after {
	background-image: url(../../design/home/cf-chevron.svg);
	background-position: center;
	background-repeat: no-repeat;
	background-size: 24px 24px;
	content: "";
	height: 24px;
	pointer-events: none;
	position: absolute;
	right: 0;
	top: 4px;
	width: 24px;
}

/* #314:283 - gradient pill. Elementor's colour control could not hold a
   gradient and Fluent's cannot either, so it has always lived here.

   Restyled 23/09 on the client's note 4. The button is now a Figma component
   (instance #514:4051, label #449:280) and every CTA on the site is an instance
   of it, so all five rules across this file carry one spec: a 90deg #000204 ->
   #040694 ramp, a solid 1px white inside stroke where it used to be 20% white,
   and a 20px background blur where it used to be 10. The old teal -> green ramp
   was the 21/09 design and is gone from Figma entirely.

   The type, radius and padding came from Pro's generated sheet and are restated
   with it: Arimo 20/1.2em, radius 20, padding 16/24. */
.elementor .elementor-element-oyocfform .ff-btn-submit {
	background-color: transparent;
	background-image: linear-gradient(90deg, #000204 0%, #040694 100%);
	/* The stroke is INSIDE, but #314:283 also carries strokesIncludedInLayout:
	   true, so in a HUG frame Figma adds it outside the padding box: 16 + 24 +
	   16 = 56 of content, painted 58 tall. Confirmed in Figma's own render -
	   #314:896's pill occupies rows 1773..1830 inclusive, and its label sits 17
	   from the edge against a declared padding of 16. A real border reproduces
	   that; an inset shadow paints the line but leaves the box 2px short, which
	   is what put every CTA band 2.41px under its Figma height. */
	border: 1px solid #ffffff;
	border-radius: 20px;
	-webkit-backdrop-filter: blur(20px);
	backdrop-filter: blur(20px);
	box-shadow: none;
	color: #ffffff;
	font-family: "Arimo", Sans-serif;
	font-weight: 400;
	font-size: 20px;
	line-height: 1.2em;
	padding: 16px 24px;
	width: auto;
}

@media (max-width: 1024px) {
	.elementor .elementor-element.elementor-element-oyocfcard,
	.elementor .elementor-element.elementor-element-oyocfframe { flex: 0 0 auto; width: 100%; height: auto; }

	/* Tracks the 20px the bullet text takes here, so the mark keeps landing on
	   the first line. See the base rule for why this is a font-size. */
	.elementor .elementor-element.elementor-element-oyocfb1i,
	.elementor .elementor-element.elementor-element-oyocfb2i,
	.elementor .elementor-element.elementor-element-oyocfb3i,
	.elementor .elementor-element.elementor-element-oyocfb4i { font-size: 20px; }
	/* Stacked, the frame goes back to wrapping the card in its 30px padding. */
	.elementor .elementor-element.elementor-element-oyocfcard2 { position: static; }

	/* Pro's responsive type controls, restated. They were three rules in
	   post-9.css keyed to this breakpoint; the ones below 768 sit in the mobile
	   block further down, which is later in the file and therefore wins there -
	   exactly the cascade Elementor's own sheet had. */
	.elementor .elementor-element-oyocfform .ff-el-input--label label,
	.elementor .elementor-element-oyocfform .ff-el-form-control {
		font-size: 18px;
	}
	.elementor .elementor-element-oyocfform .ff-btn-submit {
		font-size: 20px;
	}
}


/* The glass panels the design repeats - Elementor has no backdrop-filter. */
.elementor .elementor-element.elementor-element-oycotc1,
.elementor .elementor-element.elementor-element-oycotc2,
.elementor .elementor-element.elementor-element-oycomis {
	-webkit-backdrop-filter: blur(11.25px);
	backdrop-filter: blur(11.25px);
}

/* #314:381 / #314:387 - two cards sharing a row share its width. */
.elementor .elementor-element.elementor-element-oycotc1,
.elementor .elementor-element.elementor-element-oycotc2 { flex: 1 1 0; min-width: 0; width: auto; }

/* #314:385 / #314:391 - fill x 340. */
.elementor .elementor-element.elementor-element-oycotc1i,
.elementor .elementor-element.elementor-element-oycotc2i { flex: 0 0 340px; }

/* #314:384 is pinned to 140px in the design so the two portraits line up. The
   two cards already share a row height; letting the copy take up the slack is
   what puts both portraits on the same line, whichever card runs longer. */
.elementor .elementor-element.elementor-element-oycotc1b { min-height: 140px; }
.elementor .elementor-element.elementor-element-oycotc1t,
.elementor .elementor-element.elementor-element-oycotc2t { flex: 1 1 auto; }

/* #314:394 / #314:402 - 1fr / 1fr either side of a 60px gap. */
.elementor .elementor-element.elementor-element-oycowhyl,
.elementor .elementor-element.elementor-element-oycowhyr { flex: 1 1 0; min-width: 0; width: auto; }

/* #314:402 - fill x 500, and the badge is placed inside it. */
.elementor .elementor-element.elementor-element-oycowhyr {
	position: relative;
	height: 500px;
}

/* The AI ENG PRO mark that used to sit on the Why-Exists photograph (#314:404)
   was removed on the client's note 7, and it is gone from the 23/09 Figma too.
   The widget is deleted from the page, so its placement rules went with it. */

/* #314:414 - the same pill as the contact form's submit. */
.elementor .elementor-element-oycoctabtn .elementor-button {
	background-image: linear-gradient(90deg, #000204 0%, #040694 100%);
	border: 1px solid #ffffff;
	-webkit-backdrop-filter: blur(20px);
	backdrop-filter: blur(20px);
}

@media (max-width: 1024px) {
	/* The Why row stacks at tablet, so the two halves stop sharing a width. */
	.elementor .elementor-element.elementor-element-oycowhyl,
	.elementor .elementor-element.elementor-element-oycowhyr { flex: 0 0 auto; width: 100%; }
	.elementor .elementor-element.elementor-element-oycowhyr { height: 420px; }
	.elementor .elementor-element.elementor-element-oycotc1i,
	.elementor .elementor-element.elementor-element-oycotc2i { flex: 0 0 300px; }
	.elementor .elementor-element.elementor-element-oycotc1b { min-height: 0; }
}

@media (max-width: 767px) {
	.elementor .elementor-element.elementor-element-oycotc1,
	.elementor .elementor-element.elementor-element-oycotc2 { flex: 0 0 auto; width: 100%; }

	/* #374:4501 and #374:4507 are 350x300 and sit *above* the name and the
	   bio, where the desktop card has the portrait beside them and the stack
	   therefore drops it below. 24 + 300 + 24 + 187 + 24 is #374:4497's 561. */
	.elementor .elementor-element.elementor-element-oycotc1i,
	.elementor .elementor-element.elementor-element-oycotc2i { flex: 0 0 300px; order: -1; }

	/* #374:4560. */
	.elementor .elementor-element.elementor-element-oycowhyr { height: 356px; }
}

/* ==========================================================================
   Products page (Figma #314:700)

   The two product cards are the home page's, copied into this page keeping
   their ids, so every rule already written for oyopfc1 / oyopfc2 applies here
   as well and there is no second copy to keep in step.
   ========================================================================== */

/* #314:720 / #314:753 - 1fr / 1fr either side of a 60px gap. */
.elementor .elementor-element.elementor-element-oyprwitl,
.elementor .elementor-element.elementor-element-oyprwitimg { flex: 1 1 0; min-width: 0; width: auto; }

/* 633:4412 - 670 x 541.44. The 500 this held came from #314:753 on the 14/09
   file; the 14/10 frame redraws the slot one ratio taller, and that 41.44 is
   most of the 92px the whole page was short against 633:1234. The 440 frame
   moves with it: 400 x 323.2 is the same 0.808. */
.elementor .elementor-element.elementor-element-oyprwitimg {
	height: 541.44px;
	/* 633:4412 and 633:4414 both corner at 8. The 16 in the editor is the
	   14/09 number. Written as the property rather than --border-radius,
	   because the generated sheet sets that variable and loads last. */
	border-radius: 8px;
}

/* 633:1275 opens 53.72 below the band's own padding, which is half the
   difference between the picture and the copy: the row centres its items where
   the editor has them stretched. Below 1281 the row wraps and the column is as
   tall as its content, so this is a no-op there. */
.elementor .elementor-element.elementor-element-oyprwitl { justify-content: center; }

/* --------------------------------------------------------------------------
   Products: the two images change places - client, 13 Oct 2026.

   The annotation draws a crossing pair of arrows between the "What It Does"
   picture and the one inside the "Catch Piping Errors" card, so they swap: the
   isometric goes up, the photograph comes down. Figma 633:1234 still has them
   the other way round, so this follows the client over their own file, and is
   recorded here rather than left to be rediscovered.

   Both are redrawn at twice their box rather than scaled from what was there.
   The isometric's largest copy on this install was 634x422, too small for a
   670x500 slot, so the source is the original behind Figma's own fill, 1536 x
   1024, cropped to the slot's ratio and brought down to 1340x1000. The
   photograph comes from pr-iso.png at 1340x1000, down to 542x438. Both are
   downscales, so neither is softened.

   The card version is scoped to .elementor-11. The same card is on the home
   page and the client marked only this one, so home keeps the isometric.
   -------------------------------------------------------------------------- */
.elementor .elementor-element.elementor-element-oyprwitimg.e-con:not(.elementor-motion-effects-element-type-background) {
	background-image: url(../../design/products/wit-drawing.webp);
}

.elementor-11 .elementor-element.elementor-element-oyopfimg6 img {
	content: url(../../design/products/card-photo.webp);
}

/* #314:729 and friends - a hairline between the list rows. An empty container
   has no height of its own, so it is pinned rather than left to the flex line. */
.elementor .elementor-element.elementor-element-oyprwd1,
.elementor .elementor-element.elementor-element-oyprwd2,
.elementor .elementor-element.elementor-element-oyprwd3,
.elementor .elementor-element.elementor-element-oyprwd4 { flex: 0 0 1px; min-height: 1px; }

/* The ticks hold 24px however long a row's copy runs. */
.elementor .elementor-element.oypr-tick { flex: 0 0 24px; width: auto; }
.elementor .oypr-tick img { display: block; width: 24px; height: 24px; max-width: none; }
.elementor .elementor-element.oypr-rowtext { flex: 1 1 auto; min-width: 0; }

/* #314:888 - hug width, and Elementor has no backdrop-filter control. */
.elementor .elementor-element.elementor-element-oyprpill {
	width: auto;
	max-width: 100%;
	-webkit-backdrop-filter: blur(10px);
	backdrop-filter: blur(10px);
}

@media (max-width: 1024px) {
	/* The What It Does row stacks, so the halves stop sharing a width. */
	.elementor .elementor-element.elementor-element-oyprwitl,
	.elementor .elementor-element.elementor-element-oyprwitimg { flex: 0 0 auto; width: 100%; }
}

/* Between 768 and 1280 the row has wrapped and the picture runs the full
   column, but its height was still a fixed number: 420 against 944 at 1024,
   541 against 1000 at 1200. The fill is `cover`, so that ratio cropped the
   drawing to a letterbox and took the "Wrong gasket spec" and "Bolt length
   clash" callouts off the top and bottom with it. Both frames that exist draw
   this picture at 670 x 541.44 and 400 x 323.25, which is one ratio, so the
   stacked tiers keep that ratio and the whole drawing stays in view. There is
   no tablet frame to take a height from, and a crop that loses the labels is
   not a reading of the design either way. */
@media (min-width: 768px) and (max-width: 1280px) {
	.elementor .elementor-element.elementor-element-oyprwitimg {
		height: auto;
		aspect-ratio: 670 / 541.4391;
		/* Width-driven height needs a ceiling or the picture grows with the
		   column: 1080 wide at 1280 is 873 tall, which is larger than the
		   design ever draws it. 670 is the size both the desktop frame and the
		   1400 column give it, so it stops there and centres. */
		max-width: 670px;
		margin-left: auto;
		margin-right: auto;
	}
}

@media (max-width: 767px) {
	/* #389:4980 sits above the copy on the 440 frame; the desktop band has it
	   beside, so stacking drops it below without this. */
	.elementor .elementor-element.elementor-element-oyprwitimg { height: 323.2px; order: -1; }
}

/* ==========================================================================
   Shared — body copy
   ========================================================================== */

/* The theme gives every paragraph a bottom margin. Figma spaces these blocks
   with auto-layout gap and never with a trailing margin, so the last paragraph
   in a text block would otherwise add ~14px to every card and section it sits
   in. Only :last-child is zeroed, so multi-paragraph copy keeps its rhythm. */
.elementor .elementor-widget-text-editor p:last-child {
	margin-bottom: 0;
}



/* --------------------------------------------------------------------------
   #314:1265 and friends — the numbered step badges.

   Each is three Figma layers: a pill, a circle the height of the pill pinned
   to its left edge, and an oversized number centred on that circle at 10%
   opacity. The circle and the number carry no content, so they are
   pseudo-elements fed by the per-badge custom properties below.
   -------------------------------------------------------------------------- */
/* Elementor renders a widget's custom classes but not a container's, so every
   container here is reached by its element id. Widgets keep their classes. */
.elementor .elementor-element.elementor-element-oytsb1,
.elementor .elementor-element.elementor-element-oytsb2,
.elementor .elementor-element.elementor-element-oytsb3,
.elementor .elementor-element.elementor-element-oytsb4,
.elementor .elementor-element.elementor-element-oytsb5 {
	position: relative;
	flex: 0 0 auto;
	/* Every badge in the design is exactly as wide as its circle
	   (182/193/275/327/327), not as wide as its label; hugging lands 4px short
	   because Figma and Chrome measure a tracked string differently. */
	width: var(--oyts-d);
	height: var(--oyts-d);
	-webkit-backdrop-filter: blur(11.25px);
	backdrop-filter: blur(11.25px);
}

/* #314:1280 and #314:1285 are fill-width where the first three hug. */
.elementor .elementor-element.elementor-element-oytsb4,
.elementor .elementor-element.elementor-element-oytsb5 {
	flex: 1 1 0;
	min-width: 0;
}

.elementor .elementor-element.elementor-element-oytsb1::before,
.elementor .elementor-element.elementor-element-oytsb2::before,
.elementor .elementor-element.elementor-element-oytsb3::before,
.elementor .elementor-element.elementor-element-oytsb4::before,
.elementor .elementor-element.elementor-element-oytsb5::before {
	content: "";
	position: absolute;
	top: 0;
	left: 0;
	width: var(--oyts-d);
	height: var(--oyts-d);
	border: 2px solid #9E9FFF;
	border-radius: 50%;
	/* Two layers, not one. 633:1261 is the badge frame, a circle carrying a 5%
	   #9E9FFF fill under its own 1px stroke; 633:1262 is the ellipse on top of
	   it, whose radial runs 0 to 0.10 at 60.58% to 0.30 at the rim, all at the
	   layer's 0.70. That is where the 0.07 and 0.21 below come from. The flat
	   5% was missed first time round and is what made these read darker than
	   the frame inside the rim. */
	background-color: rgba(158, 159, 255, 0.05);
	background-image: radial-gradient(circle at 50% 50%, rgba(158, 159, 255, 0) 0%, rgba(158, 159, 255, 0.07) 61%, rgba(158, 159, 255, 0.21) 100%);
	pointer-events: none;
}

.elementor .elementor-element.elementor-element-oytsb1::after,
.elementor .elementor-element.elementor-element-oytsb2::after,
.elementor .elementor-element.elementor-element-oytsb3::after,
.elementor .elementor-element.elementor-element-oytsb4::after,
.elementor .elementor-element.elementor-element-oytsb5::after {
	content: var(--oyts-n);
	position: absolute;
	top: 0;
	left: 0;
	display: flex;
	align-items: center;
	justify-content: center;
	width: var(--oyts-d);
	height: var(--oyts-d);
	font-family: Arimo, Arial, sans-serif;
	font-size: var(--oyts-fs);
	line-height: 1.2;
	letter-spacing: -1.5px;
	color: #9E9FFF;
	-webkit-text-stroke: 2px #010306;
	/* 633:1248 and its four siblings carry opacity 0.30. The 0.10 this held
	   came from the 14/09 tech frame; the 14/10 products frame triples it, and
	   that is the difference the client's screenshot shows in the numerals. */
	opacity: 0.3;
	pointer-events: none;
}

/* The label sits over both decorations. */
.elementor .elementor-element.elementor-element-oytsb1 > *,
.elementor .elementor-element.elementor-element-oytsb2 > *,
.elementor .elementor-element.elementor-element-oytsb3 > *,
.elementor .elementor-element.elementor-element-oytsb4 > *,
.elementor .elementor-element.elementor-element-oytsb5 > * {
	position: relative;
	z-index: 1;
}

/* Figma stops tracking after the last character; CSS keeps it, so a tracked
   label measures 1.5px narrower here than in the design and wraps one step
   too late. #314:1289 is the case that proves it: "ENGINEER REVIEW" comes to
   260.89px against a 261px box, where the design breaks it over two lines. */
.elementor .elementor-element.elementor-element-oytsb1w,
.elementor .elementor-element.elementor-element-oytsb2w,
.elementor .elementor-element.elementor-element-oytsb3w,
.elementor .elementor-element.elementor-element-oytsb4w,
.elementor .elementor-element.elementor-element-oytsb5w {
	padding-right: 1.5px;
}

.elementor .elementor-element.elementor-element-oytsb1 { --oyts-d: 182px; --oyts-n: "01"; --oyts-fs: 120px; }
.elementor .elementor-element.elementor-element-oytsb2 { --oyts-d: 193px; --oyts-n: "02"; --oyts-fs: 128px; }
.elementor .elementor-element.elementor-element-oytsb3 { --oyts-d: 275px; --oyts-n: "03"; --oyts-fs: 160px; }
.elementor .elementor-element.elementor-element-oytsb4 { --oyts-d: 327px; --oyts-n: "04"; --oyts-fs: 220px; }
.elementor .elementor-element.elementor-element-oytsb5 { --oyts-d: 327px; --oyts-n: "05"; --oyts-fs: 220px; }

/* #314:1290 — a dashed stroke, which Elementor has no control for. The design
   specifies a 6,6 pattern; a CSS dashed border uses the browser's own rhythm. */
.elementor .elementor-element.elementor-element-oytsnote {
	position: relative;
	/* #314:1290 is HUG with strokesIncludedInLayout: true, so its 147 counts the
	   1px stroke top and bottom. The dash itself has to be drawn as SVG, and an
	   overlay adds no height, so a transparent border carries the box model and
	   the overlay reaches back out over it. Without this the band came out
	   2.61px under #314:1260. */
	border: 1px solid transparent;
	-webkit-backdrop-filter: blur(11.25px);
	backdrop-filter: blur(11.25px);
}

.elementor .elementor-element.elementor-element-oytsnote::before {
	content: "";
	position: absolute;
	/* -1px, not 0: an absolute child is placed against the padding box, and the
	   dash belongs on the border box edge where Figma paints its stroke. */
	inset: -1px;
	width: auto;
	height: auto;
	/* Figma gives a 6,6 dash; a CSS dashed border uses the browser rhythm
	   (~3,3 at 1px), so the stroke is drawn as SVG. stroke-width 2 centred on
	   the box edge is clipped by the SVG viewport, leaving exactly 1px inside. */
	background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='100%25' height='100%25'%3E%3Crect width='100%25' height='100%25' rx='24' ry='24' fill='none' stroke='%239E9FFF' stroke-opacity='0.4' stroke-width='2' stroke-dasharray='6 6'/%3E%3C/svg%3E");
	background-size: 100% 100%;
	background-repeat: no-repeat;
	border-radius: 24px;
	pointer-events: none;
}

/* Glass cards and their ticks. #314:1301 offsets the tick 2px down. */
.elementor .elementor-element.elementor-element-oytsseccard,
.elementor .elementor-element.elementor-element-oytsentcard {
	-webkit-backdrop-filter: blur(11.25px);
	backdrop-filter: blur(11.25px);
}

.elementor .elementor-element.oyts-tick { flex: 0 0 24px; width: auto; padding-top: 2px; }
.elementor .oyts-tick img { display: block; width: 24px; height: 24px; max-width: none; }

/* #314:1294 / #314:1336 and #314:1339 / #314:1341 — 1fr / 1fr, 60px apart. */
.elementor .elementor-element.elementor-element-oytsseccol,
.elementor .elementor-element.elementor-element-oytssecimg,
.elementor .elementor-element.elementor-element-oytsentcol,
.elementor .elementor-element.elementor-element-oytsentimg { flex: 1 1 0; min-width: 0; width: auto; }
.elementor .elementor-element.elementor-element-oytssecimg,
.elementor .elementor-element.elementor-element-oytsentimg { height: 500px; }

@media (max-width: 1024px) {
	.elementor .elementor-element.elementor-element-oytsseccol,
	.elementor .elementor-element.elementor-element-oytssecimg,
	.elementor .elementor-element.elementor-element-oytsentcol,
	.elementor .elementor-element.elementor-element-oytsentimg { flex: 0 0 auto; width: 100%; }
	.elementor .elementor-element.elementor-element-oytssecimg,
	.elementor .elementor-element.elementor-element-oytsentimg { height: 420px; }
	/* The badges wrap at tablet, so they shrink with their circles.

	   The circle is drawn by an absolutely positioned pseudo-element at exactly
	   --oyts-d, so the badge has to be that wide too: no narrower, or a
	   fill-width badge squeezed to 64px pushes its 240px circle off the page,
	   and no wider either. `width: auto` with a minimum did the first half and
	   not the second, so "FLAG DISCREPANCIES" on one line made its badge about
	   300 wide while the ring stayed 240 behind it - the label hanging out to
	   the right of its own circle at 768 and 1024, with the ring sitting off
	   centre. Fixed square, the way both the desktop row and the 440 grid
	   already have it, and the label wraps inside. */
	.elementor .elementor-element.elementor-element-oytsb1,
	.elementor .elementor-element.elementor-element-oytsb2,
	.elementor .elementor-element.elementor-element-oytsb3,
	.elementor .elementor-element.elementor-element-oytsb4,
	.elementor .elementor-element.elementor-element-oytsb5 {
		flex: 0 0 var(--oyts-d);
		width: var(--oyts-d);
		min-width: 0;
	}

	.elementor .elementor-element.elementor-element-oytsb1 { --oyts-d: 150px; --oyts-fs: 96px; }
	.elementor .elementor-element.elementor-element-oytsb2 { --oyts-d: 158px; --oyts-fs: 102px; }
	.elementor .elementor-element.elementor-element-oytsb3 { --oyts-d: 210px; --oyts-fs: 126px; }
	.elementor .elementor-element.elementor-element-oytsb4 { --oyts-d: 240px; --oyts-fs: 160px; }
	.elementor .elementor-element.elementor-element-oytsb5 { --oyts-d: 240px; --oyts-fs: 160px; }
}

@media (max-width: 767px) {
	.elementor .elementor-element.elementor-element-oytssecimg,
	.elementor .elementor-element.elementor-element-oytsentimg { height: 300px; }

	/* #392:5682 puts the photograph above the copy, where the desktop band has
	   it beside it and the stack therefore ends up below. #392:5727, the band
	   under it, already reads image-then-copy in both. */
	.elementor .elementor-element.elementor-element-oytssecimg { order: -1; }
	/* The 440 frame does not stack them. #392:5539 lays the five out two, two
	   and one — #392:5566 and #392:5567 are 400-wide rows of a pair, and
	   #392:5560 sits centred under them — with 24 between every pair and every
	   row. Two 188s and a 24 come to exactly the 400 the band leaves, so the
	   pairs fill their row and wrapping puts the fifth on its own, where
	   centring lands it at x=129 as the design has it.

	   Every badge is the same size here, unlike the desktop row's 182/193/275/
	   327/327, and the fifth is 182 where the other four are 188. The numeral
	   is 120 on all five (#392:5562), which is the desktop first badge's size.

	   606 = 188 + 24 + 188 + 24 + 182, which is #392:5539's own height. */
	/* The editor turns every container to a column at this breakpoint, and a
	   column will not wrap into a grid however the gaps are set — the direction
	   has to come back first. */
	.elementor .elementor-element.elementor-element-oytshowrow {
		flex-direction: row;
		flex-wrap: wrap;
		justify-content: center;
		gap: 24px;
	}

	.elementor .elementor-element.elementor-element-oytsb1,
	.elementor .elementor-element.elementor-element-oytsb2,
	.elementor .elementor-element.elementor-element-oytsb3,
	.elementor .elementor-element.elementor-element-oytsb4,
	.elementor .elementor-element.elementor-element-oytsb5 {
		flex: 0 0 var(--oyts-d);
		width: var(--oyts-d);
		height: var(--oyts-d);
		min-width: 0;
		/* 633:2360 keeps the desktop 33 either side at 440, where the editor
		   drops to 24. Stated as a share of the circle so it comes down with
		   it: 33 / 188. */
		padding-left: calc(var(--oyts-d) * 0.17553);
		padding-right: calc(var(--oyts-d) * 0.17553);
	}

	/* 633:2380 is "FLAG DISCREPANCIES" at 24px in a 120 box, and the design
	   renders it over three lines - Figma breaks the long word rather than let
	   it out of the circle. Without this the word measures 175 against a 122
	   box and hangs over the ring on both sides. */
	.elementor .elementor-element.elementor-element-oytsb1 .elementor-heading-title,
	.elementor .elementor-element.elementor-element-oytsb2 .elementor-heading-title,
	.elementor .elementor-element.elementor-element-oytsb3 .elementor-heading-title,
	.elementor .elementor-element.elementor-element-oytsb4 .elementor-heading-title,
	.elementor .elementor-element.elementor-element-oytsb5 .elementor-heading-title {
		overflow-wrap: anywhere;
	}

	/* 188 and 182 are the 440 frame's own numbers, and they only pair up at
	   440: two 188s and a 24 gap come to exactly the 400 that band leaves. One
	   pixel narrower and the pair no longer fits, so every badge drops onto a
	   row of its own and the band goes from 1061 to about 1470 - which is what
	   a 375 phone was showing. The design has no frame below 440, so the grid
	   is kept and the circles come down with the viewport instead: the row is
	   100vw - 40, a pair needs (row - 24) / 2, and min() holds 188 as the
	   ceiling so 440 and up is unchanged. The numeral keeps its share of the
	   circle, 120 / 188, which is the same expression for all five. */
	.elementor .elementor-element.elementor-element-oytsb1,
	.elementor .elementor-element.elementor-element-oytsb2,
	.elementor .elementor-element.elementor-element-oytsb3,
	.elementor .elementor-element.elementor-element-oytsb4 {
		--oyts-d: min(188px, calc(50vw - 32px));
		--oyts-fs: min(120px, calc(31.915vw - 20.43px));
	}

	.elementor .elementor-element.elementor-element-oytsb5 {
		--oyts-d: min(182px, calc(48.404vw - 30.98px));
		--oyts-fs: min(120px, calc(31.915vw - 20.43px));
	}
}

/* ==========================================================================
   Home — hero band (Figma #314:10)

   The band holds the nav and the hero together and carries one stretched crop
   of the Earth plate. The theme header is absolutely positioned over the page,
   so the hero section spans the whole band and the background goes on it.
   ========================================================================== */

.elementor .elementor-element.elementor-element-oyoherosec {
	/* 21/09 takes the artwork out of the band and gives it its own rectangle:
	   #450:2937 is 1600 x 469 over a 418-tall hero, so the plate no longer
	   stretches to the band — it runs at its own height and the last 51px bleed
	   into the band below. The file is the rectangle exported composited
	   (#14ef5f3d in FILL plus its 0.84 gradient), because the plates carry
	   gradients whose handles run outside the box and, on products, a rotation
	   that background-size cannot express at all. */
	background-image: url(../../design/plates/plate-home-d.webp);
	background-size: 100% 469px;
	background-position: center top;
	background-repeat: no-repeat;
}

/* The 51px tail, painted as this band's topmost layer because a hero container
   cannot draw outside itself and the band below would cover it. */
.elementor .elementor-element.elementor-element-oyopfsec.e-con {
	background-image:
		url(../../design/plates/plate-home-d.webp),
		linear-gradient(rgba(0, 2, 4, 0.7), rgba(0, 2, 4, 0.7)),
		url(../../design/home/bg-pf-earth-6db38c.webp),
		linear-gradient(rgba(0, 2, 4, 0.7), rgba(0, 2, 4, 0.7)),
		url(../../design/home/bg-pf-b-51cc05.webp);
	background-origin: border-box;
	background-size: 100% 469px, 100% 11.084%, 100% 11.084%, 100% 100%, 100% 100%;
	background-position: center -418px, center top, center top, center top, center top;
	background-repeat: no-repeat;
}

/* --------------------------------------------------------------------------
   Hero band heights

   Each frame fixes its own band and lets the copy sit inside it, so the height
   is not the content's: on the 440 frames home is 758 against 614 of content
   and company 551 against 360, with the photograph carrying the rest. Three of
   the five are FIXED in Figma and two HUG, but a min-height reproduces both —
   a hugging band is simply one whose content already reaches the number.

     desktop  #314:10  418
     mobile   #374:1787 758   #374:4132 551   #389:4770 282
              #389:5148 508   #392:5744 386

   All five live here rather than in the editor because a container's Elementor
   min-height arrives as a custom property, which a plain declaration like the
   one home already carried overrides — split across the two, the desktop value
   would have silently won at every width.
   -------------------------------------------------------------------------- */
@media (min-width: 768px) {
	.elementor .elementor-element.elementor-element-oyoherosec { min-height: 418px; }
}

@media (max-width: 767px) {
	.elementor .elementor-element.elementor-element-oyoherosec { min-height: 573px; }
	.elementor .elementor-element.elementor-element-oycoherosec { min-height: 400px; }
	.elementor .elementor-element.elementor-element-oyprherosec { min-height: 282px; }
}

/* #314:10 is 418 tall: the 116px nav, then #314:25's 260 (which carries its own
   80px bottom padding), then 42 more below it. The header sits over the page,
   so that 116 comes back as padding here and the leftover 42 joins the bottom —
   which keeps the hero copy centred where the design centres it.

   Desktop only, and block-axis only. Below 1025 the header is shorter and the
   editor's own responsive padding already clears it; a shorthand here would
   have overridden that at every breakpoint, and would have pinned the inline
   padding at 100px so the content column could never cap at 1400. */
@media (min-width: 1025px) {
	.elementor .elementor-element.elementor-element-oyoherosec {
		padding-block: 116px 122px;
	}
}

/* #314:30 is a fixed 604 inside its 688 container. That is what makes the
   design's second line start at "Time"; given the container's full width the
   first line swallows that word instead. Setting the real width reproduces the
   break by wrapping, so it still reflows on a narrow screen. */
.elementor .elementor-element.elementor-element-oyoheroclaim {
	width: 604px;
	max-width: 100%;
}

/* The other hero bands carry their own photograph too — #314:358 is the image
   alone, #314:701 puts a flat 20% black over it. */
/* #450:2949 is 1600 x 456 over a 356 band: 100px bleed into the team band. */
.elementor .elementor-element.elementor-element-oycoherosec {
	background-image: url(../../design/plates/plate-company-d.webp);
	background-size: 100% 456px;
	background-position: center top;
	background-repeat: no-repeat;
}

/* #450:2953 is 1600 x 456 over a 356 band, and its image transform carries a
   rotation (-0.0142 / 0.0884 off the diagonal), so it is exported composited
   rather than rebuilt from background-size. */
.elementor .elementor-element.elementor-element-oyprherosec {
	background-image: url(../../design/plates/plate-products-d.webp);
	background-size: 100% 456px;
	background-position: center top;
	background-repeat: no-repeat;
}

/* --------------------------------------------------------------------------
   Products hero, second line - client, 13 Oct 2026.

   Figma 633:4141 puts "AI Eng Pro ISO Checker" in the right half of the hero,
   right-aligned and ending on the content column's own right edge at 1500,
   against the existing heading in the left half from 100.

   Figma gives each half 700 of the 1400 column, and splitting it 700/700 here
   wrapped the left heading after "Drawing": the design sets that line in Arial
   MT Pro and this build sets it in Inter, which runs wider and will not fit
   700 at 38px. So the left half takes the width it needs and the right half
   takes its own content, with space-between holding both to their own edge.
   That puts each end where Figma puts it without inventing a line break the
   design does not have.

   On mobile Figma 633:4401 stacks it under the heading, left-aligned and full
   width, which is what dropping the row direction gives.
   -------------------------------------------------------------------------- */
.elementor .elementor-element.elementor-element-oyprherowrap.e-con {
	--flex-direction: row;
	--align-items: flex-start;
	--justify-content: space-between;
	--flex-wrap: nowrap;
	--gap: 0px 0px;
}

.elementor .elementor-element.elementor-element-oyprherohead {
	flex: 1 1 auto;
	min-width: 0;
	width: auto;
}

.elementor .elementor-element.elementor-element-oyprheroiso {
	flex: 0 0 auto;
	width: auto;
}

@media screen and (max-width: 767px) {
	.elementor .elementor-element.elementor-element-oyprherowrap.e-con {
		--flex-direction: column;
		--flex-wrap: wrap;
	}

	.elementor .elementor-element.elementor-element-oyprherohead,
	.elementor .elementor-element.elementor-element-oyprheroiso {
		flex: 0 0 auto;
		width: 100%;
	}
}

/* ==========================================================================
   Inner-page section backgrounds

   Each of these carries its own crop in the design, exactly like the home
   page's. Several sections share the same crop, so the files are reused rather
   than re-exported per page. Last in the file, so the image layers land on top
   of the gradients each page block already declares.
   ========================================================================== */

/* Company #314:376 / #314:393 / #314:413

   The photograph is a partial crop, not a full-height one: its transform is
   sy 0.82876, ty 0.46602, so the slice Figma shows runs from source row 46.6%
   to the bottom edge and lands on the top (1 - 0.46602) / 0.82876 = 64.43% of
   the band. Stretching it to 100% dragged its bright lower half down to the
   band's foot and left a hard step where the next band starts. Figma's own
   render of #314:376 drops at y=586 of 910 — 0.6443 x 910 — which is the check
   that settles it. Below that line only the starfield shows. */
.elementor .elementor-element.elementor-element-oycoteamsec {
	/* The starfield under the photograph is fill 0 at opacity 0.30; the
	   rgba(0, 2, 4, 0.7) layer above it reproduces that blend against the page's
	   #000204. Fill 1 is a hidden copy of the Earth plate and is not painted. */
	background-color: var(--oyo-bg);
	background-image:
		linear-gradient(180deg, rgba(0, 2, 4, 0) 0%, rgba(0, 2, 4, 0.84) 15.7327%, rgba(0, 2, 4, 0) 100%),
		url(../../design/home/bg-co-team-5e0e63.webp),
		linear-gradient(rgba(0, 2, 4, 0.7), rgba(0, 2, 4, 0.7)),
		url(../../design/home/bg-pf-b-51cc05.webp);
	background-size:
		100% 100%,
		100% 64.433%,
		100% 100%,
		100% 100%;
	background-position: center top, center top, center top, center top;
	background-repeat: no-repeat;
}

/* The plate's 100px tail, prepended as this band's topmost layer: a hero
   container cannot paint outside itself and this band would cover it. */
.elementor .elementor-element.elementor-element-oycoteamsec.e-con {
	background-image:
		url(../../design/plates/plate-company-d.webp),
		linear-gradient(180deg, rgba(0, 2, 4, 0) 0%, rgba(0, 2, 4, 0.84) 15.7327%, rgba(0, 2, 4, 0) 100%),
		url(../../design/home/bg-co-team-5e0e63.webp),
		linear-gradient(rgba(0, 2, 4, 0.7), rgba(0, 2, 4, 0.7)),
		url(../../design/home/bg-pf-b-51cc05.webp);
	background-origin: border-box;
	background-size: 100% 456px, 100% 100%, 100% 64.433%, 100% 100%, 100% 100%;
	background-position: center -356px, center top, center top, center top, center top;
	background-repeat: no-repeat;
}

/* #314:413, the company page's button-only band, is gone: it now sits inside
   #314:393 as a sibling of that band's row, because two adjacent bands each
   stretching their own copy of this crop put a smeared seam between them.
   Figma has that seam too - its own render steps 16.1 of 765 there against our
   14.3 - but WebDeveloperArif wants the starfield unbroken, so this is a
   deliberate departure from the design, not a match to it.

   The merge is approved; what was never re-derived for it is the crop.
   bg-pf-b-51cc05 is the slice Figma cuts for a 756px box, so stretching it over
   the merged 844px scales every star by 844/756 = 1.1164, and the live band
   cross-correlated with #314:393's stars at NCC 0.035. The plate below instead
   holds #314:393's star scale exactly and widens the source window to 872 rows,
   43.6% of backdrop-b.png, so the extra 86px is fresh plate rather than stretch.
   Its top 781 rows are byte-identical to bg-pf-b-51cc05. Re-cut if this band's
   height ever moves again: rows = (H - 0.41566) / 0.9676834, rounded up. It
   already moved once - the CTA pill inside it gained its 1px border and took
   the band from 842 to 844, which is exactly Figma's 756 + 88. */
.elementor .elementor-element.elementor-element-oycowhysec {
	background-color: var(--oyo-bg);
	background-image:
		linear-gradient(rgba(0, 2, 4, 0.7), rgba(0, 2, 4, 0.7)),
		url(../../design/home/bg-pf-b-merged-dbce3a.webp);
	background-size: 100% 100%;
	background-position: center top;
	background-repeat: no-repeat;
}

/* #314:755, #314:1293, #314:1338 - one visible fill each, the starfield at
   opacity 0.30 over the page's #000204. The plate is right and the crop is
   right; the 0.30 is the part that never made the trip, and the scrim is it. */
.elementor .elementor-element.elementor-element-oyprcardsec,
.elementor .elementor-element.elementor-element-oytssecsec,
.elementor .elementor-element.elementor-element-oytsentsec {
	background-color: var(--oyo-bg);
	background-image:
		linear-gradient(rgba(0, 2, 4, 0.7), rgba(0, 2, 4, 0.7)),
		url(../../design/home/bg-pf-b-51cc05.webp);
	background-size: 100% 100%;
	background-position: center top;
	background-repeat: no-repeat;
}

/* Products #314:719 — same partial crop as the company team band above:
   sy 0.84, ty 0.54255, so the slice covers the top (1 - 0.54255) / 0.84 =
   54.46% of the band and the starfield carries the rest. */
.elementor .elementor-element.elementor-element-oyprwitsec {
	background-color: var(--oyo-bg);
	background-image:
		linear-gradient(0deg, rgba(0, 0, 0, 0.2), rgba(0, 0, 0, 0.2)),
		url(../../design/home/bg-pr-what-1c784a.webp),
		linear-gradient(rgba(0, 2, 4, 0.7), rgba(0, 2, 4, 0.7)),
		url(../../design/home/bg-pf-b-51cc05.webp);
	background-size:
		100% 100%,
		100% 54.458%,
		100% 100%,
		100% 100%;
	background-position: center top, center top, center top, center top;
	background-repeat: no-repeat;
}

/* The plate's 100px tail, prepended as this band's topmost layer: a hero
   container cannot paint outside itself and this band would cover it. */
.elementor .elementor-element.elementor-element-oyprwitsec.e-con {
	background-image:
		url(../../design/plates/plate-products-d.webp),
		linear-gradient(0deg, rgba(0, 0, 0, 0.2), rgba(0, 0, 0, 0.2)),
		url(../../design/home/bg-pr-what-1c784a.webp),
		linear-gradient(rgba(0, 2, 4, 0.7), rgba(0, 2, 4, 0.7)),
		url(../../design/home/bg-pf-b-51cc05.webp);
	background-origin: border-box;
	background-size: 100% 456px, 100% 100%, 100% 54.458%, 100% 100%, 100% 100%;
	background-position: center -356px, center top, center top, center top, center top;
	background-repeat: no-repeat;
}

/* Tech & Security #314:1260 - the design stacks the same crop twice, both at
   opacity 0.30, and the two collapse exactly:
   0.3S + 0.7(0.3S + 0.7B) = 0.51S + 0.49B. So this band's effective starfield
   strength is 0.51, not 0.30, and its scrim is 0.49. Do not paste the 0.70 the
   other bands use here. One plate under a 0.49 scrim is the same result with one
   less paint than two plates under 0.70 each. */
.elementor .elementor-element.elementor-element-oytshowsec {
	background-color: var(--oyo-bg);
	background-image:
		linear-gradient(180deg, rgba(0, 2, 4, 0) 0%, rgba(0, 2, 4, 0.84) 15.7327%, rgba(0, 2, 4, 0) 100%),
		linear-gradient(rgba(0, 2, 4, 0.49), rgba(0, 2, 4, 0.49)),
		url(../../design/home/bg-pf-b-51cc05.webp);
	background-size: 100% 100%;
	background-position: center top;
	background-repeat: no-repeat;
}

/* The tech artwork this band used to carry went with the page: How It Works
   is on products now, where 633:1241 paints nothing of its own. What it does
   carry there is stated once, in the last block of this file. */

/* ==========================================================================
   Careers (Figma #332:1628)

   Two of its five bands are already-built shapes reused whole: the CV band is
   the industries grid inside the same bracketed frame, and the closing band is
   the products CTA cloned. Only the two mirrored feature bands are new.
   ========================================================================== */



/* #332:1821 carries the same fills as the industries bands on home and company,
   so it takes the same export. */
.elementor .elementor-element.elementor-element-oycrcvsec {
	position: relative;
	background-image: url(../../design/home/bg-ind-section.webp);
	background-size: 100% 100%;
	background-position: center;
	background-repeat: no-repeat;
}

/* #332:1822's frame went with the others on 15 Oct. */

/* Both children sit over the frame rather than under it. */
.elementor .elementor-element.elementor-element-oycrcvhd,
.elementor .elementor-element.elementor-element-oycrgrid {
	position: relative;
	z-index: 1;
}

/* #332:1827 is a fixed 792 — the heading breaks inside that width, not the
   full column's. */
.elementor .elementor-element.elementor-element-oycrcvhd {
	width: 792px;
	max-width: 100%;
}

/* #332:1681 / #332:1875 - the mirrored bands share the starfield, one visible
   fill each at opacity 0.30. */
.elementor .elementor-element.elementor-element-oycrfindsec,
.elementor .elementor-element.elementor-element-oycrtalsec {
	background-color: var(--oyo-bg);
	background-image:
		linear-gradient(rgba(0, 2, 4, 0.7), rgba(0, 2, 4, 0.7)),
		url(../../design/home/bg-pf-b-51cc05.webp);
	background-size: 100% 100%;
	background-position: center top;
	background-repeat: no-repeat;
}

.elementor .elementor-element.elementor-element-oycrfindl,
.elementor .elementor-element.elementor-element-oycrtall {
	flex: 1 1 0;
	min-width: 0;
	width: auto;
}

/* #485:3258 / #485:3261 — a white plate 500 tall holding a 770x506 photograph
   placed at (-100, -6), so the plate crops it. It is a background rather than
   an <img> because nothing but the crop matters here.

   Both photographs were replaced on the client's note 10 (23/09). The box
   geometry did not change — still 770x506 clipped by 670x500 — only the
   pictures did, so this is a straight swap.

   What did change is how the file is cut. The old pair were exports of the
   image node, off the design's own origin by different amounts (877 wide
   against 883), which is why each carried its own hand-fitted correction:
   -52px here and -90px at mobile, both measured rather than derived. These
   four files are exports of the *clipping frame* instead, so Figma has already
   applied the crop and the plate is the picture. That makes the offsets
   redundant - `100% 100%` over a box of exactly the export's size is the same
   pixels with nothing left to fit. */
.elementor .elementor-element.elementor-element-oycrfindimg,
.elementor .elementor-element.elementor-element-oycrtalimg {
	flex: 1 1 0;
	min-width: 0;
	width: auto;
	height: 500px;
	border-radius: 16px;
	background-color: #ffffff;
	background-size: 100% 100%;
	background-position: center;
	background-repeat: no-repeat;
}

.elementor .elementor-element.elementor-element-oycrfindimg {
	background-image: url(../../design/careers/cv-2309.webp);
}

.elementor .elementor-element.elementor-element-oycrtalimg {
	background-image: url(../../design/careers/talent-2309.webp);
}

/* #332:1863 / #332:1891 — the same pill the CTA band uses. */
.elementor .elementor-element-oycrfindbtn .elementor-button,
.elementor .elementor-element-oycrtalbtn .elementor-button {
	background-image: linear-gradient(90deg, #000204 0%, #040694 100%);
	border: 1px solid #ffffff;
	-webkit-backdrop-filter: blur(20px);
	backdrop-filter: blur(20px);
}

@media (max-width: 1024px) {
	/* The rows stack, so the halves stop sharing a width and the plate has to
	   shorten with them or it dwarfs the copy beside it. */
	.elementor .elementor-element.elementor-element-oycrfindl,
	.elementor .elementor-element.elementor-element-oycrtall,
	.elementor .elementor-element.elementor-element-oycrfindimg,
	.elementor .elementor-element.elementor-element-oycrtalimg {
		flex: 0 0 auto;
		width: 100%;
	}

	.elementor .elementor-element.elementor-element-oycrfindimg,
	.elementor .elementor-element.elementor-element-oycrtalimg {
		height: 400px;
		background-size: cover;
		background-position: center;
	}
}

@media (max-width: 767px) {
	/* #392:6067 and #392:6070 are both 300 on the 440 frame, and both bands put
	   the picture above the copy — which the talent band already does, while
	   the opportunities band has it beside on desktop and so stacks it below. */
	.elementor .elementor-element.elementor-element-oycrfindimg,
	.elementor .elementor-element.elementor-element-oycrtalimg {
		height: 300px;
	}

	/* Both frames clip an oversized picture rather than fitting one: #485:3418
	   is 548 x 360 in a 400 x 300 box and #485:3427 is 556 x 366 — a crop the
	   desktop file cannot stand in for, and #485:3427 is a different photograph
	   from its desktop twin besides. So mobile keeps its own pair, exported
	   from the clipping frame the same way, already cut to 400 x 300.

	   `cover` rather than `100% 100%` here because this box is the one that
	   moves: its width is the viewport less the 20px gutters while its height
	   stays 300. At the design's 440 the box is exactly 400 x 300 and cover is
	   a 1:1 paint with nothing cropped; away from 440 it crops instead of
	   stretching people sideways, which is the failure worth avoiding. */
	.elementor .elementor-element.elementor-element-oycrfindimg {
		background-image: url(../../design/careers/cv-m-2309.webp);
		background-size: cover;
		background-position: center;
	}

	.elementor .elementor-element.elementor-element-oycrtalimg {
		background-image: url(../../design/careers/talent-m-2309.webp);
		background-size: cover;
		background-position: center;
	}

	.elementor .elementor-element.elementor-element-oycrfindimg { order: -1; }
}

/* ==========================================================================
   Single industry — the template behind /industry/<name>/

   Built to the products page's shape: a photographic band, the body, then the
   shared call to action. The page has no Figma frame of its own, so the sizes
   here are the ones the product page already establishes, not invented ones.
   ========================================================================== */

/* This band alone opts out of the content column's padding: the photograph has
   to reach the viewport edges while the name stays in the 1400 column, and a
   container's padding cannot do both. The widget carries the gutter instead. */
.elementor > .e-con.elementor-element-oyinherosec {
	--padding-inline-start: 0px;
	--padding-inline-end: 0px;
}

.oyo-ihero {
	display: flex;
	align-items: flex-end;
	min-height: 356px;
	padding-block: 116px 40px;
	padding-inline: max(var(--oyo-gutter), (100% - var(--oyo-content)) / 2);
	/* The wash is what keeps the name legible over whatever photograph the
	   client uploads — it cannot be left to the image to be dark enough. */
	background-image:
		linear-gradient(180deg, rgba(0, 2, 4, 0.2) 0%, rgba(0, 2, 4, 0.55) 55%, rgba(0, 2, 4, 0.92) 100%),
		var(--oyo-ihero-image, none);
	background-color: var(--oyo-bg);
	background-size: cover;
	background-position: center;
	background-repeat: no-repeat;
}

.oyo-ihero__inner {
	display: flex;
	flex-direction: column;
	gap: 12px;
	width: 100%;
	max-width: var(--oyo-content);
}

.oyo-ihero__title {
	margin: 0;
	font-family: Arimo, sans-serif;
	font-size: 38px;
	font-weight: 400;
	line-height: 1.2em;
	letter-spacing: -1.5px;
	color: var(--oyo-text);
}

.oyo-ihero__standfirst {
	max-width: 760px;
	margin: 0;
	font-family: Arimo, sans-serif;
	font-size: 20px;
	line-height: 1.6em;
	color: var(--oyo-text-muted);
}

/* The body band borrows the starfield the products page's card band uses. The
   single-industry template is not in canvas #314:2, so this band has no Figma
   node of its own - but every band that does composites this plate at opacity
   0.30, so borrowing the plate without the scrim would leave this one page's
   starfield five times brighter than the rest of the site. The scrim is here
   for consistency with the design, not as a match to a node. */
.elementor .elementor-element.elementor-element-oyinbodysec {
	background-color: var(--oyo-bg);
	background-image:
		linear-gradient(rgba(0, 2, 4, 0.7), rgba(0, 2, 4, 0.7)),
		url(../../design/home/bg-pf-b-51cc05.webp);
	background-size: 100% 100%;
	background-position: center top;
	background-repeat: no-repeat;
}

/* A 1400 measure is unreadable for running prose, so the body keeps a column.
   The extra .elementor-widget is not decoration: Elementor's per-document sheet
   sets max-width on this same element at the same specificity and is enqueued
   during render, so it wins on order unless this rule outranks it. */
.elementor .elementor-element.elementor-element-oyinbody.elementor-widget {
	max-width: 900px;
	font-family: Arimo, sans-serif;
	font-size: 20px;
	line-height: 1.6em;
	color: var(--oyo-text-muted);
}

.elementor .elementor-element.elementor-element-oyinbody h2,
.elementor .elementor-element.elementor-element-oyinbody h3 {
	margin: 40px 0 12px;
	font-family: Arimo, sans-serif;
	font-weight: 400;
	line-height: 1.2em;
	letter-spacing: -1.5px;
	color: var(--oyo-text);
}

.elementor .elementor-element.elementor-element-oyinbody h2 { font-size: 34px; }
.elementor .elementor-element.elementor-element-oyinbody h3 { font-size: 26px; }

.elementor .elementor-element.elementor-element-oyinbody > *:first-child {
	margin-top: 0;
}

.elementor .elementor-element.elementor-element-oyinbody ul {
	margin: 0 0 16px;
	padding-left: 22px;
	list-style: disc;
}

.elementor .elementor-element.elementor-element-oyinbody li {
	margin-bottom: 8px;
}

@media (max-width: 1024px) {
	.oyo-ihero {
		min-height: 300px;
		padding-block: 84px 32px;
	}

	.oyo-ihero__title { font-size: 32px; }
	.oyo-ihero__standfirst { font-size: 18px; }
	.elementor .elementor-element.elementor-element-oyinbody.elementor-widget { font-size: 18px; }
}

@media (max-width: 767px) {
	.oyo-ihero {
		min-height: 240px;
		padding-block: 56px 24px;
	}

	.oyo-ihero__title { font-size: 26px; }
	.oyo-ihero__standfirst { font-size: 16px; }
	.elementor .elementor-element.elementor-element-oyinbody.elementor-widget { font-size: 16px; }
}


/* ==========================================================================
   Tablet and mobile — Phase 5

   Canvas #314:2 has no frame below 1025px (audit blocker 1), so nothing here is
   a match to the design. WebDeveloperArif delegated the two small breakpoints
   ("mobile/tablet tomar moto kore design kore dite paro"), and what follows is
   that decision, written down. Each block names the measurement that prompted
   it, so the client can disagree with a number rather than a taste.
   ========================================================================== */

@media (max-width: 1024px) {

	/* ------------------------------------------------------------------
	   S1 — band artwork was being stretched, not cropped.

	   `background-size: 100% 100%` is exact at 1600, where every band's aspect
	   matches its plate's. It is not exact anywhere else: measured anisotropy
	   (plate aspect / band aspect) reaches x3.4 at 768 and **x10.7** at 375, so
	   a 1px star is painted as a 1 x 10.7px streak and the Earth limb is drawn
	   five times taller than it was drawn. `cover` crops instead, which keeps
	   the artwork's own shape. It is the right trade here because these plates
	   are texture and sky with no subject to lose, and the design's own reading
	   at 1600 is round stars.

	   Only the full-bleed image layers change. Scrims and gradients stay at
	   100% 100% because they are geometry, not artwork, and the compositing
	   maths in the Phase 2 block depends on them covering the whole band.
	   ------------------------------------------------------------------ */

	/* The five hero bands are not here — each one's mobile fill is a different
	   window on its source than the desktop fill, so they carry their own
	   artwork and their own sizing in the block that follows this one. */

	/* One image layer. */
	.elementor .elementor-element.elementor-element-oyoindsec.e-con,
	.elementor .elementor-element.elementor-element-oycoindsec.e-con,
	.elementor .elementor-element.elementor-element-oycrcvsec.e-con {
		background-size: cover;
	}

	/* Three gradients over one image layer — oyocfsec carries a scrim more
	   than the rest of this group, so it needs its own sizing. */
	.elementor .elementor-element.elementor-element-oyocfsec.e-con {
		background-size: 100% 100%, 100% 100%, 100% 100%, cover;
	}

	/* Gradient over one image layer. */
	.elementor .elementor-element.elementor-element-oycowhysec,
	.elementor .elementor-element.elementor-element-oyprcardsec.e-con,
	.elementor .elementor-element.elementor-element-oytssecsec.e-con,
	.elementor .elementor-element.elementor-element-oytsentsec.e-con,
	.elementor .elementor-element.elementor-element-oycrfindsec.e-con,
	.elementor .elementor-element.elementor-element-oycrtalsec.e-con,
	.elementor .elementor-element.elementor-element-oyinbodysec {
		background-size: 100% 100%, cover;
	}

	/* #314:1260 stacks its gradient and its 0.49 scrim over one plate. */
	.elementor .elementor-element.elementor-element-oytshowsec.e-con {
		background-size: 100% 100%, 100% 100%, cover;
	}

	/* ------------------------------------------------------------------
	   Hero artwork at 440

	   Every mobile hero fill is a different window on its source than the
	   desktop one, so none of the desktop crops can be reused. A Figma
	   IMAGE fill maps the box onto the source as

	     u = tx + (x / W) * sx        v = ty + (y / H) * sy

	   and the window may open outside the image, in which case only the
	   part inside [0,1] is drawn. Each file below is that visible slice,
	   and the size/position put it back where the transform had it.

	     #374:1787 home     sx .34005 tx .32987  sy 1.60184 ty -.68753
	     #374:4132 company  sx .33113 tx .33444  sy  .28799 ty  .18359
	     #389:4770 products sx .38205 tx .30901  sy 2.16460 ty  .00435
	     #389:5148 tech     sx .31644 tx .35418  sy 1.37000 ty  .61290
	     #392:5744 careers  FILL, no transform — cover of the whole image

	   Two of them draw only part of their band: home's window opens above
	   the plate so the slice sits flush to the foot over 57.08% of the
	   height, and tech's runs off the bottom so its slice covers the top
	   28.26% and the gradient carries the rest. products' window is
	   authored against the 1319-tall frame that merges the hero with the
	   feature section below it; the slice here is the part of it that
	   falls inside the hero, which is why it fills the box.

	   company is the one page whose mobile hero is a different photograph,
	   not a different crop — #374:4132 references a02db058 against the
	   desktop band's 1a6ba4b7 — and it is the only band that gained a
	   gradient on mobile.
	   ------------------------------------------------------------------ */
	/* #450:2939 is 440 x 573 and the 21/09 band is 573, so the plate is flush
	   here — no overhang, and no windowed background-size. */
	.elementor .elementor-element.elementor-element-oyoherosec {
		background-image: url(../../design/plates/plate-home-m.webp);
		background-origin: border-box;
		background-size: 100% 100%;
		background-position: center top;
	}

	/* 21/09 drops #a02db058 here and reuses the desktop photograph. #450:2951
	   is 440 x 400 with #1a6ba4b7 at sx .36392 tx .31804, sy .48368 ty 0 —
	   source x 636..1364 by y 0..662, which is what the baked file holds, so
	   the layer is a plain 100% 100%.

	   Its gradient is not a plain top-to-bottom ramp: the handles run from
	   y 70.07% of the box to y 207.79%, so 0.3 alpha holds flat over the top
	   seven tenths and only the foot goes dark. Stops are restated against the
	   box: start 70.07%, the opaque stop at 70.07 + .22474 x 137.72 = 101.02%,
	   and the clear one at 207.79%. */
	.elementor .elementor-element.elementor-element-oycoherosec {
		background-image:
			linear-gradient(180deg,
				rgba(0, 2, 4, 0.3) 0%,
				rgba(0, 2, 4, 0.3) 70.07%,
				rgba(0, 2, 4, 1) 101.02%,
				rgba(0, 2, 4, 0) 207.79%),
			url(../../design/heroes/hero-company-m-2109.webp);
		background-origin: border-box;
		background-size: 100% 100%, 100% 100%;
		background-position: center top, center top;
	}

	.elementor .elementor-element.elementor-element-oyprherosec {
		background-image:
			linear-gradient(0deg, rgba(0, 0, 0, 0.2), rgba(0, 0, 0, 0.2)),
			url(../../design/heroes/hero-products-m-7014d2.webp);
		background-size: 100% 100%, 100% 100%;
		background-position: left top, left top;
	}



	/* The photograph bands keep their percentage layer: 64.433% and 54.458% are
	   where the design drops the image into the starfield, and that proportion
	   is the band's structure rather than its texture. The photograph inside it
	   is still stretched at these widths - it is the one thing in this block
	   that is left alone, because fixing it properly needs a portrait crop of
	   the two source images, which is a request for the client rather than a
	   CSS decision. */
	.elementor .elementor-element.elementor-element-oyopfsec {
		background-size: 100% 100%, 100% 11.084%, 100% 100%, cover;
	}

	.elementor .elementor-element.elementor-element-oycoteamsec.e-con {
		background-size: 100% 100%, 100% 64.433%, 100% 100%, cover;
	}

	.elementor .elementor-element.elementor-element-oyprwitsec.e-con {
		background-size: 100% 100%, 100% 54.458%, 100% 100%, cover;
	}

	/* ------------------------------------------------------------------
	   S2 — the header stopped existing after the first screen.

	   `.elementor-location-header` is absolutely positioned so the design can
	   overlay it on the hero. That is right at 1600, where the whole hero is on
	   screen. At 375 the home page is nearly 6000px and the only route to the
	   menu was y=0. Fixed, with the drawer's own glass treatment so it reads as
	   a layer rather than a bar. Nothing is hidden by it: the header measures
	   83.8 at 768 and 56.1 at 375 against hero top padding of 120 and 100.
	   ------------------------------------------------------------------ */
	/* M-12 settled. The scrim and its blur are on no Figma frame at any
	   breakpoint, and they were costing the header band MAE 18.7 on tech, 15.7
	   on company, 7.8 on careers and 5.4 on products — on home, whose plate is
	   already dark up there, 0.8. The contrast question they were held for does
	   not arise at this breakpoint: the nav labels live in the drawer, and what
	   sits over the plate is the #CCCCCC burger, which the design leaves on a
	   luminance of 25-56 — better than 7:1 even at tech's brightest. */
	.elementor-location-header {
		position: fixed;
		top: 0;
		left: 0;
		right: 0;
	}

	/* ------------------------------------------------------------------
	   S3 — footer link targets were 25.6px tall inside a 45.6px pitch, so two
	   thirds of the row was dead space. WCAG 2.2 AA 2.5.8 asks 24x24; 44 is the
	   platform norm.

	   "The pitch already allows it, so this costs no height" — which is what
	   this comment said — was wrong. The 20px that separates the items is the
	   item's own margin, so it sits *outside* the 44, and the pitch went 45.6
	   -> 64: 18.4 per item, 92 on the five-item column and 74 on the four, most
	   of the 186 by which the mobile footer overran #389:5344's 1113.5.

	   Pulling the box back by half the difference it added restores the pitch
	   the design asks for — #389:5362 sets 16/25.6 with listSpacing 20 — while
	   the target stays 44 and keeps its distance from its neighbour, since 45.6
	   still leaves 1.6 between one box and the next. The label lands back on
	   the line the design draws rather than 9.2 below it.
	   ------------------------------------------------------------------ */
	.elementor .elementor-element.elementor-element-oyoftr1 .elementor-nav-menu a {
		display: flex;
		align-items: center;
		min-height: 44px;
		margin-block: -9.2px; /* (44 - 25.6) / 2 */
	}

	/* S4 — form controls measure 36.8 at 768 and 33.6 at 375, because the
	   desktop rule above deliberately undoes the control's own height to hit
	   Figma's 32px line plus the 8px that holds the rule. That is right at 1600
	   and too small for a finger, so the target is restored here. The extra
	   height goes on padding-top so the underline stays at the foot of the box
	   and the label keeps its distance from the text. */
	.elementor .elementor-element-oyocfform .ff-el-form-control {
		min-height: 44px;
		padding-top: 7px;
		/* The 44 is a finger, not a measurement, and it was costing the row
		   6.4px each: #449:2011 is 64 on a 96 pitch and the build read 78.4 on
		   102.4, which is the whole +31.5 on #449:2010. Pulling the 7.2 out of
		   the top margin keeps the box — and so the hit area — at 44 while it
		   only contributes 36.8 to the row, and the underline stays where the
		   design puts it because the bottom edge does not move. The extra
		   reaches up into the label's own leading, which is dead space.

		   -7.2 is the full difference between the 44 and the design's 36.8, and
		   taking all of it overshot: the card closed at 707.4 against #449:2010's
		   719. Six fields share the correction, so it is 7.2 - 11.6/6.

		   The textarea is deliberately inside this selector too, exactly as it
		   was inside the Pro one this replaces: its own height wins over the
		   min-height, and it takes the same padding and the same correction as
		   every other control. */
		margin-top: -5.3px;
	}

	/* The chevron rode 5.3px high here, which is the correction above, exactly.

	   The select carries margin-top: -5.3px, and that margin collapses straight
	   through the content box - the box has no padding or border to stop it -
	   so the box and the control move together and keep a shared top edge.
	   `top: 4px` therefore measures from the control itself.

	   Pro measured from a wrapper that did not move: its chevron sat 4px below
	   a box the select had been pulled 5.3px above, so 9.3px below the
	   control's own top. Measured back off the baseline capture as 5.328px, to
	   three decimal places, which is that same -5.3 and not a fitted number. */
	.elementor .elementor-element-oyocfform .ff-el-input--content:has(> select)::after {
		top: 9.3px;
	}

	/* Pro's mobile type controls, restated. The clamps are its own, copied out
	   of the generated sheet rather than re-derived. */
	.elementor .elementor-element-oyocfform .ff-el-input--label label,
	.elementor .elementor-element-oyocfform .ff-el-form-control {
		font-size: clamp(16px, 4.0909vw, 18px);
	}

	.elementor .elementor-element-oyocfform .ff-btn-submit {
		font-size: clamp(16px, 4.5455vw, 20px);
		min-height: 44px;
	}

}

@media (max-width: 767px) {
	/* Elementor's `elementor-col-50` pair went full width below 768, so the two
	   names stacked and each carried the ordinary row gap. Fluent's grid does
	   not do that on its own - its cells keep the inline `flex-basis: 50%` at
	   every width - so the row is unwound here: block layout, full-width cells,
	   and the same 32px between them that every other field row has.
	   Without this the pair stayed side by side at 375 and the page closed 79px
	   short of the design. */
	.elementor .elementor-element-oyocfform .ff-t-container.oyo-form-row {
		display: block;
	}
	.elementor .elementor-element-oyocfform .ff-t-container.oyo-form-row > .ff-t-cell {
		width: 100%;
	}
	.elementor .elementor-element-oyocfform .ff-t-container.oyo-form-row > .ff-t-cell:first-child > .ff-el-group {
		margin-bottom: 32px;
	}
}


@media (min-width: 768px) and (max-width: 1024px) {
	/* ------------------------------------------------------------------
	   S5 — fifteen bands kept their desktop gap all the way down. 60px is 4.3%
	   of the 1400 column at 1600 and 17.9% of the 335 column at 375, so the
	   rhythm the design sets is not the rhythm that arrives. Stepped with the
	   gutter, which already runs 100 / 40 / 20.
	   ------------------------------------------------------------------ */
	.elementor .elementor-element.elementor-element-oyoindsec.e-con,
	.elementor .elementor-element.elementor-element-oyocfsec.e-con,
	.elementor .elementor-element.elementor-element-oycoteamsec.e-con,
	.elementor .elementor-element.elementor-element-oyprwitsec.e-con,
	.elementor .elementor-element.elementor-element-oyprcardsec.e-con,
	.elementor .elementor-element.oyo-band.e-con,
	.elementor .elementor-element.elementor-element-oytssecsec.e-con,
	.elementor .elementor-element.elementor-element-oytsentsec.e-con,
	.elementor .elementor-element.elementor-element-oycrfindsec.e-con,
	.elementor .elementor-element.elementor-element-oycrtalsec.e-con,
	.elementor .elementor-element.elementor-element-oycrctasec.e-con {
		--row-gap: 40px;
		--column-gap: 40px;
		gap: 40px;
	}

	.elementor .elementor-element.elementor-element-oytshowsec.e-con {
		--row-gap: 32px;
		--column-gap: 32px;
		gap: 32px;
	}
}

/* S5 above is a tablet ladder, which is why it is bounded below at 768: every
   band it names is named again in the 767 block further down with its own
   smaller step, so holding it above 768 changes nothing for those — and it lets
   a band that now has a real number off the 440 frames take that number from
   the editor instead of inheriting this one. */
@media (max-width: 1024px) {

	/* ------------------------------------------------------------------
	   S6 — two nodes carry tracking in px, so it never re-derives.

	   Everything else in the type scale is a px value Figma states for a single
	   size. These two are set once and then reused at every breakpoint: -1.5px
	   is -0.0395em on the 38px h1, but -0.0577em once the h1 is 26px, a 46%
	   tighter fit than the design asks for. Restated as the design's own ratio
	   so it follows the size down.
	   ------------------------------------------------------------------ */
	/* -0.0395 and -0.0341 are the ratios -1.5px makes at the *desktop* sizes,
	   38 and 44. The 440 frame states its own -1.5px at 32 and 40 — #449:1797
	   and #449:1799 — which is -0.046875 and -0.0375. Live measured -1.264
	   against -1.5. Each breakpoint gets the ratio its own frame states, and
	   the value still follows the size down below 440. */
	.elementor .elementor-element.elementor-element-oyoherohead.elementor-widget,
	.elementor .elementor-element.elementor-element-oyoherohead.elementor-widget h1 {
		letter-spacing: -0.046875em;
	}

	.elementor .elementor-element.elementor-element-oyoheroclaim.elementor-widget,
	.elementor .elementor-element.elementor-element-oyoheroclaim.elementor-widget h2 {
		letter-spacing: -0.0375em;
	}

	/* ------------------------------------------------------------------
	   S7 — the drawer opened over live content with nothing behind it.

	   A spread box-shadow is the scrim, so no extra element is needed and the
	   panel keeps its own stacking context. It dims but does not dismiss;
	   tap-to-close needs script and is listed with Phase 6.
	   ------------------------------------------------------------------ */
	.elementor-menu-toggle.elementor-active + .elementor-nav-menu--dropdown,
	.elementor-menu-toggle[aria-expanded="true"] + .elementor-nav-menu--dropdown {
		box-shadow: 0 0 0 100vmax rgba(0, 2, 4, 0.72);
	}
}

/* The toggle had hover and active styling but no keyboard state anywhere in the
   file, so a keyboard user could not see where they were. */
.elementor-menu-toggle:focus-visible {
	outline: 2px solid #9e9fff;
	outline-offset: 3px;
}

@media (max-width: 767px) {
	/* The same ladder, one step further down. */
	.elementor .elementor-element.oyo-band.e-con,
	.elementor .elementor-element.elementor-element-oycrctasec.e-con {
		--row-gap: 32px;
		--column-gap: 32px;
		gap: 32px;
	}

	/* This ladder was invented — there was no mobile design when it was written,
	   so every band at this breakpoint got a gap by feel. The 440 frames give
	   real numbers, and a band that now has one comes off the ladder and takes
	   its gap from the editor instead: #389:5201 sets 30, #392:5682 and
	   #392:5727 set 20. The rest are still on it, and each drops off as its own
	   frame is worked through. */

	/* Only the four closing CTA bands are still on the ladder. Their frames put
	   one child inside 100/150 of padding, so the gap never resolves against
	   anything and there is nothing to take off the design. */

	/* ------------------------------------------------------------------
	   S1 is reversed here, and only here.

	   Cropping the band plates instead of stretching them was the right call
	   while there was no frame under 1025 to check against: at 375 the
	   anisotropy reaches x10.7 and a round star is painted as a streak. The 440
	   frames settle it the other way. Every one of these bands carries the
	   *same* image transform on mobile as on desktop — 069ea631 at sy .50015,
	   14ef5f3d at sy 1.35864, and so on — which is STRETCH, and Figma's own
	   render of the frame shows the streaked stars. The design accepts them, so
	   the build does too, and matching it is what was asked for.

	   768-1024 keeps the crop: there is still no frame there, so S1's reasoning
	   still stands and nothing has come along to overrule it.
	   ------------------------------------------------------------------ */
	.elementor .elementor-element.elementor-element-oyoindsec.e-con,
	.elementor .elementor-element.elementor-element-oycoindsec.e-con,
	.elementor .elementor-element.elementor-element-oycrcvsec.e-con {
		background-size: 100% 100%;
	}

	/* The mobile band is #449:1975, 440x1394, and it nests the same two scrim
	   frames at their DESKTOP sizes: #449:1976 is still 2092x931 and #449:1977
	   still 440x795, clipped inside a section half as tall again. So the scrims
	   do not scale with the band the way percentages of the section would make
	   them - restated against 1394 they land at 795/1394 and 931/1394 rather
	   than at 100%. Left stretched, the top scrim reached 219px instead of 125
	   and the band ran the whole height instead of stopping at two thirds,
	   which read 2-3 levels too dark from a quarter of the way down. */
	.elementor .elementor-element.elementor-element-oyocfsec {
		background-image:
			linear-gradient(180deg, rgba(2, 7, 16, 0.87) 0%, rgba(0, 2, 4, 0) 8.97%),
			linear-gradient(180deg, rgba(0, 2, 4, 0) 0%, rgba(0, 2, 4, 0.25) 10.51%, rgba(0, 2, 4, 0) 66.79%),
			linear-gradient(0deg, rgba(18, 21, 31, 0.545) 0%, rgba(17, 23, 43, 0.545) 97%),
			url(../../design/home/bg-cf-section.webp);
	}

	.elementor .elementor-element.elementor-element-oyocfsec.e-con {
		background-size: 100% 100%, 100% 100%, 100% 100%, 100% 100%;
	}

	.elementor .elementor-element.elementor-element-oyprcardsec.e-con,
	.elementor .elementor-element.elementor-element-oytssecsec.e-con,
	.elementor .elementor-element.elementor-element-oytsentsec.e-con,
	.elementor .elementor-element.elementor-element-oycrfindsec.e-con,
	.elementor .elementor-element.elementor-element-oycrtalsec.e-con {
		background-size: 100% 100%, 100% 100%;
	}

	/* oycowhysec and oytshowsec are not on that list. Their 440 fill stack is
	   not the desktop stack resized - different images, different count - so
	   both are restated in full further down. */

	/* #374:3644's Earth sliver is a different window again: sx .28893 tx .36743
	   with sy 3.30049 ty .87584, where desktop reads the full width at sy
	   1.35864. It takes a narrower patch from lower down the plate — source
	   x .367..656 of rows .876..1 — and lays it across the whole band width in
	   67.8px at the top.

	   bg-pf-earth is rows 435..512 of that plate at full width, so it already
	   contains the window and no new file is needed; the crop's own top row
	   (v = .8496) lands at -14.33 and its full height renders at 82.2, which is
	   4.5567% of the 1803.5 band and -0.8325% of the space left over. The
	   starfield under it carries the desktop transform, so it goes back to the
	   stretch the frame draws rather than the crop S1 gave it. */
	.elementor .elementor-element.elementor-element-oyopfsec {
		background-size: 100% 100%, 346.1% 4.5567%, 100% 100%, 100% 100%;
		background-position: center top, 51.667% -0.8325%, center top, center top;
	}

	/* ------------------------------------------------------------------
	   Three bands whose 440 stack is a different stack, not a resized one

	   S1 above assumes the mobile frame carries the desktop fills and only the
	   box changes, which is true of every band it names. These three are the
	   exceptions in the file: one drops two of its three fills, one swaps its
	   photograph for a different image entirely, and one adds a window that
	   appears nowhere else in the design. Each is restated from its own node.

	   Each was derived by compositing the node's fill list in band coordinates
	   against the frame's own PNG, scoring only the gutter columns the content
	   never reaches. The three land at gutter MAE 0.57, 0.60 and 0.63 - the
	   floor here is about 0.33, which is the difference between Figma's render
	   of #000204 and the value itself.
	   ------------------------------------------------------------------ */

	/* #389:4946 - one fill where desktop's #314:719 has three. The photograph
	   (45c30596 at sy .84) and the 20% black over it are both gone at 440: the
	   illustration is a child image node here, which the build already carries
	   as oyprwitimg, so the band is left with the starfield alone.

	   Its window is 069ea631 at sy 2.0941 ty -1.52844, which exists on exactly
	   two nodes in the whole file and nowhere on desktop. ty is negative by more
	   than half the window, so the plate only starts at 1.52844 / 2.0941 =
	   72.99% down the band and the 757px above it is bare #000204 - the frame's
	   own gutter reads a flat 1.667 there and first lifts at band row 757.

	   The window ends at source row 1131 of 2000 and no existing crop reaches
	   that far, so bg-pf-b-tall is a fresh cut of backdrop-b: rows 0..1132, the
	   same q92 encode, its first 781 rows matching bg-pf-b-51cc05 at MAE 0.82.
	   Against that crop the window is sy 3.69973 ty -2.70043. */
	.elementor .elementor-element.elementor-element-oyprwitsec.e-con {
		background-image:
			linear-gradient(rgba(0, 2, 4, 0.7), rgba(0, 2, 4, 0.7)),
			url(../../design/home/bg-pf-b-tall-a89c57.webp);
		/* Every percentage in this block is a fraction of the node box, because
		   that is the box Figma's fill paints. background-origin defaults to
		   padding-box, which would resolve them against 1041.2 - 130 here and
		   start them 50px down. */
		background-origin: border-box;
		background-size: 100% 100%, 100% 27.028%;
		background-position: center top, center 100.023%;
	}

	/* #389:5201 - four fills, one of them hidden, against desktop's seven.
	   The pair of stacked 069ea631 copies that gave #314:1260 its 0.51 plate
	   strength is not repeated here: at 440 there is one copy at 0.30, so the
	   scrim above it goes back to 0.70.

	   Fill 1 is 14ef5f3d at sx .18647 sy 2.13004 ty .9375 - the same sliver
	   window the company band carries, and the same one bg-pf-earth was cut for
	   on the home page. That crop is rows 435..512 at full width and the window
	   needs 480..512, so it is already inside the file: on it the window reads
	   sy 14.16460 ty .58442, which renders 71.4px tall with 41.8 of that above
	   the band and 29.7 showing.

	   Fill 2's gradient runs its whole ramp inside the top 34.954% of the band -
	   handles 0 to .34954 - and its two stops at position 0 are Figma's way of
	   writing a hard start, so only the 1.0 one is painted. At the layer's own
	   0.84 that is 0.84 at the top row falling to nothing at 34.954%.

	   The last two layers are the inner frame #392:5475, which is this section's
	   content box exactly - 400 x 912 inside 50/20 padding - carrying the same
	   sy 2.0941 window as #389:4946 at its own 0.30. background-origin puts the
	   pair on the content box so the numbers are the ones above, unchanged. It
	   is worth 0.095 of gutter MAE on the rows it touches, which is under this
	   band's own 0.60 floor; it is painted because it is derivable, not because
	   it is visible. */
	.elementor .elementor-element.elementor-element-oytshowsec.e-con {
		background-image:
			url(../../design/home/bg-pf-b-tall-a89c57.webp),
			linear-gradient(rgba(0, 2, 4, 0.7), rgba(0, 2, 4, 0.7)),
			linear-gradient(180deg, rgba(0, 2, 4, 0.84) 0%, rgba(0, 2, 4, 0) 34.954%),
			url(../../design/home/bg-pf-earth-6db38c.webp),
			linear-gradient(rgba(0, 2, 4, 0.7), rgba(0, 2, 4, 0.7)),
			url(../../design/home/bg-pf-b-51cc05.webp);
		background-origin: content-box, content-box, border-box, border-box, border-box, border-box;
		background-size:
			100% 27.028%, 100% 27.028%,
			100% 100%, 536.279% 7.061%, 100% 100%, 100% 100%;
		background-position:
			center 100.023%, center 100.023%,
			center top, 50.02% -4.44%, center top, center top;
	}

	/* #374:4165 - the company band, and the one place where the 440 frame uses
	   an image desktop never sees.

	   Desktop splits this into #314:376 and #314:393 + #314:413; the mobile
	   frame draws all of it as a single node 2663 tall. The build's two
	   sections are contiguous and measure 1578.8 + 1085.2 = 2664.0 against that
	   2663, so the band is sliced rather than re-joined: each section takes the
	   same layers at the same band scale and differs only in where the band's
	   top sits relative to its own box.

	   Five fills, of which three are painted:

	     069ea631 at 0.30, the desktop window - stretched over the whole 2664,
	                so 168.680% of the team section and 245.404% of the why one.
	     14ef5f3d at sx .18647 sy 2.13004 - dropped. Its rect is band rows
	                0..78, and a02db058 below covers 0..1022 with no alpha at
	                all, so removing it changes the composite by 0.000000 across
	                every pixel of the band. It is measured, not assumed.
	     a02db058 at sx .32754 tx .33748, sy 1.37912 ty .47058 - desktop's
	                1a6ba4b7 team photograph is not here; this is a different
	                source, 1024x1536, and the window runs off its bottom edge
	                at band row 1022.28. Baked to band-co-m rather than
	                expressed: the visible rect is source x 345.58..680.98 by
	                y 722.81..1536, which is 336 x 813 mapping to 440 x 1022.28,
	                so the crop carries the anisotropy and the offset and the
	                rule needs only a height.
	     the last gradient - handles 0 to .10443386 of the band, so its whole
	                ramp lands in the top 278.2px and it holds its final 0.5
	                everywhere below. Stated as a percentage of the team
	                section, it is 0 / 4.042 / 9.552 / 17.622; by the time the
	                why section starts it is the flat 0.5 alone. */
	.elementor .elementor-element.elementor-element-oycoteamsec.e-con {
		background-image:
			linear-gradient(180deg,
				rgba(0, 2, 4, 0) 0%,
				rgba(0, 2, 4, 1) 4.042%,
				rgba(0, 2, 4, 0.965) 9.552%,
				rgba(0, 2, 4, 0.5) 17.622%),
			url(../../design/company/band-co-m-26ec63.webp),
			linear-gradient(rgba(0, 2, 4, 0.7), rgba(0, 2, 4, 0.7)),
			url(../../design/home/bg-pf-b-51cc05.webp);
		background-origin: border-box;
		background-size: 100% 100%, 100% 64.750%, 100% 100%, 100% 168.680%;
		background-position: center top, center top, center top, center top;
	}

	.elementor .elementor-element.elementor-element-oycowhysec {
		background-image:
			linear-gradient(rgba(0, 2, 4, 0.5), rgba(0, 2, 4, 0.5)),
			linear-gradient(rgba(0, 2, 4, 0.7), rgba(0, 2, 4, 0.7)),
			url(../../design/home/bg-pf-b-51cc05.webp);
		background-origin: border-box;
		background-size: 100% 100%, 100% 100%, 100% 245.404%;
		background-position: center top, center top, center bottom;
	}
}

/* ==========================================================================
   Interaction states — Phase 6

   Figma draws exactly one state in the whole file. Searched and confirmed: 0
   components, 0 component sets, 0 variants, and 0 of 274 node names matching
   hover / focus / active / press / state / disabled. The one thing drawn is the
   industries middle card, #314:197 against #314:187 and #314:209 beside it,
   same frame, same row, same 451x468 box.

   Read off that pair, and verified against the raw node data:

     surface  #0E0E10 -> #191920
     stroke   #2A2A2C -> #030695
     marker   #46464A -> #BCBDFF      (the arrow)
     label    #E4E2E4 -> #E4E2E4      unchanged
     geometry identical                nothing moves
     plus a #030695 glow, 6px stroke blurred 20 and 4px blurred 4

   Five rules fall out and they are the whole system: nothing moves, the label
   never changes, the surface steps up one notch, the stroke goes brand, the
   marker goes light-violet. Where an element has no surface and no stroke - a
   nav item, a footer link - the marker carries the state on its own. That is
   the single extension, and the geometry of a bare text link forces it.

   Everything below is therefore DERIVED, not matched. The design does not draw
   a hover, a focus ring, a pressed state or a disabled state anywhere.
   ========================================================================== */

:root {
	/* Read off #314:197 against #314:187. No new colour is introduced. */
	--oyo-state-surface: #191920;
	--oyo-state-stroke: #030695;
	--oyo-state-marker: #bcbdff;
	--oyo-state-label: #e4e2e4;

	/* The focus ring is two colours because one cannot clear 3:1 (WCAG 1.4.11)
	   on both the near-black bands and the bright hero plates. #BCBDFF is the
	   card's own marker; #000204 is the page ground, and each backs the other
	   at 11.7:1. */
	--oyo-focus: #bcbdff;
	--oyo-focus-backing: #000204;

	/* 0.28s is the duration already shipped on the cards. The other two are
	   scaled by changed area: a 451x466 surface reads as one slow area event,
	   while a 3px bar under a nav item is fixated directly and the same
	   duration reads as sticky. */
	--oyo-t-lg: 0.28s;
	--oyo-t-md: 0.2s;
	--oyo-t-sm: 0.14s;
}

/* --------------------------------------------------------------------------
   The focus ring, once.

   `:focus-visible` rather than `:focus`, so a mouse press on a card or a pill
   does not leave a ring behind it. Two rings: the marker outside, the page
   ground just inside it, so whichever the element sits on, one half has
   contrast. `outline` rather than `box-shadow` because it never participates
   in layout.

   The form's own controls are NOT in this list. The client asked for the ring
   off there, and `:focus-visible` could not deliver that on its own: a text
   field matches it on a plain mouse click, because the spec says a control that
   takes keyboard input always does. They keep a focus state of their own on the
   underline instead - see the field rule further down - so removing the ring
   removes the box, not the indication.
   -------------------------------------------------------------------------- */
.elementor a:focus-visible,
.elementor button:focus-visible,
.elementor .oyo-industry:focus-visible,
.elementor-menu-toggle:focus-visible,
.skip-link:focus-visible {
	outline: 2px solid var(--oyo-focus);
	outline-offset: 2px;
	box-shadow: 0 0 0 4px var(--oyo-focus-backing);
}

/* --------------------------------------------------------------------------
   Pressed. One declaration for every control.

   Figma draws no pressed state. Opacity is the only property that is safe on
   all of these at once - a gradient pill, a glass panel with backdrop-filter,
   an SVG marker, bare text - it is composited so it lands within a frame on a
   mid-range phone, and it moves nothing, which rule 1 forbids. 15% is enough to
   read as confirmation and far from the 45% that would read as disabled.
   Instant in, normal out: the press registers on the same frame as the click.
   -------------------------------------------------------------------------- */
.elementor a:active,
.elementor .elementor-button:active,
.elementor .oyo-industry:active,
.elementor-menu-toggle:active {
	opacity: 0.85;
	transition-duration: 0s;
}

/* --------------------------------------------------------------------------
   Header nav items — bare text, so the marker carries the state alone.

   Drawn as an inset shadow rather than a border or a pseudo-element: it cannot
   shift the item by a pixel, and Elementor's own pointer already owns
   ::before/::after on these anchors. The 3px backing under the 2px marker is
   the contrast halo - the nav sits over the hero plate, and on /industry/ that
   strip measures L 0.157, where #BCBDFF alone is 2.87:1.
   -------------------------------------------------------------------------- */
.elementor .elementor-element-oyohdrnav .elementor-nav-menu--main a.elementor-item {
	transition: box-shadow var(--oyo-t-sm) ease, color var(--oyo-t-sm) ease, opacity var(--oyo-t-sm) ease;
}

.elementor .elementor-element-oyohdrnav .elementor-nav-menu--main a.elementor-item:hover {
	box-shadow:
		inset 0 -2px 0 0 var(--oyo-state-marker),
		inset 0 -3px 0 0 var(--oyo-focus-backing);
}

/* --------------------------------------------------------------------------
   Pill buttons — all six instances.

   The pill has a surface and a stroke, so rules 3 and 4 apply and the marker
   is not needed. Only the stroke moves: #030695 measures 4.17:1 on the
   gradient's cyan stop and 8.18:1 on its green one.

   The surface deliberately does NOT step up. The pill's white label already
   measures 1.76:1 against the green stop - a pre-existing failure of the
   design's own colours, logged for sign-off - and brightening the gradient by
   the 6% a "one notch" step would imply takes it to 1.56:1. Making a contrast
   failure worse to honour a derived rule is the wrong trade.
   -------------------------------------------------------------------------- */
.elementor .elementor-element-oyocfform .ff-btn-submit,
.elementor .elementor-element-oycoctabtn .elementor-button,
.elementor .oyo-cta__btn .elementor-button,
.elementor .elementor-element-oycrctabtn .elementor-button,
.elementor .elementor-element-oycrfindbtn .elementor-button,
.elementor .elementor-element-oycrtalbtn .elementor-button {
	transition: border-color var(--oyo-t-md) ease, opacity var(--oyo-t-md) ease;
}

.elementor .elementor-element-oyocfform .ff-btn-submit:hover,
.elementor .elementor-element-oycoctabtn .elementor-button:hover,
.elementor .oyo-cta__btn .elementor-button:hover,
.elementor .elementor-element-oycrctabtn .elementor-button:hover,
.elementor .elementor-element-oycrfindbtn .elementor-button:hover,
.elementor .elementor-element-oycrtalbtn .elementor-button:hover {
	border-color: var(--oyo-state-stroke);
}

/* --------------------------------------------------------------------------
   Footer link lists — bare text with a bullet, so the marker is the bullet.

   The label lifts from the footer's muted #A3A3A3 to the card's own #E4E2E4,
   which is the one label colour the design uses for an activated thing, at
   16.2:1 on the footer. The bullet takes the marker at 11.7:1.
   -------------------------------------------------------------------------- */
.elementor-element-oyoftrnav1 .elementor-nav-menu--main .elementor-item,
.elementor-element-oyoftrnav2 .elementor-nav-menu--main .elementor-item {
	transition: color var(--oyo-t-sm) ease, opacity var(--oyo-t-sm) ease;
}

.elementor-element-oyoftrnav1 .elementor-nav-menu--main > ul > li::before,
.elementor-element-oyoftrnav2 .elementor-nav-menu--main > ul > li::before {
	transition: color var(--oyo-t-sm) ease;
}

.elementor-element-oyoftrnav1 .elementor-nav-menu--main .elementor-item:hover,
.elementor-element-oyoftrnav1 .elementor-nav-menu--main .elementor-item:focus-visible,
.elementor-element-oyoftrnav2 .elementor-nav-menu--main .elementor-item:hover,
.elementor-element-oyoftrnav2 .elementor-nav-menu--main .elementor-item:focus-visible {
	color: var(--oyo-state-label);
}

.elementor-element-oyoftrnav1 .elementor-nav-menu--main > ul > li:hover::before,
.elementor-element-oyoftrnav2 .elementor-nav-menu--main > ul > li:hover::before,
.elementor-element-oyoftrnav1 .elementor-nav-menu--main > ul > li:focus-within::before,
.elementor-element-oyoftrnav2 .elementor-nav-menu--main > ul > li:focus-within::before {
	color: var(--oyo-state-marker);
}

/* --------------------------------------------------------------------------
   Footer social marks — a 44px ring, so the ring is the stroke.
   -------------------------------------------------------------------------- */
.elementor .elementor-widget.elementor-element-oyoftrsocial .elementor-grid-item a {
	transition: border-color var(--oyo-t-sm) ease, opacity var(--oyo-t-sm) ease;
}

.elementor .elementor-widget.elementor-element-oyoftrsocial .elementor-grid-item a:hover {
	border-color: var(--oyo-state-marker);
}

/* --------------------------------------------------------------------------
   Form fields — the underline is the field's only boundary, so it is both the
   stroke and the marker.

   Rest is Figma's own rgba(204,204,204,0.15), which measures 1.30:1 on the
   field's #07080E and fails 1.4.11 as a resting state. That is a defect in the
   design's colours, not in the states, so it is logged rather than changed
   here. 0.45 is the first alpha that clears 3:1 and is what hover uses; focus
   goes to the marker at 11.30:1.
   -------------------------------------------------------------------------- */
.elementor .elementor-element-oyocfform .ff-el-form-control {
	transition: border-color var(--oyo-t-md) ease, opacity var(--oyo-t-md) ease;
}

/* Under Pro these two needed an extra class each, purely to beat a rule in
   post-9.css that sat at the same specificity and loaded later. That sheet no
   longer says anything about this form, so the tie is gone and the selectors
   are back to naming only what they mean.

   Fluent does carry a `:focus` of its own - a blue ring and a border colour -
   but at one class fewer than these, so these win without help. */
.elementor .elementor-element-oyocfform .ff-el-form-control:hover {
	border-bottom-color: rgba(204, 204, 204, 0.45);
}

.elementor .elementor-element-oyocfform .ff-el-form-control:focus {
	/* No ring, on the client's instruction. The underline is the only edge these
	   fields have, so it carries the state: it goes from rgba(204,204,204,0.15)
	   to #bcbdff and doubles in weight. The second pixel is an inset shadow
	   rather than a 2px border because a border would move the text up by one. */
	border-bottom-color: var(--oyo-state-marker);
	outline: none;
	box-shadow: inset 0 -1px 0 0 var(--oyo-state-marker);
}

/* A control that is genuinely unavailable, at the 45% that reads as disabled
   rather than the 85% that reads as pressed. */
.elementor .elementor-element-oyocfform .ff-el-form-control:disabled,
.elementor .elementor-element-oyocfform .ff-btn-submit:disabled,
.elementor .elementor-element-oyocfform .ff-btn-submit[aria-disabled="true"] {
	opacity: 0.45;
	cursor: not-allowed;
}

/* --------------------------------------------------------------------------
   The thank-you panel.

   Fluent hides the form on success and drops `.ff-message-success` in its
   place. That left one line of text in a short box at the top of a 731px
   frame with the rest of the card empty, which is what the client saw.

   The card keeps the height it had rather than collapsing. It is a flex child
   of the frame, which is a fixed 731 at full width, so growing it fills that
   frame exactly and no number has to be guessed.

   Not by pinning its bottom edge, which was the first attempt: two rules in
   this file set position on this card at the same specificity, and the later
   one wins with `relative`, so the `absolute` the rule above it asks for never
   applies and offsets do not resize anything. Worth knowing before trusting
   that older comment.

   `:has()` is what reads the state - the card carries no class to say the form
   has been submitted, but it does contain the message. The same selector is
   already used a few rules above for the country field, so support is settled.
   -------------------------------------------------------------------------- */
.elementor .elementor-element.elementor-element-oyocfcard2:has(.ff-message-success) {
	flex: 1 1 auto;
}

.elementor .elementor-element-oyocfform:has(.ff-message-success) {
	display: flex;
	flex: 1 1 auto;
	align-items: center;
	justify-content: center;
}

.elementor .elementor-element-oyocfform .ff-message-success {
	align-items: center;
	background-color: transparent;
	border: 0;
	border-radius: 0;
	color: #ffffff;
	display: flex;
	flex-direction: column;
	gap: 24px;
	justify-content: center;
	margin: 0;
	padding: 8px 0;
	text-align: center;
	width: 100%;
}

/* The mark, on the same spec as every CTA on this site - the 90deg #000204 ->
   #040694 ramp, a 1px white stroke, a 20px backdrop blur - taken fully round
   so it reads as a badge rather than a button nobody labelled. The tick is an
   SVG so it stays crisp at any density. */
.elementor .elementor-element-oyocfform .ff-message-success::before {
	content: "";
	width: 72px;
	height: 72px;
	flex: 0 0 auto;
	border: 1px solid #ffffff;
	border-radius: 50%;
	background-image:
		url(../../design/home/cf-check.svg),
		linear-gradient(90deg, #000204 0%, #040694 100%);
	background-position: center, center;
	background-repeat: no-repeat, no-repeat;
	background-size: 32px 32px, 100% 100%;
	-webkit-backdrop-filter: blur(20px);
	backdrop-filter: blur(20px);
}

/* Two paragraphs, and they come from the form's own confirmation message, so
   the client can still edit the words in Fluent without opening this file. A
   single-paragraph message still renders - it just takes the heading size. */
.elementor .elementor-element-oyocfform .ff-message-success p {
	margin: 0;
}
.elementor .elementor-element-oyocfform .ff-message-success p:first-of-type {
	font-family: "Arimo", Sans-serif;
	font-size: 28px;
	font-weight: 400;
	line-height: 1.2em;
}
.elementor .elementor-element-oyocfform .ff-message-success p + p {
	color: rgba(255, 255, 255, 0.7);
	font-family: "Arimo", Sans-serif;
	font-size: 18px;
	font-weight: 400;
	line-height: 1.6em;
	max-width: 36ch;
}

/* Kept here rather than in the 1024 block further up: these rules and the ones
   above share a selector, and the panel block is later in the file, so from up
   there they lost the cascade even though the media query matched. */
@media (max-width: 1024px) {
	/* The card is in the flow below 1024, so there is no frame edge to grow
	   against; the panel carries a height of its own instead. */
	.elementor .elementor-element-oyocfform:has(.ff-message-success) {
		min-height: 420px;
	}
	.elementor .elementor-element-oyocfform .ff-message-success p:first-of-type {
		font-size: 24px;
	}
	.elementor .elementor-element-oyocfform .ff-message-success::before {
		width: 64px;
		height: 64px;
		background-size: 28px 28px, 100% 100%;
	}
}

/* --------------------------------------------------------------------------
   The skip link. hello-elementor ships it visually hidden and never restores
   it, so it was unreachable in practice even once #content existed.
   -------------------------------------------------------------------------- */
.skip-link:focus,
.skip-link:focus-visible {
	position: fixed;
	top: 12px;
	left: 12px;
	z-index: 1000;
	width: auto;
	height: auto;
	clip: auto;
	clip-path: none;
	padding: 12px 20px;
	border-radius: 12px;
	background-color: var(--oyo-focus-backing);
	color: var(--oyo-state-label);
	font: 400 16px/1.4 Arimo, sans-serif;
	text-decoration: none;
}

/* The landmark takes focus from the skip link, and a programmatic focus target
   should not draw a ring of its own. */
main#content:focus {
	outline: none;
}

/* --------------------------------------------------------------------------
   Reduced motion, and forced colours.

   Every state above is a colour change, so removing the transition removes the
   animation and keeps the whole system intact - nothing here depends on motion
   to be legible. Under forced-colors the browser replaces the palette, so the
   ring is handed back to the system colour rather than fighting it.
   -------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
	.elementor a,
	.elementor .elementor-button,
	.elementor .oyo-industry,
	.elementor .elementor-field-textual,
	.elementor .elementor-select-wrapper select,
	.elementor-menu-toggle,
	.elementor-element-oyoftrnav1 .elementor-nav-menu--main > ul > li::before,
	.elementor-element-oyoftrnav2 .elementor-nav-menu--main > ul > li::before {
		transition-duration: 0s;
	}
}

@media (forced-colors: active) {
	.elementor a:focus-visible,
	.elementor button:focus-visible,
	.elementor .oyo-industry:focus-visible,
	.elementor-menu-toggle:focus-visible,
	.skip-link:focus-visible {
		outline-color: Highlight;
		box-shadow: none;
	}
}

/* ==========================================================================
   Legal pages — Phase 7

   /terms-conditions/ and /privacy-policy/ have no frame in canvas #314:2, so
   none of this is a design match; WebDeveloperArif asked for a basic treatment
   for the pages the design does not cover ("oi gula basic design kore dio").

   They are also the only two routes not built in Elementor. Legal copy belongs
   in the plain editor, not in a page builder - it gets pasted, revised by
   counsel and re-pasted - so they render through the_content() inside the
   <main> wrapper, and everything below styles that stream. The values are the
   site's own: the 791 measure is the tech and careers hero column (#314:1257,
   #332:1645), 38/34/22 is the heading scale the built pages already use, and
   the band treatment is the starfield at the Phase 2 compositing.
   ========================================================================== */

/* The site's content column, measured off the built bands: every one of them
   comes out x=260 w=1400 at 1920, x=100 w=1400 at 1600, x=100 w=1240 at 1440
   and x=40 w=944 at 1024 - that is min(1400, 100% - 2 gutters), centred. The
   legal pages take the same column so they line up with everything else. */
main#content.oylg {
	--oylg-col: min(1400px, 100% - var(--oyo-gutter) * 2);
}

main#content.oylg > * {
	box-sizing: border-box;
}

/* The title plate, standing in for the hero band the built pages carry. 356 is
   every other route's hero height; 150 of top padding clears the 116 the header
   overlays plus the 34 #314:1256 puts above its first line. */
main#content.oylg > .oylg-title {
	display: block;
	min-height: 356px;
	/* Full-bleed background, no horizontal padding: the plate's own text rides
	   the same column as the body below it, and the column is centred rather
	   than gutter-pinned, so the padding would put the title 160px left of the
	   prose on a 1920 window. */
	padding: 150px 0 60px;
	background-color: var(--oyo-bg);
	background-image:
		linear-gradient(rgba(0, 2, 4, 0.7), rgba(0, 2, 4, 0.7)),
		url(../../design/home/bg-pf-b-51cc05.webp);
	background-size: 100% 100%;
	background-position: center top;
	background-repeat: no-repeat;
}

main#content.oylg > .oylg-title h1 {
	width: var(--oylg-col);
	margin-inline: auto;
	margin-block: 0;
	font: 400 38px/1.2 Arimo, sans-serif;
	letter-spacing: -1.5px;
	color: var(--oyo-text);
}

main#content.oylg > .oylg-title .oylg-updated {
	width: var(--oylg-col);
	margin-inline: auto;
	margin-block: 16px 0;
	font: 400 18px/1.5 Arimo, sans-serif;
	color: var(--oyo-text-muted);
}

/* The body stream. One rule covers both pages and anything else that ever
   renders through the_content(), which is the point of styling the stream
   rather than a document. */
/* The body stream sits in the site's own content column.

   It used to be a 791 measure produced by capping each child at 791 + gutter*2
   and giving it that gutter as padding. Two things were wrong with it. The box
   started at x=0 and only the text was inset, so anything with a background of
   its own - the placeholder callout - drew itself flush to the window edge
   while its text lined up with the headings, which is the misalignment the
   client reported. And the measure left the right two fifths of a 1600 window
   empty. Margin instead of padding puts the box itself on the column, so a
   panel aligns with the prose, and dropping the cap gives the same 1400 at
   x=100 that every built band uses - the gutter variable already steps
   100/40/20, so this follows it down. */
main#content.oylg > *:not(.oylg-title) {
	width: var(--oylg-col);
	margin-inline: auto;
	font: 400 22px/35.2px Arimo, sans-serif;
	color: var(--oyo-text-muted);
}

/* Rhythm: 48 between sections, 8 from a heading to the text it introduces, 16
   between paragraphs. The old 56/56 on h2 and 16/16 on p made the gap under a
   heading as big as the gap between sections, so a heading floated between two
   blocks instead of belonging to the one below it. */
main#content.oylg > h2:not(.oylg-title) {
	/* margin-block, not the shorthand: the shorthand resets margin-inline and
	   takes the column off again. */
	margin-block: 48px 8px;
	font: 400 34px/40.8px Arimo, sans-serif;
	letter-spacing: -1.5px;
	color: var(--oyo-text);
}

main#content.oylg > h3:not(.oylg-title) {
	margin-block: 32px 6px;
	font: 400 24px/33.6px Arimo, sans-serif;
	color: var(--oyo-text);
}

main#content.oylg > p:not(.oylg-title) {
	margin-block: 0 16px;
}

main#content.oylg > ul:not(.oylg-title),
main#content.oylg > ol:not(.oylg-title) {
	margin-block: 0 16px;
	padding-inline-start: 24px;
}

main#content.oylg > ul li,
main#content.oylg > ol li {
	margin-top: 8px;
}

main#content.oylg a {
	color: var(--oyo-blue);
	text-decoration: underline;
	text-underline-offset: 3px;
}

/* The first paragraph of the terms outline says in the copy that it is a
   placeholder. This makes it read as one at a glance, so it cannot be mistaken
   for approved wording, and it is one class to delete when the real text
   lands. */
main#content.oylg > .oylg-placeholder {
	margin-top: 40px;
	padding: 20px 24px;
	border: 1px solid var(--oyo-state-stroke);
	border-radius: 16px;
	background-color: var(--oyo-state-surface);
	font-size: 18px;
	line-height: 1.6;
	color: var(--oyo-state-label);
}

main#content.oylg > .oylg-meta {
	font-size: 18px;
}

/* The stream has no band of its own, so the last element carries the space that
   separates it from the footer. */
main#content.oylg > *:last-child {
	margin-bottom: 128px;
}

@media (max-width: 1024px) {
	main#content.oylg > .oylg-title {
		min-height: 0;
		padding-top: 120px;
		padding-bottom: 48px;
	}

	main#content.oylg > .oylg-title h1 {
		font-size: 30px;
		letter-spacing: -0.0395em;
	}

	main#content.oylg > h2:not(.oylg-title) {
		margin-top: 40px;
		font-size: 28px;
		line-height: 1.2;
		letter-spacing: -0.0395em;
	}

	main#content.oylg > *:not(.oylg-title) {
		font-size: 20px;
		line-height: 1.6;
	}

	main#content.oylg > *:last-child {
		margin-bottom: 80px;
	}
}

@media (max-width: 767px) {
	main#content.oylg > .oylg-title {
		padding-top: 100px;
		padding-bottom: 40px;
	}

	main#content.oylg > .oylg-title h1 {
		font-size: 26px;
	}

	main#content.oylg > h2:not(.oylg-title) {
		margin-top: 32px;
		font-size: 24px;
	}

	main#content.oylg > *:not(.oylg-title) {
		font-size: 18px;
	}

	main#content.oylg > *:last-child {
		margin-bottom: 64px;
	}
}

/* ==========================================================================
   Desktop between the design width and the tablet breakpoint
   (1025px - 1599px)

   Figma supplies one desktop frame, 1600 wide with a 1400 content column, and
   the rules above reproduce it exactly. They also pinned the second column of
   two rows to a fixed width - #314:72 hugs 708px of fixed children and #314:249
   is a fixed 660x731 box - so below 1600 every pixel the viewport lost came out
   of the first column alone. Measured before this block: the product-feature
   card fell 666 -> 506 at 1440 and 91 at 1025, its bullets wrapped to one or
   two words a line, and the page ran 3332 -> 3724 at 1440 and 5700 at 1025.

   The fix is to make both columns proportional instead of one fixed and one
   fluid. Flex distributes free space after the gap is taken out, so a grow
   factor equal to the design width reproduces the design exactly at 1600 and
   scales it from there. The factors are CONTENT widths, not the design's
   border-box widths: Chrome resolves flex-basis: 0 against the content box, so
   an item's outer size comes out as its own padding and border plus its share
   of what is left. The product row has 1376 less 2x50 of chrome to split
   616:660, the contact row 1340 less 80 + 60 to split 600:600, the sub-cards
   644 less 2x50 to split 273:271, and the pill/image pair carries no chrome at
   all so it splits 534 as 263:271. Read as 666:710 the first column came out
   1.6px over its share at 1599 and the error grew with the deficit.

   Below 1280 two columns can no longer hold their content at a readable
   measure, so the rows stack there rather than at 1024. Everything in this
   section is a decision about widths Figma does not cover, taken under the
   same delegation as the tablet and mobile layouts.
   ========================================================================== */

@media (max-width: 1599px) {
	/* --- product feature row (home #314:46, products #314:719) ------------- */
	.elementor .elementor-element.elementor-element-oyopfc1 { flex: 616 1 0; }
	/* height: auto hands the card back to the row's own stretch, so the pair
	   stays equal-height and the band keeps the height card 1 asks for. */
	.elementor .elementor-element.elementor-element-oyopfc2 { flex: 660 1 0; min-width: 0; width: auto; height: auto; }
	.elementor .elementor-element.elementor-element-oyopfc2a { flex: 273 1 0; min-width: 0; width: auto; }
	.elementor .elementor-element.elementor-element-oyopfc2b { flex: 271 1 0; min-width: 0; width: auto; }
	.elementor .elementor-element.elementor-element-oyopfpills { flex: 263 1 0; }
	.elementor .elementor-element.elementor-element-oyopfimg6 { flex: 271 1 0; min-width: 0; width: auto; }
	/* Capped at the design size so the stacked layouts below 1280, which hand
	   this column the whole row, keep the 271px image the tablet and mobile
	   passes were signed off with instead of blowing it up to 417. */
	.elementor .elementor-element-oyopfimg6 img { width: 100%; max-width: 271px; height: auto; aspect-ratio: 271 / 219; }
	/* The badges keep their exported shadow bleed, so they are sized in px; the
	   cap is what stops a 188px SVG bursting a column narrower than itself. */
	.elementor .elementor-element-oyopfc2abi img,
	.elementor .elementor-element-oyopfc2bbi img { max-width: 100%; height: auto; }

	/* #314:78's photo is placed as an oversized 332px crop offset -29, which
	   covers the 273px plate at the design width and nothing wider. Once the
	   plate can grow past 303 the crop runs out and the plate shows through on
	   the right - 87px of it at 1024, where this was already happening before
	   the columns became fluid. A cover fill crops the same photo to whatever
	   the plate is. #314:85's dashboard is left alone: at 483x332 it is wider
	   and taller than its plate at every width, so it never under-fills, and
	   cover would shrink the mockup instead of cropping it. */
	.elementor .elementor-element.elementor-element-oyopfc2ai { left: 0; top: 0; right: 0; bottom: 0; width: auto; height: auto; }
	.elementor .elementor-element-oyopfc2ai img { width: 100%; height: 100%; max-width: none; object-fit: cover; object-position: 50% 50%; }

	/* --- contact row (#314:223) ------------------------------------------- */
	.elementor .elementor-element.elementor-element-oyocfcard { flex: 600 1 0; }
	.elementor .elementor-element.elementor-element-oyocfframe { flex: 600 1 0; min-width: 0; width: auto; height: auto; }
	/* #314:249 has no auto-layout, so at the design width the form card is
	   placed absolutely inside it. Once the frame has to grow with the card,
	   the card has to be in the flow - and the frame's padding carries the
	   design's asymmetric 30 above / 8 below, which is what keeps the frame at
	   731 on the 1599 side of the boundary. Elementor sets padding on this
	   container itself, so this needs one class more than its 0-3-0. */
	.elementor .elementor-element.elementor-element-oyocfcard2 { position: static; }
	.elementor .elementor-element.elementor-element-oyocfframe.e-con { padding: 30px 30px 8px; }
	/* 76 is Figma's squeeze on two lines of 38.4; below the design width the
	   text takes a third line and the pin would clip it. */
	.elementor .elementor-element.elementor-element-oyocfb1,
	.elementor .elementor-element.elementor-element-oyocfb2,
	.elementor .elementor-element.elementor-element-oyocfb3,
	.elementor .elementor-element.elementor-element-oyocfb4 { height: auto; }
}

@media (max-width: 1280px) {
	/* The rows are nowrap at desktop, so full-width children sit side by side and
	   run off the page rather than stacking - 1080 + 1080 against a 1080 row. */
	.elementor .elementor-element.elementor-element-oyopfrow,
	.elementor .elementor-element.elementor-element-oyocfrow,
	.elementor .elementor-element.elementor-element-oyprwitsec { flex-wrap: wrap; }

	/* Two columns stop working here: the product row's first column is down to
	   ~510 and the second's sub-cards to ~240, which is narrower than the
	   188px badge they carry. Stacking is the same treatment the tablet rules
	   apply, brought up to the width where it is actually needed. */
	.elementor .elementor-element.elementor-element-oyopfc1,
	.elementor .elementor-element.elementor-element-oyopfc2 { flex: 0 0 auto; width: 100%; height: auto; min-height: 0; }
	.elementor .elementor-element.elementor-element-oyocfcard,
	.elementor .elementor-element.elementor-element-oyocfframe { flex: 0 0 auto; width: 100%; height: auto; }
	/* Full width again, so the form card goes back to sitting in the frame's
	   own even padding. */
	.elementor .elementor-element.elementor-element-oyocfframe.e-con { padding: 30px; }
	.elementor .elementor-element.elementor-element-oyprwitl,
	.elementor .elementor-element.elementor-element-oyprwitimg { flex: 0 0 auto; width: 100%; }
}

@media (max-width: 767px) {
	/* Restated after the two blocks above, which are later in the file than the
	   original mobile rules and would otherwise put these back side by side. */
	.elementor .elementor-element.elementor-element-oyopfpills,
	.elementor .elementor-element.elementor-element-oyopfimg6,
	.elementor .elementor-element.elementor-element-oyopfc2a,
	.elementor .elementor-element.elementor-element-oyopfc2b { flex: 0 0 auto; width: 100%; min-width: 0; }

	/* #374:3672 and #374:3679 are siblings at 440 — the design has no card
	   around the pair, only around each of them. #374:3843 does wrap them at
	   1600 and that is left alone; here the wrapper gives up everything that
	   makes it read as a card, so its two children become the 400-wide cards
	   the frame draws instead of 358-wide ones inside a third box.

	   Its padding, border, radius and gap went through Elementor's own mobile
	   controls, where the client can still see them. These two have no
	   responsive control in Elementor, so they land here with them. */
	.elementor .elementor-element.elementor-element-oyopfc2 {
		background-color: transparent;
		-webkit-backdrop-filter: none;
		backdrop-filter: none;
	}

	/* The 271px cap two blocks up was set when 375 was the only small width
	   anyone had measured, and it is later in the file than the mobile rule it
	   overrides. #399:26 gives the real number: inside a 400 card at 24 and an
	   inner card at 16, the column is 400 - 48 - 2 - 32 - 2 = 316, and the
	   image fills it at the same 271/219 ratio. */
	.elementor .elementor-element-oyopfimg6 img {
		width: 100%;
		max-width: none;
		height: auto;
		aspect-ratio: 271 / 219;
	}
}

/* --------------------------------------------------------------------------
   Tech & Security — #314:1264, the five step circles, below the design width

   The row is exactly 1400 in Figma: diameters 182 + 193 + 275 + 327 + 327 and
   four 24px gaps. The first three were pinned and only the last two could
   shrink, so below 1600 those two absorbed the whole deficit - 167px each at
   1280 against a 327px design - and the row overflowed its own box by 81px at
   1440, hidden inside the gutter, then past the viewport below 1281.

   Everything here scales together instead: the gaps and the badge padding go
   to their share of the row (24/1400 and 33/1400), and each badge grows by its
   own content width, so every badge lands at exactly d/1400 of the row at any
   width and the design's progression is preserved. With the padding and gaps
   proportional too, content/outer is constant, which is what lets the numeral
   be sized in cqw - it stays the same fraction of its circle everywhere.

   Bounded below at 1025 so none of it reaches the tablet rules, which give the
   badges their own fixed diameters and let the row wrap. Elementor also drops
   the badge padding to 48/24 there, and restating this block's percentage
   padding afterwards had put the desktop 84/33 back and pushed the first two
   badges to 170 tall.
   -------------------------------------------------------------------------- */
@media (min-width: 1025px) and (max-width: 1599px) {
	.elementor .elementor-element.elementor-element-oytshowrow { column-gap: 1.71428%; }

	.elementor .elementor-element.elementor-element-oytsb1,
	.elementor .elementor-element.elementor-element-oytsb2,
	.elementor .elementor-element.elementor-element-oytsb3,
	.elementor .elementor-element.elementor-element-oytsb4,
	.elementor .elementor-element.elementor-element-oytsb5 {
		width: auto;
		height: auto;
		aspect-ratio: 1;
		min-width: 0;
		/* Figma's first badge is 182 tall carrying 84 + 24 + 84 = 192 of
		   content, so the design squeezes it. A flex item's automatic minimum
		   size lets the content win instead, and the first two badges came out
		   162 wide by 206 tall - no longer circles. */
		min-height: 0;
		/* 33 and 84 of 1400. Percentage padding resolves against the row on
		   both axes, so all five keep the design's values at every width. */
		padding: 6% 2.35714%;
		container-type: inline-size;
	}
	/* Grow factors are content widths - Chrome resolves flex-basis: 0 against
	   the content box, so the outer size is the padding plus this share. */
	.elementor .elementor-element.elementor-element-oytsb1 { flex: 116 1 0; }
	.elementor .elementor-element.elementor-element-oytsb2 { flex: 127 1 0; }
	.elementor .elementor-element.elementor-element-oytsb3 { flex: 209 1 0; }
	.elementor .elementor-element.elementor-element-oytsb4 { flex: 261 1 0; }
	.elementor .elementor-element.elementor-element-oytsb5 { flex: 261 1 0; }

	/* The circle and the numeral fill the badge rather than carrying the fixed
	   diameter, which is the same thing at 1600 and follows it below. */
	.elementor .elementor-element.elementor-element-oytsb1::before,
	.elementor .elementor-element.elementor-element-oytsb2::before,
	.elementor .elementor-element.elementor-element-oytsb3::before,
	.elementor .elementor-element.elementor-element-oytsb4::before,
	.elementor .elementor-element.elementor-element-oytsb5::before,
	.elementor .elementor-element.elementor-element-oytsb1::after,
	.elementor .elementor-element.elementor-element-oytsb2::after,
	.elementor .elementor-element.elementor-element-oytsb3::after,
	.elementor .elementor-element.elementor-element-oytsb4::after,
	.elementor .elementor-element.elementor-element-oytsb5::after { width: 100%; height: 100%; }

	/* Each numeral as a fraction of its own circle's content box: 120/116,
	   128/127, 160/209, 220/261. */
	.elementor .elementor-element.elementor-element-oytsb1::after { font-size: 103.4483cqw; }
	.elementor .elementor-element.elementor-element-oytsb2::after { font-size: 100.7874cqw; }
	.elementor .elementor-element.elementor-element-oytsb3::after { font-size: 76.5550cqw; }
	.elementor .elementor-element.elementor-element-oytsb4::after,
	.elementor .elementor-element.elementor-element-oytsb5::after { font-size: 84.2912cqw; }
}

/* --------------------------------------------------------------------------
   Containers Elementor pins to a fixed --width

   Six containers across three documents carry a fixed width from the design
   rather than a percentage: the company team and industries headers (1164 and
   792), the tech hero wrap and How-It-Works header (791 and 792), and the two
   home hero columns (687 and 688). Elementor writes `max-width: var(--width)`
   alongside the width, so none of them shrink, and once the content column is
   narrower than the pin the block centres and hangs out of the page on both
   sides. The company team header did exactly that: at 1025 a 1164px block in
   an 825px column put the document at 1095 and gave the page a horizontal
   scrollbar.

   Capping at the available width is a no-op at 1600 - the widest of the six is
   1164 against a 1400 content column - and stops the overflow everywhere below.
   -------------------------------------------------------------------------- */
.elementor .elementor-element.elementor-element-oycoteamhd,
.elementor .elementor-element.elementor-element-oycoindhd,
.elementor .elementor-element.elementor-element-oytshowhd,
.elementor .elementor-element.elementor-element-oyoherol,
.elementor .elementor-element.elementor-element-oyoheror { max-width: 100%; }

/* --------------------------------------------------------------------------
   Contact form at phone width — asked for by the client, 17 Sep 2026

   At 375 a field had 233px of a 375px window, because three boxes each take a
   side inset before the field gets any: the bracket frame's 30, the card's 20
   and Elementor's own 12 on the field group. The card goes to the 15 the client
   asked for, and the frame comes in to 18 — the width of its own corner artwork
   at this breakpoint — so the card sits exactly inside the brackets instead of
   12px in from them and nothing covers a corner mark. Desktop keeps Figma's
   44/36 on #314:255, which is the geometry the form box is measured against.
   -------------------------------------------------------------------------- */
@media (max-width: 767px) {
	/* 21/09 settles it a third way, and better than either: #449:2005 draws the
	   bracket frame at x10 w420 and #449:2010 the card at x20 w400 — the frame
	   sits *outside* the card rather than insetting it, so the card keeps the
	   band's full 400 and the fields land at x41 w358, which is #449:2011. That
	   is wider than the 15/18 compromise, so the client's 17 Sep ask is met by
	   following the design rather than deviating from it. */
	/* The bullet text goes fluid here, so the mark's offset follows the same
	   clamp rather than a fixed value. */
	.elementor .elementor-element.elementor-element-oyocfb1i,
	.elementor .elementor-element.elementor-element-oyocfb2i,
	.elementor .elementor-element.elementor-element-oyocfb3i,
	.elementor .elementor-element.elementor-element-oyocfb4i { font-size: clamp(16px, 4.0909vw, 18px); }
	.elementor .elementor-element.elementor-element-oyocfcard2.e-con { padding-inline: 20px; }
	.elementor .elementor-element.elementor-element-oyocfframe.e-con { padding-inline: 0; }
}


/* ==========================================================================
   Home only — the 21/09 feature image (#449:67 / #455:3159)

   21/09 splits home from products here. Products keeps #0b733f3b at 271x219
   and 316x255.4 (#449:777, #449:2363) — the geometry the earlier phase built,
   which must not move. Home gets a new 1536x1024 source in FILL mode inside a
   white card: #450:3156 is 271x219 #F9FAF9 radius 8 with the image at 271x181,
   and #455:3158 is 316x219 with the image at 317x211. The card, its colour and
   its padding are Elementor controls on the widget; only the image's own box
   lives here, because Elementor has no aspect-ratio control.

   Scoped to .elementor-9 so post 11 keeps every rule above untouched.
   ========================================================================== */
.elementor.elementor-9 .elementor-element-oyopfimg6 img {
	height: 181px;
	object-fit: cover;
	border-radius: 0;
}

@media (max-width: 1536px) {
	.elementor.elementor-9 .elementor-element-oyopfimg6 img {
		width: 100%;
		max-width: 271px;
		height: auto;
		aspect-ratio: 271 / 181;
	}
}

@media (max-width: 767px) {
	.elementor.elementor-9 .elementor-element-oyopfimg6 img {
		width: 100%;
		max-width: none;
		height: auto;
		aspect-ratio: 317 / 211;
	}
}


/* ==========================================================================
   Tech at <=767 — the 21/09 BG group (#450:2993)

   These three bands are the only ones the client actually stripped: #449:2571,
   #449:2608 and #449:2653 all read `fills: []` on the 21/09 frame, and the
   artwork moved into standalone rectangles that tile at a fixed pitch behind
   them. (Careers looked like the same change and is not — #485:3210, #485:3251,
   #485:3260, #485:3271 all still carry their own fills, so its BG group sits
   behind bands that already paint themselves. Only tech mobile is tiled.)

   Every rectangle carries the same fill: #069ea631 STRETCH at sy .292214
   ty -.000149 and opacity .30, plus a linear gradient whose handles run
   (0.5,0) -> (0.5,4.5776), so its 0.1357 stop lands at 0.1357 x 457.76 =
   62.12% of the rectangle. sx .275 tx .3625 gives 100/.275 = 363.64% of 440 =
   exactly 1600px with pos-x at centre — the same 1600-wide plate the desktop
   frame draws, cropped to its middle 440. So one baked tile serves both.

   The pitch is 579 and the rectangles fall in two runs: 508..2541 and
   2547..4001, each ending in a half tile that repeat-y reproduces by being
   clipped at the band's own foot. Offsets are the run start minus the live
   band top: 508-510, then (1521.2-508) mod 579 = 434.2 back, then 2547-2541.6.

   The .7 scrim is the .30 fill opacity resolved against the page colour, the
   same way every other starfield band in this file states it.
   ========================================================================== */
@media (max-width: 767px) {
	.elementor .elementor-element.elementor-element-oytshowsec.e-con,
	.elementor .elementor-element.elementor-element-oytssecsec.e-con,
	.elementor .elementor-element.elementor-element-oytsentsec.e-con {
		background-color: var(--oyo-bg);
		background-image:
			linear-gradient(180deg, rgba(0, 2, 4, 1) 0%, rgba(0, 2, 4, 0) 62.12%),
			linear-gradient(rgba(0, 2, 4, 0.7), rgba(0, 2, 4, 0.7)),
			url(../../design/home/bg-tile-2109.webp);
		background-origin: border-box;
		background-size: 1600px 579px, 100% 100%, 1600px 579px;
		background-repeat: repeat-y, no-repeat, repeat-y;
	}

	.elementor .elementor-element.elementor-element-oytshowsec.e-con {
		background-position: center -2px, center top, center -2px;
	}

	.elementor .elementor-element.elementor-element-oytssecsec.e-con {
		background-position: center -434.2px, center top, center -434.2px;
	}

	.elementor .elementor-element.elementor-element-oytsentsec.e-con {
		background-position: center 5.4px, center top, center 5.4px;
	}
}



/* Desktop only. The exported plate bakes #450:2973's own gradient in, so the
   scrim that stood in for it would double-darken there — but #449:2553 on the
   440 frame states its own (0.5 / 0.5 at .2163 / 0.6 at .5433 / 1.0), which is
   what this ::before already draws, and without it that band measured twice the
   design's brightness. */
@media (min-width: 768px) {
}


/* ==========================================================================
   A — the bands the 21/09 design paints nothing on

   Reading `visible` on the Figma fills changes the map. #449:40, #449:372,
   #449:715, #449:1800 and #449:2129 all carry fills, and every one of them is
   `visible: false`. The plate rectangles took over, and where a plate does not
   reach, the design is the page colour and nothing else — #000204 exactly, as
   the frame export's gutter confirms (`[0 2 4]`).

   Tech and careers are NOT in this list: their hidden bands sit under the BG
   tiles, which do reach.

   Last block in the file and one class past Elementor's own selector, so this
   is the final word on these five.
   ========================================================================== */
.elementor .elementor-element.elementor-element-oyopfsec.e-con {
	background-color: var(--oyo-bg);
	background-image: url(../../design/plates/plate-home-d.webp);
	background-origin: border-box;
	background-size: 100% 469px;
	background-position: center -418px;
	background-repeat: no-repeat;
}

.elementor .elementor-element.elementor-element-oycoteamsec.e-con {
	background-color: var(--oyo-bg);
	background-image: url(../../design/plates/plate-company-d.webp);
	background-origin: border-box;
	background-size: 100% 456px;
	background-position: center -356px;
	background-repeat: no-repeat;
}

/* Products, 14 Oct 2026: the client moved How It Works onto this page, so the
   band that sits under the hero is no longer What It Does. 633:1234 states the
   consequence plainly - Rectangle 14 is 456 tall over a 356 hero, so the 100px
   tail belongs to whichever band comes next, and that is oytshowsec now.

   What It Does loses everything it used to paint. Its fills on 633:1274 are all
   `visible: false`, and so are How It Works' on 633:1241: below the plate this
   page is #000204 and nothing else at the desktop tier. The frame export agrees
   - sampled down the left gutter both bands peak at [0 2 4], while the card
   band below them still shows stars. The starfield returns at 440, where
   633:2389 does carry it; that is in the 767 block further down. */
.elementor .elementor-element.elementor-element-oytshowsec.e-con {
	background-color: var(--oyo-bg);
	background-image: url(../../design/plates/plate-products-d.webp);
	background-origin: border-box;
	background-size: 100% 456px;
	background-position: center -356px;
	background-repeat: no-repeat;
}

.elementor .elementor-element.elementor-element-oyprwitsec.e-con {
	background-color: var(--oyo-bg);
	background-image: none;
}

@media (max-width: 767px) {
	/* #449:1800 — 573..2340, nothing. #450:2939 is flush with the hero above,
	   so there is no tail to carry here either. */
	.elementor .elementor-element.elementor-element-oyopfsec.e-con {
		background-color: var(--oyo-bg);
		background-image: none;
	}

	/* #449:2129 — 400..3063, nothing, and #450:2951 is flush with its band.
	   The build splits that stretch into two containers; both go flat. */
	.elementor .elementor-element.elementor-element-oycoteamsec.e-con {
		background-color: var(--oyo-bg);
		background-image: none;
	}

	/* Except for one sliver: #449:2166 is an 88-tall child at design y2925
	   carrying #069ea631 at sy .39063 opacity .30 — which is exactly the crop
	   bg-pf-b-51cc05 holds. oycowhysec starts at 1978.8, so it lands 946.2 in.
	   The .7 scrim is sized to the image, not the band, or it would darken the
	   #000204 the design leaves either side of it. */
	.elementor .elementor-element.elementor-element-oycowhysec.e-con {
		background-color: var(--oyo-bg);
		background-image:
			linear-gradient(rgba(0, 2, 4, 0.7), rgba(0, 2, 4, 0.7)),
			url(../../design/home/bg-pf-b-51cc05.webp);
		background-origin: border-box;
		background-size: 100% 88px, 100% 88px;
		background-position: center 946.2px, center 946.2px;
		background-repeat: no-repeat;
	}

	/* Products mobile has a plate of its own that the first pass missed:
	   #450:2961, 440 x 456, over a 282 hero — so 174 bleed into the band below,
	   which is the ~50px strip that read 2.0 against the design's 124. */
	.elementor .elementor-element.elementor-element-oyprherosec.e-con {
		background-color: var(--oyo-bg);
		background-image: url(../../design/plates/plate-products-m.webp);
		background-origin: border-box;
		background-size: 100% 456px;
		background-position: center top;
		background-repeat: no-repeat;
	}

	/* The plate's tail follows the band order here too. 633:2346 puts Rectangle
	   15, 456 tall, over a 330 hero, and How It Works is what comes next.

	   The offset is the hero's own height, and that is content-driven below
	   768: 331.2 at 440, 319.9 at 375, 355.7 at 360, because the title wraps
	   differently. 440 is the width the mobile frame is drawn at and the width
	   every other number in this file is tuned to, so the tail is placed for
	   440 and reads a few pixels late either side of it. 633:2353 carries no
	   fill of its own, so there is nothing under the tail but the page colour. */
	.elementor .elementor-element.elementor-element-oytshowsec.e-con {
		background-color: var(--oyo-bg);
		background-image: url(../../design/plates/plate-products-m.webp);
		background-origin: border-box;
		background-size: 100% 456px;
		background-position: center -331.2px;
		background-repeat: no-repeat;
	}

	/* #449:2301's starfield, which 633:2389 still carries at 440 where the
	   desktop frame has dropped it. The window is 069ea631 at sy 2.09410
	   ty -1.52844, so the image covers 1 / 2.0941 = 47.753% of the band and
	   opens 1.52844 / 2.0941 = 72.988% down it. Stated as fractions rather
	   than the old pixel pair, because the band's height moves with the
	   illustration above it: a percentage background-position resolves against
	   (box - image), so 72.988 / (1 - 0.47753) = 139.698%. */
	.elementor .elementor-element.elementor-element-oyprwitsec.e-con {
		background-color: var(--oyo-bg);
		background-image:
			linear-gradient(rgba(0, 2, 4, 0.7), rgba(0, 2, 4, 0.7)),
			url(../../design/home/bg-pf-b-51cc05.webp);
		background-origin: border-box;
		background-size: 100% 47.753%, 100% 47.753%;
		background-position: center 139.698%, center 139.698%;
		background-repeat: no-repeat;
	}
}


/* ==========================================================================
   C — careers' desktop CTA is not the shared one

   #485:3271 differs from #449:887 and #449:1350 in exactly two ways, and only
   at desktop — #485:3433 on the 440 frame is the standard stack.

     1. #14ef5f3d is `visible: false` there, so the earth crop comes out.
     2. its gradient holds alpha 1.0 until 0.1835 before falling to 0.5, where
        the others start falling at 0. That is why the design's first rows are
        pure black (0.9) and the build's read 8.9.

   Opacity is 1.00 on this one, not the 0.84 the shared rule bakes in.
   ========================================================================== */
@media (min-width: 768px) {
	.elementor .elementor-element.elementor-element-oycrctasec.e-con {
		background-image:
			linear-gradient(180deg,
				rgba(0, 2, 4, 1) 0%,
				rgba(0, 2, 4, 1) 18.35%,
				rgba(0, 2, 4, 0.5) 100%),
			url(../../design/home/bg-cta-41b588.webp),
			url(../../design/home/bg-cf-b-18419d.webp);
		background-size: 100% 100%;
		background-position: center;
		background-repeat: no-repeat;
	}
}


/* ==========================================================================
   D — the footer wash, settled by the file rather than by asking

   The split is not by page, it is by breakpoint. On the 1600 frames #449:895,
   #449:1358 and #485:3280 hold `#000000` at full opacity with the
   rgba(158,159,255,.05) wash `visible: false`, while #449:282 and #449:455 keep
   it at 0.90 with the wash on. On the 440 frames **all five** keep 0.90 and the
   wash. So only products, tech and careers change, and only at desktop; their
   footers measured about twice the design's brightness (products y2020-2140:
   live [12.8 12.9 21.2] against [6.3 6.3 10.1]).

   The footer is one template, so the page is picked out by WordPress's own body
   class, which also takes the selector one class past Elementor's.
   ========================================================================== */
@media (min-width: 768px) {
	body.elementor-page-11 .elementor .elementor-element.elementor-element-oyoftr1,
	body.elementor-page-12 .elementor .elementor-element.elementor-element-oyoftr1,
	body.elementor-page-13 .elementor .elementor-element.elementor-element-oyoftr1 {
		background-color: #000000;
	}

	body.elementor-page-11 .elementor-element-oyoftr1::after,
	body.elementor-page-12 .elementor-element-oyoftr1::after,
	body.elementor-page-13 .elementor-element-oyoftr1::after {
		background-image: none;
	}
}


/* ==========================================================================
   B (continued) — every other 440 frame that clips an oversized photograph

   Same finding as the careers pair and the industry cards, found by walking
   every `clipsContent` frame whose image child overflows it. `cover` picks its
   own zoom and centre; these frames state theirs. Design numbers, each one the
   image's own box and its offset inside the clip:

     #449:2303  606 x 378 at (-133, -39)  in #449:2302  400 x 300
     #449:2136  638 x 425 at (-144, -30)  in #449:2135  350 x 300
     #449:2142  752 x 501 at (-201, -100) in #449:2141  350 x 300
     #449:2156  534 x 357 at  (-67, 0)    in #449:2155  400 x 356
     #449:2610  920 x 506 at (-235, -106) in #449:2609  400 x 300
     #449:2655  519 x 346 at (-119, -15)  in #449:2654  400 x 300
     #449:1834  352 x 234 at   (0, -11)   in #449:1833  350 x 198

   Only the last of those is served by the file it already has. The other five
   ship the *desktop* cut re-used at 440, and no scale-and-offset of a desktop
   cut reproduces a 440 window — fitted against Figma's render the best any of
   them managed was 15 to 40, where the careers pair and the industry cards fit
   to 2.5-7. So each image node is exported at 2x and cropped to exactly the
   window its frame clips, which makes the rule a plain 100% 100% and takes the
   arithmetic out of the CSS entirely.
   Elementor writes these containers' background as
   `.elementor-12 .elementor-element.elementor-element-X:not(.elementor-motion-
   effects-element-type-background)`, and `:not()` carries its argument's
   specificity — so that rule is 0,4,0 and renders after this file. Matching it
   and adding one more class is not enough; `.elementor-element` is repeated to
   take these to 0,5,0.
   ========================================================================== */
@media (max-width: 767px) {
	/* The 13 Oct swap reaches this breakpoint too. The desktop rule moved the
	   isometric into this slot, so the 440 cut has to be the isometric as well,
	   or the two images are only exchanged above 767. Same centred crop of the
	   same 1536x1024 original, brought down to the 800x600 this window clips
	   at 2x, so it is a downscale like every other cut in this block. */
	.elementor .elementor-element.elementor-element.elementor-element-oyprwitimg.e-con {
		background-image: url(../../design/products/wit-drawing-m.webp);
		background-size: 100% 100%;
		background-position: center;
		background-repeat: no-repeat;
	}

	.elementor .elementor-element.elementor-element.elementor-element-oycotc1i.e-con {
		background-image: url(../../design/crops/co-founder-m-2109.webp);
		background-size: 100% 100%;
		background-position: center;
		background-repeat: no-repeat;
	}

	.elementor .elementor-element.elementor-element.elementor-element-oycotc2i.e-con {
		background-image: url(../../design/crops/co-techlead-m-2109.webp);
		background-size: 100% 100%;
		background-position: center;
		background-repeat: no-repeat;
	}

	/* oycowhyr is left as it was: `cover` scores 9.9 there, the design's own
	   534 x 357 at (-67, 0) scores 11.7 and the best fit of the shipped file
	   12.45, so the crop it already has is the closest available. */

	.elementor .elementor-element.elementor-element.elementor-element-oytssecimg.e-con {
		background-image: url(../../design/crops/ts-security-m-2109.webp);
		background-size: 100% 100%;
		background-position: center;
		background-repeat: no-repeat;
	}

	.elementor .elementor-element.elementor-element.elementor-element-oytsentimg.e-con {
		background-image: url(../../design/crops/ts-enterprise-m-2109.webp);
		background-size: 100% 100%;
		background-position: center;
		background-repeat: no-repeat;
	}

	/* This one is an <img>, so the clip has to be made rather than assumed. */
	.elementor .elementor-element.elementor-element-oyopfc2aw {
		position: relative;
		overflow: hidden;
	}

	.elementor .elementor-element-oyopfc2ai img {
		position: absolute;
		top: -11px;
		left: 0;
		width: 352px;
		height: 234px;
		max-width: none;
		object-fit: cover;
	}
}


/* ==========================================================================
   Tech's mobile hero plate — #449:2553

   Removing the scrim uncovered this: the band carries #c19ed97f at
   sx .59244 tx .17125, sy 1.0 ty .63217. sy = 1 means the box maps the whole
   source height, and ty .63217 starts it at row .63217, so only the last
   36.783% of the source lands inside — the artwork occupies the top
   .36783 x 508 = 186.8px of the band and the rest is the page colour. The
   design's own gutter confirms it: 6.2 at y180, 2.4 at y195.

   Source window x .17125..:76369 by y .63217..1, baked pre-squashed at 2x so
   the rule carries only the box: 100/.59244 = 168.79% wide, placed at
   -.17125/(.59244-1) = 42.04%.
   ========================================================================== */
@media (max-width: 767px) {
}


/* ==========================================================================
   Tech's hero plate lost the band it used to run into

   633:1722 is the 14/10 tech page: hero, Security, Enterprise, CTA. How It
   Works is gone from it, so the 140px that Rectangle 15 carries past the 356
   hero now lands on Security, not on the band that moved to products. Nothing
   painted it in between, which is why the horizon stopped dead at the hero's
   foot while the design keeps it going.

   Same plate, same offset, restacked over Security's own starfield instead.
   Desktop only: the 440 frame, 633:2565, starts its BG group at 508, exactly
   where that frame's hero ends, so below 768 there is no tail to carry, and
   768 to 1024 is left on the sizing the tablet block already gives it.
   ========================================================================== */
@media (min-width: 1025px) {
	/* The hero takes the same plate, from its first row. It used to paint a
	   media-library photograph that Elementor compiled onto the container, and
	   that photograph is not what 633:1723 holds: measured against the frame
	   export, the hero rows ran MAE 22 to 37 while the tail rows below them,
	   already on the plate, ran 0.8 to 2.4. One image across both is also the
	   only way the two cannot drift apart at the seam.

	   plate-tech-d.webp is now the render of 633:1723 itself - the #060918
	   plate, the photograph at its own window, and the gradient that takes the
	   last third to black - so nothing here recomposes what Figma already
	   composed. Three element classes, because Elementor's generated rule for
	   this container scores four and loads after us. */
	.elementor .elementor-element.elementor-element.elementor-element-oytsherosec.e-con {
		background-color: var(--oyo-bg);
		background-image: url(../../design/plates/plate-tech-d.webp);
		background-origin: border-box;
		background-size: 100% 496px;
		background-position: center top;
		background-repeat: no-repeat;
	}

	.elementor .elementor-element.elementor-element-oytssecsec.e-con {
		background-color: var(--oyo-bg);
		background-image:
			url(../../design/plates/plate-tech-d.webp),
			linear-gradient(rgba(0, 2, 4, 0.7), rgba(0, 2, 4, 0.7)),
			url(../../design/home/bg-pf-b-51cc05.webp);
		background-origin: border-box;
		background-size: 100% 496px, 100% 100%, 100% 100%;
		background-position: center -356px, center top, center top;
		background-repeat: no-repeat;
	}
}
