/* HyperKit - Bento Grid
 *
 * An asymmetric tile grid. Every tile is one repeater item that declares how
 * many columns and rows it spans; the grid itself only declares a column count,
 * a gap and a row height, so adding a tile never means re-tuning the others.
 *
 * Layering inside a tile is fixed and worth keeping straight:
 *   .hk-bn__tile    the grid cell. Span, background, border, radius, shadow.
 *   .hk-bn__lift    the element that moves on hover. Nothing else transforms,
 *                   or the hover fights the entrance animation.
 *   .hk-bn__media   z 0   image / video / icon plate
 *   .hk-bn__scrim   z 1   readability wash, only in "fill" layout
 *   .hk-bn__glow    z 2   cursor spotlight, driven by --hk-bn-mx / --hk-bn-my
 *   .hk-bn__body    z 3   copy
 *
 * Sizing rules name two classes on purpose. Elementor ships
 * `.elementor img { height:auto; max-width:100%; border-radius:0 }` at (0,1,1),
 * which beats a bare `.hk-bn__media img` and silently undoes both the height and
 * the radius. Every image and video rule here carries the root class as well.
 */

/* =========================================================================
   Grid
   ========================================================================= */

.hk-bn {
	--hk-bn-cols: 4;
	--hk-bn-gap: 16px;
	--hk-bn-row: 180px;

	--hk-bn-tile-bg: #ffffff;
	--hk-bn-tile-border: rgba(17, 17, 17, 0.08);
	--hk-bn-tile-radius: 22px;
	--hk-bn-tile-pad: 24px;
	--hk-bn-tile-shadow: 0 1px 2px rgba(17, 17, 17, 0.04), 0 10px 30px rgba(17, 17, 17, 0.06);

	--hk-bn-title: #111111;
	--hk-bn-text: rgba(17, 17, 17, 0.62);
	--hk-bn-eyebrow: rgba(17, 17, 17, 0.45);
	--hk-bn-accent: #111111;

	--hk-bn-lift: 6px;
	--hk-bn-zoom: 1.05;
	--hk-bn-dur: 0.45s;
	--hk-bn-ease: cubic-bezier(0.22, 1, 0.36, 1);

	display: grid;
	grid-template-columns: repeat(var(--hk-bn-cols), minmax(0, 1fr));
	grid-auto-rows: var(--hk-bn-row);
	/* An implicit column can only appear if a span outruns the column count.
	 * JS clamps spans so it should never happen, but sizing the implicit track
	 * like a real one keeps a no-JS page from collapsing into slivers. */
	grid-auto-columns: minmax(0, 1fr);
	gap: var(--hk-bn-gap);
}

/* minmax() rather than a flat track: tiles grow past the row height when their
 * copy needs it instead of overflowing the tile. */
.hk-bn--rows-auto {
	grid-auto-rows: minmax(var(--hk-bn-row), auto);
}

.hk-bn--dense {
	grid-auto-flow: row dense;
}

/* =========================================================================
   Tile
   ========================================================================= */

.hk-bn__tile {
	--hk-bn-cs: 1;
	--hk-bn-rs: 1;
	--hk-bn-mx: 50%;
	--hk-bn-my: 50%;

	grid-column: span var(--hk-bn-cs);
	grid-row: span var(--hk-bn-rs);

	position: relative;
	display: block;
	min-width: 0;
	min-height: 0;
	color: inherit;
	text-decoration: none;
	border-radius: var(--hk-bn-tile-radius);
	/* The tile clips, so the lift's shadow has to live on the lift element. */
	overflow: hidden;
	isolation: isolate;
}

.hk-bn__lift {
	position: relative;
	display: flex;
	width: 100%;
	height: 100%;
	border-radius: inherit;
	background: var(--hk-bn-tile-bg);
	border: 1px solid var(--hk-bn-tile-border);
	box-shadow: var(--hk-bn-tile-shadow);
	overflow: hidden;
	transform: translate3d(0, 0, 0);
	transition:
		transform var(--hk-bn-dur) var(--hk-bn-ease),
		box-shadow var(--hk-bn-dur) var(--hk-bn-ease),
		border-color var(--hk-bn-dur) var(--hk-bn-ease);
}

/* A tile that clips its own overflow cannot show a lift shadow, so the lift is
 * only visible once the tile stops clipping. Switched on together. */
.hk-bn--hover-lift .hk-bn__tile {
	overflow: visible;
}

.hk-bn--hover-lift .hk-bn__tile:hover .hk-bn__lift,
.hk-bn--hover-lift .hk-bn__tile:focus-visible .hk-bn__lift {
	transform: translate3d(0, calc(var(--hk-bn-lift) * -1), 0);
	box-shadow: 0 2px 4px rgba(17, 17, 17, 0.05), 0 22px 50px rgba(17, 17, 17, 0.14);
}

.hk-bn__tile:focus-visible {
	outline: 2px solid var(--hk-bn-accent);
	outline-offset: 3px;
}

/* =========================================================================
   Layouts
   ========================================================================= */

/* fill: media is the tile, copy sits on top of it. */
.hk-bn__tile--fill .hk-bn__lift {
	flex-direction: column;
	justify-content: flex-end;
}

.hk-bn__tile--fill .hk-bn__media {
	position: absolute;
	inset: 0;
	z-index: 0;
}

/* top / bottom: media is a band, copy is a block. */
.hk-bn__tile--top .hk-bn__lift,
.hk-bn__tile--bottom .hk-bn__lift {
	flex-direction: column;
}

.hk-bn__tile--bottom .hk-bn__lift {
	flex-direction: column-reverse;
}

.hk-bn__tile--top .hk-bn__media,
.hk-bn__tile--bottom .hk-bn__media {
	position: relative;
	flex: 1 1 auto;
	min-height: 0;
}

/* side: media column beside the copy. */
.hk-bn__tile--side .hk-bn__lift {
	flex-direction: row;
	align-items: stretch;
}

.hk-bn__tile--side-right .hk-bn__lift {
	flex-direction: row-reverse;
}

.hk-bn__tile--side .hk-bn__media {
	position: relative;
	flex: 0 0 var(--hk-bn-side, 42%);
	min-width: 0;
}

/* icon / text: no media box at all, the body owns the whole tile. */
.hk-bn__tile--icon .hk-bn__lift,
.hk-bn__tile--text .hk-bn__lift {
	flex-direction: column;
}

/* =========================================================================
   Media
   ========================================================================= */

.hk-bn__media {
	overflow: hidden;
	line-height: 0;
	background: rgba(17, 17, 17, 0.04);
}

.hk-bn .hk-bn__media img,
.hk-bn .hk-bn__media video {
	display: block;
	width: 100%;
	height: 100%;
	max-width: 100%;
	object-fit: cover;
	object-position: center;
	border-radius: 0;
	transform: scale(1);
	transition: transform 0.7s var(--hk-bn-ease);
}

.hk-bn--hover-zoom .hk-bn__tile:hover .hk-bn__media img,
.hk-bn--hover-zoom .hk-bn__tile:hover .hk-bn__media video,
.hk-bn--hover-zoom .hk-bn__tile:focus-visible .hk-bn__media img,
.hk-bn--hover-zoom .hk-bn__tile:focus-visible .hk-bn__media video {
	transform: scale(var(--hk-bn-zoom));
}

/* Inset media gets the tile padding and its own radius, so a logo or a product
 * shot is not cropped to the tile's corners. */
.hk-bn__tile--inset .hk-bn__media {
	margin: var(--hk-bn-tile-pad);
	margin-bottom: 0;
	border-radius: calc(var(--hk-bn-tile-radius) - 8px);
	background: transparent;
}

.hk-bn__tile--bottom.hk-bn__tile--inset .hk-bn__media {
	margin-bottom: var(--hk-bn-tile-pad);
	margin-top: 0;
}

.hk-bn__tile--side.hk-bn__tile--inset .hk-bn__media {
	margin: var(--hk-bn-tile-pad);
	margin-right: 0;
}

.hk-bn__tile--side-right.hk-bn__tile--inset .hk-bn__media {
	margin: var(--hk-bn-tile-pad);
	margin-left: 0;
}

.hk-bn__tile--inset .hk-bn__media img,
.hk-bn__tile--inset .hk-bn__media video {
	object-fit: var(--hk-bn-fit, contain);
}

/* Scrim only exists under copy laid over media. */
.hk-bn__scrim {
	position: absolute;
	inset: 0;
	z-index: 1;
	pointer-events: none;
	background: linear-gradient(
		to top,
		rgba(0, 0, 0, var(--hk-bn-scrim, 0.55)) 0%,
		rgba(0, 0, 0, calc(var(--hk-bn-scrim, 0.55) * 0.45)) 38%,
		rgba(0, 0, 0, 0) 78%
	);
}

/* =========================================================================
   Icon plate
   ========================================================================= */

.hk-bn__icon {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: var(--hk-bn-icon-box, 52px);
	height: var(--hk-bn-icon-box, 52px);
	margin-bottom: 14px;
	border-radius: var(--hk-bn-icon-radius, 16px);
	background: var(--hk-bn-icon-bg, rgba(17, 17, 17, 0.06));
	color: var(--hk-bn-icon-color, var(--hk-bn-accent));
	font-size: var(--hk-bn-icon-size, 24px);
	line-height: 1;
	flex: 0 0 auto;
	transition: transform var(--hk-bn-dur) var(--hk-bn-ease);
}

.hk-bn--hover-icon .hk-bn__tile:hover .hk-bn__icon {
	transform: translateY(-2px) rotate(-6deg);
}

.hk-bn .hk-bn__icon svg {
	width: 1em;
	height: 1em;
}

/* Icon paint in three cases, the same rule the rest of the plugin uses:
 *   1. no fill attribute (Font Awesome inline SVGs) - paint the fill
 *   2. fill="none" (outline icons) - painting the fill makes a black blob,
 *      so paint the stroke
 *   3. children of an outline icon that hardcode a stroke of their own, which
 *      a rule on the <svg> alone loses to */
.hk-bn .hk-bn__icon svg:not([fill]) {
	fill: currentColor;
}

.hk-bn .hk-bn__icon svg[fill="none"],
.hk-bn .hk-bn__icon svg[fill="none"] [stroke]:not([stroke="none"]) {
	stroke: currentColor;
}

.hk-bn .hk-bn__icon i {
	font-size: inherit;
	line-height: 1;
}

/* =========================================================================
   Body
   ========================================================================= */

.hk-bn__body {
	position: relative;
	z-index: 3;
	display: flex;
	flex-direction: column;
	min-width: 0;
	padding: var(--hk-bn-tile-pad);
	gap: 8px;
}

.hk-bn__tile--fill .hk-bn__body {
	width: 100%;
}

.hk-bn__tile--top .hk-bn__body,
.hk-bn__tile--bottom .hk-bn__body,
.hk-bn__tile--side .hk-bn__body {
	flex: 0 0 auto;
}

.hk-bn__tile--icon .hk-bn__body,
.hk-bn__tile--text .hk-bn__body,
.hk-bn__tile--side .hk-bn__body {
	flex: 1 1 auto;
	justify-content: var(--hk-bn-vjust, flex-start);
}

.hk-bn__tile--v-center .hk-bn__body { justify-content: center; }
.hk-bn__tile--v-end .hk-bn__body    { justify-content: flex-end; }
.hk-bn__tile--h-center              { text-align: center; }
.hk-bn__tile--h-center .hk-bn__body { align-items: center; }
.hk-bn__tile--h-end                 { text-align: right; }
.hk-bn__tile--h-end .hk-bn__body    { align-items: flex-end; }

/* Colours are stated against the root class, and for every link state.
 * A bare `.hk-bn__title { color }` is (0,1,0) and loses to any theme rule
 * like `.entry-content a`, which is how a colour control ends up doing
 * nothing on a real site while looking fine on a blank test page. */
.hk-bn .hk-bn__eyebrow {
	margin: 0;
	color: var(--hk-bn-eyebrow);
	font-size: 12px;
	font-weight: 600;
	letter-spacing: 0.08em;
	text-transform: uppercase;
	line-height: 1.2;
}

.hk-bn .hk-bn__title {
	margin: 0;
	color: var(--hk-bn-title);
	font-size: 20px;
	font-weight: 600;
	line-height: 1.25;
	letter-spacing: -0.01em;
}

.hk-bn .hk-bn__text {
	margin: 0;
	color: var(--hk-bn-text);
	font-size: 14px;
	line-height: 1.55;
}

.hk-bn .hk-bn__title,
.hk-bn .hk-bn__eyebrow,
.hk-bn .hk-bn__text {
	overflow-wrap: anywhere;
}

/* A tile laid over media inverts the palette unless the author says otherwise. */
.hk-bn__tile--on-media {
	--hk-bn-title: #ffffff;
	--hk-bn-text: rgba(255, 255, 255, 0.78);
	--hk-bn-eyebrow: rgba(255, 255, 255, 0.66);
	--hk-bn-accent: #ffffff;
}

/* =========================================================================
   CTA
   ========================================================================= */

.hk-bn__cta {
	display: inline-flex;
	align-items: center;
	gap: 7px;
	margin-top: 4px;
	color: var(--hk-bn-accent);
	font-size: 14px;
	font-weight: 600;
	line-height: 1.2;
}

.hk-bn .hk-bn__cta svg {
	width: 1em;
	height: 1em;
	transition: transform var(--hk-bn-dur) var(--hk-bn-ease);
}

.hk-bn__tile:hover .hk-bn__cta svg,
.hk-bn__tile:focus-visible .hk-bn__cta svg {
	transform: translateX(3px);
}

/* Corner arrow, the bento convention for "this tile is a link". */
.hk-bn__arrow {
	position: absolute;
	z-index: 4;
	top: 14px;
	right: 14px;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 34px;
	height: 34px;
	border-radius: 50%;
	background: var(--hk-bn-arrow-bg, rgba(17, 17, 17, 0.06));
	color: var(--hk-bn-arrow-color, var(--hk-bn-accent));
	opacity: 0;
	transform: translate3d(4px, -4px, 0);
	transition:
		opacity var(--hk-bn-dur) var(--hk-bn-ease),
		transform var(--hk-bn-dur) var(--hk-bn-ease);
	pointer-events: none;
}

.hk-bn .hk-bn__arrow svg {
	width: 16px;
	height: 16px;
}

.hk-bn__arrow--always,
.hk-bn__tile:hover .hk-bn__arrow,
.hk-bn__tile:focus-visible .hk-bn__arrow {
	opacity: 1;
	transform: translate3d(0, 0, 0);
}

/* =========================================================================
   Cursor spotlight
   ========================================================================= */

.hk-bn__glow {
	position: absolute;
	inset: 0;
	z-index: 2;
	pointer-events: none;
	opacity: 0;
	transition: opacity var(--hk-bn-dur) var(--hk-bn-ease);
	background: radial-gradient(
		var(--hk-bn-glow-size, 320px) circle at var(--hk-bn-mx) var(--hk-bn-my),
		var(--hk-bn-glow-color, rgba(255, 255, 255, 0.35)),
		transparent 70%
	);
}

.hk-bn--hover-glow .hk-bn__tile:hover .hk-bn__glow {
	opacity: 1;
}

/* =========================================================================
   Entrance
   ========================================================================= */

.hk-bn--reveal .hk-bn__tile {
	opacity: 0;
	transform: translate3d(0, var(--hk-bn-reveal-y, 22px), 0);
}

.hk-bn--reveal .hk-bn__tile.is-in {
	opacity: 1;
	transform: translate3d(0, 0, 0);
	transition:
		opacity 0.7s var(--hk-bn-ease),
		transform 0.7s var(--hk-bn-ease);
	transition-delay: calc(var(--hk-bn-i, 0) * var(--hk-bn-stagger, 70ms));
}

/* No JS, no IntersectionObserver, or an editor re-render: never leave the grid
 * invisible. The script removes this class the moment it takes over. */
.hk-bn--reveal.hk-bn--no-js .hk-bn__tile {
	opacity: 1;
	transform: none;
}

/* =========================================================================
   Reduced motion
   ========================================================================= */

@media (prefers-reduced-motion: reduce) {
	.hk-bn__lift,
	.hk-bn .hk-bn__media img,
	.hk-bn .hk-bn__media video,
	.hk-bn__icon,
	.hk-bn__arrow,
	.hk-bn__glow,
	.hk-bn--reveal .hk-bn__tile.is-in {
		transition-duration: 0.01ms !important;
		transition-delay: 0ms !important;
	}

	.hk-bn--reveal .hk-bn__tile {
		opacity: 1;
		transform: none;
	}

	.hk-bn--hover-lift .hk-bn__tile:hover .hk-bn__lift,
	.hk-bn--hover-zoom .hk-bn__tile:hover .hk-bn__media img,
	.hk-bn--hover-zoom .hk-bn__tile:hover .hk-bn__media video {
		transform: none;
	}
}

/* =========================================================================
   Dark theme
   =========================================================================
   One class swaps the whole palette. Everything downstream reads these five
   properties, so a dark grid needs no second set of rules. Anything the Style
   tab sets explicitly still wins, because Elementor writes it on the same
   element at a far higher specificity. */

.hk-bn--dark {
	--hk-bn-tile-bg: #161616;
	--hk-bn-tile-border: rgba(255, 255, 255, 0.08);
	--hk-bn-tile-shadow: 0 1px 2px rgba(0, 0, 0, 0.4), 0 10px 30px rgba(0, 0, 0, 0.35);

	--hk-bn-title: #f4f4f4;
	--hk-bn-text: rgba(244, 244, 244, 0.58);
	--hk-bn-eyebrow: rgba(244, 244, 244, 0.42);
	--hk-bn-accent: #f4f4f4;

	--hk-bn-icon-bg: rgba(255, 255, 255, 0.07);
	--hk-bn-arrow-bg: rgba(255, 255, 255, 0.09);
}

.hk-bn--dark .hk-bn__media {
	background: rgba(255, 255, 255, 0.04);
}

.hk-bn--hover-lift.hk-bn--dark .hk-bn__tile:hover .hk-bn__lift,
.hk-bn--hover-lift.hk-bn--dark .hk-bn__tile:focus-visible .hk-bn__lift {
	box-shadow: 0 2px 4px rgba(0, 0, 0, 0.45), 0 22px 50px rgba(0, 0, 0, 0.5);
	border-color: rgba(255, 255, 255, 0.16);
}

/* =========================================================================
   Icon-only tile
   =========================================================================
   The social-button tile: one icon, centred, no copy. The plate is the tile
   itself rather than a badge inside it, so the whole square is the target. */

.hk-bn__tile--icon-only .hk-bn__lift {
	align-items: center;
	justify-content: center;
}

.hk-bn__tile--icon-only .hk-bn__icon {
	width: auto;
	height: auto;
	margin: 0;
	border-radius: 0;
	background: transparent;
	font-size: var(--hk-bn-icon-solo, 26px);
	transition: transform var(--hk-bn-dur) var(--hk-bn-ease);
}

.hk-bn--hover-icon .hk-bn__tile--icon-only:hover .hk-bn__icon {
	transform: scale(1.12) rotate(0deg);
}

/* An icon-only tile never needs a corner arrow: the icon IS the affordance,
   and a 1x1 tile has no room for both. */
.hk-bn__tile--icon-only .hk-bn__arrow {
	display: none;
}

/* =========================================================================
   Logo row
   =========================================================================
   The "stack I use" tile: a wrapping row of small square logos. Sized in one
   place so a row of five and a row of two look like the same tile. */

.hk-bn__logos {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: var(--hk-bn-logo-gap, 12px);
	margin-top: 2px;
}

.hk-bn .hk-bn__logos img {
	display: block;
	width: var(--hk-bn-logo-size, 44px);
	height: var(--hk-bn-logo-size, 44px);
	max-width: none;
	object-fit: contain;
	border-radius: var(--hk-bn-logo-radius, 12px);
	transition: transform var(--hk-bn-dur) var(--hk-bn-ease);
}

.hk-bn--hover-icon .hk-bn__tile:hover .hk-bn__logos img {
	transform: translateY(-3px);
}

/* Stagger the hop so the row lifts as a wave rather than a block. Six is
   enough: past that the eye stops counting. */
.hk-bn__logos img:nth-child(2) { transition-delay: 40ms; }
.hk-bn__logos img:nth-child(3) { transition-delay: 80ms; }
.hk-bn__logos img:nth-child(4) { transition-delay: 120ms; }
.hk-bn__logos img:nth-child(5) { transition-delay: 160ms; }
.hk-bn__logos img:nth-child(6) { transition-delay: 200ms; }

/* =========================================================================
   Copy to clipboard
   ========================================================================= */

.hk-bn__copy {
	display: inline-flex;
	align-items: center;
	gap: 8px;
	align-self: flex-start;
	margin-top: 8px;
	padding: 9px 14px;
	border: 1px solid var(--hk-bn-tile-border);
	border-radius: 999px;
	background: transparent;
	color: var(--hk-bn-accent);
	font: inherit;
	font-size: 13px;
	font-weight: 600;
	line-height: 1.2;
	cursor: pointer;
	transition:
		background-color var(--hk-bn-dur) var(--hk-bn-ease),
		border-color var(--hk-bn-dur) var(--hk-bn-ease);
}

.hk-bn__tile--h-center .hk-bn__copy { align-self: center; }
.hk-bn__tile--h-end .hk-bn__copy    { align-self: flex-end; }

.hk-bn__copy:hover,
.hk-bn__copy:focus-visible {
	background: var(--hk-bn-icon-bg, rgba(17, 17, 17, 0.06));
}

.hk-bn .hk-bn__copy svg {
	width: 15px;
	height: 15px;
}

/* The tick and the clipboard occupy the same slot; only one is ever shown, so
   the pill never changes width mid-click. */
.hk-bn__copy .hk-bn__copy-done { display: none; }
.hk-bn__copy.is-copied .hk-bn__copy-idle { display: none; }
.hk-bn__copy.is-copied .hk-bn__copy-done { display: inline-flex; }

/* An icon-alone tile carries no visible label, so its title is kept for screen
 * readers. Not `screen-reader-text`: that class belongs to the theme and half
 * of them do not define it. */
.hk-bn__sr {
	position: absolute;
	width: 1px;
	height: 1px;
	margin: -1px;
	padding: 0;
	overflow: hidden;
	clip: rect(0, 0, 0, 0);
	white-space: nowrap;
	border: 0;
}

/* =========================================================================
   Pictures only
   =========================================================================
   Every tile is its picture. render() has already dropped the copy and put
   media layouts into "fill", so all that is left is to stop the body reserving
   padding that nothing occupies, and to let an icon or a logo row centre in
   the tile the way a photograph fills it. */

.hk-bn--media-only .hk-bn__body {
	padding: 0;
}

/* An icon or logo tile still wants its breathing room: it is a small mark on a
   plate, not a photograph running to the edges. */
.hk-bn--media-only .hk-bn__tile--icon .hk-bn__body,
.hk-bn--media-only .hk-bn__tile--icon-only .hk-bn__body,
.hk-bn--media-only .hk-bn__tile--logos .hk-bn__body {
	padding: var(--hk-bn-tile-pad);
	align-items: center;
	justify-content: center;
}

.hk-bn--media-only .hk-bn__tile--icon .hk-bn__icon {
	margin-bottom: 0;
}

.hk-bn--media-only .hk-bn__logos {
	justify-content: center;
	margin-top: 0;
}
