/* Typography roles: Bangla prose uses the supplied Kalpurush font; titles use Hind. */
@font-face{font-family:Kalpurush;src:url('/fonts/Kalpurush.ttf') format('truetype');font-weight:400;font-style:normal;font-display:swap}
html[lang=bn] .refresh-site{font-family:Kalpurush,sans-serif!important;font-size:18px;line-height:1.85}
html[lang=bn] .refresh-site :is(p,li,td,label,input,textarea,select,.entry-excerpt,.uvc-sub-heading,.aio-icon-description){font-family:Kalpurush,sans-serif!important}
html[lang=bn] .refresh-site :is(h1,h2,h3,h4,h5,h6,.uvc-main-heading,.widget-title,.section-title,.eyebrow,.refresh-eyebrow,.refresh-header,.refresh-header a,.refresh-header summary,.refresh-menu-button,th){font-family:'Hind Siliguri',sans-serif!important}
html[lang=en] .refresh-site :is(p,li,h1,h2,h3,h4,h5,h6,button,input,select,textarea,td,th,label){font-family:Inter,sans-serif!important}
html[lang=bn] .refresh-site #main p{font-size:19px!important;line-height:1.85!important}
/* Same readability boost for English and Arabic -- a live audit found
   paragraph/list text on several pages (verify, about, etc.) still
   rendering at 14-16px because the legacy WordPress CSS's own font-size
   rules on nested text elements out-specificity the plain .refresh-site
   base size. !important here matches the existing Bengali rule's approach. */
html[lang=en] .refresh-site #main :is(p,li):not(.arabic){font-size:17px!important;line-height:1.85!important}
html[lang=ar] .refresh-site #main :is(p,li){font-size:19px!important;line-height:1.95!important}
.refresh-site :is(h1,h2,h3,h4,h5,h6){overflow-wrap:anywhere;text-wrap:pretty}
.refresh-site :is(p,li,.aio-icon-description,.uvc-sub-heading){overflow-wrap:break-word}
/* Legacy Ultimate Addons wrote viewport heights onto content containers. Let text set height. */
.refresh-site #main :is(.vc_row,.upb-background-text-wrapper,.upb-background-text):not(.vc_row-o-equal-height):not(.vc_row-flex){height:auto!important;min-height:0!important}
.refresh-site #main .upb-background-text-wrapper{width:100%!important;position:relative!important}
/* A live audit found the grey intro-section background (and others using the
   same Ultimate-Addons "browser size" background trick) still running past
   its text on several pages. Root cause: the element carrying this fixed
   height sits outside #main's ancestry on at least one page, so the rule
   above never matched it at all -- not a specificity loss, a selector miss.
   .full-browser-size is the actual marker class for this behaviour
   (data-bg-override="browser_size" in the source), so target it directly
   without depending on #main or any one page's auto-generated vc_custom_NNN
   class, which differs per row/page. */
.refresh-site .full-browser-size,
.refresh-site .upb-background-text-wrapper.full-browser-size{height:auto!important;min-height:0!important}
/* A live re-audit found this still losing: the source's own inline rule is
   #content > div.vc_row....vc_custom_NNN{height:500px!important}, which
   carries an ID selector (#content) that the class-only override above
   cannot out-specificity, !important or not. Matching #content here (every
   generated page has this wrapper id) restores parity and wins on
   declaration order within the same specificity bucket, since this
   stylesheet loads after the page's own inline <style> block. */
#content#content .full-browser-size,
#content#content div.upb-background-text-wrapper.full-browser-size{height:auto!important;min-height:0!important}
/* The round above fixed the inner .upb-background-text-wrapper (confirmed by
   a live audit: it now measures 788px, no longer 500px), but the ROW itself
   -- the direct #content > child that actually determines where the grey
   background ends -- is a SEPARATE element from that wrapper and was never
   targeted; it's still held at 500px by the same source rule. Scoped to
   .vc_row-has-fill specifically (the real marker for a row with its own
   background fill, confirmed in the source's own selector list) rather than
   every vc_custom_NNN row, which is effectively all of them and would undo
   the equal-height exclusion above. */
#content#content > div.vc_row.vc_row-has-fill{height:auto!important;min-height:0!important}
/* Scoped to the specific "welcome" row the audit measured (not every
   .vc_row-has-fill -- the grey intro band right after the hero is a
   DIFFERENT row that already reads correctly with zero top padding;
   adding padding there too would recreate the hero-gap bug this round's
   earlier fix just closed). Heading sits flush against the band's top
   edge with 0px clearance; ~95px of clearance exists at the bottom. */
#content#content > div.vc_row.vc_custom_1718718769637{padding-top:64px!important}
/* Confirmed by a live audit: #main's own padding-top (48px/20px, in
   refresh/site.css) is what creates the white gap between the hero and
   the grey intro band on the homepage -- the hero itself sits outside
   #main, so #main's top padding pushes its first child (the grey row)
   down from where the hero visually ends, rather than from #content's
   own top. build.mjs now marks homepage-only pages with body.has-hero. */
.refresh-site.has-hero #main{padding-top:0!important}
/* Source content scattered through many pages (About's Chairman/Founder
   role line, accredited-training-centers' numbered qualifications list,
   confirmed on both by a live audit) carries a hardcoded
   style="text-align: right" -- correct for the original Arabic (RTL
   "right" = reading-start), but a physical right, not a logical one. In
   English/Bengali (LTR) it pushes that one element to the opposite side
   from its neighbours, which reads as misaligned or flip-flopping list
   items. "start" resolves to the same side as the original authors'
   intent in both directions, so this is safe everywhere this inline
   style appears -- center/justify are untouched since those already
   look the same regardless of direction. */
.refresh-site #main [style*="text-align: right"],
.refresh-site #main [style*="text-align:right"]{text-align:start!important}
/* Same family of bug, confirmed on /طلب-اعتماد-مركز-تدريب/'s "Requirements
   and conditions" tab: some <li> items in source carry a literal dir="rtl"
   attribute (items 3-11 of 19), left over from authoring, while the rest
   don't -- so in English/Bengali the list visually zig-zags between left-
   and right-aligned items. Arabic is unaffected (rtl is already correct
   there). Force ltr/start on any such item outside the Arabic page. */
html:not([dir=rtl]) .refresh-site #main li[dir=rtl]{direction:ltr!important;text-align:start!important}
.refresh-site #main .upb-background-text{position:relative!important;top:auto!important;left:auto!important;right:auto!important;transform:none!important}
.refresh-site #main .vc_row:after,.refresh-site .wpb_wrapper:after{content:'';display:table;clear:both}
.refresh-site #main .vc_column-inner,.refresh-site #main .wpb_wrapper{min-width:0;max-width:100%}
.refresh-site .aio-icon-box{height:auto!important;min-height:0;max-width:100%;margin-block:0 24px!important}
.refresh-site .aio-icon-box:is(.left-icon,.right-icon){display:flex!important;align-items:flex-start;gap:16px;direction:inherit;text-align:start}
.refresh-site .aio-icon-box:is(.left-icon,.right-icon)>:is(.aio-icon-left,.aio-icon-right){flex:0 0 auto;float:none!important;padding:0!important;margin:0!important;position:static!important}
.refresh-site .aio-icon-box:is(.left-icon,.right-icon)>.aio-ibd-block{flex:1;min-width:0;padding:0!important;margin:0!important;width:auto!important;display:block!important}
.refresh-site .aio-icon-header h3{margin-top:0!important;line-height:1.5!important}
.refresh-site .aio-icon-description{line-height:1.85!important;margin-top:10px!important}
.refresh-site .aio-icon{display:inline-flex!important;align-items:center;justify-content:center;flex-shrink:0}
.refresh-site .aio-icon i{line-height:1!important;display:block}
.refresh-site .top-icon .aio-icon-top{margin-bottom:16px}
/* Equal-height news cards, including cloned carousel slides. No article body is clipped. */
.refresh-site .blog-carousel-shortcode .dt-owl-stage{display:flex;align-items:stretch}
.refresh-site .blog-carousel-shortcode .dt-owl-item{display:flex;float:none;flex-shrink:0;height:auto!important}
/* The pager (site.mjs) correctly sets the [hidden] attribute on paged-out
   cards, but this rule's own display:flex -- needed so VISIBLE cards lay
   out correctly -- also overrides the browser's built-in [hidden]{display:
   none} default, since both are plain element-state selectors of equal
   specificity and this one loads later. A live audit confirmed the
   attribute toggles correctly; cards just never actually disappeared. */
.refresh-site .blog-carousel-shortcode .dt-owl-item[hidden]{display:none!important}
.refresh-site :is(.blog-carousel-shortcode,.blog-shortcode) article,.refresh-site .dt-css-grid>.wf-cell>article{display:flex!important;flex-direction:column;height:100%!important;width:100%;margin:0!important;overflow:hidden;border:1px solid #e7dcd3;border-radius:16px;background:#fffdfb}
.refresh-site :is(.blog-carousel-shortcode,.blog-shortcode,.dt-css-grid) .post-thumbnail-wrap{flex:none;width:100%;margin:0!important}
.refresh-site :is(.blog-carousel-shortcode,.blog-shortcode,.dt-css-grid) .post-thumbnail{width:100%;aspect-ratio:16/10;overflow:hidden}
.refresh-site :is(.blog-carousel-shortcode,.blog-shortcode,.dt-css-grid) .post-thumbnail>a{display:block!important;width:100%!important;height:100%!important;padding:0!important}
.refresh-site :is(.blog-carousel-shortcode,.blog-shortcode,.dt-css-grid) .post-thumbnail img{position:static!important;width:100%!important;height:100%!important;object-fit:cover!important;transform:none!important}
.refresh-site :is(.blog-carousel-shortcode,.blog-shortcode,.dt-css-grid) .post-entry-content{display:flex;flex-direction:column;flex:1;min-width:0;padding:24px!important}
.refresh-site :is(.blog-carousel-shortcode,.blog-shortcode,.dt-css-grid) .entry-title{font-size:21px!important;line-height:1.5!important;margin:0 0 14px!important}
.refresh-site :is(.blog-carousel-shortcode,.blog-shortcode,.dt-css-grid) .entry-meta{line-height:1.6;margin-bottom:14px;display:flex;gap:6px 12px;flex-wrap:wrap}
.refresh-site :is(.blog-carousel-shortcode,.blog-shortcode,.dt-css-grid) .entry-excerpt{flex:1;margin-bottom:18px}
.refresh-site :is(.blog-carousel-shortcode,.blog-shortcode,.dt-css-grid) .entry-excerpt p{margin:0;font-size:17px!important;line-height:1.8!important}
.refresh-site :is(.blog-carousel-shortcode,.blog-shortcode,.dt-css-grid) .post-entry-content>.dt-btn{margin-top:auto;align-self:flex-start}
.refresh-site .dt-css-grid{align-items:stretch;grid-auto-rows:1fr}
.refresh-site .dt-css-grid>.wf-cell{height:100%}
/* Larger desktop menu; collapse early enough to prevent crowding. */
@media(min-width:1281px){.refresh-site #refresh-menu{gap:16px}.refresh-site #refresh-menu>a,.refresh-site .refresh-dropdown>summary{font-size:16px!important;font-weight:700!important;line-height:1.5}.refresh-site .refresh-nav{gap:16px;padding-inline:24px}}
@media(max-width:767px){.refresh-site #main .vc_row{margin-inline:0!important}.refresh-site #main .vc_column_container{width:100%!important;float:none!important}.refresh-site #main .vc_column-inner{padding-inline:8px!important}.refresh-site .aio-icon-box:is(.left-icon,.right-icon){gap:12px}.refresh-site .vc_empty_space{max-height:40px}.refresh-site #main p{line-height:1.85!important}.refresh-site .dt-css-grid{grid-template-columns:minmax(0,1fr)!important}}
@media(prefers-reduced-motion:reduce){.refresh-site :is(.vc_row,.aio-icon,.animation-triggered){transform:none!important;opacity:1!important}}
/* Resilience fallback: the theme's own CSS sets .owl-carousel{display:none} until
   JS adds .owl-loaded. If that JS never runs (slow network, a blocked script, a
   remote image failing), the carousel's real content -- including the news items --
   must not disappear. Force it visible and let items wrap naturally instead of
   depending on owl's JS-driven absolute positioning. */
.refresh-site .owl-carousel:not(.owl-loaded){display:flex!important;flex-wrap:wrap;gap:24px}
.refresh-site .owl-carousel:not(.owl-loaded) :is(.owl-stage,.owl-stage-outer){all:unset;display:contents}
.refresh-site .owl-carousel:not(.owl-loaded) .dt-owl-item{float:none!important;width:calc(33.333% - 16px)!important;min-width:260px}
@media(max-width:767px){.refresh-site .owl-carousel:not(.owl-loaded) .dt-owl-item{width:100%!important}}
/* The news carousel's own JS measured/positioned its stage incorrectly (all
   slides landing at the same far-offscreen x regardless of .owl-loaded state
   -- confirmed by a live audit, not assumed), so owl's native sliding is
   dropped entirely. A real custom track replaces it: .blog-carousel-shortcode
   is the fixed-width viewport (overflow:hidden), .owl-stage is the actual
   flex track site.mjs slides with a CSS transform, each real .dt-owl-item is
   sized to exactly 1/3 of the viewport width (confirmed by a live audit's
   own math: 3 cards need to fit without wrapping, so no stray item
   margin-right or min-width can push the total past 100%). The exam-types
   carousel is unaffected and keeps its own native sliding behavior. */
/* Side padding makes room for the nav arrows without overlapping the edge
   cards or needing a negative offset (a negative offset on these arrows was
   tried once before on a different carousel in this project and caused a
   confirmed horizontal-overflow regression on RTL pages -- not repeating
   that here). flex-basis below is already calculated against the content
   box, which excludes this padding automatically, so the 3-card math still
   holds. */
.refresh-site .blog-carousel-shortcode.owl-carousel{position:relative;display:block!important;padding-inline:48px!important;box-sizing:border-box!important}
/* overflow:hidden (needed for the sliding track to look like a carousel, not
   a wrapped grid) only applies once site.mjs confirms paging actually took
   over -- js-paged is added at that point. If JS never runs, the stage
   wraps and every real item stays visible with no overflow:hidden to lose
   content behind. */
.refresh-site .blog-carousel-shortcode.owl-carousel.js-paged{overflow:hidden}
.refresh-site .blog-carousel-shortcode.owl-carousel .owl-stage-outer{overflow:visible!important}
/* `all:unset!important` resets EVERY longhand property (including gap) with
   an implicit !important of its own -- a live audit found this was also
   cancelling the gap set later in this same rule (0px between cards,
   confirmed) and, worse, cancelling site.mjs's own inline
   `transform:translateX(...)` on every click (computed transform stayed
   `none` despite the inline style being set, confirmed by the audit
   reading it directly). Every property that needs to stick now repeats
   !important explicitly so it isn't just relying on declaration order
   within the same rule. The transform itself is intentionally NOT set
   here -- site.mjs sets it with setProperty(...,'important') per click,
   which is the only way an inline style can still beat this rule. */
.refresh-site .blog-carousel-shortcode.owl-carousel .owl-stage{all:unset!important;display:flex!important;flex-wrap:wrap!important;gap:24px!important;transition:transform .35s ease!important;will-change:transform!important}
.refresh-site .blog-carousel-shortcode.owl-carousel.js-paged .owl-stage{flex-wrap:nowrap!important}
.refresh-site .blog-carousel-shortcode.owl-carousel .dt-owl-item{float:none!important;position:static!important;transform:none!important;margin:0!important;flex:0 0 calc(33.333% - 16px)!important;min-width:260px}
.refresh-site .blog-carousel-shortcode.owl-carousel.js-paged .dt-owl-item{flex-basis:calc((100% - 48px)/3)!important;min-width:0!important;max-width:none!important}
.refresh-site .blog-carousel-shortcode .owl-nav,.refresh-site .blog-carousel-shortcode .owl-dots{display:none!important}
/* Owl clones its slides for seamless-loop sliding (8 clones alongside the 7
   real ones here) -- confirmed by a live audit: 15 <article> elements, only
   7 unique titles, clones not hidden. The custom track only ever moves real
   items (site.mjs filters them out), so the clones just sit unused past the
   end of the track; hide them so they can never show through on a resize. */
.refresh-site .blog-carousel-shortcode .dt-owl-item.cloned{display:none!important}
@media(max-width:767px){.refresh-site .blog-carousel-shortcode.owl-carousel .dt-owl-item{flex-basis:100%!important}}
/* 3-at-a-time paging. Arrows sit centered over the carousel's vertical
   midpoint, pinned to the left/right edges of the wrapping container
   site.mjs creates; [dir=rtl] mirrors which edge is "next". Without JS (or
   before it runs), the track shows all items in a wrapped grid -- not
   sliding, but never hidden behind broken JS either. */
.refresh-news-wrap{position:relative}
.refresh-news-nav button{
 position:absolute;top:50%;transform:translateY(-50%);z-index:2;
 width:40px;height:40px;border-radius:50%;border:1px solid #e7dcd3;background:#fffdfbee;
 color:#2b1a16;font-size:18px;cursor:pointer;
}
.refresh-news-nav .refresh-news-prev{left:4px}
.refresh-news-nav .refresh-news-next{right:4px}
[dir=rtl] .refresh-news-nav .refresh-news-prev{left:auto;right:4px}
[dir=rtl] .refresh-news-nav .refresh-news-next{right:auto;left:4px}
.refresh-news-nav button:disabled{opacity:.35;cursor:default}
.refresh-news-nav button:hover:not(:disabled){background:#9d2f20;color:#fff;border-color:#9d2f20}
.refresh-news-nav button:disabled{opacity:.35;cursor:default}
/* Pre-existing contrast bug confirmed in source (source-pages/our-specialists/index.htm
   already has page-title.solid-bg, predating this refresh): these page-title banners pair
   a pale solid background with a near-white heading/breadcrumb color meant for a dark
   photo background, making the title unreadable wherever no image is set. */
.refresh-site .page-title.solid-bg :is(.page-title-head,.hgroup,h1,h2){color:#2b1a16!important}
.refresh-site .page-title.solid-bg .breadcrumbs,.refresh-site .page-title.solid-bg .breadcrumbs a,.refresh-site .page-title.solid-bg .assistive-text{color:#6a5a57!important}
.refresh-site #footer .refresh-dev-credit{display:inline-block;margin-left:10px;padding-left:10px;border-left:1px solid #9b8d8a60;font-size:12px;color:#9b8d8a}
.refresh-site #footer .refresh-dev-credit a{color:#9b8d8a;text-decoration:underline}
.refresh-site #footer .refresh-dev-credit a:hover{color:#6a5a57}
.refresh-site #footer .refresh-dev-credit-row{text-align:center;padding:14px 0}
.refresh-site #footer .refresh-dev-credit-row .refresh-dev-credit{border-left:none;margin-left:0;padding-left:0}
.reg-popup-backdrop{position:fixed;inset:0;background:#1a0f0dbf;backdrop-filter:blur(3px);display:flex;align-items:center;justify-content:center;padding:20px;z-index:999}
.reg-popup-backdrop[hidden]{display:none}
.reg-popup-card{position:relative;max-width:460px;width:100%;background:#fffdfb;border-radius:14px;padding:36px 32px;box-shadow:0 30px 70px #0006;font-family:inherit}
.reg-popup-close{position:absolute;top:14px;right:14px;background:none;border:none;color:#6a5a57;cursor:pointer;font-size:22px;line-height:1;padding:6px}
.reg-popup-eyebrow{font:700 12px/1.5 sans-serif;letter-spacing:1.5px;color:#ab821a}
.reg-popup-card h3{font:500 24px/1.3 serif;margin:10px 0 14px;color:#2b1a16}
.reg-popup-card p{font-size:15px;font-weight:500;line-height:1.75;color:#6a5a57;margin:0 0 22px}
.reg-popup-button{display:inline-flex;align-items:center;justify-content:center;width:100%;min-height:48px;border-radius:7px;background:#9f2c16;color:#fff;border:2px solid transparent;background-image:linear-gradient(#9f2c16,#9f2c16),linear-gradient(120deg,#39d1c4,#ffd36b);background-origin:border-box;background-clip:padding-box,border-box;text-decoration:none;font-weight:500}
@media (max-width:520px){.reg-popup-card{padding:28px 22px}}
