/* ==========================================================================
   ALFATH MEDIA — SITE CHROME
   Shared cross-page polish layer: scroll progress, back-to-top, cursor glow,
   magnetic CTAs and page transitions. Purely additive — does not alter any
   selector the CMS content engine binds to.
   ========================================================================== */

/* ---- Scroll progress bar ---- */
.site-scroll-progress {
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 3px;
    z-index: 2000;
    background: transparent;
    pointer-events: none;
}

.site-scroll-progress__bar {
    height: 100%;
    width: 0%;
    background: linear-gradient(90deg, #1A5DAC 0%, #8D1EA4 55%, #9F1850 100%);
    box-shadow: 0 0 12px rgba(26, 93, 172, 0.6);
    transform-origin: left;
    will-change: width;
}

/* ---- Back to top ---- */
.site-back-to-top {
    position: fixed;
    right: 28px;
    bottom: 96px;
    width: 46px;
    height: 46px;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    background: rgba(10, 10, 12, 0.72);
    border: 1px solid rgba(255, 255, 255, 0.18);
    backdrop-filter: blur(10px);
    -webkit-backdrop-filter: blur(10px);
    color: #FFFFFF;
    cursor: pointer;
    z-index: 999;
    opacity: 0;
    visibility: hidden;
    transform: translateY(12px) scale(0.9);
    transition: opacity 0.35s ease, transform 0.35s cubic-bezier(0.34, 1.56, 0.64, 1), visibility 0.35s ease, border-color 0.25s ease, background 0.25s ease;
}

.site-back-to-top.is-visible {
    opacity: 1;
    visibility: visible;
    transform: translateY(0) scale(1);
}

.site-back-to-top:hover {
    border-color: rgba(26, 93, 172, 0.8);
    background: rgba(26, 93, 172, 0.25);
}

.site-back-to-top svg {
    width: 18px;
    height: 18px;
    transition: transform 0.25s ease;
}

.site-back-to-top:hover svg {
    transform: translateY(-2px);
}

@media (max-width: 767px) {
    .site-back-to-top {
        right: 18px;
        bottom: 86px;
        width: 40px;
        height: 40px;
    }
}

/* ---- Cursor glow (desktop hero sections only) ---- */
.site-cursor-glow {
    position: absolute;
    inset: 0;
    z-index: 3;
    pointer-events: none;
    opacity: 0;
    transition: opacity 0.5s ease;
    background: radial-gradient(
        520px circle at var(--glow-x, 50%) var(--glow-y, 50%),
        rgba(26, 93, 172, 0.16),
        rgba(141, 30, 164, 0.08) 40%,
        transparent 70%
    );
    mix-blend-mode: screen;
}

.site-cursor-glow.is-active {
    opacity: 1;
}

/* ---- Magnetic CTA wrapper (JS toggles transform inline; this just adds the easing) ---- */
.site-magnetic {
    transition: transform 0.35s cubic-bezier(0.34, 1.56, 0.64, 1);
    will-change: transform;
}

/* ---- Page transition veil ---- */
.site-page-veil {
    position: fixed;
    inset: 0;
    z-index: 3000;
    background: #000000;
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.28s ease;
}

.site-page-veil.is-active {
    opacity: 1;
    pointer-events: all;
}

body.site-fade-in {
    animation: siteFadeIn 0.45s ease both;
}

@keyframes siteFadeIn {
    from { opacity: 0; }
    to { opacity: 1; }
}

@media (prefers-reduced-motion: reduce) {
    .site-back-to-top,
    .site-magnetic,
    .site-page-veil,
    body.site-fade-in,
    [data-cms-hover] {
        transition: none !important;
        animation: none !important;
    }
}

/* ---- Page Section background layer (admin "Section Style" panel) ----
   Injected only into sections where an admin has configured an image/video
   background + optional overlay — untouched sections are unaffected. Lives
   here (not in cms-engine.js's edit-mode-only injected <style>) because it
   must render for regular site visitors too, not just inside the admin
   editor. The host <section> is switched to position:relative + isolation:
   isolate at the same time this layer is added (see cms-engine.js), which
   scopes this layer's z-index:-1 to just that section so it can never slip
   behind a sibling section or the page background. */
.cms-sec-bg {
    position: absolute;
    inset: 0;
    z-index: -1;
    overflow: hidden;
    pointer-events: none;
}

.cms-sec-bg-media {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    background-size: cover;
    background-position: center;
    background-repeat: no-repeat;
    object-fit: cover;
    border: 0;
    display: block;
}

.cms-sec-bg-overlay {
    position: absolute;
    inset: 0;
    pointer-events: none;
}

/* ==========================================================================
   CMS CONTENT BLOCKS — the admin's Elementor-style widgets (Heading, Image,
   Button, Divider, Spacer, Video, YouTube, Maps, Container, Flexbox, Grid,
   Tabs, Icon), inserted via the 🧩 "Add Widget" button on a Page Section's
   or another Content Block's hover toolbar in the admin editor. Public,
   always-loaded styling — see assets/js/cms-engine.js's buildWidgetBlock()
   for the markup these rules target. Purely additive, same as the rest of
   this file: nothing here changes any pre-existing selector.
   ========================================================================== */
.cms-block { position: relative; max-width: 100%; }
.cms-block + .cms-block { margin-top: 24px; }

/* Boxed width — matches the max-width/centering/gutter pattern every
   hand-built section on this site already uses (see e.g. .who-we-are-container,
   .solutions-container, .cta-container in home.css: max-width 1440px,
   centered, 4vw side padding). Applied to a Content Block that sits
   directly in a Page Section when the admin wants it to line up with the
   rest of the page instead of stretching edge-to-edge full width (the
   default for a brand-new widget — see insertWidget() in cms-engine.js).
   Toggled per widget via the ⬚ button on its hover toolbar. Only relevant
   at the top level: a widget nested inside a Container/Flexbox/Grid
   already takes its width from that parent, so this class is not offered
   there. */
.cms-block-boxed {
    max-width: 1440px;
    margin-left: auto;
    margin-right: auto;
    padding-left: 4vw;
    padding-right: 4vw;
    box-sizing: border-box;
}

/* Drop Shadow presets (✨ Animation panel's "Drop Shadow" group in
   cms-engine.js) — a plain attribute-driven set of static box-shadow
   looks. Deliberately pure CSS, no JS beyond setting
   data-cms-shadow="<key>" on the block: nothing to bind, nothing that can
   break if a script fails to load. "none" needs no rule — a block simply
   has no box-shadow by default. */
[data-cms-shadow="soft"]   { box-shadow: 0 4px 14px rgba(0, 0, 0, .08); }
[data-cms-shadow="medium"] { box-shadow: 0 10px 28px rgba(0, 0, 0, .16); }
[data-cms-shadow="strong"] { box-shadow: 0 18px 44px rgba(0, 0, 0, .26); }
[data-cms-shadow="lifted"] { box-shadow: 0 24px 60px rgba(0, 0, 0, .2); }
[data-cms-shadow="glow"]   { box-shadow: 0 0 34px rgba(26, 93, 172, .38); }

/* Hover Animation presets (✨ Animation panel's "Hover Animation" group) —
   same attribute-driven, pure-CSS approach as Drop Shadow above: a
   transform/box-shadow transition on :hover needs no JS binding at all,
   so unlike the scroll-in reveal above it never depends on GSAP having
   loaded, and there's nothing to rebind after undo/redo or a fresh page
   load — the attribute alone is the whole mechanism. Every
   [data-cms-hover] block gets the same transition regardless of which
   preset it uses, so switching presets never has to also touch a
   duration/easing rule.
   cubic-bezier(0.25, 1, 0.5, 1) is the site's actual dominant hover
   curve — it's what .btn-primary/.btn-secondary already use site-wide
   (home/contact/portfolio CSS) and appears on interactive elements
   roughly 16x more often than the bouncier overshoot curve used on
   .site-magnetic/.site-back-to-top above, which is reserved for small
   chrome controls rather than page content. 0.4s sits at the slower end
   of that same curve's real usage on this site (buttons run it at 0.3s;
   0.4s is the site's other common pairing, and reads noticeably calmer
   for a bigger content block than a small button needs) — bumped up from
   0.3s after the .3s version still felt too quick on a whole block.
   box-shadow keeps a plain "ease" curve to match how the site treats
   non-transform hover properties (color/background/box-shadow)
   elsewhere. will-change:transform hints the browser to composite the
   hover motion on its own layer — the same trick .site-magnetic above
   already relies on — so the transition stays smooth rather than
   occasionally dropping frames on a heavier block. */
[data-cms-hover] {
    transition: transform 0.4s cubic-bezier(0.25, 1, 0.5, 1), box-shadow 0.4s ease;
    will-change: transform;
}

[data-cms-hover="lift"]:hover   { transform: translateY(-8px); }
[data-cms-hover="grow"]:hover   { transform: scale(1.045); }
[data-cms-hover="shrink"]:hover { transform: scale(0.96); }
[data-cms-hover="tilt"]:hover   { transform: rotate(-1.5deg) scale(1.02); }
[data-cms-hover="glow"]:hover   { box-shadow: 0 0 30px rgba(26, 93, 172, .45); }

.cms-block-heading .cms-block-inner,
.cms-block-text .cms-block-inner {
    margin: 0;
}

.cms-block-image .cms-block-img-el {
    max-width: 100%;
    height: auto;
    display: block;
}

/* Corners and Borders presets (✨ Animation panel's "Corners"/"Borders"
   groups — see RADIUS_PRESETS/BORDER_PRESETS and
   applyBlockRadius()/applyBlockBorder() in cms-engine.js). Pure CSS,
   attribute-driven like Drop Shadow/Hover Animation above — available on
   EVERY Content Block (Heading, Image, Button, Container, Video, ...), not
   just one widget type. box-sizing: border-box on the border presets keeps
   an added border inset within the block's own max-width instead of
   pushing it past its container's edge.
   Radii are matched to values already used on the site's own imagery
   (home.css's 24px "Premium rounded corners" cards, 20px card photos) so a
   rounded widget looks native next to them; "circle" is the plain 50%
   used for every avatar/logo roundel elsewhere on the site.
   Border presets go from a subtle neutral outline up to "Framed" — an
   8px solid white border, the same "framed photo" look about.css already
   uses (5px solid white) on the Who We Are portrait, just sized to read
   clearly at arbitrary widget widths — and "Accent", 3px of the site's
   own primary blue (#1A5DAC), matching the "Thin Primary Blue Border"
   already used on interactive cards in home.css. */
[data-cms-radius="small"]  { border-radius: 10px; }
[data-cms-radius="medium"] { border-radius: 20px; }
[data-cms-radius="large"]  { border-radius: 28px; }
[data-cms-radius="circle"] { border-radius: 50%; }

[data-cms-border] { box-sizing: border-box; }
[data-cms-border="thin"]   { border: 1px solid rgba(0, 0, 0, .14); }
[data-cms-border="medium"] { border: 3px solid rgba(0, 0, 0, .18); }
[data-cms-border="thick"]  { border: 6px solid rgba(0, 0, 0, .22); }
[data-cms-border="framed"] { border: 8px solid #ffffff; box-shadow: 0 2px 10px rgba(0, 0, 0, .12); }
[data-cms-border="accent"] { border: 3px solid #1A5DAC; }

/* A Corners radius on the plain block wrapper above doesn't, by itself,
   visually clip an edge-to-edge media element sitting inside it (Image/
   Video/YouTube/Maps) — the wrapper would show rounded corners with a
   rectangular photo or embed still poking past them. Mirror the same
   radius directly onto those "filled" inner elements too so the actual
   media clips to match — border-radius on a replaced element like <img>
   or an <iframe> clips its own painted content directly, no
   overflow:hidden required. Text-only widgets (Heading, Button, ...) have
   no such inner element, so the wrapper rule above is already the whole
   effect for them. */
[data-cms-radius="small"]  .cms-block-img-el,
[data-cms-radius="small"]  .cms-block-video-el,
[data-cms-radius="small"]  .cms-block-yt-el,
[data-cms-radius="small"]  .cms-block-maps-el,
[data-cms-radius="small"]  .cms-media-placeholder { border-radius: 10px; }
[data-cms-radius="medium"] .cms-block-img-el,
[data-cms-radius="medium"] .cms-block-video-el,
[data-cms-radius="medium"] .cms-block-yt-el,
[data-cms-radius="medium"] .cms-block-maps-el,
[data-cms-radius="medium"] .cms-media-placeholder { border-radius: 20px; }
[data-cms-radius="large"]  .cms-block-img-el,
[data-cms-radius="large"]  .cms-block-video-el,
[data-cms-radius="large"]  .cms-block-yt-el,
[data-cms-radius="large"]  .cms-block-maps-el,
[data-cms-radius="large"]  .cms-media-placeholder { border-radius: 28px; }
[data-cms-radius="circle"] .cms-block-img-el,
[data-cms-radius="circle"] .cms-block-video-el,
[data-cms-radius="circle"] .cms-block-yt-el,
[data-cms-radius="circle"] .cms-block-maps-el,
[data-cms-radius="circle"] .cms-media-placeholder { border-radius: 50%; }

/* The Button widget's default look is a direct copy of the real
   "Explore All Services" button already on the homepage (.btn-primary-blue
   in home.css) — same font, padding, pill radius, solid blue fill, lift +
   darken on hover, and the arrow micro-interaction — so a newly-inserted
   Button widget reads as a native part of the site rather than a generic
   CMS default. --cms-btn-bg/--cms-btn-bg-hover are CSS custom properties
   rather than plain background-color so the Button Style panel's per-block
   Normal/Hover color pickers (see setButtonBg()/setButtonBgHover() in
   cms-engine.js) can override just ONE block's colors via a plain inline
   style, while still correctly feeding the :hover rule below — a bare
   inline background-color could never do that, since inline styles have no
   way to express a pseudo-class-only value, but a custom property
   substitutes at compute time and so applies equally under :hover. Radius
   and stroke are deliberately plain inline border-radius/border on this
   same element (not the generic [data-cms-radius]/[data-cms-border]
   attribute system a couple hundred lines up) — that system targets the
   invisible wrapper .cms-block, which would have no visible effect on a
   Button's own inline-flex pill, and would otherwise silently fight the
   Button Style panel over the same CSS properties. */
.cms-block-btn-el {
    font-family: var(--font-body, inherit);
    font-size: 1rem;
    font-weight: 500;
    color: var(--primary-white, #fff);
    background-color: var(--cms-btn-bg, #1A5DAC);
    text-decoration: none;
    padding: 16px 36px;
    border-radius: 50px;
    display: inline-flex;
    align-items: center;
    gap: 12px;
    transition: all 0.3s cubic-bezier(0.25, 1, 0.5, 1);
    box-shadow: 0 6px 20px rgba(26, 93, 172, 0.3);
}

.cms-block-btn-el .cms-btn-arrow {
    transition: transform 0.3s ease;
}

.cms-block-btn-el:hover {
    background-color: var(--cms-btn-bg-hover, #144988);
    transform: translateY(-3px);
    box-shadow: 0 10px 30px rgba(26, 93, 172, 0.45);
}

.cms-block-btn-el:hover .cms-btn-arrow {
    transform: translateX(4px);
}

/* Button Shapes — ✨ Block Effects' "Shapes" group, Button blocks only (see
   the .anp-only-button toggle in cms-engine.js's refreshAnimPickerActive()).
   Six quick-pick silhouettes for .cms-block-btn-el, keyed off data-cms-shape
   on the wrapping .cms-block — same attribute-driven, zero-JS-binding
   mechanism as [data-cms-radius]/[data-cms-border] above, just scoped to
   this one widget type instead of universal, and deliberately living down
   here next to the button's own rules rather than up with that generic
   system (same reasoning as the Button Style panel's inline radius/border:
   a rule up there targets the invisible .cms-block wrapper, which has no
   visible effect on this element's own inline-flex pill). "Pill" is the
   button's own built-in default look (border-radius: 50px above), so it
   needs no override rule here — only the five that change that default get
   one. Cut Corner uses clip-path instead of border-radius so it reads as a
   genuinely different silhouette, not just a smaller radius. Circle fixes
   the button to an equal width/height, centers the arrow, and visually
   hides the text label (kept in the DOM/still readable to screen readers —
   see .cms-btn-label below — rather than removed, so the link keeps a real
   accessible name) so it reads as a small round icon button. */
[data-cms-shape="square"] .cms-block-btn-el { border-radius: 0; }
[data-cms-shape="soft"] .cms-block-btn-el { border-radius: 4px; }
[data-cms-shape="rounded"] .cms-block-btn-el { border-radius: 12px; }
[data-cms-shape="cut"] .cms-block-btn-el {
    border-radius: 0;
    clip-path: polygon(14px 0, 100% 0, 100% calc(100% - 14px), calc(100% - 14px) 100%, 0 100%, 0 14px);
}
[data-cms-shape="circle"] .cms-block-btn-el {
    border-radius: 50%;
    width: 56px;
    height: 56px;
    padding: 0;
    gap: 0;
    justify-content: center;
}
[data-cms-shape="circle"] .cms-block-btn-el .cms-btn-label {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}

.cms-block-divider-el {
    border: none;
    border-top: 1px solid rgba(0, 0, 0, .12);
    margin: 0;
}

.cms-block-spacer-el {
    height: 40px;
}

.cms-media-placeholder {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 8px;
    background: #eef1f5;
    border: 1px dashed #b7bfca;
    border-radius: 8px;
    padding: 48px 20px;
    color: #6b7280;
    font-family: Arial, sans-serif;
    font-size: 13px;
    text-align: center;
}

.cms-media-ph-icon {
    font-size: 28px;
}

.cms-block-video-el,
.cms-block-yt-el,
.cms-block-maps-el {
    width: 100%;
    aspect-ratio: 16 / 9;
    border: 0;
    display: block;
    border-radius: 8px;
}

/* Gallery widget (🧩 Add Widget → Gallery — see buildWidgetBlock()'s
   'gallery' case / renderGalleryWidgetThumbs() in cms-engine.js). No
   existing "photo gallery grid" component exists elsewhere on the site to
   copy verbatim (the homepage Solutions panel is a single hover-swap image,
   not a grid; portfolio.php's editorial grid has no lightbox), so this grid
   is new — but its hover language (lift + zoom + blue accent) matches the
   site's own established conventions, e.g. home.css's .preview-thumb and
   portfolio.css's .grid-item hover treatments. The actual click-to-enlarge
   behavior comes entirely from gallery-lightbox.js/.css's already-shipped
   .af-lightbox* fullscreen viewer — nothing here duplicates that, this is
   just the grid of trigger thumbnails that opens it. */
.cms-block-gallery-el {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
    gap: 14px;
}

.cms-gallery-thumb {
    position: relative;
    display: block;
    width: 100%;
    aspect-ratio: 1 / 1;
    padding: 0;
    border: 0;
    border-radius: 10px;
    overflow: hidden;
    background: #111111;
    cursor: zoom-in;
    box-shadow: 0 4px 14px rgba(0, 0, 0, .18);
    transition: transform .25s ease, box-shadow .25s ease;
}

.cms-gallery-thumb img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
    transition: transform .4s ease;
}

.cms-gallery-thumb:hover {
    transform: translateY(-4px);
    box-shadow: 0 10px 26px rgba(26, 93, 172, .35);
}

.cms-gallery-thumb:hover img {
    transform: scale(1.06);
}

.cms-block-container-el {
    min-height: 60px;
}

/* Multi-column Container (see buildWidgetBlock()'s 'container' case in
   cms-engine.js) — a plain 1-column Container never gets this class, so it
   keeps using the min-height rule above unchanged. Columns are always
   equal-width for v1 (no asymmetric ratios), matching flex/basis 200px so
   they wrap into a single stacked column on narrow screens the same way
   .cms-block-flex-el already does. */
.cms-block-container-el.cms-block-container-cols {
    display: flex;
    flex-wrap: wrap;
    gap: 16px;
    min-height: 0;
}

.cms-block-col {
    flex: 1 1 200px;
    min-width: 0;
}

/* The per-column "+ add widget" button only exists for the admin editor
   (see refreshBlockEditables() in cms-engine.js, which also strips it back
   out before anything is saved) — hidden here as a defensive fallback in
   case it's ever present in markup a visitor sees. */
.cms-col-add-btn {
    display: none;
}

.cms-block-flex-el {
    display: flex;
    gap: 16px;
    flex-wrap: wrap;
    min-height: 60px;
}

.cms-block-flex-el > .cms-block {
    flex: 1 1 200px;
}

.cms-block-grid-el {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
    gap: 16px;
    min-height: 60px;
}

.cms-block-icon-el {
    display: inline-block;
    width: 40px;
    height: 40px;
    color: var(--primary-blue, #1A5DAC);
}

.cms-block-icon-el svg {
    width: 100%;
    height: 100%;
    display: block;
}

/* Tabs — pure CSS, radio-driven, no JavaScript needed so it also works the
   same way whether it was just inserted or restored from saved content. */
.cms-tab-radio {
    position: absolute;
    opacity: 0;
    pointer-events: none;
}

.cms-tabs-nav {
    display: flex;
    gap: 8px;
    border-bottom: 2px solid rgba(0, 0, 0, .1);
    margin-bottom: 16px;
    flex-wrap: wrap;
}

.cms-tab-label {
    padding: 10px 18px;
    cursor: pointer;
    font-weight: 600;
    color: #6b7280;
    border-bottom: 2px solid transparent;
    margin-bottom: -2px;
}

.cms-tab-panel {
    display: none;
}

.cms-tab-radio:nth-of-type(1):checked ~ .cms-tab-panel-1 { display: block; }
.cms-tab-radio:nth-of-type(2):checked ~ .cms-tab-panel-2 { display: block; }

.cms-tabs:has(.cms-tab-radio:nth-of-type(1):checked) .cms-tabs-nav .cms-tab-label:nth-of-type(1),
.cms-tabs:has(.cms-tab-radio:nth-of-type(2):checked) .cms-tabs-nav .cms-tab-label:nth-of-type(2) {
    color: var(--primary-blue, #1A5DAC);
    border-bottom-color: var(--primary-blue, #1A5DAC);
}
