/* =========================================================================
   Alrasly — reusable presentation components (site-wide). Loaded on every page
   after main.css. Two components, both documented in CLAUDE.md §18:
     .al-duo  — duotone image block (photo + brand-colour/grid overlay that
                clears on hover/focus; permanent scrim for AAA text).
     .al-flow — single-rail process infographic (one in-flow rail, pulse-by-%,
                scales to any step count, stacks to a vertical timeline). An
                .al-flow--on-dark variant reads against dark surfaces.
   Palette only via tokens, radius 0, squares only, AAA. Reveal reuses the
   sitewide reveal.js observer (the .is-visible class it adds). Extracted from
   services.css so the homepage and future pages can reuse them.
   ========================================================================= */

/* component-shared easing + the navy-duotone placeholder (the established
   hero-gradient navy shades, same as service.css .svc-ph / .svc-hero). */
:root{
	--al-ease:cubic-bezier(.16,1,.3,1);
	--al-duo-fallback:linear-gradient(135deg,#211d4e,#292561);
}

/* =========================================================================
   COMPONENT 1 — .al-duo  (duotone image block)
   ========================================================================= */
.al-duo{
	position:relative; display:block; overflow:hidden; isolation:isolate;
	color:var(--white); border:1px solid rgba(41,37,97,.12); text-decoration:none;
	--al-duo-grid:rgba(255,255,255,.14);
	--al-duo-ov-rest:.58; /* rest brand-tint opacity: photo reads through the duotone. Hover clears further (wrapper → .18). */
}
/* z0 — photo. --al-duo-img (CSS background) or the duotone placeholder; when a
   responsive base name is supplied the helper layers .al-duo__img (a real <img>
   with srcset + lazy-load) on top, using this same duotone as its loading fallback. */
.al-duo__photo{
	position:absolute; inset:0; z-index:0; background-size:cover; background-position:center;
	background-image:var(--al-duo-img,var(--al-duo-fallback));
	filter:saturate(.7) brightness(.9);
	transition:filter .45s var(--al-ease), transform .6s var(--al-ease);
}
/* z0 — responsive photo (srcset/lazy). Sits over the duotone placeholder, under the overlay. */
.al-duo__img{
	position:absolute; inset:0; z-index:0; width:100%; height:100%;
	object-fit:cover; object-position:center; display:block;
	filter:saturate(.7) brightness(.9);
	transition:filter .45s var(--al-ease), transform .6s var(--al-ease);
}
/* z1 — brand-colour fill + square-grid texture (the resting "square" look) */
.al-duo__overlay{ position:absolute; inset:0; z-index:1; transition:opacity .45s var(--al-ease); }
.al-duo__overlay::before{ content:""; position:absolute; inset:0; background:var(--al-duo-ov,var(--navy)); opacity:var(--al-duo-ov-rest); }
.al-duo__overlay::after{
	content:""; position:absolute; inset:0;
	background-image:linear-gradient(var(--al-duo-grid) 1px,transparent 1px),linear-gradient(90deg,var(--al-duo-grid) 1px,transparent 1px);
	background-size:22px 22px;
}
.al-duo--navy{ --al-duo-ov:var(--navy); }
.al-duo--blue{ --al-duo-ov:var(--blue); }
.al-duo--purple{ --al-duo-ov:var(--purple-blue); }
/* z2 — PERMANENT dark scrim: the AAA-legibility guarantee (stays even when overlay clears) */
.al-duo__scrim{ position:absolute; inset:0; z-index:2; background:linear-gradient(to top,rgba(20,18,48,.92) 0%,rgba(20,18,48,.45) 34%,transparent 62%); }
/* z3 — text */
.al-duo__txt{ position:absolute; z-index:3; left:0; right:0; bottom:0; padding:var(--space-6); transition:padding .45s var(--al-ease); }
.al-duo__name{ font-size:clamp(1.4rem,1.1rem + 1vw,1.9rem); line-height:1.1; font-weight:var(--fw-bold); color:var(--white); margin:0 0 6px; transition:font-size .45s var(--al-ease); }
.al-duo__tag{ font-size:var(--fs-small); line-height:var(--lh-small); color:rgba(255,255,255,.9); margin:0; max-height:60px; opacity:1; overflow:hidden; transition:opacity .35s var(--al-ease), max-height .45s var(--al-ease), margin .45s var(--al-ease); }
.al-duo__more{ display:inline-block; margin-top:var(--space-3); font-size:var(--fs-small); font-weight:var(--fw-bold); color:var(--sky); opacity:0; transform:translateY(6px); transition:opacity .4s var(--al-ease), transform .4s var(--al-ease); }

/* hover + focus: colour clears to the photo, name shrinks + tucks to the corner,
   tagline collapses, "Learn more" appears */
.al-duo:hover .al-duo__overlay,
.al-duo:focus-visible .al-duo__overlay{ opacity:.18; }
.al-duo:hover .al-duo__photo,
.al-duo:focus-visible .al-duo__photo,
.al-duo:hover .al-duo__img,
.al-duo:focus-visible .al-duo__img{ filter:saturate(1.05) brightness(1); transform:scale(1.04); }
.al-duo:hover .al-duo__txt,
.al-duo:focus-visible .al-duo__txt{ padding:var(--space-4); }
.al-duo:hover .al-duo__name,
.al-duo:focus-visible .al-duo__name{ font-size:var(--fs-body); }
.al-duo:hover .al-duo__tag,
.al-duo:focus-visible .al-duo__tag{ opacity:0; max-height:0; margin:0; }
.al-duo:hover .al-duo__more,
.al-duo:focus-visible .al-duo__more{ opacity:1; transform:none; }
/* square focus ring — sky for contrast on the dark image cards (blue fails on the navy/blue fills) */
.al-duo:focus-visible{ outline:2px solid var(--sky); outline-offset:2px; }

/* square variant (service grids) */
.al-duo--square{ aspect-ratio:1/1; }

/* teaser variant (full-width image band; centred text; sky CTA chip).
   Richer, more photographic placeholder than the flat navy-duotone (mockup values)
   until a real photo drops into --al-duo-img; the resting overlay is lighter here
   so the image reads through — text stays AAA via the dark-navy base + scrim. */
.al-duo--teaser{
	min-height:clamp(300px,30vw,380px); --al-duo-grid:rgba(174,234,253,.12);
	--al-duo-fallback:
		radial-gradient(70% 130% at 78% 25%,#4a59b0,transparent 60%),
		radial-gradient(60% 120% at 18% 80%,#3a2f8c,transparent 60%),
		linear-gradient(120deg,#23204f,#292561 55%,#15122e);
}
.al-duo--teaser{ --al-duo-ov-rest:.6; } /* centered text over a weaker radial scrim — keep the tint a touch higher */
.al-duo--teaser .al-duo__scrim{ background:radial-gradient(120% 120% at 50% 50%,rgba(18,16,42,.35),rgba(18,16,42,.82)); }
.al-duo--teaser .al-duo__txt{ position:absolute; inset:0; display:flex; flex-direction:column; align-items:center; justify-content:center; text-align:center; padding:var(--space-8) var(--space-6); }
.al-duo--teaser .al-duo__kick{ font-size:var(--fs-caption); font-weight:var(--fw-bold); letter-spacing:.14em; text-transform:uppercase; color:var(--sky); margin-bottom:var(--space-4); }
[dir="rtl"] .al-duo--teaser .al-duo__kick{ letter-spacing:normal; text-transform:none; }
.al-duo--teaser .al-duo__h2{ font-size:var(--fs-h2); line-height:var(--lh-h2); font-weight:var(--fw-bold); color:var(--white); max-width:20ch; margin:0; letter-spacing:-.4px; }
.al-duo--teaser .al-duo__body{ font-size:var(--fs-body-lg); line-height:var(--lh-body); color:rgba(255,255,255,.88); max-width:54ch; margin:var(--space-4) 0 0; }
.al-duo--teaser .al-duo__go{ display:inline-block; margin-top:var(--space-6); padding:var(--space-3) var(--space-6); background:var(--sky); color:var(--navy); font-weight:var(--fw-bold); font-size:var(--fs-body); transition:transform .3s var(--al-ease); }
.al-duo--teaser:hover .al-duo__go,
.al-duo--teaser:focus-visible .al-duo__go{ transform:translateX(4px); }

/* =========================================================================
   COMPONENT 2 — .al-flow  (single-rail process infographic)
   --al-steps (set inline) drives the rail inset (50%/steps) so it scales to any
   step count. The rail is the ONLY positioned decorative element (one full-bleed
   line, ::before); the pulse (::after) rides it by % and never reads node positions.
   ========================================================================= */
.al-flow{
	--al-tile:72px; --al-steps:4;
	position:relative; display:grid; grid-template-columns:repeat(var(--al-steps),1fr);
	gap:var(--space-5); margin:var(--space-8) 0 0; padding:0; list-style:none;
}
/* the single in-flow rail — spans first→last node centre */
.al-flow::before{
	content:""; position:absolute; z-index:0;
	top:calc(var(--al-tile) / 2); height:2px;
	left:calc(50% / var(--al-steps)); right:calc(50% / var(--al-steps));
	background:var(--navy);
}
/* the travelling pulse — rides the rail by % only */
.al-flow::after{
	content:""; position:absolute; z-index:1; opacity:0;
	top:calc(var(--al-tile) / 2 - 6px); left:calc(50% / var(--al-steps));
	width:12px; height:12px; background:var(--sky);
}
.al-flow.is-visible::after{ animation:al-flow-travel 2.2s var(--al-ease) .3s forwards; }
@keyframes al-flow-travel{
	0%{ left:calc(50% / var(--al-steps)); opacity:1; }
	92%{ opacity:1; }
	100%{ left:calc(100% - 50% / var(--al-steps)); opacity:0; }
}

.al-flow__step{ position:relative; z-index:2; text-align:center; margin:0; }
.al-flow__tile{ position:relative; width:var(--al-tile); height:var(--al-tile); margin:0 auto var(--space-4); display:grid; place-items:center; }
.al-flow__tile--navy{ background:var(--navy); }
.al-flow__tile--blue{ background:var(--blue); }
.al-flow__tile--purple{ background:var(--purple-blue); }
.al-flow__tile--sky{ background:var(--sky); }
/* icon = committed Lucide glyph via mask (recoloured, not edited) */
.al-flow__ic{ width:30px; height:30px; background:var(--white); -webkit-mask:center / contain no-repeat; mask:center / contain no-repeat; }
.al-flow__tile--sky .al-flow__ic{ background:var(--navy); } /* navy glyph on sky (§5) */
/* small square number badge — positioned within its own tile (its containing block) */
.al-flow__num{ position:absolute; top:-9px; inset-inline-end:-9px; width:24px; height:24px; background:var(--white); border:1px solid rgba(41,37,97,.12); display:grid; place-items:center; font-size:var(--fs-caption); font-weight:var(--fw-bold); color:var(--navy); }
.al-flow__title{ font-size:var(--fs-h4); line-height:var(--lh-h4); font-weight:var(--fw-bold); color:var(--navy); margin:0 0 6px; }
.al-flow__desc{ font-size:var(--fs-small); line-height:var(--lh-small); color:var(--ink); margin:0; }

/* on-dark variant — legible on a dark surface: translucent light rail, a visible
   edge on the first (navy) node, white labels/descriptions. Nodes stay opaque; the
   white number badges + sky pulse already read on dark. */
.al-flow--on-dark::before{ background:rgba(255,255,255,.22); }
.al-flow--on-dark .al-flow__tile--navy{ outline:1px solid rgba(255,255,255,.30); outline-offset:-1px; }
.al-flow--on-dark .al-flow__title{ color:var(--white); }
.al-flow--on-dark .al-flow__desc{ color:rgba(255,255,255,.8); }

/* reveal: the flow container stays put (so the pulse fires on .is-visible) and its
   nodes stagger in. Uses the sitewide reveal.js + main.css [data-reveal] base. */
.js .al-flow[data-reveal]{ opacity:1; transform:none; transition:none; }
.js .al-flow[data-reveal] .al-flow__step{ opacity:0; transform:translateY(12px); transition:opacity .25s ease, transform .25s ease; }
.js .al-flow[data-reveal].is-visible .al-flow__step{ opacity:1; transform:none; }
.js .al-flow[data-reveal].is-visible .al-flow__step:nth-child(2){ transition-delay:.06s; }
.js .al-flow[data-reveal].is-visible .al-flow__step:nth-child(3){ transition-delay:.12s; }
.js .al-flow[data-reveal].is-visible .al-flow__step:nth-child(4){ transition-delay:.18s; }
.js .al-flow[data-reveal].is-visible .al-flow__step:nth-child(5){ transition-delay:.24s; }
.js .al-flow[data-reveal].is-visible .al-flow__step:nth-child(6){ transition-delay:.30s; }

/* .al-flow collapses to a vertical left-rail timeline at ≤760px OR when forced
   (step count ≥6 → .al-flow--stack). Same component, stacked. */
@media (max-width:760px){
	.al-flow{ grid-template-columns:1fr; gap:var(--space-6); }
	.al-flow::before{ top:0; bottom:0; height:auto; left:calc(var(--al-tile) / 2); right:auto; width:2px; }
	.al-flow::after{ display:none; }
	.al-flow__step{ display:grid; grid-template-columns:var(--al-tile) 1fr; gap:var(--space-4); align-items:start; text-align:left; }
	.al-flow__tile{ margin:0; }
}
.al-flow--stack{ grid-template-columns:1fr; gap:var(--space-6); }
.al-flow--stack::before{ top:0; bottom:0; height:auto; left:calc(var(--al-tile) / 2); right:auto; width:2px; }
.al-flow--stack::after{ display:none; }
.al-flow--stack .al-flow__step{ display:grid; grid-template-columns:var(--al-tile) 1fr; gap:var(--space-4); align-items:start; text-align:left; }
.al-flow--stack .al-flow__tile{ margin:0; }

/* =========================================================================
   COMPONENT 3 — .al-mosaic  (square-grid image reveal; page-agnostic)
   A 6×6 grid of navy squares over a photo, inside its own card. At rest the
   squares sit at .72 opacity (image reads navy-duotone). On hover/focus of the
   mosaic OR its interactive host (.al-mosaic-host) the squares clear (opacity 0,
   scale .82) staggered diagonally by index, and the photo scales + saturates.
   Each square is a CSS-grid cell — it never reads another element's position.
   ========================================================================= */
.al-mosaic{
	--al-mosaic-fallback:linear-gradient(135deg,#211d4e,#292561);
	position:relative; display:block; overflow:hidden; isolation:isolate;
	width:100%; height:100%; background:var(--navy);
}
/* z0 — photo (per-item --al-mosaic-img, else the navy-duotone placeholder). When a
   responsive base name is supplied the helper layers .al-mosaic__img (a real <img>
   with srcset + lazy) on top, using this same duotone as its loading fallback. */
.al-mosaic__photo{
	position:absolute; inset:0; z-index:0; background-size:cover; background-position:center;
	background-image:var(--al-mosaic-img,var(--al-mosaic-fallback));
	filter:saturate(.75) brightness(.92);
	transition:filter .5s var(--al-ease), transform .6s var(--al-ease);
}
/* z0 — responsive photo (srcset/lazy). Over the duotone placeholder, under the grid. */
.al-mosaic__img{
	position:absolute; inset:0; z-index:0; width:100%; height:100%;
	object-fit:cover; object-position:center; display:block;
	filter:saturate(.75) brightness(.92);
	transition:filter .5s var(--al-ease), transform .6s var(--al-ease);
}
/* z1 — the 6×6 navy grid */
.al-mosaic__grid{ position:absolute; inset:0; z-index:1; display:grid; grid-template-columns:repeat(6,1fr); grid-template-rows:repeat(6,1fr); }
.al-mosaic__grid i{
	display:block; background:var(--navy); opacity:.72; transform-origin:center;
	transition:opacity .4s var(--al-ease), transform .4s var(--al-ease);
	transition-delay:calc((var(--c) + var(--r)) * 18ms);
}
.al-mosaic--blue .al-mosaic__grid i{ background:var(--blue); }
.al-mosaic--purple .al-mosaic__grid i{ background:var(--purple-blue); }
/* z2 — optional caller text (index number, etc.) sits above the grid */
.al-mosaic__txt{ position:absolute; inset:0; z-index:2; }

/* reveal on hover/focus of the mosaic OR its interactive host */
.al-mosaic:hover .al-mosaic__grid i,
.al-mosaic:focus-visible .al-mosaic__grid i,
.al-mosaic-host:hover .al-mosaic__grid i,
.al-mosaic-host:focus-visible .al-mosaic__grid i{ opacity:0; transform:scale(.82); }
.al-mosaic:hover .al-mosaic__photo,
.al-mosaic:focus-visible .al-mosaic__photo,
.al-mosaic-host:hover .al-mosaic__photo,
.al-mosaic-host:focus-visible .al-mosaic__photo,
.al-mosaic:hover .al-mosaic__img,
.al-mosaic:focus-visible .al-mosaic__img,
.al-mosaic-host:hover .al-mosaic__img,
.al-mosaic-host:focus-visible .al-mosaic__img{ filter:saturate(1) brightness(1); transform:scale(1.05); }

/* component-level reduced-motion (final states; no hover transforms; no pulse) */
@media (prefers-reduced-motion:reduce){
	.al-duo__photo,.al-duo__img,.al-duo__overlay,.al-duo__txt,.al-duo__name,.al-duo__tag,.al-duo__more,.al-duo--teaser .al-duo__go{ transition:none !important; }
	.al-duo:hover .al-duo__photo,.al-duo:focus-visible .al-duo__photo,.al-duo:hover .al-duo__img,.al-duo:focus-visible .al-duo__img{ transform:none; }
	.al-flow.is-visible::after{ animation:none; opacity:0; }
	.js .al-flow[data-reveal] .al-flow__step{ opacity:1 !important; transform:none !important; transition:none !important; }
	/* mosaic: no transitions; squares stay at rest opacity (image stays duotone) */
	.al-mosaic__photo,.al-mosaic__img,.al-mosaic__grid i{ transition:none !important; }
	.al-mosaic:hover .al-mosaic__grid i,.al-mosaic:focus-visible .al-mosaic__grid i,
	.al-mosaic-host:hover .al-mosaic__grid i,.al-mosaic-host:focus-visible .al-mosaic__grid i{ opacity:.72; transform:none; }
	.al-mosaic:hover .al-mosaic__photo,.al-mosaic:focus-visible .al-mosaic__photo,
	.al-mosaic-host:hover .al-mosaic__photo,.al-mosaic-host:focus-visible .al-mosaic__photo,
	.al-mosaic:hover .al-mosaic__img,.al-mosaic:focus-visible .al-mosaic__img,
	.al-mosaic-host:hover .al-mosaic__img,.al-mosaic-host:focus-visible .al-mosaic__img{ transform:none; filter:saturate(.75) brightness(.92); }
}
