/*
 Theme Name:   Crack-Ajax Web Technologies 2026
 Description:  Improvise Child Theme for Crack-Ajax Web Technologies 2026
 Author:       Crack-Ajax
 Author URI:   https://crack-ajax.com
 Template:     improvise
 Version:      2.0
*/

/* ============================================================
   Child Theme Variables
   Bespoke values with no home in the parent theme's ACF-driven
   :root vars (see improvise-styling skill, Rule 1/2) — tints,
   shades, and one-off UI colors specific to the hero build.
   The hero text gradient is NOT here: it's an exact match for
   the "Text Shine" ACF gradient, so it uses the theme's own
   var(--wp--preset--gradient--text-shine) instead of a duplicate.
   =========================================================== */
:root {
	--ca-wine-deep: #6e1236;
	--ca-eyebrow-text: #bfe0d2;
	--ca-lead-text: #d8e6e0;
	--ca-hero-note-text: #b9cfc6;
	--ca-audit-shadow: rgba(6, 24, 34, .45);
	--ca-tab-tray-bg: #eef1ee;
	--ca-tab-shadow: rgba(20, 56, 76, .14);
	--ca-neutral-text: #5b6672;
	--ca-label-text: #39434f;
	--ca-border: #e3e8e4;
	--ca-msg-them-bg: #eef3f6;
	--ca-msg-them-text: #2c3945;
	--ca-ticker-text: #e4eee9;
	--ca-muted-white: #DDF2E5;
	--ca-paper: #F7F8F6;
	--ca-border-rad: 14px;
	--ca-muted-accent: #F7E6ED;
	--ca-muted-secondary: #EAF0E6;
	--ca-muted-tertiary: #ECE7F5;
	--ca-muted-quaternary: #eee5d6;
}

/* ============================================================
   Global heading sizes
   Parent theme's h1-h3 are small, fixed, non-fluid sizes meant
   for a small default scale. These override just font-size with
   clamp() so large editorial headings scale down on mobile
   instead of overflowing. h4-h6 are left as the parent set them.
   Loads after parent-style, so plain element selectors here win
   on source order without needing !important.
   ============================================================ */

h1 {
	font-size: clamp(38px, 4.6vw, 58px);
}

h2 {
	font-size: clamp(28px, 3.2vw, 40px);
}

h3 {
	font-size: clamp(20px, 2.2vw, 26px);
}

.mobile-telephone-button a {

	&:link, &:visited {
		color: var(--color-white);
	}
}

/* CTA band gets a slightly larger H2 than the site default */
.ca-cta-band {
	& h2 {
		font-size: clamp(30px, 3.4vw, 44px);
	}

	@media (max-width: 480px) {
		padding-top: var(--l-spacing) !important;
		padding-bottom: var(--l-spacing) !important;
	}
}

/* Thicker separator bar than the parent theme's 2px default, with
   extra top margin. Loads after parent-style, so this plain selector
   wins on source order without needing !important (same reasoning as
   the heading sizes above). */
.wp-block-separator {
	height: 4px;
	margin-top: var(--m-spacing);
}

/* ============================================================
   Site header — top accent bar
   .document-header is position:fixed in the parent theme, which
   already establishes a containing block, so this pseudo-element
   just needs top:0 — no extra position/relative needed. Same
   brand-colors-bar gradient preset as the .ca-audit card's
   accent bar. z-index set above the header's own 99999 so it
   isn't painted under .main-bar's background in the has-top-bar
   layout.
   ============================================================ */
body.improvise .document-header {

	&::before {
		content: "";
		position: absolute;
		top: 0;
		left: 0;
		right: 0;
		height: 4px;
		z-index: 100000;
		background: var(--wp--preset--gradient--brand-colors-bar);
	}

	& .primary-nav {
		flex: auto;
        justify-content: center;
		border-bottom: 1px solid var(--color-primary);

		& .navbar-nav {
			flex: auto;

			/* Parent theme's own desktop default is justify-content:
			   space-between (spreads every li edge-to-edge); its <1200px
			   breakpoint switches that to space-around for the collapsed
			   mobile menu. Scoped to match that same 1200px boundary so
			   only the desktop horizontal bar changes.
			   .button is pulled fully out of this flex flow below
			   (position:absolute) rather than centered-via-margin:auto —
			   margin-left:auto on a flex item claims *all* the
			   container's free space before justify-content gets any,
			   so once .navbar-nav stretches (flex:auto above) to fill
			   .primary-nav's width, an auto-margin on .button would
			   leave nothing left for the other li's to center within;
			   they'd collapse flush against the logo. Taking .button out
			   of flow entirely lets the remaining li's center across the
			   *whole* available width unopposed. container-type
			   establishes .navbar-nav itself as the reference for the
			   cqw buffer below, so that reserved space scales with the
			   bar's own width instead of a fixed pixel guess tuned for
			   one viewport. */
			@media (min-width: 1201px) {
				container-type: inline-size;
				position: relative;
				justify-content: center;
				align-items: center;
				/* Reserves room on the right so the centered li's never
				   visually run into the absolutely-positioned button. */
				padding-right: 14cqw;
			}
		}

		& .button {
			color: var(--color-primary);
			background-color: var(--color-white);
			border-color: var(--color-primary);
			border-radius: 50px;
			padding: 8px 20px;
			transition: all 0.5s ease;

			@media (min-width: 1201px) {
				position: absolute;
				right: 0;
				top: 50%;
				transform: translateY(-50%);
			}

			a {
				border-bottom: none;
				font-size: 0.8rem;
				font-weight: 900;
				display: inline-flex;
				align-items: center;
				gap: 6px;

				/* Same icon-phone SVG already used on the live site's
				   floating "Ready when you are!" mobile CTA — reused
				   here via mask-image (not background-image) so it
				   picks up the link's actual text color instead of the
				   flat black a data-URI background-image would render:
				   the original SVG's fill="currentColor" only resolves
				   against real inherited color in an inline <svg>, not
				   one loaded as a CSS image resource, so mask-image
				   (which only reads the shape's alpha, painted by
				   background-color) is the correct technique for an
				   icon that needs to track surrounding text color. */
				&::before {
					content: "";
					flex: none;
					width: 18px;
					height: 18px;
					background-color: currentColor;
					-webkit-mask-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M7 2a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V4a2 2 0 0 0-2-2H7zm0 2h10v16H7V4zm3 13a1 1 0 1 0 2 0 1 1 0 0 0-2 0z"/></svg>');
					mask-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M7 2a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V4a2 2 0 0 0-2-2H7zm0 2h10v16H7V4zm3 13a1 1 0 1 0 2 0 1 1 0 0 0-2 0z"/></svg>');
					-webkit-mask-repeat: no-repeat;
					mask-repeat: no-repeat;
					-webkit-mask-position: center;
					mask-position: center;
					-webkit-mask-size: contain;
					mask-size: contain;
				}
			}

			&:hover {
				background-color: var(--color-primary);
				transform: translateY(-2px);

				/* The base ≥1201px rule above uses translateY(-50%) to
				   vertically center the absolutely-positioned button —
				   this hover lift would otherwise replace that outright
				   and knock it off-center. Combines both in one
				   transform instead of just adding the -2px lift. */
				@media (min-width: 1201px) {
					transform: translateY(calc(-50% - 2px));
				}

				a {
					color: var(--color-white);
					border-bottom: none !important;
				}
			}

			@media (max-width: 850px) {
				width: 202px;
				margin: 90px auto 50px;
				text-align: center;

				a {
					padding-left: 0;
					line-height: 1.5;
				}

				&:before {
					content: "Ready when you are!";
					position: absolute;
					top: -45px;
					left: -20px;
					white-space: nowrap;
					font-size: 25px;
				}
			}
		}

		& .caret {
			top: 0.5px;
			border-radius: 3px;
		}
	}
}

body.improvise.fixed .document-header {

	& .button {
		padding: 4px 20px;
	}
}

/* The admin-bar-slides-under-header bug this used to patch (see
   git history / cawt-2026/CLAUDE.md 2026-08-25 entry if the old
   version of this rule is ever needed for reference) is now fixed at
   the source, in the parent theme itself (improvise/style.css's own
   .document-header rule, mirrored to the pav.crack-ajax.com starter
   copy too) — see improvise.md's changelog. Fixing it there instead
   of here means every future site built on this theme gets it for
   free, not just this one. */

article {
	padding-bottom: 0;
}

a {

	&:link, &:visited {
		color: var(--color-primary);
	}

	&:hover {
		color: var(--color-accent);
	}
}

.wp-block-button__link.has-light-text-color.has-accent-background-color {
	border: none;
	box-shadow: 0 8px 18px -8px color-mix(in srgb, var(--color-accent) 32%, transparent);
	transition: background .2s, box-shadow .15s, transform .15s;

	&:hover {
		background-color: var(--ca-wine-deep) !important;
		color: var(--color-white) !important;
		transform: translateY(-2px);
	}
}

/* Button treatments the color/border panels can't express:
	shadow, and a hover state (must beat the block's own inline
	background-color, hence !important on that one property) */
& .wp-block-button.ca-btn-wine .wp-block-button__link {
	box-shadow: 0 6px 18px color-mix(in srgb, var(--color-accent) 32%, transparent);
	transition: background-color .15s, box-shadow .15s, transform .15s;
	border: 2px solid white !important;

	&:hover {
		background-color: var(--ca-wine-deep) !important;
		box-shadow: 0 8px 22px color-mix(in srgb, var(--color-accent) 42%, transparent);
		transform: translateY(-2px);
		border-color: white !important;
	}
}

& .ca-btn-ghost .wp-block-button__link {
	border-color: color-mix(in srgb, var(--color-light-text) 55%, transparent) !important;
	transition: background-color .15s;

	&:hover {
		background: color-mix(in srgb, var(--color-light-text) 12%, transparent);
	}
}

/* ============================================================
   Child Theme Custom Block Toggles
   Styles for classes added via the custom "Improvise Settings"
   panel toggles registered in js/block-*.js (see
   js/block-paragraph.js). Add a new subsection here for each
   toggle's class as more get added.
   ============================================================ */

/* Paragraph block "Kicker" toggle — small eyebrow-style label */
.ca-kicker {
	font-size: 13px;
	font-weight: 700;
	letter-spacing: .14em;
	text-transform: uppercase;
	color: var(--color-primary);
}

/* ============================================================
   Home hero — Cover block, className "ca-hero"
   Covers only what the block editor's own controls can't reach:
   gradient text, pseudo-element decoration, hover states, the
   raw-HTML client ticker, and color for children the cover
   block doesn't auto-tint against its dark background.
   ============================================================ */

.ca-hero {

  & > .wp-block-cover__inner-container {
    padding-bottom: 15px;
    /* Core's .wp-block-cover__background gradient span has no
       explicit z-index (paints in the "auto" layer), and our
       ::before puzzle decoration below needs an explicit z-index
       to paint above that span — which would otherwise also lift
       it above the actual hero content. Lifting the real content
       one layer higher keeps the stacking order correct: gradient
       (auto) < puzzle (1) < content (2). */
    position: relative;
    z-index: 2;
  }

	/* Faint puzzle-piece watermark, matching the homepage.html mockup's
	   hero decoration — a classic jigsaw tab/blank shape (pinched neck,
	   round bulb), not a plain semicircle bump. Sits above the cover
	   block's own gradient background span but behind the real content
	   — see the z-index note on .wp-block-cover__inner-container above
	   for why an explicit z-index is required here at all. Centered in
	   the hero rather than tucked in a corner. */
	&::before {
		content: "";
		position: absolute;
		top: 34%;
		left: 57%;
		width: 560px;
		height: 560px;
		background: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="6 -13 106 106"><path d="M8,8 L37.40,8.00 C37.40,2.96 39.92,-10.48 50.00,-10.48 C60.08,-10.48 62.60,2.96 62.60,8.00 L92.00,8.00 L92.00,37.40 C97.04,37.40 110.48,39.92 110.48,50.00 C110.48,60.08 97.04,62.60 92.00,62.60 L92.00,92.00 L62.60,92.00 C62.60,86.96 60.08,73.52 50.00,73.52 C39.92,73.52 37.40,86.96 37.40,92.00 L8.00,92.00 L8.00,62.60 C13.04,62.60 26.48,60.08 26.48,50.00 C26.48,39.92 13.04,37.40 8.00,37.40 L8.00,8.00 Z" fill="none" stroke="white" stroke-width="1.4" opacity=".14"/></svg>') no-repeat center/contain;
		transform: translate(-50%, -50%) rotate(-38deg);
		pointer-events: none;
		z-index: 1;
	}

	/* Gradient-clipped emphasis inside the H1 */
	& h1 em {
		font-style: normal;
		background: var(--wp--preset--gradient--text-shine);
		-webkit-background-clip: text;
		background-clip: text;
		color: transparent;
	}

	/* Eyebrow label + gradient tick mark */
	& .ca-eyebrow {
		display: inline-flex;
		align-items: center;
		/* inline-flex is shrink-to-fit (indeterminate width), so a %
		   gap here would resolve to 0 per spec — px stays intentional */
		gap: 10px;
		font-size: 13px;
		font-weight: 700;
		letter-spacing: .14em;
		text-transform: uppercase;
		color: var(--ca-eyebrow-text);

		&::before {
			content: "";
			width: 26px;
			height: 3px;
			border-radius: 2px;
			background: linear-gradient(90deg, var(--color-accent), var(--color-quaternary));
		}
	}

	& .ca-lead {
		color: var(--ca-lead-text);
		max-width: 34em;
	}

	& .ca-hero-note {
		color: var(--ca-hero-note-text);
	}

	/* Quick form / Ask AI card. ".ca-audit" is the 42%-width column, and
	   it's the single white card here — the tab tray and whichever panel
	   is active both sit inside it, so it (not the individual panels)
	   gets the background/radius/shadow/accent-bar. */
	& .ca-audit {
		background: var(--color-white);
		border-radius: var(--ca-border-rad);
		padding: var(--s-spacing);
		box-shadow: 0 24px 60px var(--ca-audit-shadow);
		position: relative;

		&::before {
			content: "";
			position: absolute;
			top: 0;
			left: 0;
			right: 0;
			height: 10px;
			border-radius: var(--ca-border-rad)var(--ca-border-rad) 0 0;
			background: var(--wp--preset--gradient--brand-colors-bar);
		}

		& > .wp-block-buttons {
			display: flex;
			gap: 1.5%;
			background: var(--ca-tab-tray-bg);
			border-radius: 99px;
			padding: 4px;
			margin-bottom: 18px;

			& .wp-block-button {
				flex: 1;
			}

			/* Neutralizes whatever background/color/padding the editor set
			   per-button (one has is-style-fill baked in, one doesn't) so
			   both tabs share one look, with active state fully JS-driven
			   via .ca-tab-active — hence !important throughout. */
			& .wp-block-button__link {
				display: flex;
				align-items: center;
				justify-content: center;
				gap: 2%;
				width: 100%;
				border: none !important;
				border-radius: 99px !important;
				padding: 2px 10px !important;
				font-size: 14px !important;
				font-weight: 600 !important;
				color: var(--ca-neutral-text) !important;
				background: transparent !important;
				box-shadow: none !important;
				cursor: pointer;
				transition: background .2s, color .2s, box-shadow .2s;

				&.ca-tab-active {
					background: var(--color-white) !important;
					color: var(--color-dark-text) !important;
					box-shadow: 0 2px 8px var(--ca-tab-shadow) !important;
				}
			}
		}
	}

	/* .panel-form arrives from the block editor with its own
	   background/radius/padding (set via the group block's own style
	   attributes when it was built) — that would nest a second white
	   card inside .ca-audit's, so it's neutralized flush here. Needs
	   !important to beat those inline styles. .panel-ai has no such
	   inline styles (empty group), so it just never gets any. */
	& .panel-form {
		padding: var(--s-spacing) 0 0 !important;
		margin-top: 0;
		margin-bottom: 0;

		/* Tighten the heading/intro above the form — parent theme's
		   default heading/paragraph margins are looser than the mockup */
		& > h3 {
			margin-bottom: 0px;
			color: var(--color-dark-text);
			font-size: 21px;
		}

		& > p {
			margin-top: 0;
			margin-bottom: var(--s-spacing);
			color: var(--color-dark-text);
			font-size: 14.5px;
		}

		/* Gravity Forms styling. Its own gravity-theme CSS (basic.min.css /
		   theme.min.css) loads AFTER this stylesheet, so overriding its
		   defaults needs !important throughout — it doesn't use !important
		   on any of these same properties, so this reliably wins. GF's own
		   CSS still handles the name-field grid layout and honeypot
		   hiding; nothing here touches structure, only look + spacing. */

		/* Redundant with the per-field required asterisks */
		& .gform_required_legend {
			display: none !important;
		}

    & .gform_wrapper.gravity-theme {
      margin-top: var(--s-spacing);

      /* .gform_fields is a CSS Grid with grid-template-rows: repeat(auto-fill, auto)
         (GF's own basic.min.css) — every row is auto-height, so the container's
         own height is intrinsic/indeterminate. A % row-gap needs a definite
         height to resolve against and collapses to ~0 here instead, which is
         what let the last field (the select) sit flush against .gform_footer
         with no breathing room. GF's own un-overridden default is 16px for
         exactly this reason — stays px, not %. Column-gap is fine as GF's
         own 2% default (untouched here) since .gform_fields does have a
         definite width. */
      & .gform_fields {
        grid-row-gap: 2px;
      }

		  & .gfield_label {
			  font-size: 13px;
			  font-weight: 600;
			  color: var(--ca-label-text);
		  }

		  & input[type="text"],
		  & input[type="email"],
		  & input[type="url"],
		  & select {
			  border: 1.5px solid var(--ca-border) !important;
			  border-radius: 9px;
			  font-size: 15px !important;

			  &:focus {
				  border-color: var(--color-primary) !important;
				  outline: none;
			  }
		  }

		  & .gform_footer {
        	padding-bottom: 8px;

			& .gform_button {
				width: 100%;
				max-width: 100%;
				font-size: 18px;
                font-weight: 800;
				border: none;
				border-radius: 50px;
				color: var(--color-light-text);
				background: var(--color-accent);
				/* Negative spread shrinks the shadow's shape before the blur
					softens it, so it reaches much less to the sides (~10px)
					while still dropping ~18px below — needs far less side
					clearance than a plain 0/6px/18px/0 shadow would on a
					width:100% button flush with its container. */
				box-shadow: 0 8px 18px -8px color-mix(in srgb, var(--color-accent) 32%, transparent);
				transition: background .2s, box-shadow .15s, transform .15s;

				&:hover {
					background: var(--ca-wine-deep) !important;
					transform: translateY(-2px);
				}
			}
		}
    }
	}

	/* Hidden by default so there's no flash-of-both-panels before
	   theme.js runs; theme.js sets an explicit inline display to
	   toggle between the two from then on. */
	& .panel-ai {
		display: none;
		padding-top: var(--s-spacing);
		margin-top: 0;
		margin-bottom: 0;

		& > h3 {
			margin-bottom: 0;
			color: var(--color-dark-text);
			font-size: 21px;
		}

		& > p {
			margin-top: 0;
			margin-bottom: var(--s-spacing);
			color: var(--color-dark-text);
			font-size: 14.5px;
		}
	}

	/* Ask-AI demo conversation, built as a raw wp:html block inside
	   .panel-ai (same reasoning as .ca-ticker above) */
	& .ca-chat {
		display: grid;
		/* This gap is vertical (row-gap between stacked bubbles), which
		   resolves against the container's height — auto/intrinsic here,
		   so a % gap would resolve to 0 per spec. Stays px. */
		gap: 10px;
		margin: 6px 0 14px;
	}

	& .ca-msg {
		padding: 11px 14px;
		border-radius: var(--ca-border-rad);
		font-size: 14.5px;
		line-height: 1.5;
		max-width: 92%;

		&.ca-msg-them {
			background: var(--ca-msg-them-bg);
			color: var(--ca-msg-them-text);
			border-bottom-left-radius: 4px;
			justify-self: start;
		}

		&.ca-msg-me {
			background: var(--color-primary);
			color: var(--color-light-text);
			border-bottom-right-radius: 4px;
			justify-self: end;
		}
	}

	& .ca-chat-row {
		display: flex;
		gap: 2%;

		& input {
			flex: 1;
			padding: 11px 13px;
			border: 1.5px solid var(--ca-border);
			border-radius: 99px;
			font-size: 14.5px;

			&:focus {
				border-color: var(--color-primary);
				outline: none;
			}
		}
	}

	& .ca-chat-send {
		display: inline-flex;
		align-items: center;
		justify-content: center;
		padding: 10px 16px;
		border-radius: 99px;
		border: none;
		background: var(--color-accent);
		color: var(--color-light-text);
		font-weight: 600;
		cursor: pointer;
		box-shadow: 0 6px 18px color-mix(in srgb, var(--color-accent) 32%, transparent);
		transition: background .2s, transform .15s;

		&:hover {
			background: var(--ca-wine-deep);
			transform: translateY(-1px);
		}
	}

	& .ca-chat-hint {
		display: block;
		text-align: center;
		margin-top: 10px;
		color: var(--ca-neutral-text);
		font-size: 12.5px;
	}

	& .ca-proof {

		/* Star rating + client count — no textColor set on the block,
		   so without this it inherits the dark default body color
		   and disappears against the cover's background */
		& .ca-rating {
			display: flex;
			align-items: center;
			/* .ca-rating is a flex item with no flex-grow, so it shrink-
			   wraps to its own content — indeterminate width, % gap
			   would resolve to 0. Stays px. */
			gap: 8px;
			color: var(--color-light-text);

			& strong {
				font-weight: 600;
				font-size: 15px;
			}
		}

		& .ca-stars {
			color: var(--color-quaternary);
			letter-spacing: 2px;
			font-size: 17px;
		}

		/* Client-name ticker: a raw wp:html block, so it has no block
		   settings at all — every rule here is required, not optional */
		& .ca-ticker {
			flex: 1;
			min-width: 280px;
			overflow: hidden;
			position: relative;
			-webkit-mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent);
			mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent);

			&:hover .ca-ticker-track {
				animation-play-state: paused;
			}
		}

		& .ca-ticker-track {
			display: flex;
			/* width:max-content below is load-bearing for the marquee
			   (it must size to its own duplicated content, not its
			   container) — that makes this width indeterminate for gap
			   purposes too, so a % gap would collapse to 0 and the
			   scrolling items would overlap. Stays px. */
			gap: 44px;
			width: max-content;
			font-family: var(--font-primary-heading);
			font-weight: 600;
			font-size: 14.5px;
			color: var(--ca-ticker-text);
			opacity: .9;
			animation: ca-ticker-scroll 34s linear infinite;

			& span {
				white-space: nowrap;
			}
		}
	}
}

/* Editor-only override: theme.js can't drive the tab switching inside
   wp-admin (it's enqueued into the outer admin window, not the block
   editor's iframed canvas, and Gutenberg intercepts clicks on the tab
   buttons for block-selection before any click handler would fire
   anyway) — so without this, .panel-ai stays permanently display:none
   and its group block can never be selected/edited visually. Scoped to
   .editor-styles-wrapper (the class WP puts on the iframe's content
   root when editor-styles are enabled) so it only applies in wp-admin,
   never on the live front end. */
.editor-styles-wrapper .ca-hero .panel-ai {
	display: block !important;
	margin-top: 16px;
	border-top: 1px dashed var(--ca-border);
	padding-top: 16px;
}

@keyframes ca-ticker-scroll {
	to { transform: translateX(-50%); }
}

@media (prefers-reduced-motion: reduce) {
	.ca-hero .ca-ticker-track {
		animation: none;
		flex-wrap: wrap;
		width: auto;

		& span[aria-hidden] {
			display: none;
		}
	}

	.ca-hero .ca-ticker {
		mask-image: none;
		-webkit-mask-image: none;
	}
}

.ca-includes {

	@media (max-width: 480px) {
		padding-top: var(--l-spacing) !important;
		padding-bottom: var(--l-spacing) !important;
	}
}

.ca-feature {

	& .wp-block-column {
		position: relative;
		background-color: var(--color-white);
		border: 1px solid var(--ca-border);
		border-radius: var(--ca-border-rad);
		padding: var(--s-spacing);
		box-shadow: none;
		transition: box-shadow .6s;

		&:before {
			content: "";
			position: absolute;
			top: 0;
			left: 0;
			right: 0;
			height: 8px;
			border-radius: var(--ca-border-rad) var(--ca-border-rad) 0 0;
		}

		&:hover {
			box-shadow: 0 10px 30px rgba(20,56,76,.10);
		}
	}

	& .wp-block-column:first-child {
		&:before,
		& .svg-style {
			background-color: var(--color-accent);
		}
	}

	& .wp-block-column:nth-child(2) {
		&:before,
		& .svg-style {
			background-color: var(--color-tertiary);
		}
	}

	& .wp-block-column:nth-child(3) {
		&:before,
		& .svg-style {
			background-color: var(--color-secondary);
		}
	}

	& .wp-block-column:last-child {
		&:before,
		& .svg-style {
			background-color: var(--color-quaternary);
		}
	}

	& .svg-style {
		width: 44px;
		height: 44px;
		border-radius: 11px;
		transform: rotate(45deg);
		display: flex;
		align-items: center;
		justify-content: center;
		margin: 6px 0 22px;

		img {
			transform: rotate(-45deg);
		}
	}
}

.ca-result {

	& .ca-gradient-text {
		font-family: var(--font-primary-heading);
		font-weight: 800;
		font-size: 34px;
		background: var(--wp--preset--gradient--gradient-text);
		background-clip: text;
		color: transparent;
	}

	& .wp-block-column {
		background: var(--color-white);
		border: 1px solid var(--ca-border);
		border-radius: var(--ca-border-rad);
		padding: var(--s-spacing);

		&:hover {
			box-shadow: 0 10px 30px rgba(20,56,76,.10);
		}

		& .wp-block-button__link {
			border: none;
			padding: 10px 16px;
			line-height: normal;
		}

		&:first-child {
			& .wp-block-button__link:hover {
				background-color: var(--color-accent) !important;
				color: var(--ca-muted-accent) !important;
			}
		}

		&:nth-child(2) {
			& .wp-block-button__link:hover {
				background-color: var(--color-tertiary) !important;
				color: var(--ca-muted-tertiary) !important;
			}
		}

		&:nth-child(3) {
			& .wp-block-button__link:hover {
				background-color: var(--color-secondary) !important;
				color: var(--ca-muted-secondary) !important;
			}
		}

		&:last-child {
			& .wp-block-button__link:hover {
				background-color: var(--color-quaternary) !important;
				color: var(--ca-muted-quaternary) !important;
			}
		}
	}
}

.ca-band-green {

	& .ca-service-list {
		padding-left: 0;
	
		&> li {
			position: relative;
			isolation: isolate;
			display: flex;
			flex-direction: column;
			align-items: flex-start;
			background: rgba(255, 255, 255, .07);
			border: 1px solid rgba(255, 255, 255, .14);
			border-radius: var(--ca-border-rad);
			padding: 15px var(--s-spacing);
			padding-left: var(--m-spacing);
			font-size: 0.9rem;

			/* Default comet/bullet color for this li — overridden per
			   position below so both stay in sync off one value. */
			--ca-comet-color: var(--color-quaternary);

			/* Animated gradient "comet" border on hover — see the
			   @property/@keyframes block below the .ca-band-green
			   rule for the full explanation of the non-linear speed. */
			&::before {
				content: "";
				position: absolute;
				inset: -2px;
				z-index: -1;
				padding: 2px;
				border-radius: inherit;
				background: conic-gradient(
					from var(--ca-border-angle),
					transparent 0deg,
					transparent 200deg,
					var(--ca-comet-color) 240deg,
					var(--ca-comet-color) 280deg,
					var(--color-light-text) 315deg,
					transparent 322deg,
					transparent 360deg
				);
				-webkit-mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
				        mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
				-webkit-mask-composite: xor;
				        mask-composite: exclude;
				filter: drop-shadow(0 0 5px var(--ca-comet-color));
				opacity: 0;
				transition: opacity .35s ease;
			}

			&:hover::before,
			&:focus-within::before {
				opacity: 1;
				animation-name: ca-border-chase;
				animation-duration: 4.5s;
				animation-iteration-count: infinite;
				animation-timing-function: linear(0.0 0.0%, 0.031 1.58%, 0.062 3.25%, 0.094 5.13%, 0.125 7.38%, 0.156 10.22%, 0.188 13.99%, 0.219 18.97%, 0.25 25.0%, 0.281 31.03%, 0.312 36.01%, 0.344 39.78%, 0.375 42.62%, 0.406 44.87%, 0.438 46.75%, 0.469 48.42%, 0.5 50.0%, 0.531 51.58%, 0.562 53.25%, 0.594 55.13%, 0.625 57.38%, 0.656 60.22%, 0.688 63.99%, 0.719 68.97%, 0.75 75.0%, 0.781 81.03%, 0.812 86.01%, 0.844 89.78%, 0.875 92.62%, 0.906 94.87%, 0.938 96.75%, 0.969 98.42%, 1.0 100.0%);
			}

			ul {
				list-style: none;
				padding-left: 0;

				li {
					font-size: 0.8rem;
					margin-top: 0;
					color: var(--ca-muted-white);
				}
			}

			strong {
				position: relative;

				&:before {
					content: "";
					position: absolute;
					flex: none;
					top: 6px;
					left: calc(var(--s-spacing) * -1);
					width: 12px;
					height: 12px;
					border-radius: 3px;
					transform: rotate(45deg);
					background: var(--ca-comet-color);
				}
			}
		}

		&> li:first-child {
			--ca-comet-color: var(--color-quaternary);
		}

		&> li:nth-child(2) {
			--ca-comet-color: var(--color-secondary);
		}

		&> li:nth-child(3) {
			--ca-comet-color: var(--color-tertiary);
		}

		&> li:last-child {
			--ca-comet-color: var(--color-accent);
		}
	}

	& .wp-block-column:has(.ca-pricing) {

		@media (max-width: 1200px) {
			padding-left: 0 !important;
			padding-right: 0 !important;
		}
	}

	& .ca-pricing {
		border-radius: var(--ca-border-rad);
		padding: var(--m-spacing) !important;
    	box-shadow: 0 24px 60px rgba(6, 24, 34, .4);

		table {
			min-width: auto;
		
			td {
				border: none;
				border-bottom: 0.5px solid var(--ca-border);
			}
		}

		@media (max-width: 480px) {
			padding: var(--s-spacing) !important;
		}
	}

	@media (max-width: 480px) {
		padding-top: var(--l-spacing) !important;
		padding-bottom: var(--l-spacing) !important;
	}
}

/* ============================================================
   Animated gradient border — .ca-service-list item hover
   (rule itself lives above, nested in .ca-band-green > .ca-service-list > li)
   A bright "comet" chases around each list item's border on
   hover: a conic-gradient sits in a 2px ring punched out with
   mask-composite (no image, no JS), and its rotation angle is
   driven by an animated @property custom property so the browser
   can interpolate it smoothly frame to frame.

   The @keyframes below are a plain, constant-rate 0deg->360deg
   sweep on purpose — ALL of the speed shaping lives in the
   animation-timing-function's linear() curve set on the hover
   rule above, not in the keyframe stops. A multi-stop @keyframes
   (dwell here, jump there) still gets an ease in/out at every
   stop by default, which reads as a stutter/pulse rather than
   one continuous motion. linear() instead plots ~33 closely-
   spaced points along a single smooth sine-modulated velocity
   curve — v(angle) = 1 + 0.6*cos(2*angle) — so the card (much
   wider than tall, so both right corners cluster near 90deg and
   both left corners near 270deg in angle-space) glides smoothly
   slower through the corners and smoothly faster across the top
   and bottom straight edges, with no visible speed jumps.
   =========================================================== */

@property --ca-border-angle {
	syntax: '<angle>';
	inherits: false;
	initial-value: 0deg;
}

@keyframes ca-border-chase {
	from { --ca-border-angle: 0deg; }
	to   { --ca-border-angle: 360deg; }
}

@media (prefers-reduced-motion: reduce) {

	.ca-band-green .ca-service-list > li:hover::before,
	.ca-band-green .ca-service-list > li:focus-within::before {
		animation: none;
	}
}

.ca-meet {

	@media (max-width: 480px) {
		padding-top: var(--l-spacing) !important;
		padding-bottom: var(--l-spacing) !important;
	}
}

.ca-about {

	& .wp-block-media-text__media {
		position: relative;

		&:before {
			content: "";
			position: absolute;
			bottom: 0;
			left: 0;
			right: 0;
			height: 10px;
			border-radius: 0 0 var(--ca-border-rad) var(--ca-border-rad);
			background: var(--wp--preset--gradient--brand-colors-bar);
		}

		img {
			padding-bottom: 10px;
			border-radius: var(--ca-border-rad) var(--ca-border-rad) 0 0;
		}
	}
}

.wp-block-pullquote {

    &:not(.is-style-solid-color) {
		border-color: var(--color-secondary);
	}

	blockquote {

		&:before,
		cite {
			color: var(--color-secondary) !important;
		}
	}
}

.ca-tint-blue {
	background: linear-gradient(180deg,var(--ca-paper),#EDF3F6);

	& .wp-block-column {
		border: 1px solid var(--ca-border);
		border-radius: var(--ca-border-rad);
		padding: var(--s-spacing);

		a {
			text-decoration: none;
		}

		h3{
			position: relative;

			&:after {
				content: "→";
				position: absolute;
				right: 0;
				top: 0;
				color: var(--color-dark-text);
				font-family: var(--font-primary-heading);
				font-weight: 600;
				transition: transform .2s;
			}

			&:hover:after {
				transform: translateX(4px);
			}
		}

		&:hover {
			border: 1px solid var(--color-primary);
		}
	}

	@media (max-width: 480px) {
		padding-top: var(--l-spacing) !important;
		padding-bottom: var(--l-spacing) !important;
	}
}

.ca-client-stories {
	background: linear-gradient(180deg, var(--ca-paper), #E7F4EC);

	& .wp-block-column {
		padding: var(--s-spacing) var(--m-spacing);
		border-radius: var(--ca-border-rad);
	}

	@media (max-width: 480px) {
		padding-top: var(--l-spacing) !important;
		padding-bottom: var(--l-spacing) !important;
	}
}

.ca-faqs {
	background: linear-gradient(180deg, #E7F4EC, var(--ca-paper));

	& .schema-faq-section {
		background-color: var(--color-white);
		border: 1px solid var(--ca-border);
		border-radius: var(--ca-border-rad);
		max-width: var(--restricted-width);
		margin-inline: auto;

		& .schema-faq-question {
			color: var(--color-dark-text);
			font-weight: 800;
			font-size: 17px;
		}

		& .schema-faq-answer {
			color: var(--color-dark-text);
			font-size: 15.5px;
		}
	}

	@media (max-width: 480px) {
		padding-top: var(--l-spacing) !important;
		padding-bottom: var(--l-spacing) !important;
	}
}

.document-footer {

	&:before{
		content: "";
		position: absolute;
		top: 0;
		left: 0;
		right: 0;
		height: 6px;
		background: var(--wp--preset--gradient--brand-colors-bar);
	}

	.wp-block-group {
		padding: 0 !important;
	}

	.footer-widgets {
		/* Scoped to the desktop range only (matches the site's own
		   1200px mobile-nav breakpoint, see the parent theme's own
		   .footer-widgets reflow breakpoint below). Previously
		   unconditional, so this wide-logo-column ratio kept
		   overriding the parent theme's own responsive
		   grid-template-columns at every mobile breakpoint (992/768/
		   540px) — same selector/specificity, later in the cascade,
		   so it always won. That left the grid's column COUNT fixed
		   at 4 while the parent's own breakpoint rules were
		   simultaneously reassigning each li's grid-ROW on the
		   assumption of a different (2, 3, or 1-column) layout —
		   a genuine column/row mismatch that caused severe content
		   overlap at every mobile width, not just uneven spacing.
		   Confirmed via Playwright screenshots at 1200/992/850/768/
		   540/480/375px before and after this fix. */
		&:has(#footer4) {
			@media (min-width: 1201px) {
				grid-template-columns: 2fr 1fr 1fr 1fr;
				gap: 5%;
			}
		}
	}

	a {
		&:link, &:visited {
			color: #afc2bb;
			text-decoration: none;
		}

		&:hover {
			color: var(--color-white) !important;
			opacity: 1;
		}
	}

	h3 {
		font-size: 15px;
		font-weight: 900;
	}

	li {
		font-size: 14.5px;
		line-height: 2;
	}

	& #footer1 {

		p {
			margin: 0 0 var(--s-spacing);

			&:first-of-type {
				margin-top: var(--s-spacing);
				margin-bottom: 0;
			}
		}

		img {
			background-color: white;
    		border-radius: 14px;
			padding: 10px;
		}
	}

	/* footer1 (the logo/contact card) is already centered by the
	   parent theme's own li:first-child rule at this width — this
	   only needs to center the other three (Websites/Support/AI &
	   marketing), which the parent leaves left-aligned at every
	   width. */
	@media (max-width: 480px) {
		.footer-widgets > li:not(:first-child) .widget-area {
			text-align: center;
		}
	}

	.footer-bottom {

		.copyright {
			justify-content: space-between;
			width: 100%;

			.menu-item-254 .pipe {
				display: none;
			} 
		}
		
		.crack-ajax-plug {
			display: none;
		}
	}
}

/* ============================================================
   Reveal on scroll — .ca-reveal / .ca-in
   Matches homepage.html's .rv/.rv.in scroll-reveal pattern:
   toggled onto blocks via the "Reveal on Scroll" control in the
   Improvise Settings panel (see js/block-reveal.js). The actual
   trigger — an IntersectionObserver that adds .ca-in the first
   time an element scrolls into view — lives in js/theme.js, not
   here; this is just the two visual states.
   =========================================================== */

.ca-reveal {
	opacity: 0;
	transform: translateY(18px);
	transition: opacity .6s, transform .6s;

	&.ca-in {
		opacity: 1;
		transform: none;
	}
}

@media (prefers-reduced-motion: reduce) {

	.ca-reveal {
		opacity: 1;
		transform: none;
		transition: none;
	}
}

/* Editor-only override, same root cause as the .panel-ai override above:
   js/theme.js's IntersectionObserver is enqueued into the outer wp-admin
   window, not the block editor's iframed canvas, so it can never see/
   reveal .ca-reveal elements in there — they'd otherwise sit at
   opacity:0 forever, making the content impossible to select or edit.
   No !important needed here (unlike the .panel-ai override, which is
   fighting an inline style theme.js sets): this class only ever sets
   opacity/transform/transition, nothing inline competes with it, so
   plain specificity (.editor-styles-wrapper .ca-reveal beats .ca-reveal
   on its own) is enough. Scoped to .editor-styles-wrapper so it only
   applies in wp-admin, never on the live front end. */
.editor-styles-wrapper .ca-reveal {
	opacity: 1;
	transform: none;
	transition: none;
}
