/*
 * Al Bairaq — integration layer.
 *
 * This file exists so `albairaq.css` can stay the untouched, ported design system.
 * Nothing here invents design. Every value below is copied from `albairaq.css`, and
 * the only job is to make markup we do not control — plugin and builder output —
 * land on the design the client already signed off.
 *
 * Enqueued after `albairaq.css`, so it wins ties on equal specificity.
 *
 * ---------------------------------------------------------------------------
 * 1. Bricks form  ->  the design system's .form
 * ---------------------------------------------------------------------------
 *
 * The Bricks form element is used deliberately: it is the native element, it has
 * real server-side submission, and hand-rolling a form would give us markup with
 * no handler. But it emits its own structure:
 *
 *   form.brxe-form
 *     div.form-group            (one per field: label + control)
 *     div.form-group.submit-button-wrapper
 *       button.bricks-button
 *
 * where the design system expects `.form__field`, `.form__label`, `.form__control`
 * and `.btn.btn--primary.btn--block`. Those classes cannot be added to Bricks' own
 * field wrappers, so the mapping happens here instead.
 *
 * The `.form` class itself is on the element, so the two-column grid, white ground,
 * 14px radius and padding all come from `albairaq.css` already.
 */

/* Each Bricks field wrapper behaves as .form__field. */
.form.brxe-form .form-group {
	display: flex;
	flex-direction: column;
	gap: 6px;
	/*
	 * Bricks can emit a per-field width percentage. The grid owns layout here, so
	 * any such width is neutralised rather than left to fight the track sizing.
	 */
	width: auto;
	margin: 0;
}

/*
 * The long fields span the full row, matching .form__field--full.
 * Targeted by what they contain rather than by position, so reordering fields in
 * the Bricks panel cannot silently break the layout.
 */
.form.brxe-form .form-group:has( textarea ),
.form.brxe-form .form-group:has( .form__note ),
.form.brxe-form .form-group.submit-button-wrapper {
	grid-column: 1 / -1;
}

/* .form__label */
.form.brxe-form .form-group > label {
	font-size: 14px;
	font-weight: 700;
	color: var(--ink-900);
	line-height: 1.6;
}

/* .form__control */
.form.brxe-form input:not( [type="checkbox"] ):not( [type="radio"] ):not( [type="submit"] ),
.form.brxe-form select,
.form.brxe-form textarea {
	font-family: var(--font-ar);
	font-size: 16px;
	color: var(--ink-900);
	padding: 12px var(--s-2);
	border: 1px solid var(--line);
	border-radius: var(--radius-sm);
	background: var(--surface-alt);
	width: 100%;
}

.form.brxe-form input:not( [type="checkbox"] ):not( [type="radio"] ):hover,
.form.brxe-form select:hover,
.form.brxe-form textarea:hover {
	border-color: #CFCFD6;
}

.form.brxe-form input:not( [type="checkbox"] ):not( [type="radio"] ):focus,
.form.brxe-form select:focus,
.form.brxe-form textarea:focus {
	outline: 2px solid var(--brand-purple);
	outline-offset: 1px;
	background: #fff;
}

.form.brxe-form textarea {
	min-height: 96px;
	resize: vertical;
}

/*
 * Textarea leading, set on the parent on purpose.
 *
 * Bricks' frontend stylesheet ships:
 *   textarea { line-height: inherit !important; ... }
 *
 * and it ships it inside a CSS cascade layer. For `!important` declarations layer
 * order is reversed, so a layered `!important` outranks an unlayered one no matter
 * how specific the unlayered selector is. A child-theme rule therefore cannot win
 * this by force, with or without `!important` of its own. (Verified: an injected
 * `html body .form.brxe-form textarea { line-height: 1.7 }` had no effect.)
 *
 * Note this also defeats albairaq.css's own
 * `textarea.form__control { line-height: 1.7 }`, so the clash is between Bricks and
 * the design system, not something this bridge introduced.
 *
 * Since Bricks forces the textarea to *inherit*, the fix is to give it the right
 * thing to inherit: set the value on the field wrapper. No `!important`, no layer
 * games, and no need for Bricks' global `disableBricksCascadeLayer` setting. The
 * label in the same wrapper sets its own line-height above, so it is unaffected.
 */
.form.brxe-form .form-group:has( textarea ) {
	line-height: 1.7;
}

/* The submit button is .btn.btn--primary.btn--block. */
.form.brxe-form .bricks-button[type="submit"] {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: var(--s-1);
	width: 100%;
	font-family: var(--font-ar);
	font-size: 16px;
	font-weight: 700;
	line-height: 1.2;
	padding: 14px var(--s-3);
	border-radius: 999px;
	border: 2px solid transparent;
	background: var(--brand-purple);
	color: #fff;
	cursor: pointer;
	text-align: center;
	transition: background-color .18s, color .18s, border-color .18s;
}

.form.brxe-form .bricks-button[type="submit"]:hover {
	background: var(--brand-purple-tint);
	color: #fff;
}

.form.brxe-form .bricks-button[type="submit"]:active {
	background: #6C1A6E;
	color: #fff;
}

/*
 * Bricks ships a spinner span inside the button and reveals it while submitting.
 * Keep it out of the flow until then, so it does not offset the label.
 */
.form.brxe-form .bricks-button[type="submit"] > .loading {
	display: none;
}

.form.brxe-form .bricks-button[type="submit"].sending > .loading {
	display: inline-flex;
}

.form.brxe-form .bricks-button[type="submit"] > .loading svg {
	width: 18px;
	height: 18px;
}

/*
 * The English layer switches controls to Inter, exactly as albairaq.css does for
 * its own `.form__control`.
 */
.page.lang-en .form.brxe-form input:not( [type="checkbox"] ):not( [type="radio"] ),
.page.lang-en .form.brxe-form select,
.page.lang-en .form.brxe-form textarea,
.page[lang="en"] .form.brxe-form input:not( [type="checkbox"] ):not( [type="radio"] ),
.page[lang="en"] .form.brxe-form select,
.page[lang="en"] .form.brxe-form textarea {
	font-family: "Inter", sans-serif;
}

/*
 * ---------------------------------------------------------------------------
 * 2. Bricks term tags inside an eyebrow
 * ---------------------------------------------------------------------------
 *
 * `{post_terms_<tax>}` renders the term as a link. The design uses `.eyebrow` as
 * plain text, and on the dark `.pagehero` ground the inherited link colour
 * (`--brand-purple`) fails contrast badly against `#040811`.
 *
 * Keeping the link is the better outcome — it lets a reader browse the category —
 * so it inherits the eyebrow's own colour instead, whichever ground it sits on.
 */
.eyebrow a {
	color: inherit;
	text-decoration: none;
}

.eyebrow a:hover {
	color: inherit;
	text-decoration: underline;
}

/*
 * ---------------------------------------------------------------------------
 * 3. Bricks query-loop trail markers
 * ---------------------------------------------------------------------------
 *
 * Bricks appends an empty element after every query loop to anchor infinite
 * scroll. We do not use infinite scroll anywhere, and the empty markers are not
 * harmless in these three places:
 *
 *   - in `.faq` the trail is an empty `<details>`, and a `<details>` with no
 *     `<summary>` gets the browser's own "Details" disclosure marker, so a stray
 *     control appears at the end of the accordion
 *   - in `.aside__list` and `.footer__list` the trail is an empty grid item, which
 *     still draws its gap and leaves a dangling row
 *
 * This was first written as a per-list allowlist and immediately missed a case:
 * `.card-service__list` gained a phantom fourth item on every home-page card. Since
 * nothing on this site uses infinite scroll, hiding the trail everywhere is both
 * simpler and actually correct.
 *
 * If infinite scroll is ever wanted on some list, remove this rule and hide the
 * trail per-list instead — the trail is the element Bricks scrolls to.
 */
.brx-query-trail {
	display: none;
}

/*
 * ---------------------------------------------------------------------------
 * 4. Restore the hero scrim that Bricks' lazy-load class wipes out
 * ---------------------------------------------------------------------------
 *
 * Bricks stamps `bricks-lazy-hidden` on every div it renders, and that class is
 * `background-image: none !important`. It removes the class again only for
 * elements whose background *it* set, so on a div styled by our own stylesheet the
 * class is permanent.
 *
 * For most elements that is harmless. For `.hero__overlay` it is fatal: the entire
 * scrim is a linear-gradient background-image, so the hero lost its darkening layer
 * and white hero text was sitting on a near-white ground.
 *
 * Fixed with a pseudo-element rather than by fighting the cascade. A class on the
 * host cannot affect `::before`, so this needs no `!important` and is not subject to
 * the cascade-layer precedence that makes Bricks' `!important` unbeatable.
 *
 * Values copied exactly from albairaq.css, including the LTR flip — the gradient is
 * directional and does not mirror with `direction`.
 */
.hero__overlay::before {
	content: "";
	position: absolute;
	inset: 0;
	background: linear-gradient( to left, rgba( 4, 8, 17, .88 ) 8%, rgba( 4, 8, 17, .72 ) 46%, rgba( 4, 8, 17, .42 ) 100% );
}

[dir="ltr"] .hero__overlay::before {
	background: linear-gradient( to right, rgba( 4, 8, 17, .88 ) 8%, rgba( 4, 8, 17, .72 ) 46%, rgba( 4, 8, 17, .42 ) 100% );
}

/*
 * ---------------------------------------------------------------------------
 * 5. Bricks pagination  ->  the design system's .pagination / .page-num
 * ---------------------------------------------------------------------------
 *
 * Bricks' pagination element renders WordPress `paginate_links` markup, so the
 * items are `.page-numbers` (with `.current` on the active one and `.prev` /
 * `.next` on the arrows) rather than the design's `.page-num`.
 *
 * The `.pagination` class goes on the element itself, so the flex row, gap and
 * centring come from albairaq.css already; this only restyles the items.
 */
.pagination .page-numbers {
	min-width: 44px;
	height: 44px;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	border: 1px solid var(--line);
	border-radius: 999px;
	font-family: "Inter", var(--font-ar);
	font-weight: 700;
	font-size: 15px;
	color: var(--ink-600);
	background: #fff;
	text-decoration: none;
}

.pagination a.page-numbers:hover {
	border-color: var(--brand-purple);
	color: var(--brand-purple);
	text-decoration: none;
}

.pagination .page-numbers.current {
	background: var(--brand-purple);
	border-color: var(--brand-purple);
	color: #fff;
}

/* Prev / next carry words, not a single digit, so they get the wide treatment. */
.pagination .page-numbers.prev,
.pagination .page-numbers.next {
	padding-inline: var(--s-2);
}

/*
 * ---------------------------------------------------------------------------
 * 6. Filters rendered as links
 * ---------------------------------------------------------------------------
 *
 * The mockup draws the archive filters as `<button>` driven by JetSmartFilters,
 * which is not part of this stack. They are built as real links to the term
 * archives instead, which works with no plugin and degrades gracefully.
 *
 * `.filter` in albairaq.css assumes a button, so an anchor needs the text
 * decoration and line-height normalising to match.
 */
a.filter {
	text-decoration: none;
	display: inline-flex;
	align-items: center;
}

a.filter:hover {
	text-decoration: none;
}

/*
 * ---------------------------------------------------------------------------
 * 7. Declared image placeholder
 * ---------------------------------------------------------------------------
 *
 * Stands in wherever the design expects a photograph and none has been supplied
 * yet, so no image slot is ever a collapsed or blank box.
 *
 * Flat `--brand-purple-soft` with a hairline, deliberately: it is on-palette, it
 * reads as intentional rather than broken, and it introduces no gradient — the
 * design's Don'ts allow gradients only for the hero scrim and the banner glow.
 *
 * Heights mirror the real `img` heights in albairaq.css for each context, so
 * swapping a photo in does not shift the layout.
 */
.ab-ph {
	background: var(--brand-purple-soft);
	border: 1px solid #E6D3E6;
	display: block;
	width: 100%;
}

/* Hero: fills the absolutely-positioned media layer under the scrim. */
.hero__media .ab-ph {
	height: 100%;
	border: 0;
}

/* Wide framed media, e.g. the about split and article leads (1000x520). */
.media .ab-ph {
	aspect-ratio: 1000 / 520;
	border: 0;
}

/* The sticky panel image in the dark "why" section. */
.why__media .ab-ph {
	aspect-ratio: 3 / 4;
	border: 0;
}

/* Card figures, matching each card's fixed image height. */
.card-service__figure .ab-ph {
	height: 150px;
	border: 0;
}

.card-case__figure .ab-ph,
.card-post__figure .ab-ph {
	height: 190px;
	border: 0;
}

/* Featured archive item. */
.feature__media .ab-ph {
	min-height: 320px;
	height: 100%;
	border: 0;
}

/* Client logo tile: sits inside the tile's own border, so no second one. */
.logo-tile .ab-ph {
	height: 48px;
	max-width: 120px;
	border: 0;
}

/* Team portrait. */
.team__photo .ab-ph {
	height: 240px;
	border: 0;
}

/*
 * Contact map. The design styles `.map img { height: 380px }`; the placeholder has to
 * match that height or the bordered `.map` frame collapses to nothing while no map
 * embed exists. `.map` supplies its own border and radius, so this adds neither.
 */
.map .ab-ph {
	height: 380px;
	border: 0;
}

/*
 * ---------------------------------------------------------------------------
 * 5. WPML language switcher  ->  .lang
 * ---------------------------------------------------------------------------
 *
 * Deliberately not written yet. WPML's switcher currently renders a single item
 * because no English translations exist, so any styling would be guesswork against
 * markup that will change shape once a second language has content. The design's
 * `.lang` also shows "AR | EN" rather than native names, which is a WPML display
 * setting, not a CSS problem.
 *
 * Revisit together with the English build.
 */

/*
 * ---------------------------------------------------------------------------
 * 8. Empty-result state
 * ---------------------------------------------------------------------------
 *
 * Bricks has no reliable per-loop "no results" hook we can bind an element
 * condition to — `{query_results_count:<id>}` did not evaluate, so the block showed
 * even when there were hits. CSS can see the DOM truth instead: the block appears
 * only when the grid has no article child other than the query trail.
 *
 * `:has()` is doing real work here, not decoration — it is what makes this
 * dependency-free.
 */
.ab-empty {
	display: none;
}

.grid-3:not( :has( > article:not( .brx-query-trail ) ) ) ~ .ab-empty {
	display: grid;
}

/*
 * A whole section that should not appear until its loop has content.
 *
 * The About page's team section is headed "من سيعمل على ملفك" over a `.team` grid fed by
 * a query loop on the `team_member` CPT, which is empty until the client supplies real
 * people. A heading with nothing under it reads as broken, and inventing placeholder
 * names for a real firm is not acceptable — so the section hides itself instead, and
 * appears the moment the first team member is published. No template edit needed.
 *
 * Bricks always emits `.brx-query-trail` inside the grid, so "empty" means "has no child
 * that is not the trail" — the same test §8 uses.
 */
.ab-team:not( :has( .team > *:not( .brx-query-trail ) ) ) {
	display: none;
}

/*
 * ---------------------------------------------------------------------------
 * 9. Prose list markers for WYSIWYG content
 * ---------------------------------------------------------------------------
 *
 * The design gives every prose list item an inline check icon and no bullet:
 *
 *   .prose ul li  { display: flex; gap: 10px; align-items: flex-start }
 *   .prose ul .icon { width: 18px; height: 18px; margin-block-start: 5px;
 *                     color: var(--brand-purple); flex: none }
 *
 * There is no `list-style` anywhere, so an item without that icon renders with no
 * marker at all — not a fallback bullet, nothing.
 *
 * That matters because these lists come from JetEngine WYSIWYG fields, and **Bricks
 * strips the icon out**. `bricks_render_dynamic_data()` passes the value through
 * `wp_kses_post()`, which does not allow `<svg>`. The markup is stored correctly and
 * `the_content` keeps it — only the dynamic-data path drops it, which is why the
 * field looks right in the editor and wrong on the page. (Verified on
 * `service.whats_included`: stored with 5 icons, rendered with 0.)
 *
 * Rather than allowing `<svg>` through `wp_kses_post` — which widens what any editor
 * can inject sitewide, for a purely visual marker — the icon is redrawn here as a
 * masked `::before`. Two things follow from that, both wanted:
 *
 *   - editors write an ordinary bulleted list in the WYSIWYG and get the designed
 *     marker, with no inline SVG to paste or preserve
 *   - the mask takes its colour from `background-color`, so the marker stays on
 *     `--brand-purple` exactly as `.prose ul .icon` specifies
 *
 * The path, size, offset and colour are copied from albairaq.css. Every `<ul>` in
 * every mockup (Service, Case Study, Blog Post) uses this icon and none uses a plain
 * bullet, so applying it to all prose lists follows the design rather than extending
 * it. `:not(:has(> .icon))` leaves any item that *does* carry a real icon alone, so
 * hand-built Bricks markup never gets a doubled marker.
 */
.prose ul li:not( :has( > .icon ) )::before {
	--ab-check: url( "data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.75' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 6L9 17l-5-5'/%3E%3C/svg%3E" );

	content: "";
	inline-size: 18px;
	block-size: 18px;
	flex: none;
	margin-block-start: 5px;
	background-color: var(--brand-purple);
	-webkit-mask: var( --ab-check ) center / 18px 18px no-repeat;
	mask: var( --ab-check ) center / 18px 18px no-repeat;
}
