/* Harimatec — WordPress compatibility layer for the ported artifact.
   The artifact paints its own full-bleed section backgrounds and uses .wrap
   for the inner measure, so every wrapper above it must be edge to edge. */

/* --- 1. Full bleed: unbox Astra's content container --- */
#content.site-content{padding:0;margin:0}
#content .ast-container{max-width:100%;width:100%;padding-left:0;padding-right:0;margin:0}
.ast-plain-container #primary,.ast-plain-container.ast-no-sidebar #primary{max-width:100%;margin:0;padding:0}
.ast-page-builder-template .ast-container{max-width:100%;padding:0}

/* --- 2. Full bleed: Elementor page + theme-builder containers --- */
.elementor-template-full-width .elementor{width:100%;max-width:100%}
.elementor .e-con.e-parent,
.elementor-location-header .e-con,
.elementor-location-footer .e-con{--container-max-width:100%;width:100%;max-width:100%;padding-inline:0;margin:0}
.elementor .e-con>.elementor-widget-html,.elementor-widget-html{width:100%;max-width:100%}
.elementor-widget:not(:last-child){margin-block-end:0}
.elementor-location-header,.elementor-location-footer{width:100%}
.elementor-location-header{position:sticky;top:0;z-index:100}

/* --- 3. The artifact owns its own colour and type. Stop the theme repainting it. --- */
.page a,.hdr a,.ft a,.btn{text-decoration:none}
.btn-p,.btn-d,.btn-o{color:#fff}
.btn-l{color:var(--head)}
.btn-p:hover,.btn-o:hover,.btn-l:hover,.btn-d:hover{color:#fff}
.hero .btn-p:hover,.band .btn-p:hover,.bg-n .btn-p:hover,
.corecard .btn-p:hover,.ct-r .btn-p:hover,.ctab-bx .btn-p:hover{color:var(--navy)}
.btn,.pc-more,.nb-arw,.nb-dot,.ptab,.jn-y-btn,.numc,.theme-t,.burger{box-shadow:none}

/* --- 3b. Elementor ships `.elementor img{height:auto}` (0,1,1), which outranks
   any artifact rule that sizes an image by a single class on the <img> itself
   (0,1,0). .core-mark is the only one: without this it renders at its natural
   416px instead of the intended clamp. --- */
.elementor .core-mark,.page img.core-mark{height:clamp(150px,15vw,210px);width:auto}
/* Same fight, and these matter more: without it the hero and band photos keep
   their intrinsic height inside an inset:0 box, so object-fit:cover never gets
   the section's real height and the crop is wrong. */
.elementor .hero-ph,.page img.hero-ph,
.elementor .band-img,.page img.band-img{width:100%;height:100%;object-fit:cover}

/* --- 4. Astra list / image resets that fight the artifact --- */
.page ul,.ft ul,.hdr ul{margin:0;padding:0}
.page li,.ft li{list-style:none}
.page img,.hdr img,.ft img,.pmodal img{border-radius:0;box-shadow:none}
.page h1,.page h2,.page h3,.page h4,.page h5,.page h6{text-transform:none}
.page p{margin:0}

/* --- 5. Elementor injects its own paragraph spacing into HTML widgets --- */
.elementor-widget-html p:last-child{margin-bottom:0}

/* --- 6. One sticky header, not two.
   The location wrapper is what actually scrolls with the page; the inner
   .hdr would only ever stick inside its own 86px box. --- */
.elementor-location-header .hdr{position:static;z-index:auto}

/* --- 7. Clear the WordPress admin bar, by measurement not by guess.
   --hmt-adminbar is set from the real #wpadminbar box by hmt-core.php:
   0 when there is no bar, when it is hidden, or when it scrolls away
   (position:absolute below 601px); its real height when it is fixed.
   A hard-coded 32px leaves a visible gap in every one of those cases. --- */
:root{--hmt-adminbar:0px}
.elementor-location-header{top:var(--hmt-adminbar,0px)}
.menu{top:calc(86px + var(--hmt-adminbar,0px))}

/* --- 8. Pin the WordPress toolbar and close the gap above it.
   Core bumps the document with `html{margin-top:32px !important}` and relies on
   a fixed toolbar to cover that strip. If anything stops the toolbar being
   fixed to the viewport, the strip is left showing as empty space above it.
   So: drop the bump, pin the bar ourselves, and re-create the clearance as
   padding inside body -- which reads the same whether the bar is truly fixed
   or has been re-parented by a transformed ancestor.
   Front end only; hmt-core.php never enqueues this in wp-admin. --- */
html:root{margin-top:0 !important}
#wpadminbar{position:fixed !important;top:0 !important;left:0 !important;right:0 !important;margin:0 !important}
body.admin-bar{padding-top:32px}
@media screen and (max-width:782px){
	body.admin-bar{padding-top:46px}
}

/* --- 9. Native header, Theme Builder template 56 (section 9) ---------------
   The artifact classes .hdr / .wrap / .hdr-in / .brand-lock sit on real
   containers, so the layout carries over untouched. These rules only bridge
   the places where an Elementor widget wraps its markup differently. --- */
.brand-lock > .elementor-element{display:flex;align-items:center;flex:none}
.brand-lock > .elementor-element + .elementor-element{border-left:1px solid var(--line);padding-left:.85rem;align-self:stretch}
.brand-lock .elementor-widget-container{display:flex;align-items:center;line-height:0}
.brand-lock .elementor-widget-image a{display:flex;align-items:center;line-height:0}
.logomark-hdr img{height:46px;width:auto;max-width:none}
.bl-mc img{height:30px;width:auto;max-width:none}
.bl-name .elementor-heading-title{line-height:1}
.bl-name .elementor-heading-title,.bl-name .elementor-heading-title a{display:flex;flex-direction:column;align-items:flex-start;gap:5px;color:inherit}

/* primary navigation (Elementor Pro Nav Menu) styled to match .menu a */
.hm-nav .elementor-nav-menu--main .elementor-item{font-family:var(--fb);font-size:.8125rem;font-weight:500;color:var(--body);padding:.5rem .6rem;fill:var(--body)}
.hm-nav .elementor-nav-menu--main .elementor-item:hover,.hm-nav .elementor-nav-menu--main .elementor-item:focus{color:var(--acc)}
.hm-nav .elementor-nav-menu--main .elementor-item.elementor-item-active{color:var(--head);font-weight:600}
.hm-nav .elementor-nav-menu--main .elementor-item.elementor-item-active:after{content:"";position:absolute;left:.6rem;right:.6rem;bottom:-1px;height:2px;background:var(--acc)}
.hm-nav .elementor-nav-menu--main .elementor-item{position:relative}
.hm-nav .elementor-nav-menu--dropdown .elementor-item{font-family:var(--fb);font-size:.9375rem;color:var(--body)}
.hm-nav div.elementor-menu-toggle{color:var(--head);border:1px solid var(--line);width:42px;height:42px;border-radius:0}
.hm-nav div.elementor-menu-toggle:hover{border-color:var(--acc);color:var(--acc)}

/* the header CTA keeps its look in Elementor settings; this only kills the
   rounded corners Astra and the kit would otherwise impose */
.hm-cta .elementor-button{border-radius:0}

/* Elementor writes --width:100% onto every container from its own settings,
   at a higher specificity than the artifact .wrap. Hand the measure back. */
.elementor .e-con.wrap{width:min(100% - 2.5rem,var(--maxw));max-width:var(--maxw);margin-inline:auto}

.elementor .e-con.brand-lock{width:auto;max-width:none;flex:0 0 auto;margin-right:auto}
.elementor .e-con.hdr-in{flex-wrap:nowrap}

/* --- 10. Native footer, Theme Builder template 57 (section 10) --- */
.elementor .e-con.ft-top{display:grid;grid-template-columns:1.6fr 1fr 1fr 1fr;gap:clamp(1.5rem,1rem + 2.5vw,3rem);align-items:start}
@media(max-width:900px){.elementor .e-con.ft-top{grid-template-columns:1fr 1fr}}
@media(max-width:560px){.elementor .e-con.ft-top{grid-template-columns:1fr}}
.elementor .e-con.ft-top > .e-con{width:auto;max-width:none;display:block}
.logomark-ft img{height:86px;width:auto;max-width:none}
.ft .ft-desc p{font-size:.8125rem;line-height:1.8;color:var(--body);margin:0}
.ft .ft-desc{max-width:36ch}
.hm-ftnav .elementor-nav-menu--main .elementor-item{font-family:var(--fb);font-size:.8125rem;font-weight:400;color:var(--body);padding:.28rem 0;transition:color .2s,transform .25s var(--ease)}
.hm-ftnav .elementor-nav-menu--main .elementor-item:hover{color:var(--acc);transform:translateX(4px);background:0 0}
.hm-ftnav .elementor-nav-menu--main .elementor-item.elementor-item-active{color:var(--body);background:0 0}
.ft-info .elementor-icon-list-items{display:flex;flex-direction:column;gap:.8rem}
.ft-info .elementor-icon-list-item{align-items:flex-start}
.ft-info .elementor-icon-list-item a,.ft-info .elementor-icon-list-item span.elementor-icon-list-text{font-size:.8125rem;line-height:1.6;color:var(--body)}
.ft-info .elementor-icon-list-item:hover .elementor-icon-list-text{color:var(--acc)}
.ft-info .elementor-icon-list-icon{margin-top:.28rem}
.ft-info .elementor-icon-list-icon svg,.ft-info .elementor-icon-list-icon i{width:12px;height:12px;font-size:12px;color:var(--acc);fill:var(--acc)}
.elementor .e-con.ft-bot{border-top:1px solid var(--line);padding:1.35rem 0;display:block}
.ft-bot p{font-size:.75rem;color:var(--ink-3);margin:0}

/* --- 11. Products page: JetEngine listing card + Elementor nested tabs (section 11) --- */
.jet-listing-grid__items{margin:0 -.75rem}
.pgrid .jet-listing-grid__item{padding:0 .75rem;margin-bottom:1.5rem}
.elementor .e-con.pc{background:var(--surface);border:1px solid var(--line);height:100%;gap:0}
.elementor .e-con.pc-img{aspect-ratio:4/3;overflow:hidden;background:#fff;border-bottom:1px solid var(--line);display:block}
.pc-img .jet-listing-dynamic-image img{width:100%;height:100%;object-fit:contain;padding:.9rem;transition:transform .6s var(--ease)}
.pc:hover .pc-img .jet-listing-dynamic-image img{transform:scale(1.06)}
.elementor .e-con.pc-hd{padding:1.25rem 1.35rem 1rem;background:var(--xlight);border-bottom:1px solid var(--line);gap:.15rem;transition:background .3s}
.pc:hover .pc-hd{background:var(--acc-soft)}
.pc-title{font-family:var(--fd);font-size:1.25rem;font-weight:600;color:var(--head);line-height:1.2}
.pc-sub{font-size:.8125rem;font-weight:500;color:var(--acc)}
.elementor .e-con.pc-bd{padding:1.15rem 1.35rem 1.35rem;gap:.85rem;flex-grow:1;justify-content:flex-start}
.pc-desc{font-size:.875rem;line-height:1.7;color:var(--body)}
.pc-more{margin-top:auto}
.pc-more .jet-listing-dynamic-link__link{border:1px solid var(--line);padding:.7rem 1.1rem;font-family:var(--fb);font-size:.6875rem;font-weight:600;letter-spacing:.09em;text-transform:uppercase;color:var(--head);display:inline-flex;align-items:center;gap:.5rem;transition:background .22s,color .22s,border-color .22s}
.pc-more .jet-listing-dynamic-link__link:hover{background:var(--acc);border-color:var(--acc);color:#fff}
.pc-more .jet-listing-dynamic-link__icon svg{width:12px;height:12px;fill:currentColor}

/* nested tabs styled as the artifact .ptabs / .ptab */
.hm-ptabs .e-n-tabs-heading{display:grid;grid-template-columns:repeat(4,1fr);border:1px solid var(--line);background:var(--surface);margin-bottom:2.5rem;gap:0}
@media(max-width:760px){.hm-ptabs .e-n-tabs-heading{grid-template-columns:1fr 1fr}}
@media(max-width:420px){.hm-ptabs .e-n-tabs-heading{grid-template-columns:1fr}}
.hm-ptabs .e-n-tab-title{background:0 0;border:0;border-right:1px solid var(--line);border-top:3px solid transparent;border-radius:0;padding:1.15rem 1rem;font-family:var(--fb);font-size:.875rem;font-weight:600;color:var(--body);justify-content:center;transition:.2s}
.hm-ptabs .e-n-tab-title:last-child{border-right:0}
.hm-ptabs .e-n-tab-title:hover{background:var(--xlight);color:var(--head)}
.hm-ptabs .e-n-tab-title[aria-selected="true"]{background:var(--acc);color:#fff;border-top-color:var(--acc)}
.hm-ptabs .e-n-tabs-content > .e-con{padding:0}
.elementor .e-con.cathd{display:block;margin-bottom:2rem;max-width:72ch}
.cathd h2{margin-bottom:.5rem}
.cathd p{font-size:.9375rem;line-height:1.8;color:var(--body)}

/* --- 12. Native page sections (section 12) -------------------------------
   Artifact classes sit on real containers, so most layout already applies.
   These rules re-point the rules that assumed a bare <img> or <a>. --- */

/* full-bleed photo layers are now image WIDGETS, not bare imgs */
.elementor .hero-ph,.elementor .band-img{position:absolute;inset:0;z-index:-2;width:100%;height:100%;margin:0}
.hero-ph .elementor-widget-container,.band-img .elementor-widget-container,.hero-ph figure,.band-img figure{width:100%;height:100%;margin:0}
.hero-ph img{width:100%;height:100%;object-fit:cover;opacity:.22;mix-blend-mode:luminosity}
.band-img img{width:100%;height:100%;object-fit:cover}
.elementor .e-con.hero-bg{position:absolute;inset:0;z-index:-2;background:linear-gradient(100deg,var(--navy-3) 0,var(--navy) 45%,#0a6d5c 100%);min-height:0;padding:0}
.elementor .e-con.hero{position:relative;isolation:isolate;overflow:hidden;background:var(--navy);display:block}


.hero-fig img{width:100%;aspect-ratio:4/3;object-fit:cover}

/* Elementor buttons wearing the artifact button skin */
.hm-btn .elementor-button,.hm-btn-o .elementor-button,.hm-btn-l .elementor-button{font-family:var(--fb);font-size:.75rem;font-weight:600;letter-spacing:.09em;text-transform:uppercase;padding:.95rem 1.6rem;border-radius:0;border:1px solid transparent;transition:background .2s,color .2s,border-color .2s}
.hm-btn .elementor-button{background:var(--acc);color:#fff;border-color:var(--acc)}
.hm-btn .elementor-button:hover{background:var(--navy);border-color:var(--navy);color:#fff}
.hero .hm-btn .elementor-button:hover,.band .hm-btn .elementor-button:hover,.ctab-bx .hm-btn .elementor-button:hover{background:#fff;border-color:#fff;color:var(--navy)}
.hm-btn-o .elementor-button{background:0 0;color:#fff;border-color:var(--w20)}
.hm-btn-o .elementor-button:hover{background:var(--acc);border-color:var(--acc);color:#fff}
.hm-btn-l .elementor-button{background:0 0;color:var(--head);border-color:var(--line)}
.hm-btn-l .elementor-button:hover{background:var(--acc);border-color:var(--acc);color:#fff}
.elementor .e-con.btns{gap:.85rem;flex-wrap:wrap}
.elementor .e-con.hm-center{justify-content:center}

/* two-column splits */
.elementor .e-con.wwa,.elementor .e-con.sus-row,.elementor .e-con.corewrap{display:grid;align-items:center;gap:clamp(2rem,1rem + 3.5vw,4rem)}
.elementor .e-con.wwa{grid-template-columns:1fr 1fr}
.elementor .e-con.sus-row{grid-template-columns:1.08fr .92fr}
.elementor .e-con.corewrap{grid-template-columns:1.02fr .98fr;align-items:stretch;gap:clamp(1.25rem,.75rem + 1.6vw,1.75rem);margin-top:1.5rem}
@media(max-width:940px){.elementor .e-con.wwa,.elementor .e-con.sus-row,.elementor .e-con.corewrap{grid-template-columns:1fr}}
.wwa-shot img{aspect-ratio:4/3;object-fit:cover;width:100%;background:var(--xlight)}
.elementor .e-con.corestack{display:flex;flex-direction:column;gap:clamp(1.25rem,.75rem + 1.6vw,1.75rem)}
.elementor .e-con.corecard{flex:1;justify-content:center;gap:1rem}
.core-mark img{height:clamp(150px,15vw,210px);width:auto;margin-inline:auto}
.corecard .coreq p{font-family:var(--fb);font-size:.9375rem;line-height:1.8;color:#cfdbd8;margin:0;max-width:56ch}
.corecard .coretag p{color:var(--acc);font-weight:600;font-size:.9375rem;margin:0}
.corecard .ticks li{color:#cfdbd8;font-size:.9375rem}

/* icon boxes: .ibx row and .feat-c cards */
.elementor .e-con.ibx-row,.elementor .e-con.icards,.elementor .e-con.feat,.elementor .e-con.numgrid,.elementor .e-con.cbar{display:grid;flex-wrap:wrap}
.elementor .e-con.ibx-row{grid-template-columns:repeat(4,1fr);gap:1rem;margin-top:clamp(2.5rem,1.5rem + 3vw,3.5rem)}
@media(max-width:860px){.elementor .e-con.ibx-row{grid-template-columns:1fr 1fr}}
@media(max-width:520px){.elementor .e-con.ibx-row{grid-template-columns:1fr}}
.ibx.elementor-widget-icon-box{background:var(--surface);border:1px solid var(--line);padding:1.15rem 1.25rem;transition:border-color .28s,transform .28s var(--ease),box-shadow .28s}
.ibx.elementor-widget-icon-box:hover{border-color:var(--acc);transform:translateY(var(--lift));box-shadow:var(--sh-h)}
.ibx .elementor-icon-box-wrapper{display:flex;align-items:center;gap:1rem;text-align:left}
.ibx .elementor-icon-box-icon{margin:0;flex:none}
.ibx .elementor-icon{width:42px;height:42px;background:var(--acc);color:#fff;display:grid;place-items:center;font-size:18px}
.ibx .elementor-icon-box-title{margin:0}
.ibx .elementor-icon-box-title,.ibx .elementor-icon-box-title a{font-size:1rem;font-weight:600;color:var(--head);line-height:1.3}

.elementor .e-con.feat{grid-template-columns:repeat(auto-fit,minmax(230px,1fr));gap:1.5rem;margin-top:3.25rem}
.feat-c.elementor-widget-icon-box{background:#ffffff14;border:1px solid #ffffff26;padding:2.25rem 1.6rem;text-align:center;backdrop-filter:blur(6px);transition:background .25s,border-color .25s,transform .3s var(--ease)}
.feat-c.elementor-widget-icon-box:hover{background:var(--acc);border-color:var(--acc);transform:translateY(-3px)}
.feat-c .elementor-icon{color:#fff;font-size:34px}
.feat-c .elementor-icon-box-icon{margin-bottom:1.1rem}
.feat-c .elementor-icon-box-title,.feat-c .elementor-icon-box-title a{color:#fff;font-size:1.0625rem;font-weight:600;line-height:1.35}
.feat-c .elementor-icon-box-description{color:#ffffffcc;font-size:.875rem;line-height:1.7}

/* industries */
.elementor .e-con.icards{grid-template-columns:repeat(auto-fit,minmax(230px,1fr));gap:1.25rem}
.elementor .e-con.icard{background:var(--surface);border:1px solid var(--line);overflow:hidden;gap:0;transition:transform .3s var(--ease),box-shadow .3s,border-color .3s}
.elementor .e-con.icard:hover{transform:translateY(var(--lift));box-shadow:var(--sh-h);border-color:var(--acc)}
.elementor .e-con.icard .fig{aspect-ratio:16/10;overflow:hidden;display:block;padding:0}
.icard-shot img{width:100%;height:100%;object-fit:cover;filter:grayscale(1);transition:filter .35s,transform .5s}
.icard:hover .icard-shot img{filter:grayscale(0);transform:scale(1.04)}
.elementor .e-con.icard-b{padding:1.1rem 1.25rem}
.icard-lbl .elementor-icon-box-wrapper{display:flex;align-items:center;gap:.8rem;text-align:left}
.icard-lbl .elementor-icon-box-icon{margin:0}
.icard-lbl .elementor-icon{color:var(--acc);font-size:22px}
.icard-lbl .elementor-icon-box-title{margin:0;font-size:1rem;font-weight:600;color:var(--head)}

/* sustainability numbers */
.elementor .e-con.numgrid{grid-template-columns:repeat(auto-fit,minmax(215px,1fr));gap:1.25rem}
.elementor .e-con.sus-grid{grid-template-columns:repeat(4,1fr);margin-top:clamp(3rem,2rem + 3vw,4.5rem)}
@media(max-width:900px){.elementor .e-con.sus-grid{grid-template-columns:1fr 1fr}}
@media(max-width:480px){.elementor .e-con.sus-grid{grid-template-columns:1fr}}
.elementor .e-con.numc{background:var(--surface);border:1px solid var(--line);border-top:3px solid var(--acc);padding:1.5rem 1.35rem;gap:.5rem;transition:transform .28s var(--ease),box-shadow .28s,border-color .28s}
.elementor .e-con.numc:hover{transform:translateY(var(--lift));box-shadow:var(--sh-h)}
.numc-n{font-family:var(--fd);font-size:1.75rem;font-weight:800;color:var(--acc);line-height:1}
.numc h4{font-size:1rem;font-weight:600;color:var(--head);line-height:1.35}
.elementor .e-con.offset{position:relative;padding:0 0 2.25rem 2.25rem;display:block}
.offset .a img,.offset .b img{aspect-ratio:4/3;object-fit:cover;background:var(--xlight);width:100%}
.offset .a{width:78%}
.offset .b{position:absolute;right:0;bottom:0;width:58%;border:8px solid var(--surface)}
@media(max-width:560px){.elementor .e-con.offset{padding:0}.offset .a{width:100%}.offset .b{position:static;width:100%;margin-top:.6rem;border:0}}

/* world map + counters */
.elementor .e-con.wmapwrap{position:relative;background:var(--xlight);border:1px solid var(--line);padding:clamp(.75rem,2vw,1.75rem);display:block}
.wmap-holder svg{width:100%;height:auto;display:block}
.elementor .e-con.cbar{background:var(--acc);grid-template-columns:repeat(auto-fit,minmax(150px,1fr));gap:0}
.cbar-item{padding:1.75rem 1rem;text-align:center;border-right:1px solid #ffffff33}
.cbar-item:last-child{border-right:0}
.cbar-item .elementor-counter-number-wrapper{font-family:var(--fd);font-size:clamp(1.75rem,1.3rem + 1.5vw,2.375rem);font-weight:700;color:#fff;line-height:1.1;justify-content:center}
.cbar-item .elementor-counter-title{font-size:.8125rem;color:#ffffffd9;margin-top:.15rem;font-family:var(--fb);font-weight:400}

/* certification listing inside the band */
.cert-grid .jet-listing-grid__items{margin:0 -.75rem}
.cert-grid .jet-listing-grid__item{padding:0 .75rem;margin-bottom:1.5rem}
.elementor .e-con.feat-c{background:#ffffff14;border:1px solid #ffffff26;padding:2.25rem 1.6rem;text-align:center;height:100%;align-items:center;transition:background .25s,border-color .25s,transform .3s var(--ease)}
.elementor .e-con.feat-c:hover{background:var(--acc);border-color:var(--acc);transform:translateY(-3px)}
.elementor .e-con.cert-doc{display:block;width:clamp(118px,13vw,158px);aspect-ratio:1/1.33;margin:0 auto 1.15rem;background:#fff;border:1px solid #ffffff4d;padding:5px;overflow:hidden}
.cert-shot img{width:100%;height:100%;object-fit:contain}
.cert-name{color:#fff;font-size:1.0625rem;font-weight:600;margin-bottom:.65rem;line-height:1.35}
.cert-desc{color:#ffffffcc;font-size:.875rem;line-height:1.7}

/* CTA band */
.elementor .e-con.ctab{display:grid;grid-template-columns:1.05fr .95fr;align-items:stretch;background:var(--light);overflow:hidden;gap:0;position:relative}
@media(max-width:1024px){.elementor .e-con.ctab{grid-template-columns:1fr}}
.elementor .e-con.ctab-img{position:relative;min-height:300px;overflow:hidden;display:block;padding:0}
.ctab-shot,.ctab-shot .elementor-widget-container,.ctab-shot figure{height:100%}
.ctab-shot img{width:100%;height:100%;object-fit:cover}
.elementor .e-con.ctab-bx{background:var(--navy);color:var(--w60);padding:clamp(2rem,1.5rem + 2.5vw,3.5rem);justify-content:center;position:relative;gap:.6rem}
.ctab-bx:after{content:"";position:absolute;right:0;bottom:0;width:120px;height:8px;background:var(--acc)}
.ctab-bx h2{color:#fff;max-width:19ch}
.ctab-bx p{margin-top:1rem;font-size:.875rem;line-height:1.8;max-width:52ch;color:var(--w60)}

/* announcement carousel */
.nb-grid .jet-listing-grid__item{padding:0}
.elementor .e-con.nb-box{display:grid;grid-template-columns:.54fr .46fr;border:1px solid var(--line);background:var(--surface);overflow:hidden;height:440px;gap:0}
@media(max-width:900px){.elementor .e-con.nb-box{grid-template-columns:1fr;grid-template-rows:210px 1fr;height:660px}.elementor .e-con.nb-fig{grid-row:1}.elementor .e-con.nb-bx{grid-row:2}}
.elementor .e-con.nb-bx{padding:clamp(1.9rem,1.4rem + 2.4vw,3rem);justify-content:space-between;min-width:0;overflow:hidden}
.nb-h{font-size:clamp(1.3rem,1.05rem + 1vw,1.75rem);max-width:22ch;color:var(--head)}
.nb-p{margin-top:.8rem;font-size:.9375rem;line-height:1.8;color:var(--body);max-width:54ch}
.elementor .e-con.nb-meta{margin-top:1rem;padding-top:.95rem;border-top:1px solid var(--line);flex-direction:row;flex-wrap:wrap;gap:.4rem 1rem;align-items:baseline}
.nb-date{font-family:var(--fd);font-size:.8125rem;font-weight:700;color:var(--head)}
.nb-note{font-size:.8125rem;color:var(--ink-3)}
.elementor .e-con.nb-fig{position:relative;overflow:hidden;isolation:isolate;background:linear-gradient(135deg,var(--navy-3) 0,var(--navy) 55%,var(--acc) 165%);padding:0;display:block}
.nb-shot,.nb-shot .elementor-widget-container,.nb-shot figure{position:absolute;inset:0;height:100%;width:100%;margin:0}
.nb-shot img{width:100%;height:100%;object-fit:cover}
.elementor .e-con.nb-fig:before{content:"";position:absolute;inset:0;z-index:1;background:linear-gradient(180deg,rgba(0,0,0,0) 0,rgba(0,0,0,0) 34%,rgba(0,0,0,.18) 55%,rgba(0,0,0,.52) 78%,rgba(0,0,0,.78) 100%)}
.elementor .e-con.nb-greet{position:absolute;inset:auto 0 0 0;z-index:2;padding:clamp(1.6rem,1.2rem + 1.8vw,2.5rem)}
.nb-greet-t{font-family:var(--fd);font-weight:700;color:#fff;line-height:1.15;text-shadow:0 1px 12px rgba(0,0,0,.5);font-size:clamp(1.25rem,.85rem + 1.7vw,2.05rem);max-width:13ch;display:block}

/* --- 13. Native inner pages: about, compliance, sustainability, downloads,
   contact, 404 (section 13) --------------------------------------------------
   Same principle as section 12: the artifact classes ride on real containers
   and widgets, so these rules only re-point the ones that assumed bare
   <img>, <ul>, <svg> or <form> markup. --- */

/* page hero (.ph) shared by all five inner pages */
.elementor .e-con.ph{position:relative;display:block;padding:0}
.elementor .e-con.ph-img{position:relative;height:clamp(200px,14vw + 130px,290px);overflow:hidden;background:var(--navy);display:block;padding:0}
.ph-shot,.ph-shot .elementor-widget-container,.ph-shot figure{height:100%;width:100%;margin:0}
.ph-shot img{width:100%;height:100%;object-fit:cover;display:block}
.elementor .e-con.ph-card{background:var(--surface);max-width:640px;margin:-96px auto 0;position:relative;z-index:2;padding:2.25rem 2.5rem;text-align:center;display:block;box-shadow:0 18px 50px -24px #19295340}
.ph-card h1{font-size:clamp(1.75rem,1.3rem + 2vw,2.5rem)}
.ph-rule{margin:1.15rem auto;max-width:70%}
.ph-rule .elementor-divider{padding-block:0}
.ph-rule .elementor-divider-separator{border-top-color:var(--line)}
.crumb .elementor-widget-container{display:flex;justify-content:center;gap:.6rem;align-items:center;font-size:.8125rem;color:var(--body);flex-wrap:wrap}
.crumb a{color:var(--body)}
.crumb a:hover{color:var(--acc)}
.crumb i{font-style:normal;color:var(--ink-3)}
.crumb b{font-weight:500;color:var(--body)}
.ph-lead p{margin-top:.9rem;font-size:.875rem;color:var(--body);line-height:1.75}

/* generic figure wrappers now hold an image widget */
.elementor .e-con.fig{position:relative;overflow:hidden;background:var(--xlight);display:block;padding:0}
.elementor .e-con.fig-169{aspect-ratio:16/9}
.elementor .e-con.mb2{margin-bottom:2rem}
.fig-acc:after{content:"";position:absolute;left:0;bottom:0;width:84px;height:6px;background:var(--acc);z-index:2}
.elementor .e-con.fig>.elementor-widget-image,
.fig>.elementor-widget-image .elementor-widget-container,
.fig>.elementor-widget-image figure{height:100%;width:100%;margin:0}
.fig>.elementor-widget-image img{width:100%;height:100%;object-fit:cover;display:block;transition:transform .6s var(--ease)}
.fig:hover>.elementor-widget-image img{transform:scale(1.05)}

/* two-column layouts used by the inner pages */
.elementor .e-con.grid-2{display:grid;grid-template-columns:1fr 1fr;gap:clamp(1.75rem,1rem + 3vw,3.5rem);align-items:stretch}
@media(max-width:860px){.elementor .e-con.grid-2{grid-template-columns:1fr}}
.elementor .e-con.grid-2>.fig{min-height:320px}
.elementor .e-con.qual-row{display:grid;grid-template-columns:1.02fr .98fr;gap:clamp(2rem,1rem + 4vw,4.5rem);align-items:center}
@media(max-width:900px){.elementor .e-con.qual-row{grid-template-columns:1fr}}
.elementor .e-con.split-head{display:grid;grid-template-columns:.95fr 1.05fr;gap:clamp(1.5rem,1rem + 3vw,4rem);align-items:end;margin-bottom:clamp(2.25rem,1.5rem + 2vw,3.25rem)}
@media(max-width:820px){.elementor .e-con.split-head{grid-template-columns:1fr}}
.split-head>.elementor-widget-heading .elementor-heading-title{max-width:16ch}
.split-head .lead .elementor-widget-container{max-width:none}
.split-head-r .lead .elementor-widget-container{text-align:right}
@media(max-width:820px){.split-head-r .lead .elementor-widget-container{text-align:left}}

/* band lead paragraphs sit on dark ground */
.band-lead .elementor-widget-container{text-align:center;margin:1.15rem auto 0;max-width:70ch}
.band-lead-left .elementor-widget-container{margin:1.15rem 0 0;max-width:72ch}
.band-lead p,.band-lead-left p{color:var(--w60)}

/* vision / mission / values */
.elementor .e-con.vmm{display:grid;grid-template-columns:1fr 1fr;gap:1.25rem;align-items:stretch}
@media(max-width:560px){.elementor .e-con.vmm{grid-template-columns:1fr}}
.vmm-c.elementor-widget-icon-box{padding:1.85rem 1.5rem;text-align:center;position:relative;overflow:hidden;transition:transform .3s var(--ease),box-shadow .3s ease,background .3s,border-color .3s}
.vmm-c .elementor-icon-box-wrapper{display:flex;flex-direction:column;align-items:center;gap:.6rem;text-align:center}
.vmm-c .elementor-icon-box-icon{margin:0}
.vmm-c .elementor-icon{width:44px;height:44px;display:grid;place-items:center;font-size:22px;transition:transform .35s var(--ease),background .3s}
.vmm-c .elementor-icon-box-title{margin:0}
.vmm-c .elementor-icon-box-title,.vmm-c .elementor-icon-box-title a{font-size:1.125rem;font-weight:600}
.vmm-c .elementor-icon-box-description{font-size:.8125rem;line-height:1.75}
.vmm-c:after{content:"";position:absolute;left:0;right:0;bottom:0;height:4px;background:var(--acc);transform:scaleX(0);transform-origin:left;transition:transform .4s var(--ease)}
.vmm-c:hover{transform:translateY(-6px);box-shadow:0 20px 44px -22px #19295359}
.vmm-c:hover:after{transform:scaleX(1)}
.vmm-c:hover .elementor-icon{transform:scale(1.12) rotate(-6deg)}
.vmm-a.elementor-widget-icon-box{background:var(--navy);grid-row:span 2;display:flex;flex-direction:column;justify-content:center}
.vmm-a .elementor-icon-box-title,.vmm-a .elementor-icon{color:#fff}
.vmm-a .elementor-icon{background:#ffffff1f}
.vmm-a .elementor-icon-box-description{color:var(--w60)}
.vmm-b.elementor-widget-icon-box{background:var(--surface);border:1px solid var(--line)}
.vmm-b:hover{border-color:var(--acc)}
.vmm-b .elementor-icon{color:var(--acc);background:var(--acc-soft)}
.vmm-c2.elementor-widget-icon-box{background:var(--acc)}
.vmm-c2 .elementor-icon-box-title,.vmm-c2 .elementor-icon{color:#fff}
.vmm-c2 .elementor-icon{background:#ffffff2b}
.vmm-c2 .elementor-icon-box-description{color:#ffffffe0}
.vmm-a:after,.vmm-c2:after{background:#fff}
@media(max-width:560px){.vmm-a.elementor-widget-icon-box{grid-row:auto}}

/* journey: Elementor nested tabs with the year strip moved below the panel,
   each pane rendering one milestone through JetEngine listing 163 */
.elementor .e-con.jn{border:1px solid var(--line);background:var(--surface);display:block;padding:0}
.hm-jntabs .e-n-tabs{display:flex;flex-direction:column-reverse;gap:0}
.hm-jntabs .e-n-tabs-heading{display:grid;grid-template-columns:repeat(5,1fr);border-top:1px solid var(--line);gap:0}
@media(max-width:640px){.hm-jntabs .e-n-tabs-heading{grid-template-columns:repeat(3,1fr)}
.hm-jntabs .e-n-tab-title{border-bottom:1px solid var(--line)}
.hm-jntabs .e-n-tab-title:nth-child(3n){border-right:0}}
.hm-jntabs .e-n-tab-title{background:var(--surface);border:0;border-right:1px solid var(--line);border-top:3px solid transparent;border-radius:0;padding:1.05rem .6rem;font-family:var(--fd);font-size:1.0625rem;font-weight:700;color:var(--ink-3);justify-content:center;transition:color .2s,background .2s,border-color .2s}
.hm-jntabs .e-n-tab-title:last-child{border-right:0}
.hm-jntabs .e-n-tab-title:hover{color:var(--head);background:var(--xlight)}
.hm-jntabs .e-n-tab-title[aria-selected="true"]{color:var(--acc);border-top-color:var(--acc);background:var(--xlight)}
.hm-jntabs .e-n-tabs-content>.e-con{padding:0}
.elementor .e-con.jn-pane{padding:0}
.jn-grid .jet-listing-grid__items{margin:0}
.jn-grid .jet-listing-grid__item{padding:0;margin:0}
.elementor .e-con.jn-panel{display:grid;grid-template-columns:1fr 1fr;min-height:340px;gap:0}
@media(max-width:820px){.elementor .e-con.jn-panel{grid-template-columns:1fr}}
.elementor .e-con.jn-fig{position:relative;overflow:hidden;background:var(--xlight);min-height:260px;display:block;padding:0}
.jn-shot,.jn-shot .jet-listing-dynamic-image,.jn-shot .jet-listing-dynamic-image a{position:absolute;inset:0;display:block}
.jn-shot img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;transition:transform .6s var(--ease)}
.jn-fig:hover .jn-shot img{transform:scale(1.05)}
.elementor .e-con.jn-body{padding:clamp(1.75rem,1.25rem + 2vw,3rem);justify-content:center;gap:.75rem}
.jn-y{font-family:var(--fd);font-size:clamp(2.5rem,2rem + 2.2vw,3.75rem);font-weight:800;color:var(--acc);line-height:1;letter-spacing:-.03em}
.jn-h h3{font-size:clamp(1.2rem,1.05rem + .6vw,1.5rem);color:var(--head)}
.jn-p p{font-size:.9375rem;line-height:1.8;color:var(--body);max-width:52ch}

/* compliance framework cards: icon-box header + icon-list ticks */
.elementor .e-con.sup{display:grid;grid-template-columns:repeat(auto-fit,minmax(245px,1fr));gap:1.5rem}
.elementor .e-con.sup-c{background:var(--surface);border:1px solid var(--line);padding:1.5rem 1.35rem;gap:1rem;position:relative;overflow:hidden;transition:transform .3s var(--ease),box-shadow .3s ease,border-color .3s}
.elementor .e-con.sup-c:hover{transform:translateY(var(--lift));box-shadow:var(--sh-h);border-color:var(--acc)}
.sup-c:after{content:"";position:absolute;left:0;right:0;bottom:0;height:3px;background:var(--acc);transform:scaleX(0);transform-origin:left;transition:transform .4s var(--ease)}
.sup-c:hover:after{transform:scaleX(1)}
.sup-hd .elementor-icon-box-wrapper{display:flex;gap:.85rem;align-items:flex-start;text-align:left}
.sup-hd .elementor-icon-box-icon{margin:0;flex:none}
.sup-hd .elementor-icon{width:38px;height:38px;display:grid;place-items:center;background:var(--acc-soft);color:var(--acc);font-size:17px;transition:transform .35s var(--ease)}
.sup-c:hover .sup-hd .elementor-icon{transform:scale(1.09) rotate(-5deg)}
.sup-hd .elementor-icon-box-title{margin:0 0 .3rem}
.sup-hd .elementor-icon-box-title,.sup-hd .elementor-icon-box-title a{font-size:1rem;font-weight:600;color:var(--head)}
.sup-hd .elementor-icon-box-description{font-size:.8125rem;line-height:1.6;color:var(--body)}
.ticks-el .elementor-icon-list-items{display:flex;flex-direction:column;gap:.55rem}
.ticks-el .elementor-icon-list-item{align-items:flex-start}
.ticks-el .elementor-icon-list-icon{margin-top:.32rem}
.ticks-el .elementor-icon-list-icon i,.ticks-el .elementor-icon-list-icon svg{font-size:12px;width:12px;height:12px;color:var(--acc);fill:var(--acc)}
.ticks-el .elementor-icon-list-text{font-size:.875rem;line-height:1.7;color:var(--body)}
.elementor .e-con.sup-c.on{background:var(--navy);border-color:var(--navy)}
.sup-c.on .sup-hd .elementor-icon-box-title{color:#fff}
.sup-c.on .sup-hd .elementor-icon{background:#ffffff1f;color:#fff}
.sup-c.on .sup-hd .elementor-icon-box-description{color:var(--w60)}
.sup-c.on .ticks-el .elementor-icon-list-text{color:#ffffffcc}
.sup-c.on:after{background:#fff}
.elementor .e-con.sup-c.on:hover{border-color:var(--acc)}

/* licence icon boxes */
.elementor .e-con.ibx-grid{display:grid;gap:1rem}
.elementor .e-con.ibx-2{grid-template-columns:repeat(auto-fit,minmax(250px,1fr))}
.ibx-2 .ibx .elementor-icon-box-wrapper{align-items:flex-start}
.ibx .elementor-icon-box-title{margin-bottom:.35rem}
.ibx-2 .ibx .elementor-icon-box-title,.ibx-2 .ibx .elementor-icon-box-title a{font-size:.9375rem}
.ibx .elementor-icon-box-description{font-size:.8125rem;line-height:1.7;color:var(--body)}

/* sustainability: cards drive the stage cross-fade. The cards come first in
   the DOM so the sibling combinator can reach the stage; flex order puts the
   stage back on top visually. */
.elementor .e-con.sus-wrap{display:flex;flex-direction:column;gap:0}
.elementor .e-con.sus-wrap>.sus-stage{order:1;margin-bottom:1.5rem}
.elementor .e-con.sus-wrap>.numgrid{order:2}
.elementor .e-con.sus-stage{position:relative;aspect-ratio:16/9;overflow:hidden;background:var(--xlight);display:block;padding:0}
.sus-stage:after{content:"";position:absolute;left:0;bottom:0;width:120px;height:6px;background:var(--acc);z-index:2}
.sus-stage>.elementor-widget-image{position:absolute;inset:0;opacity:0;margin:0;transition:opacity .5s cubic-bezier(.16,1,.3,1)}
.sus-stage>.elementor-widget-image:first-child{opacity:1}
.sus-stage>.elementor-widget-image .elementor-widget-container,
.sus-stage>.elementor-widget-image figure{height:100%;width:100%;margin:0}
.sus-stage>.elementor-widget-image img{width:100%;height:100%;object-fit:cover;display:block}
.elementor .e-con.sus-4{grid-template-columns:repeat(4,1fr)}
@media(max-width:900px){.elementor .e-con.sus-4{grid-template-columns:1fr 1fr}}
@media(max-width:480px){.elementor .e-con.sus-4{grid-template-columns:1fr}}
.sus-hover>.numc{cursor:pointer;position:relative;overflow:hidden;border-top-color:var(--line);transition:border-color .25s,background .25s,transform .25s}
.sus-hover>.numc:after{content:"";position:absolute;left:0;right:0;bottom:0;height:3px;background:var(--acc);transform:scaleX(0);transform-origin:left;transition:transform .35s cubic-bezier(.16,1,.3,1)}
/* 92. Sustainability pillar 1 no longer carries a resting 'active' underline. The old
   rest/hover pair for :first-child sat at (0,4,0), above the generic :hover at (0,3,0), so
   hovering card 1 REMOVED its underline while every other card gained one -- states read as
   swapped. All four pillars now share one behaviour: plain at rest, teal underline on hover.
   The stage still shows image 1 at rest (section 13). */
.sus-hover>.numc:hover{border-top-color:var(--acc)}
.sus-hover>.numc:hover:after{transform:scaleX(1)}
/* superseded by section 84 */
/* superseded by section 84 */
.elementor .e-con.sus-foot{display:flex;flex-direction:row;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:1.25rem;margin-top:clamp(2.25rem,1.5rem + 2vw,3.25rem);padding-top:clamp(1.5rem,1rem + 1.5vw,2.25rem);border-top:1px solid var(--line)}
.sus-foot .lead .elementor-widget-container{margin:0;max-width:56ch}

/* download centre cards */
.elementor .e-con.grid-dl{display:grid;grid-template-columns:repeat(auto-fit,minmax(250px,1fr));gap:1.25rem}
.elementor .e-con.dlc{background:var(--surface);border:1px solid var(--line);border-top:3px solid var(--acc);padding:1.5rem 1.35rem;gap:0;transition:transform .3s var(--ease),box-shadow .3s ease,border-color .3s}
.elementor .e-con.dlc:hover{transform:translateY(var(--lift));box-shadow:var(--sh-h);border-color:var(--acc)}
.elementor .e-con.dlc>.fig{aspect-ratio:16/9;margin:-1.5rem -1.35rem 1.15rem;width:calc(100% + 2.7rem);max-width:none}
.dlc h4{font-size:1.0625rem;font-weight:600;color:var(--head);margin-bottom:.6rem}
.dlc-note p{font-size:.8125rem;color:var(--ink-3);font-style:italic}

/* contact */
.elementor .e-con.ct{display:grid;grid-template-columns:1fr 1fr;gap:0;align-items:stretch}
@media(max-width:900px){.elementor .e-con.ct{grid-template-columns:1fr}}
.elementor .e-con.ct-l{padding-right:clamp(1rem,.5rem + 2vw,3rem)}
@media(max-width:900px){.elementor .e-con.ct-l{padding-right:0;padding-bottom:2.5rem}}
.elementor .e-con.ct-cards{display:grid;grid-template-columns:1fr 1fr;gap:1.15rem;margin-top:2rem}
@media(max-width:480px){.elementor .e-con.ct-cards{grid-template-columns:1fr}}
.ct-c.elementor-widget-icon-box{background:var(--surface);border:1px solid var(--line);padding:1.5rem 1.25rem;text-align:center;transition:transform .3s var(--ease),box-shadow .3s ease,border-color .3s}
.ct-c.elementor-widget-icon-box:hover{transform:translateY(var(--lift));box-shadow:var(--sh-h);border-color:var(--acc)}
.ct-c .elementor-icon-box-wrapper{display:flex;flex-direction:column;align-items:center;text-align:center}
.ct-c .elementor-icon-box-icon{margin:0 auto .8rem}
.ct-c .elementor-icon{width:40px;height:40px;display:grid;place-items:center;background:var(--acc-soft);color:var(--acc);font-size:19px;transition:transform .35s var(--ease)}
.ct-c:hover .elementor-icon{transform:scale(1.1) rotate(-6deg)}
.ct-c .elementor-icon-box-title{margin:0 0 .45rem}
.ct-c .elementor-icon-box-title,.ct-c .elementor-icon-box-title a{font-size:1rem;font-weight:600;color:var(--head)}
.ct-c .elementor-icon-box-description{font-size:.8125rem;line-height:1.7;color:var(--body)}
.ct-c .elementor-icon-box-description a{color:var(--body)}
.ct-c .elementor-icon-box-description a:hover{color:var(--acc)}
.ct-c.on.elementor-widget-icon-box{background:var(--acc);border-color:var(--acc)}
.ct-c.on .elementor-icon-box-title,
.ct-c.on .elementor-icon-box-description,
.ct-c.on .elementor-icon-box-description a{color:#fff}
.ct-c.on .elementor-icon{background:#ffffff2b;color:#fff}
.elementor .e-con.ct-r{background:var(--navy);color:var(--w60);padding:clamp(1.75rem,1.25rem + 2vw,2.75rem);gap:0}
.ct-r h2{color:#fff}
.ct-r-note p{font-size:.875rem;line-height:1.8;margin-top:.85rem;margin-bottom:1.75rem;color:var(--w60)}

/* Contact Form 7 wearing the artifact form skin (.field / .f2 come from
   hmt-site.css and already match CF7's markup) */
.hm-cf7 .wpcf7-form{display:grid;gap:1rem}
.hm-cf7 .wpcf7-form-control-wrap{display:block}
.hm-cf7 .wpcf7-submit{width:100%;background:var(--acc);color:#fff;border:1px solid var(--acc);font-family:var(--fb);font-size:.75rem;font-weight:600;letter-spacing:.09em;text-transform:uppercase;padding:.95rem 1.6rem;border-radius:0;cursor:pointer;transition:background .2s,color .2s,border-color .2s}
.hm-cf7 .wpcf7-submit:hover{background:#fff;border-color:#fff;color:var(--navy)}
.hm-cf7 .wpcf7-spinner{display:block;margin:.5rem auto 0}
.hm-cf7 .wpcf7-response-output{margin:1rem 0 0;padding:.85rem 1rem;border:0;background:var(--acc);color:#fff;font-size:.875rem;font-weight:500}
.hm-cf7 form.invalid .wpcf7-response-output,.hm-cf7 form.unaccepted .wpcf7-response-output,.hm-cf7 form.failed .wpcf7-response-output{background:#B3261E}
.hm-cf7 .wpcf7-not-valid-tip{color:#FFB4A8;font-size:.75rem;margin-top:.25rem}




/* 404 */
.elementor .e-con.e404-sec{padding-block:clamp(4rem,3rem + 5vw,7rem)}
.elementor .e-con.wrap.e404{max-width:56ch;text-align:center;align-items:center}
.e404-n{font-family:var(--fd);font-size:clamp(4rem,3rem + 7vw,7rem);font-weight:800;color:var(--acc);line-height:1}
.e404 h1{margin-top:.5rem;font-size:clamp(1.75rem,1.3rem + 2vw,2.5rem)}

/* --- 14. Elementor kit overrides (section 14) -------------------------------
   Two systemic faults that only appeared once the pages stopped being HTML
   widgets. Both are cascade problems, not layout mistakes:

   (a) SPACING. The kit sets `--widgets-spacing:15px 40px`, and Elementor
       applies `gap:var(--row-gap) var(--column-gap)` to EVERY container. The
       artifact spaces with element margins, never with flex gap, so every
       stacked block gained 15px between its children and every row 40px
       between its columns — on top of the margins that were already there.

   (b) TYPE AND COLOUR. `.elementor-kit-10 h2` is (0,1,1) and the artifact's
       `h2` is (0,0,1), so the kit wins no matter which file loads last: every
       heading rendered at the kit scale (h2 38px against the artifact's 33px,
       h4 28px against 15-19px). Worse, the per-page CSS binds
       `.elementor-widget-heading .elementor-heading-title{color:var(--e-global-color-primary)}`
       at (0,2,0), which beats `.band h2{color:#fff}` (0,1,1) — so every heading
       sitting on a dark band was painted #192953 navy on dark green, and every
       .eb eyebrow lost its teal.

   hmt-wp.css loads after post-10.css and every post-NN.css, so restating the
   artifact's own rules at matching specificity is enough. --- */

/* (a) hand spacing back to the artifact's margins. Containers that genuinely
   need a gap set the `gap` shorthand in sections 9-13 and still win. */
.elementor .e-con{--gap:0px;--row-gap:0px;--column-gap:0px}

/* (b2) heading colour. Base first, then the light-on-dark contexts, then the
   eyebrows — each at a specificity that clears the one before it. */
.elementor-widget-heading .elementor-heading-title{color:var(--head);font-family:var(--fd);font-weight:700}
.bl-name .elementor-heading-title{font-family:inherit;color:inherit;font-weight:inherit}
.hero .elementor-widget-heading .elementor-heading-title,
.band .elementor-widget-heading .elementor-heading-title,
.bg-n .elementor-widget-heading .elementor-heading-title,
.corecard .elementor-widget-heading .elementor-heading-title,
.ctab-bx .elementor-widget-heading .elementor-heading-title,
.ct-r .elementor-widget-heading .elementor-heading-title{color:#fff}
.eb .elementor-heading-title{color:var(--acc);font-family:var(--fb);font-weight:600}
.dlc .elementor-heading-title,.numc .elementor-heading-title,
.sup-hd .elementor-heading-title,.ct-c .elementor-heading-title{font-weight:600}
.hero .eb .elementor-heading-title,
.band .eb .elementor-heading-title,
.corecard .eb .elementor-heading-title,
.ctab-bx .eb .elementor-heading-title,
.ct-r .eb .elementor-heading-title{color:var(--acc)}
.numc-n .elementor-heading-title,
.jn-y .elementor-heading-title,
.e404-n .elementor-heading-title{color:var(--acc);font-family:var(--fd);font-weight:800}

/* (b3) the same binding hits icon-box titles and descriptions */
.feat-c .elementor-icon-box-title,.feat-c .elementor-icon-box-title a,
.vmm-a .elementor-icon-box-title,.vmm-a .elementor-icon-box-title a,
.vmm-c2 .elementor-icon-box-title,.vmm-c2 .elementor-icon-box-title a,
.sup-c.on .elementor-icon-box-title,.sup-c.on .elementor-icon-box-title a,
.ct-c.on .elementor-icon-box-title,.ct-c.on .elementor-icon-box-title a{color:#fff}

/* (b4) text-editor paragraphs with no artifact class fall back to the kit's
   18px. The artifact body measure is 15.5px/1.72. */
.elementor-widget-text-editor{font-family:var(--fb);font-size:15.5px;line-height:1.72;color:var(--body)}
.band .elementor-widget-text-editor,.bg-n .elementor-widget-text-editor,
.ctab-bx .elementor-widget-text-editor,.ct-r .elementor-widget-text-editor,
.corecard .elementor-widget-text-editor,.hero .elementor-widget-text-editor{color:var(--w60)}
.lead .elementor-widget-container,.lead p{font-size:.9375rem;line-height:1.8}

/* --- 15. Flex direction (section 15) ---------------------------------------
   Elementor's containers default to `--flex-direction:column`, applied at
   `.elementor-element:where(.e-con-full,.elementor-widget)` — (0,1,0). The
   artifact's own rules (`.btns{display:flex;flex-wrap:wrap;gap:.85rem}`) never
   state a direction because the CSS default is row, so every button group on
   the site was stacking vertically instead of sitting side by side. Same trap
   for any artifact row that relied on the default. --- */
.elementor .e-con.btns{flex-direction:row;align-items:center}
.elementor .e-con.icard-b{flex-direction:row;align-items:center;gap:.8rem}
@media(max-width:420px){.elementor .e-con.btns{flex-direction:column;align-items:stretch}}

/* --- 16. The two kit bindings that outrank a plain class (section 16) -------
   Everything else Elementor binds to the global palette sits at (0,2,0), so the
   rules in sections 9-15 beat it on load order. These two do not:

   * `.elementor-widget-icon-box:has(:hover) .elementor-icon-box-title` is
     (0,3,0) because :has() carries the specificity of :hover — so hovering a
     card repainted its title with the kit's primary colour, turning the white
     titles on the dark bands navy for as long as the pointer was over them.
   * the nested-tabs title binding is roughly (0,5,0), so the artifact's tab
     colours never applied to the Products category tabs or the About journey
     year strip. --- */

/* icon-box hover: keep the artifact's colour through the hover state */
.elementor-widget-icon-box.feat-c:has(:hover) .elementor-icon-box-title,
.elementor-widget-icon-box.vmm-a:has(:hover) .elementor-icon-box-title,
.elementor-widget-icon-box.vmm-c2:has(:hover) .elementor-icon-box-title,
.ct-c.on.elementor-widget-icon-box:has(:hover) .elementor-icon-box-title{color:#fff}
.elementor-widget-icon-box.ibx:has(:hover) .elementor-icon-box-title,
.elementor-widget-icon-box.vmm-b:has(:hover) .elementor-icon-box-title,
.elementor-widget-icon-box.ct-c:has(:hover) .elementor-icon-box-title,
.elementor-widget-icon-box.icard-lbl:has(:hover) .elementor-icon-box-title{color:var(--head)}
.sup-c .elementor-widget-icon-box:has(:hover) .elementor-icon-box-title{color:var(--head)}
.sup-c.on .elementor-widget-icon-box:has(:hover) .elementor-icon-box-title{color:#fff}

/* product category tabs — the artifact's .ptab */
.hm-ptabs.elementor-widget-n-tabs > .e-n-tabs > .e-n-tabs-heading > .e-n-tab-title,
.hm-ptabs.elementor-widget-n-tabs > .e-n-tabs > .e-n-tabs-heading > .e-n-tab-title > .e-n-tab-title-text{color:var(--body)}
.hm-ptabs.elementor-widget-n-tabs > .e-n-tabs > .e-n-tabs-heading > .e-n-tab-title:hover,
.hm-ptabs.elementor-widget-n-tabs > .e-n-tabs > .e-n-tabs-heading > .e-n-tab-title:hover > .e-n-tab-title-text{color:var(--head)}
.hm-ptabs.elementor-widget-n-tabs > .e-n-tabs > .e-n-tabs-heading > .e-n-tab-title[aria-selected="true"],
.hm-ptabs.elementor-widget-n-tabs > .e-n-tabs > .e-n-tabs-heading > .e-n-tab-title[aria-selected="true"] > .e-n-tab-title-text{color:#fff}

/* About journey year strip — the artifact's .jn-y-btn */
.hm-jntabs.elementor-widget-n-tabs > .e-n-tabs > .e-n-tabs-heading > .e-n-tab-title,
.hm-jntabs.elementor-widget-n-tabs > .e-n-tabs > .e-n-tabs-heading > .e-n-tab-title > .e-n-tab-title-text{color:var(--ink-3)}
.hm-jntabs.elementor-widget-n-tabs > .e-n-tabs > .e-n-tabs-heading > .e-n-tab-title:hover,
.hm-jntabs.elementor-widget-n-tabs > .e-n-tabs > .e-n-tabs-heading > .e-n-tab-title:hover > .e-n-tab-title-text{color:var(--head)}
.hm-jntabs.elementor-widget-n-tabs > .e-n-tabs > .e-n-tabs-heading > .e-n-tab-title[aria-selected="true"],
.hm-jntabs.elementor-widget-n-tabs > .e-n-tabs > .e-n-tabs-heading > .e-n-tab-title[aria-selected="true"] > .e-n-tab-title-text{color:var(--acc)}

/* --- 17. Guard against the artifact's bare .rule (section 17) ---------------
   `.ph-card .rule{height:1px;background:var(--line);...}` was written for a
   1px <div> in the artifact. Put that class on an Elementor widget and it
   collapses the widget WRAPPER to 1px while the divider inside keeps its own
   padding and separator, which then paint straight over the breadcrumb below.
   That is what the stray line through "Home > Products" was. The Products hero
   is retagged .ph-rule now; this makes the failure impossible if the class is
   ever reapplied by hand in the editor. --- */
.elementor .elementor-widget.rule{height:auto;background:0 0;max-width:70%;margin:1.15rem auto}
.elementor .elementor-widget.rule .elementor-divider{padding-block:0}
.elementor .elementor-widget.rule .elementor-divider-separator{border-top-color:var(--line)}

/* --- 18. Navigation hover: colour only (section 18) ------------------------
   The menu links keep the colour change and lose the slide. Applied to both
   navigations: the header nav never had a transform (its slide could only have
   come from a Pro pointer animation, which is off), so that half is a guard;
   the footer's Quick Links did carry `transform:translateX(4px)`, ported from
   the artifact's `.ft-links a:hover`, and that is the one being removed. --- */
.hm-nav .elementor-nav-menu--main .elementor-item,
.hm-nav .elementor-nav-menu--main .elementor-item:hover,
.hm-nav .elementor-nav-menu--main .elementor-item:focus,
.hm-nav .elementor-nav-menu--dropdown .elementor-item,
.hm-nav .elementor-nav-menu--dropdown .elementor-item:hover,
.hm-ftnav .elementor-nav-menu--main .elementor-item,
.hm-ftnav .elementor-nav-menu--main .elementor-item:hover,
.hm-ftnav .elementor-nav-menu--main .elementor-item:focus{transform:none;transition:color .2s ease}

/* --- 19. The nav padding jump (section 19) ---------------------------------
   THIS is the flicker, and it was never a transform.

   Elementor Pro ships, ungated by any pointer setting:
     .elementor-nav-menu--main .elementor-nav-menu a,
     .elementor-nav-menu--main .elementor-nav-menu a:hover,
     .elementor-nav-menu--main .elementor-nav-menu a:focus{padding:13px 20px}
   That is (0,3,1). Section 9's `.hm-nav .elementor-nav-menu--main
   .elementor-item{padding:.5rem .6rem}` is only (0,3,0), so it wins at rest and
   LOSES on hover: the item's horizontal padding jumps 9.6px -> 20px, the item
   widens by ~21px, and because `.logo{margin-right:auto}` right-aligns the
   whole nav block, the nav's left edge snaps 20px to the LEFT and back.
   Measured in a local replica: left edge 770 -> 750 on hover, 0 with this rule.

   Fixed by matching Pro's own `a.elementor-item` shape, which lifts these to
   (0,4,1). The footer nav had the same latent jump. --- */
.hm-nav .elementor-nav-menu--main .elementor-nav-menu a.elementor-item,
.hm-nav .elementor-nav-menu--main .elementor-nav-menu a.elementor-item:hover,
.hm-nav .elementor-nav-menu--main .elementor-nav-menu a.elementor-item:focus,
.hm-nav .elementor-nav-menu--main .elementor-nav-menu a.elementor-item.highlighted{padding:.5rem .6rem}
.hm-ftnav .elementor-nav-menu--main .elementor-nav-menu a.elementor-item,
.hm-ftnav .elementor-nav-menu--main .elementor-nav-menu a.elementor-item:hover,
.hm-ftnav .elementor-nav-menu--main .elementor-nav-menu a.elementor-item:focus,
.hm-ftnav .elementor-nav-menu--main .elementor-nav-menu a.elementor-item.highlighted{padding:.28rem 0}

/* Pro also gives every item an empty :before/:after that transitions opacity
   over .3s on hover. Only the active item's :after is given a `content` by
   section 9 (the teal underline); pin it so it cannot fade in and out. */
.hm-nav .elementor-nav-menu--main .elementor-item:before,
.hm-ftnav .elementor-nav-menu--main .elementor-item:before,
.hm-ftnav .elementor-nav-menu--main .elementor-item:after{content:none;display:none}
.hm-nav .elementor-nav-menu--main .elementor-item:not(.elementor-item-active):after{content:none;display:none}
.hm-nav .elementor-nav-menu--main .elementor-item.elementor-item-active:after{opacity:1;transform:none;transition:none}

/* --- 20. Icon-box glyph colour + JetEngine image wrappers (section 20) ------

   (a) BLUE ICONS. Elementor renders Font Awesome as inline <svg>, and the
       per-page CSS binds
         .elementor-widget-icon-box.elementor-view-default .elementor-icon,
         .elementor-widget-icon-box.elementor-view-framed  .elementor-icon
           {fill:var(--e-global-color-primary);color:var(--e-global-color-primary)}
       at (0,3,0). Sections 12-13 set the glyph colour with `.ibx .elementor-icon`
       and friends at only (0,2,0), so they lost on BOTH `fill` and `color` and
       every icon rendered #192953 navy — measured, not guessed. The teal tile
       behind them still applied, which is why they read as blue-on-teal.
       `fill:currentColor` makes the glyph follow whatever colour we set, and
       each context restates that colour at matching specificity.

   (b) THE ANNOUNCEMENT SLIDE PHOTOS. jet-listing-dynamic-image renders
       <div class="jet-listing jet-listing-dynamic-image"><img></div> — no
       .elementor-widget-container and no <figure>, which is what section 12's
       .nb-shot rule assumed. So .nb-shot filled .nb-fig but the inner div kept
       auto height, `height:100%` on the img resolved to `auto`, and the photo
       sat at its natural ratio against the top of a 440px panel with the
       gradient showing underneath. Same wrapper fix .jn-shot already has. --- */

/* (a) glyphs follow their context colour */
.elementor-widget-icon-box.elementor-view-default .elementor-icon,
.elementor-widget-icon-box.elementor-view-framed .elementor-icon,
.elementor-widget-icon-box.elementor-view-stacked .elementor-icon{fill:currentColor}
.ibx.elementor-widget-icon-box .elementor-icon{color:#fff}
.feat-c.elementor-widget-icon-box .elementor-icon{color:#fff}
.vmm-a.elementor-widget-icon-box .elementor-icon,
.vmm-c2.elementor-widget-icon-box .elementor-icon{color:#fff}
.vmm-b.elementor-widget-icon-box .elementor-icon{color:var(--acc)}
.sup-hd.elementor-widget-icon-box .elementor-icon{color:var(--acc)}
.sup-c.on .sup-hd.elementor-widget-icon-box .elementor-icon{color:#fff}
.ct-c.elementor-widget-icon-box .elementor-icon{color:var(--acc)}
.ct-c.on.elementor-widget-icon-box .elementor-icon{color:#fff}
.icard-lbl.elementor-widget-icon-box .elementor-icon{color:var(--acc)}

/* (b) JetEngine dynamic images need their own wrapper stretched */
.nb-shot .jet-listing-dynamic-image,
.nb-shot .jet-listing-dynamic-image a{position:absolute;inset:0;display:block}
.nb-shot img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}
.cert-doc .jet-listing-dynamic-image,
.cert-doc .jet-listing-dynamic-image a{display:block;height:100%}
.cert-shot img{width:100%;height:100%;object-fit:contain;display:block}

/* --- 21. The announcement photos were transparent (section 21) --------------
   Section 20 fixed the wrapper but the photos still did not appear, because
   the wrapper was never the whole story. The artifact's own stylesheet says:

     .nb-fig img{...;z-index:-2;opacity:0;transition:opacity .55s ...}
     .nb-fig img.on{opacity:1}

   In the artifact the carousel was hand-written and its script added `.on` to
   the active slide's image to cross-fade it in. On WordPress the carousel is
   JetEngine/Slick, nothing ever adds `.on`, so every announcement photo sat at
   opacity:0 — and at z-index:-2, behind .nb-fig's own gradient background for
   good measure. The markup, the files and the bindings were all correct the
   whole time; the images were simply invisible.

   Section 20's `.nb-shot img` rule ties with `.nb-fig img` on specificity and
   wins on order, but it only declared position/size/object-fit — so opacity and
   z-index kept the artifact's values. Declaring them here finishes the job.
   Also ports the artifact's `.nb-fig::after` accent bar, which the native
   rebuild had missed. --- */
.nb-shot .jet-listing-dynamic-image,
.nb-shot .jet-listing-dynamic-image a{position:absolute;inset:0;display:block}
.nb-shot img,.nb-fig img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;opacity:1;z-index:auto;transition:none}
.elementor .e-con.nb-fig:after{content:"";position:absolute;right:0;bottom:0;width:120px;height:6px;background:var(--acc);z-index:3}

/* Same trap on the Sustainability stage: the artifact has
   `.sus-stage img{...opacity:0...}` with its script adding `.on` to the
   active one. The native build fades the WIDGET WRAPPER instead (section
   13), so the <img> inside stayed at opacity 0 and all four pillar photos
   were invisible. Hand opacity control back to the wrapper. */
.sus-stage img{opacity:1}
.sus-stage .elementor-widget-image img{opacity:1}

/* --- 22. Announcement slide: back to the artifact's layout (section 22) -----
   Section 12 gave .nb-box, .nb-bx, .nb-fig and .nb-meta rules but never ported
   `.nb-top`, so that row fell back to an Elementor flex COLUMN container and
   the "What's Happening" eyebrow lost its left alignment. The artifact has:

     .nb-top{display:flex;align-items:center;justify-content:space-between;
             gap:1rem;margin-bottom:.15rem;min-height:30px;flex:none}
     .nb-top .eb{margin-bottom:0}

   — a row with the eyebrow hard left and the status badge hard right. Also
   restores the artifact's line clamps, which keep a long announcement from
   pushing the 440px card out of shape. --- */
.elementor .e-con.nb-top{display:flex;flex-direction:row;align-items:center;justify-content:space-between;gap:1rem;margin-bottom:.15rem;min-height:30px;flex:none;text-align:left}
.nb-top>.elementor-widget{flex:0 0 auto;width:auto;text-align:left}
.nb-top .eb{margin-bottom:0}
.nb-top .eb .elementor-widget-container,
.nb-top .eb .elementor-heading-title{text-align:left}

/* the whole left column reads left, top-down */
.elementor .e-con.nb-bx{align-items:stretch;text-align:left}
.elementor .e-con.nb-copy{min-width:0;min-height:0;display:flex;flex-direction:column;align-items:stretch;gap:0;text-align:left}
.elementor .e-con.nb-meta{margin-top:auto}

/* artifact line clamps — 3 lines of title, 4 of body */
.nb-h .jet-listing-dynamic-field__content{display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:3;overflow:hidden}
.nb-p .jet-listing-dynamic-field__content{display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:4;overflow:hidden}
.nb-p p{margin-top:.8rem;margin-bottom:1.15rem}

/* JetEngine builds the carousel with Swiper and injects the controls at run
   time, so only their appearance is set here — the artifact's .nb-arw square
   and .nb-dot pill. Placement is left to JetEngine for now. */
.nb-grid .jet-listing-grid__slider-icon{width:38px;height:38px;display:inline-flex;align-items:center;justify-content:center;background:var(--surface);border:1px solid var(--line);border-radius:0;color:var(--head);cursor:pointer;transition:background .2s,border-color .2s,color .2s}
.nb-grid .jet-listing-grid__slider-icon:hover{background:var(--acc);border-color:var(--acc);color:#fff}
.nb-grid .jet-listing-grid__slider-icon svg{width:15px;height:15px}
.nb-grid .jet-listing-grid__slider-icon svg path{fill:currentColor}
.nb-grid .swiper-pagination-bullet{width:9px;height:9px;border-radius:50%;background:var(--line);opacity:1;transition:background .25s,width .25s}
.nb-grid .swiper-pagination-bullet-active{background:var(--acc);width:26px;border-radius:5px}

/* --- 23. No button inside a button (section 23) -----------------------------
   The native rebuild put the artifact's button classes on the Elementor WIDGET
   WRAPPER (`_css_classes:"btn btn-p hm-btn"`) while section 12 skinned the real
   <a class="elementor-button"> inside it. Both got the same treatment, so every
   button rendered as a teal box inside a teal box — measured in the replica as a
   197x53 wrapper wrapping a 144x49 button, each with its own background,
   padding and 1px border.

   Fixed at source: `btn btn-p / btn-o / btn-l / btn-d / btn-w` stripped from all
   14 button widgets across home, products, sustainability, downloads, about,
   compliance and 404. Only the `hm-btn*` hook remains, which is what section 12
   actually styles. Backups in options hmt_btnclass_backup_<id>.

   `.pc-more` on the product cards is the same bug but its class is a live CSS
   hook (section 11 targets `.pc-more .jet-listing-dynamic-link__link`), so the
   wrapper is stripped of its decoration here instead of being renamed.

   The `.btn` block is a guard: re-adding those classes by hand in the editor
   can no longer produce the outer box. --- */
.elementor .elementor-widget.pc-more,
.elementor .elementor-widget.pc-more:hover,
.elementor .elementor-widget.pc-more:focus{background:0 0;border:0;padding:0;min-height:0;box-shadow:none;overflow:visible;position:static;letter-spacing:normal;text-transform:none;color:inherit;font-size:inherit}
.elementor .elementor-widget-button.btn,
.elementor .elementor-widget-button.btn:hover,
.elementor .elementor-widget-button.btn:focus{background:0 0;border:0;padding:0;min-height:0;box-shadow:none;overflow:visible;position:static;transform:none}
.elementor .elementor-widget.pc-more:before,
.elementor .elementor-widget.pc-more:after,
.elementor .elementor-widget-button.btn:before,
.elementor .elementor-widget-button.btn:after{content:none;display:none}

/* --- 24. Tab labels on the teal state (section 24) --------------------------
   post-NN.css binds BOTH the hover and the selected background of every nested
   tab to the kit accent:
     ... .e-n-tab-title[aria-selected="false"]:hover{background:var(--e-global-color-accent)}
     ... .e-n-tab-title[aria-selected="true"]      {background:var(--e-global-color-accent)}
   at ~(0,5,0), which beats section 13's `background:var(--xlight)` (0,2,0). So
   those states are teal, and section 16 was still painting the About journey's
   year label var(--acc) on top of it — teal text on a teal tile, i.e. invisible.
   Both tab strips now use white on the teal states. --- */
.hm-jntabs.elementor-widget-n-tabs > .e-n-tabs > .e-n-tabs-heading > .e-n-tab-title:hover,
.hm-jntabs.elementor-widget-n-tabs > .e-n-tabs > .e-n-tabs-heading > .e-n-tab-title:hover > .e-n-tab-title-text,
.hm-jntabs.elementor-widget-n-tabs > .e-n-tabs > .e-n-tabs-heading > .e-n-tab-title[aria-selected="true"],
.hm-jntabs.elementor-widget-n-tabs > .e-n-tabs > .e-n-tabs-heading > .e-n-tab-title[aria-selected="true"] > .e-n-tab-title-text,
.hm-ptabs.elementor-widget-n-tabs > .e-n-tabs > .e-n-tabs-heading > .e-n-tab-title:hover,
.hm-ptabs.elementor-widget-n-tabs > .e-n-tabs > .e-n-tabs-heading > .e-n-tab-title:hover > .e-n-tab-title-text,
.hm-ptabs.elementor-widget-n-tabs > .e-n-tabs > .e-n-tabs-heading > .e-n-tab-title[aria-selected="true"],
.hm-ptabs.elementor-widget-n-tabs > .e-n-tabs > .e-n-tabs-heading > .e-n-tab-title[aria-selected="true"] > .e-n-tab-title-text{color:#fff}

/* --- 25. Product pagination (section 25, rewritten) --------------------------
   JSF nests its markup. Each page renders as
     <div class="jet-filters-pagination__item">
       <div class="jet-filters-pagination__link">2</div>
     </div>
   — the inner div comes from the `templates.pagination.item` string published in
   JetSmartFilterSettings. The first cut of this section gave the tile treatment
   to BOTH nodes, so every page number rendered as a box inside a box: [[2]]
   instead of [2]. Exactly the trap section 23 fixed for the buttons — style the
   inner node, keep the wrapper bare. --- */
.hm-pag{margin-top:clamp(1.75rem,1.25rem + 1.5vw,2.5rem)}
.hm-pag .jet-filters-pagination{display:flex;justify-content:center;align-items:center;flex-wrap:wrap;gap:.45rem}

/* wrapper: carries no box of its own */
.hm-pag .jet-filters-pagination__item,
.hm-pag .jet-filters-pagination__item:hover{background:0 0;border:0;padding:0;margin:0;min-width:0;height:auto;display:inline-flex;box-shadow:none}

/* the tile */
.hm-pag .jet-filters-pagination__link{min-width:38px;height:38px;display:inline-flex;align-items:center;justify-content:center;padding:0 .65rem;border:1px solid var(--line);background:var(--surface);color:var(--head);font-family:var(--fb);font-size:.75rem;font-weight:600;letter-spacing:.06em;text-transform:uppercase;border-radius:0;cursor:pointer;transition:background .2s,border-color .2s,color .2s}
.hm-pag .jet-filters-pagination__link:hover{background:var(--acc);border-color:var(--acc);color:#fff}

/* current page */
.hm-pag .jet-filters-pagination__current .jet-filters-pagination__link,
.hm-pag .jet-filters-pagination__item.jet-filters-pagination__current .jet-filters-pagination__link{background:var(--acc);border-color:var(--acc);color:#fff}

/* ellipsis is text, not a tile */
.hm-pag .jet-filters-pagination__dots,
.hm-pag .jet-filters-pagination__dots:hover{border:0;background:0 0;color:var(--ink-3);min-width:auto;height:38px;padding:0 .2rem;cursor:default;display:inline-flex;align-items:center}

/* --- 26. Section-title spacing (section 26) ---------------------------------
   In the artifact every `.sec-ttl` block carries its own bottom margin as an
   inline style (36px, 40px on Products and Sustainability). Inline styles were
   not ported to the native build, and once section 14 zeroed the container gap
   there was nothing left between a section's title block and the content under
   it — which is why the Products tab strip sat hard against "Built Around
   Manufacturing Requirements". Measured from the artifact: mb 36px generally,
   40px where the block is centred. --- */
.elementor .e-con.sec-ttl{margin-bottom:2.25rem}
.elementor .e-con.sec-ttl.ctr{margin-bottom:2.5rem;margin-inline:auto;text-align:center}
.sec-ttl.ctr .lead .elementor-widget-container{margin-inline:auto}

/* --- 27. About page corrections (section 27) --------------------------------

   (a) JOURNEY PHOTO. Belt-and-braces fill for the milestone image. The panel
       photo sits in an absolutely positioned stack — widget > .jet-listing-
       dynamic-image > img — and post-163.css styles that middle node as a flex
       box (`justify-content:flex-start`) at (0,4,0). Restated here at (0,4,1)
       so every node in the chain fills .jn-fig regardless.

   (b) ICON ALIGNMENT. Elementor ships
         .elementor-widget-icon-box.elementor-position-block-start
           .elementor-icon-box-wrapper{align-items:unset!important; ...}
       — an !important that no plain rule can beat, so the icon block stretched
       and its glyph sat hard left while the text below stayed centred. Rather
       than fight the !important, centre the icon INSIDE its own block. Applies
       to every top-positioned icon box: vision/mission/values, why-choose-us
       and the contact cards.

   (c) WHY CHOOSE US, left aligned on About, using the artifact's own
       `.band-left` variant. `.band .eb` and section 13's `.band-lead` both
       centre by default, so both are re-pointed here. --- */

/* (a) */
.elementor .e-con.jn-fig .jn-shot,
.elementor .e-con.jn-fig .jn-shot .jet-listing-dynamic-image,
.elementor .e-con.jn-fig .jn-shot .jet-listing-dynamic-image a,
.elementor .e-con.jn-fig .jn-shot .jet-listing-dynamic-image__figure{position:absolute;inset:0;display:block;width:100%;height:100%;margin:0;padding:0}
.elementor .e-con.jn-fig .jn-shot img{position:absolute;inset:0;width:100%;height:100%;max-width:none;object-fit:cover;display:block}

/* (b) */
.vmm-c .elementor-icon-box-icon,
.feat-c .elementor-icon-box-icon,
.ct-c .elementor-icon-box-icon{display:flex;justify-content:center;width:100%}
.vmm-c .elementor-icon,
.feat-c .elementor-icon,
.ct-c .elementor-icon{margin-inline:auto}

/* (c) */
.band-left .eb,
.band-left .eb .elementor-widget-container,
.band-left .eb .elementor-heading-title{text-align:left}
.band-left .elementor-widget-heading .elementor-heading-title{text-align:left;margin-inline:0}
.band-left .band-lead .elementor-widget-container{text-align:left;margin:1.15rem 0 0}

/* ============ 28 — footer logo left-aligned ============
   Elementor's widget-image.min.css ships .elementor-widget-image{text-align:center}
   and .elementor-widget-image img{display:inline-block}. Conditional widget CSS can
   load after hmt-site.css, so .logomark img{display:block} loses on order.
   Restate at (0,3,x) so the footer lockup sits flush left like the artifact. */
.elementor .elementor-widget-image.logomark-ft{text-align:left}
.elementor .elementor-widget-image.logomark-ft img{display:block;margin-inline-start:0;margin-inline-end:auto}
.elementor .elementor-widget-image.logomark-ft a{display:inline-block}

/* ============ 29 — announcement greeting: pin bottom-left ============
   The artifact wrote .nb-greet as a flex ROW with align-items:flex-end, which in a
   row means 'push the child to the BOTTOM'. Elementor forces flex-direction:column
   on every .e-con, so the same declaration was re-read as 'push the child to the
   RIGHT' on the cross axis, and justify-content defaulted to flex-start = TOP.
   Result: greeting rendered top-right. Restate the whole box explicitly.

   2026-09-11: `display:flex` deliberately NOT restated here. At (0,3,0) it out-specified
   Elementor's own `.elementor .elementor-hidden-desktop{display:none}` at (0,2,0), so the
   builder's Advanced > Responsive toggles silently did nothing on this container. The box is
   `e-flex e-con`, so Elementor's own `--display:flex` already makes it a flex box; we only
   need to restate the axis. Leaving display out hands the hide toggles back to the client. */
.elementor .e-con.nb-greet{position:absolute;top:auto;right:0;bottom:0;left:0;height:auto;z-index:2;flex-direction:column;align-items:flex-start;justify-content:flex-end;text-align:left}
.elementor .e-con.nb-greet > .elementor-widget{margin-left:0;margin-right:auto}
.nb-greet .jet-listing-dynamic-field{justify-content:flex-start}
.nb-greet .jet-listing-dynamic-field__content{text-align:left}

/* ============ 30 — announcement photo: drop the teal corner accent ============
   The artifact draws a 120x6 teal tab at the bottom-right of the slide photo via
   .nb-fig::after. Client asked for it removed. Suppressed here rather than edited
   out of hmt-site.css, so the artifact stylesheet stays a faithful copy of the
   approved design and this can be reverted by deleting this block. */
.elementor .e-con.nb-fig:after{display:none;content:none}

/* ============ 31 (rev3) — announcement slider: full-width card, arrows in the gutter ============
   The card must line up with every other section, so the slider keeps the full .wrap
   width and the arrows are pushed OUTSIDE it instead.
   Safe because JetEngine appends the arrows to listingWrapper = .jet-listing-grid
   (the PARENT of .swiper) — see jet-engine/assets/js/frontend/src/components/slider.js:
       let listingWrapper = swiperElement.closest('.jet-listing-grid.jet-listing');
       listingWrapper.appendChild( nextArrowElement );
   so a negative offset is not clipped by the swiper's overflow:hidden.
   The offset is capped by the gutter that actually exists: .wrap is
   width:min(100% - 2.5rem, 1280px), so the free space each side is (100vw - 100%)/2.
   min() takes the smaller of the 56px we want and the room available (less 16px of
   breathing space), so the buttons can never leave the viewport or force a scrollbar.
   Full clearance from ~1392px viewport up; below that they ride the card corner,
   because there is only ~20px of gutter to work with.
   rev1 put margin on .nb-box — that opened a 112px gap between cards and the previous
   slide showed through. rev2 padded .jet-listing-grid — that shrank the card out of
   alignment with the rest of the page. Do not reintroduce either. */
.nb-grid .jet-listing-grid.jet-listing{position:relative}
.nb-grid .jet-listing-grid__slider-icon.swiper-arrow{margin-top:-19px;left:calc(-1 * min(56px, max(0px, (100vw - 100% - 16px)/2)))}
.nb-grid .jet-listing-grid__slider-icon.swiper-arrow.next-arrow{left:auto;right:calc(-1 * min(56px, max(0px, (100vw - 100% - 16px)/2)))}

/* ============ 32 — Home page revision pass ============ */

/* 32a — cards now carry title only; kill the gap the description used to fill.
   (The 12 icon-boxes had no description_text set at all, so Elementor was
   rendering its built-in Lorem ipsum placeholder on the live site.) */
.ibx .elementor-icon-box-title{margin-bottom:0}
.feat-c .elementor-icon-box-icon{margin-bottom:.9rem}
.elementor .e-con.feat-c,.feat-c.elementor-widget-icon-box{padding:2rem 1.6rem}

/* 32b — world map at full width.
   JetElements ships .jet-inline-svg{display:inline-block}, so the widget
   shrink-wrapped the SVG to its 300px intrinsic default and svg_alignment:center
   parked it in the middle of the row. jet-elements.css loads AFTER hmt-wp.css,
   so these have to win on specificity, not order. */
.wmap-holder .jet-inline-svg,
.wmap-holder .jet-inline-svg__wrapper,
.wmap-holder .jet-inline-svg__inner,
.wmap-holder .elementor-jet-inline-svg{display:block;width:100%;max-width:100%;font-size:0;line-height:0}
.wmap-holder .jet-inline-svg svg,
.wmap-holder svg.wmap{width:100%;height:auto;min-width:0;display:block}
.elementor .e-con.wmapwrap{padding:clamp(1rem,2vw,2rem)}

/* 32c — marker hover tooltip (country, type, facility list).
   The ported hmt-app.js looks for #wtip, which the WP build never had, so the
   whole hover block was inert. New markup id is #hmtWtip and the behaviour is
   driven by the appended IIFE, leaving the old block permanently dormant. */
.wmap-tip,.wmap-tip .elementor-widget-container{position:static;margin:0;line-height:0}
.wtip{max-width:min(320px,72vw);white-space:normal}
.wtip em{display:block;font-style:normal;margin-top:.5rem;padding-top:.5rem;border-top:1px solid #ffffff2e}
.wtip em:empty{display:none;margin:0;padding:0;border:0}
.wtip em i{display:block;font-style:normal;font-size:.75rem;line-height:1.5;color:#ffffffd6}
.wtip em i + i{margin-top:.12rem}
.wtip.below{transform:translate(-50%,14px) scale(.96)}
.wtip.below.on{transform:translate(-50%,10px) scale(1)}
.wtip.below::after{bottom:auto;top:-5px}
.mk,.mk-hit{cursor:pointer}

/* 32d — bigger figures and captions on the three stat cards */
.cbar-item .elementor-counter-number-wrapper{font-size:clamp(2.5rem,1.7rem + 2.4vw,3.5rem);line-height:1.05}
.cbar-item .elementor-counter-title{font-size:clamp(.875rem,.8rem + .25vw,1rem);margin-top:.45rem;letter-spacing:.01em}
.elementor .e-con.cbar .cbar-item{padding:2.25rem 1rem}

/* ============ 33 — industries icons left, bigger bulleted map tooltip ============ */

/* 33a — Industries Served: icon beside the label, both flush left.
   The widgets carried position:top, so Elementor emitted
   .elementor-position-block-start .elementor-icon-box-wrapper{
     align-items:unset!important;flex-direction:column;text-align:center}
   at (0,2,0) WITH !important, loaded after hmt-wp.css — it beat our row rule and
   stacked the icon centred above the title. Fixed at source by setting the widget
   position to left (desktop, tablet and mobile), which emits
   .elementor-position-inline-start{flex-direction:row;text-align:start} instead.
   These belt-and-braces rules keep it correct if the setting is ever reset. */
.icard-lbl.elementor-widget-icon-box .elementor-icon-box-wrapper{flex-direction:row;align-items:center;text-align:left;gap:.8rem}
.icard-lbl.elementor-widget-icon-box .elementor-icon-box-icon{margin:0;flex:none}
.icard-lbl.elementor-widget-icon-box .elementor-icon-box-content{width:auto;text-align:left}

/* 33b — map tooltip: bulleted, larger type.
   Hanging indent so wrapped facility names line up under the first character
   rather than under the bullet. */
.wtip{max-width:min(360px,76vw);padding:.7rem .95rem}
.wtip b{font-size:1.0625rem;line-height:1.25}
.wtip span{font-size:.75rem;margin-top:.25rem}
.wtip em{margin-top:.6rem;padding-top:.6rem}
.wtip em i{position:relative;padding-left:.95rem;font-size:.875rem;line-height:1.6;color:#ffffffe6}
.wtip em i:before{content:"";position:absolute;left:.15rem;top:.62em;width:5px;height:5px;border-radius:50%;background:var(--acc)}
.wtip.grp em i:before{background:#ffffffa6}
.wtip em i + i{margin-top:.2rem}

/* ============ 34 — map tooltip placement model ============
   The artifact positioned the tooltip with transform:translate(-50%,-100%), i.e.
   the vertical offset lived in CSS. With the bulleted list the China card is ~470px
   tall on a ~478px map, so it needed real clamping, which CSS cannot do.
   The JS now computes the box top itself — above the marker, below it, or clamped
   inside the map when neither fits — so the transform must only centre horizontally.
   .flat = clamped placement; its arrow is hidden because it no longer points at
   the marker it describes. */
.wtip,.wtip.below{transform:translateX(-50%) scale(.96)}
.wtip.on,.wtip.below.on{transform:translateX(-50%) scale(1)}
.wtip.flat:after{display:none}
.wtip{max-width:min(400px,80vw)}
.wtip em i{line-height:1.5}

/* ============ 35 — tooltip: left-edge positioning, arrow follows the marker ============
   translateX(-50%) meant the CSS left was the tooltip CENTRE, but an absolutely
   positioned box still takes its shrink-to-fit width from (containing block width
   minus left). Near the right edge that left only ~half the box width available, so
   the tooltip squeezed narrow and grew tall AFTER the height had been measured for
   the above/below decision — China then chose below and ran 120px past the map.
   Now the JS sets the LEFT EDGE directly and clamps it to keep the full width
   available, so the measured height is the final height. The arrow is offset by
   --ax (marker x minus box left) so it still points at its dot. */
.wtip,.wtip.below{transform:scale(.96);transform-origin:bottom center}
.wtip.on,.wtip.below.on{transform:scale(1)}
.wtip.below{transform-origin:top center}
.wtip:after{left:var(--ax,50%);transform:translateX(-50%) rotate(45deg)}

/* ============ 36 — stat bar type scale (decisive specificity) ============
   Section 32d set these at (0,2,0) — the same weight as the earlier rule it was
   meant to replace AND the same weight as Elementor widget-counter.min.css
   (.elementor-counter .elementor-counter-number-wrapper{font-size:69px}), which
   loads AFTER hmt-wp.css. Client screenshot measured the digits at ~38px cap-27px,
   i.e. the old 2.375rem cap was still winning. Restated at (0,4,0) so nothing in
   the plugin chain can outrank it regardless of load order. */
.elementor .elementor-widget-counter.cbar-item .elementor-counter-number-wrapper{font-family:var(--fd);font-size:clamp(2.75rem,1.9rem + 2.8vw,4.25rem);font-weight:700;line-height:1.04;color:#fff;justify-content:center;font-variant-numeric:tabular-nums}
.elementor .elementor-widget-counter.cbar-item .elementor-counter-title{font-family:var(--fb);font-size:clamp(.9375rem,.85rem + .3vw,1.125rem);font-weight:500;line-height:1.5;color:#fff;margin-top:.5rem;letter-spacing:.01em}
.elementor .e-con.cbar .cbar-item{padding:2.5rem 1.25rem}

/* ============ 37 — stat bar: the NUMBER is a span, and .cbar div hits everything ============
   Sections 32d and 36 both set font-size on .elementor-counter-number-wrapper, but
   Elementor renders the figure as <span class="elementor-counter-number"> INSIDE that
   wrapper — and hmt-site.css carries the artifact rule
       .cbar span{display:block;font-size:.8125rem;color:#ffffffd9;margin-top:.15rem}
   written when the span WAS the caption. A rule matching the element always beats an
   inherited value from its parent, however large the parent font-size, so the wrapper
   said 68px and the digits still rendered 13px. Reproduced exactly in hp/cbar-fixture.
   Same trap on the box: .cbar div{padding:1.75rem 1rem;border-right:...} matches
   .elementor-counter, the title div and the number wrapper, which is what put the stray
   vertical strokes beside each caption. Reset both here at (0,3,0). */
.elementor .e-con.cbar .elementor-counter-number,
.elementor .e-con.cbar .elementor-counter-number-prefix,
.elementor .e-con.cbar .elementor-counter-number-suffix{display:inline;margin:0;font-family:var(--fd);font-size:clamp(2.75rem,1.9rem + 2.8vw,4.25rem);font-weight:700;line-height:1.04;color:#fff;font-variant-numeric:tabular-nums}
.elementor .e-con.cbar .elementor-counter,
.elementor .e-con.cbar .elementor-counter-number-wrapper,
.elementor .e-con.cbar .elementor-counter-title{padding:0;border-right:0}

/* ============ 38 — compliance framework cards: divider + tighter bullets ============
   Each .sup-c card is icon-box (title + description) then icon-list (the ticks).
   The rule goes on the LIST widget as a top border rather than adding a divider
   widget, so the three cards stay structurally identical and the client can still
   add or remove bullets in Elementor without touching the divider.
   .sup-c.on is the dark navy card — it needs a light divider, not var(--line). */
.elementor .e-con.sup-c > .ticks-el{border-top:1px solid var(--line);padding-top:.95rem}
.elementor .e-con.sup-c.on > .ticks-el{border-top-color:#ffffff2e}
.ticks-el .elementor-icon-list-items{gap:.38rem}
.ticks-el .elementor-icon-list-text{line-height:1.45}
.ticks-el .elementor-icon-list-icon{margin-top:.26rem}

/* ============ 39 — contact form fills its panel ============
   .ct is already a grid with align-items:stretch, so the navy panel and the left
   column were the same HEIGHT — but the form did not fill it. The textarea was pinned
   at its 110px min-height, so the content stopped short and left dead space above the
   panel floor (measured 72px at 1390 and 166px at 900 in hp/ct-fixture).
   Making the column a flex chain and letting the textarea take the slack means the
   form ends exactly one padding-step above the panel edge at every width, so the
   button lines up with the bottom of the contact cards opposite.
   Form is Contact Form 7 id 11 (hash fee9b200…), rendered by the shortcode widget —
   unchanged, this is layout only. */
.elementor .e-con.ct-r{display:flex;flex-direction:column}
.hm-cf7,.hm-cf7 .elementor-widget-container,.hm-cf7 .wpcf7{flex:1 1 auto;display:flex;flex-direction:column;min-height:0}
.hm-cf7 .wpcf7-form{flex:1 1 auto;display:flex;flex-direction:column;gap:1rem;min-height:0}
.hm-cf7 .wpcf7-form .field:has(textarea){flex:1 1 auto;min-height:0}
.hm-cf7 .wpcf7-form textarea{flex:1 1 auto;height:110px;min-height:110px}

/* ============ 40 — contact form: make the message field actually absorb the slack ============
   Measured the client screenshot: textarea exactly 110px, panel 643px, left column 579px.
   The textarea sitting at precisely its base height proved flex-grow was never working.
   Reason, from the REAL CF7 markup: the textarea is not a child of .field — CF7 wraps every
   control in <span class="wpcf7-form-control-wrap">, and section 39 set that span to
   display:block. So .field grew, the span did not, and the textarea could not stretch.
   Second cause: CF7 appends <span class="wpcf7-spinner"> after the submit. Section 39 gave it
   display:block, so an invisible 24px box plus margins plus the form gap reserved ~50px of the
   ~63px overshoot. The message field alone could never have closed that — it would have had to
   shrink to about 47px, roughly two lines.
   Spinner still appears during submit (form gains .submitting), it just no longer reserves
   space while idle. */
.hm-cf7 .wpcf7-form .field:has(textarea) .wpcf7-form-control-wrap{flex:1 1 auto;display:flex;min-height:0}
.hm-cf7 .wpcf7-form textarea{flex:1 1 auto;height:80px;min-height:80px}
.hm-cf7 .wpcf7-spinner{display:none;margin:0}
.hm-cf7 form.submitting .wpcf7-spinner{display:block;margin:.5rem auto 0}

/* ============ 41 — footer contact list: linked rows centred their icon ============
   Phone and Email carry links, Fax and Working Hours do not. Elementor renders the
   linked ones as  <li><a><span icon><span text></a></li>  and the plain ones as
   <li><span icon><span text></li>, then styles BOTH as the flex row:
       .elementor-widget .elementor-icon-list-item,
       .elementor-widget .elementor-icon-list-item a{align-items:var(--icon-vertical-align,center)}
   Our top-align rule only named .elementor-icon-list-item, so on the linked rows the real
   flex container was the untouched <a> and the icon centred itself between the two lines.
   --icon-vertical-align is not set on this widget (post-57.css only emits icon-size and
   vertical-offset), so the fallback centre applied.
   Both selectors restated at (0,3,x) so it holds whichever stylesheet loads last. */
.elementor .ft-info .elementor-icon-list-item,
.elementor .ft-info .elementor-icon-list-item > a{align-items:flex-start}

/* ============ 42 — footer: brand lockup + Contact heading gap ============
   The footer now runs the same three-part lockup as the header (Harima mark, Multicore
   mark, HARIMATEC/Malaysia wordmark) inside a .brand-lock container, so it inherits the
   header rules for the dividers, gaps and wordmark. Only the Harima mark needs resizing:
   standing alone in the footer it was 86px, which would dwarf the other two, so inside
   .ft-lock it drops to the header 46px.
   Contact column: Quick Links and Address both had breathing room under the underlined
   h4 (the nav items carry padding, .ft-desc carries margin-top:1rem) but the icon-list
   had none, so Phone Number sat straight under the rule. 1rem matches Address exactly.
   The 901-1150px band is the only place the footer is still four columns AND narrow
   enough to crowd the lockup — below 900 it becomes two columns and regains width. */
.elementor .ft .ft-info{margin-top:1rem}
.ft-lock .logomark-ft img{height:46px}
@media(max-width:1150px) and (min-width:901px){
  .elementor .e-con.ft-lock{gap:10px}
  .ft-lock .logomark-ft img{height:40px}
  .ft-lock .bl-mc img{height:24px}
  .ft-lock .bl-name b{font-size:.95rem}
  .ft-lock .bl-name em{font-size:.55rem;letter-spacing:.2em}
  .brand-lock.ft-lock > .elementor-element + .elementor-element{padding-left:.6rem}
}

/* ============ 43 — footer Quick Links gap ============
   Same fault as the Contact column: only .ft-desc carried a margin under the underlined
   h4, so the nav sat tight against it. .8rem rather than the 1rem used on .ft-info because
   the nav link already contributes .28rem of its own padding above the text — measured,
   that lands the first item within 2px of the Address column ink line (34 vs 36).
   Harmless if these columns ever revert to block layout: at 12.8px it is smaller than the
   h4 margin-bottom (17.6px) and simply collapses away. */
.elementor .ft .hm-ftnav{margin-top:.8rem}

/* ============ 44 — product detail lightbox ============
   All .pmodal* styling already ships in hmt-site.css (the artifact stylesheet), so this
   is only the WordPress glue: the host container must add no layout, and the three
   trigger areas need to look clickable. Content is populated from
   uploads/hmt-assets/hmt-products.json, fetched lazily on first open. */
.elementor .e-con.pmodal-host{padding:0;min-height:0;display:block}
.pmodal-wrap,.pmodal-wrap .elementor-widget-container{margin:0;line-height:0}
.pmodal-wrap .pmodal{line-height:1.72}
.pc-title,.pc-img,.pc-more,.pc-more a{cursor:pointer}
.pc-title:focus-visible,.pc-img:focus-visible{outline:2px solid var(--acc);outline-offset:2px}

/* ============ 45 — lightbox: safe centring, never clipped ============
   The artifact centres the panel with display:grid + place-items:center. That is the
   classic unsafe-centring pattern: once the item is taller than the container it
   overflows BOTH edges and the top becomes unreachable, because you cannot scroll to
   negative offsets. Swapped to flex + margin:auto on the panel, which overflows only
   downward, plus overflow-y:auto on the modal so the whole panel is always reachable
   whatever the viewport.
   Cap lowered from min(88vh,860px) to min(86dvh,760px): 860 rendered a 862px-tall panel
   that filled almost the entire window on a tall screen. dvh so mobile browser chrome
   is accounted for, with a vh fallback for older engines. */
.elementor .pmodal{display:flex;align-items:center;justify-content:center;overflow-y:auto;overscroll-behavior:contain}
.elementor .pmodal-panel{margin:auto;max-height:min(86dvh,760px)}
@supports not (height:1dvh){.elementor .pmodal-panel{max-height:min(86vh,760px)}}

/* ============ 46 — REGRESSION FIX: section 45 defeated the hidden state ============
   Section 45 wrote .elementor .pmodal{display:flex} — (0,2,0). The artifact hides the
   closed modal with .pmodal[hidden]{display:none}, which is ALSO (0,2,0) (one class +
   one attribute) and lives in hmt-site.css, which loads BEFORE hmt-wp.css. Equal
   specificity, so my later rule won and the modal was permanently displayed: a fixed,
   full-viewport, effectively invisible layer over the whole Products page, swallowing
   every click and scroll.
   Restated at (0,3,0) so the hidden state always wins. */
.elementor .pmodal[hidden]{display:none}


/* ============ 47 — lightbox: literal viewport centring + cheap backdrop ============
   TWO problems, one section.

   (a) OFF-CENTRE. Section 45 centred the panel with flex + margin:auto inside
   .pmodal, which also carries the artifact's padding:clamp(.75rem,3vw,2.5rem)
   and (from 45) overflow-y:auto. That is three separate things that can each
   shift the result: the padding box, the scroll offset, and any stray in-flow
   content. Live it landed ~72px below centre; a local replica of the same rules
   centred perfectly, so the mechanism is something in the real page the replica
   does not carry. Rather than keep hunting it, the panel is now positioned
   outright: absolute, top/left 50%, translate(-50%,-50%) inside a fixed
   inset:0 box. That is the literal centre of the viewport and cannot be moved
   by padding, scroll position, alignment or extra flow content.
   .pmodal goes display:block + overflow:hidden — nothing is clipped because the
   panel is capped at 86dvh — and the width the panel lost to the padding box is
   handed back explicitly, so the side gutters are unchanged.

   (b) LAG. .pmodal-bd carries backdrop-filter:blur(3px) over a full-viewport
   layer, so every frame re-blurs the whole page composite beneath it. Measured
   on a 400-card page, scrolling the modal body: mean frame 29.8ms / p95 66.7ms
   / worst 100ms with the blur, versus 16.6 / 16.7 / 16.8 without it — i.e. 60fps
   locked once the blur is gone. Replaced with a slightly denser flat scrim,
   which reads the same at this opacity.

   The hidden state is restated again here: section 47 writes display on .pmodal
   at (0,2,0), which ties with .pmodal[hidden] in hmt-site.css. See section 46. */
.elementor .pmodal{display:block;overflow:hidden;overscroll-behavior:contain}
.elementor .pmodal[hidden]{display:none}
.elementor .pmodal-bd{backdrop-filter:none;-webkit-backdrop-filter:none;background:rgba(11,21,18,.74)}
.elementor .pmodal-panel{position:absolute;top:50%;left:50%;margin:0;width:min(1280px,calc(100% - 2 * clamp(.75rem,3vw,2.5rem)));max-height:min(86dvh,760px);transform:translate(-50%,calc(-50% + 14px)) scale(.98)}
@supports not (height:1dvh){.elementor .pmodal-panel{max-height:min(86vh,760px)}}
.elementor .pmodal.on .pmodal-panel{transform:translate(-50%,-50%)}
@media(prefers-reduced-motion:reduce){.elementor .pmodal-panel{transform:translate(-50%,-50%)}}


/* ============ 48 — the panel is pinned to the VIEWPORT, not to .pmodal ============
   The client's diagnosis: "the lightbox positioning depends on the length of the
   contents — the simple ones are centred, the ones with a lot of detail get pushed
   lower and lower." That is the missing variable section 47 could not see.

   Working the screenshot arithmetic backwards: viewport 926px, panel 760px, gaps
   155 above / 11 below. A panel centred in a box of height H sits at (H-760)/2, so
   H = 1070 — the box the panel was being centred in is ~144px TALLER than the
   viewport, and it grows with the modal's content. Reproduced in the harness by
   forcing .pmodal 224px taller than the viewport: the panel lands at top=194
   instead of 82, i.e. 112px low, exactly (224/2). Section 47 did not fix this,
   because top:50% on an absolutely positioned child resolves against .pmodal's own
   padding box — so an oversized .pmodal drags the "centre" down with it.

   The fix is to stop measuring against .pmodal at all. The panel is now
   position:FIXED, so top:50% is 50% of the viewport, whatever .pmodal is doing.
   Verified safe: nothing in the ancestor chain of #pmodal (pmhost2 → pmhost1 →
   .elementor-58 → .ast-container → #content → #page → body) declares transform,
   filter, perspective, will-change or contain in any enqueued stylesheet, so
   position:fixed genuinely resolves to the viewport here.

   .pmodal itself is pinned the same way — left/right/top plus an explicit
   100dvh height — so the scrim is exactly the viewport too, and its padding is
   dropped since the panel now sets its own gutter.

   Harness, .pmodal deliberately oversized by 144-224px, six viewport sizes, short
   product (7 highlights) and longest product (GC 10, 17 highlights + 8 specs):
   dY = 0 in every cell. */
.elementor .pmodal{position:fixed;top:0;left:0;right:0;bottom:auto;height:100dvh;max-height:100dvh;padding:0;display:block;overflow:hidden;overscroll-behavior:contain}
@supports not (height:1dvh){.elementor .pmodal{height:100vh;max-height:100vh}}
.elementor .pmodal[hidden]{display:none}
.elementor .pmodal-panel{position:fixed;top:50%;left:50%;margin:0;width:min(1280px,calc(100% - 2 * clamp(.75rem,3vw,2.5rem)));max-height:min(86dvh,760px);transform:translate(-50%,calc(-50% + 14px)) scale(.98)}
@supports not (height:1dvh){.elementor .pmodal-panel{max-height:min(86vh,760px)}}
.elementor .pmodal.on .pmodal-panel{transform:translate(-50%,-50%)}
@media(prefers-reduced-motion:reduce){.elementor .pmodal-panel{transform:translate(-50%,-50%)}}


/* ============ 49 — the modal is moved to <body>; centring goes back to the artifact's ============
   Sections 45→48 all failed the same way, and the harness finally showed why. Feeding the
   fixture a transformed ancestor (`.elementor-58{transform:translateZ(0)}`) reproduces the
   client's screenshot exactly: a transform, filter, perspective, will-change or contain on ANY
   ancestor makes that ancestor — not the viewport — the containing block for position:fixed
   descendants. .pmodal then measures the ancestor (1600px tall in the fixture, starting 18px
   down) instead of the screen, the scrim stops covering the page, and the panel lands 716px
   low. Static CSS says no ancestor declares any of those properties, so it is being applied at
   runtime — an inline transform from Elementor/Jet, which no stylesheet scan can see.

   No amount of CSS on .pmodal can escape a containing block set by an ancestor. So the modal
   is now moved out of the tree: hmt-app.js appends #pmodal to <body> on load. A direct child
   of body has no ancestor that can trap it, and position:fixed means the viewport again.

   With that settled the centring goes back to the artifact's own display:grid + place-items:
   center — safe now because the panel is capped at min(86dvh,760px) and can never be taller
   than the box it is centred in. Everything sections 45-48 bolted on (flex, margin:auto,
   overflow-y:auto, absolute/fixed panel, height:100dvh, bottom:auto) is unwound here; those
   rules are also dead once #pmodal leaves .elementor, but they are restated so the page is
   still correct if the JS never runs.

   Selectors are doubled — `.elementor .pmodal` for the pre-move state, `body>.pmodal` for the
   moved one. Harness: portal on/off × transformed ancestor on/off × three viewports × shortest
   and longest product. dY=0 in every portalled cell; 716 in every un-portalled one. */
.elementor .pmodal,body>.pmodal{position:fixed;top:0;right:0;bottom:0;left:0;z-index:9999;width:auto;height:auto;max-height:none;display:grid;place-items:center;padding:clamp(.75rem,3vw,2.5rem);overflow:hidden;overscroll-behavior:contain;line-height:1.72}
.elementor .pmodal[hidden],body>.pmodal[hidden]{display:none}
.elementor .pmodal-bd,body>.pmodal .pmodal-bd{backdrop-filter:none;-webkit-backdrop-filter:none;background:rgba(11,21,18,.74)}
.elementor .pmodal-panel,body>.pmodal .pmodal-panel{position:relative;top:auto;left:auto;margin:0;width:min(1280px,100%);max-height:min(86dvh,760px);transform:translateY(14px) scale(.98)}
@supports not (height:1dvh){.elementor .pmodal-panel,body>.pmodal .pmodal-panel{max-height:min(86vh,760px)}}
.elementor .pmodal.on .pmodal-panel,body>.pmodal.on .pmodal-panel{transform:none}
@media(prefers-reduced-motion:reduce){.elementor .pmodal-panel,body>.pmodal .pmodal-panel{transform:none}}


/* ============ 52 — lightbox polish: teal bar, highlights table, close button ============
   Three client tweaks on the now-working lightbox.

   (a) The teal accent bar under the product image (.pmodal-sq::after, an artifact flourish)
       is removed.

   (b) Highlights become a real table instead of two loose columns: each bullet is its own
       bordered cell. Built as a grid with collapsed borders — every cell carries a full
       1px border and pulls itself 1px left and up (margin:0 0 -1px -1px), so adjacent
       borders overlap into single lines. That is what makes a partial last row still read
       as complete boxes; a border-bottom/border-left scheme leaves a half-width rule under
       a lone final cell, and highlight counts run 3–17, so odd counts are the norm.
       Columns come from auto-fit/minmax(240px) rather than the --rows variable the script
       sets, so the count adapts to the panel width and collapses to one column on mobile.
       The tick marker is re-anchored to the new cell padding (.ticks li::before is
       absolutely positioned against the li, which now has padding of its own).

   (c) The close button is pinned to 44x44 with box-sizing:border-box and padding:0 — Astra
       styles bare <button> elements with `padding:.6em 1em .4em`, which was widening the box
       to ~61px on the live page and pushing the glyph ~8px right of centre — then centred
       with flex rather than relying on grid place-items surviving those overrides. */
body>.pmodal .pmodal-sq::after,.elementor .pmodal-sq::after{content:none;display:none}

body>.pmodal #pmHi .hi-cols,.elementor #pmHi .hi-cols{display:grid;grid-auto-flow:row;grid-template-rows:none;grid-template-columns:repeat(auto-fit,minmax(240px,1fr));gap:0;margin-top:.9rem}
body>.pmodal #pmHi .hi-cols li,.elementor #pmHi .hi-cols li{margin:0 0 -1px -1px;border:1px solid var(--line);padding:.65rem .85rem .65rem 2.35rem;font-size:.8125rem;line-height:1.6}
body>.pmodal #pmHi .hi-cols li::before,.elementor #pmHi .hi-cols li::before{left:.85rem;top:calc(.65rem + .38em)}

body>.pmodal .pmodal-x,.elementor .pmodal-x{box-sizing:border-box;width:44px;height:44px;min-width:0;min-height:0;padding:0;margin:0;display:flex;align-items:center;justify-content:center;line-height:1;border-radius:0}
body>.pmodal .pmodal-x svg,.elementor .pmodal-x svg{display:block;width:16px;height:16px;flex:none}


/* ============ 53 — the spec table's bottom border was detached ============
   Astra styles bare <table> elements with `margin:0 0 1.5em`. The artifact draws the table's
   outer box on the .tbl-wrap wrapper, not on the table itself, so that bottom margin sat
   INSIDE the border — leaving the wrapper's left and right borders running down past the last
   row to a bottom border floating 19.5px below it, open at both sides.

   Measured off the client's screenshot: wrapper 512→1249, rules at y 417 / 454 / 497, last row
   ending at 539, wrapper bottom border at 559 — a 19px void with only the side borders in it.
   Astra's 1.5em on the modal's 13px table is 19.5px. Reproduced in the harness at 19.5px and
   closed to 0.

   The column divider is also stated explicitly. It currently comes from a leftover of Astra's
   `th,td{border-width:0 1px 1px 0}` surviving the artifact's border-collapse override — correct
   by accident, and one theme update from disappearing. */
body>.pmodal .tbl-wrap table,.elementor .tbl-wrap table{margin:0}
body>.pmodal .tbl-wrap td:first-child,body>.pmodal .tbl-wrap th:first-child,.elementor .tbl-wrap td:first-child,.elementor .tbl-wrap th:first-child{border-right:1px solid var(--line)}


/* ============ 54 — subtitle line spacing on product cards ============
   ROOT CAUSE, worth stating because it will resurface: the Elementor kit sets
   `.elementor-kit-10{ … font-size:15.5px; line-height:1.72em }` — with a UNIT. `1.72em`
   computes once, on the kit element, to **26.66px**, and that fixed length is what every
   descendant inherits, whatever its own font-size. A unitless `1.72` would have been
   re-evaluated per element instead.

   So 13px card subtitles inherit a 26.66px line box — a 2.05 ratio — and any subtitle that
   wraps to two lines shows a gap nearly twice the text height. Measured on the client's
   screenshot: C 502's two teal lines sit 27px apart on 10px caps. Harness reproduces
   26.66px on 13px text and closes it to 18.85px.

   Fixed here on the two places the subtitle appears. NOT fixed globally: 56 selectors across
   the two stylesheets set a font-size below 15.5px without a line-height, and all of them are
   inheriting that same 26.66px. Most are single-line (buttons, nav items, labels) where it is
   invisible or even desirable. Flipping the kit to unitless would correct all of them at once
   but would also loosen every element ABOVE 15.5px that relies on the inherited value — a
   site-wide typographic change that needs a visual pass across all seven pages, not a
   drive-by. Flagged to the client. */
.pc-sub,.pc-hd span{line-height:1.45}
body>.pmodal .pmodal-sub,.elementor .pmodal-sub{line-height:1.45}


/* ============ 55 — header brand name sat 6.5px high ============
   Measured on the client's screenshot: HARIMA logo centre y=42.5, Multicore centre y=42.5,
   nav items ~42 — and the HARIMATEC/MALAYSIA block centre **36.0**. The dividers either side
   run y 20→65, i.e. the full 46px lockup height, which proves the widget itself IS stretched
   correctly; only its contents were sitting at the top.

   Cause: `.brand-lock > .elementor-element{align-items:center}` has nothing to centre, because
   `.elementor-heading-title` is itself stretched to the full height of the stretched widget.
   It is a column flex box with default `justify-content:flex-start`, so the name and the
   MALAYSIA line pile up at the top of it. The logos escaped this only because their centring
   rule (`.brand-lock .elementor-widget-image a`) lands on the <a>, which wraps a fixed-height
   image.

   Rather than hunt which of Elementor's generated rules does the stretching, the geometry is
   asserted: the title is pinned to its content height and centred with auto block margins,
   which beat whatever `align-items` resolves to. `align-self:stretch` is deliberately KEPT on
   the widget so the 1px divider still runs the full height of the lockup.

   Harness (hp/hdr-*.html), lockup 20→66: with the title force-stretched the text centre lands
   at 36.4 against a lockup centre of 43 — offset −6.6, matching the screenshot's −6.5. With
   this section the offset is 0.0 in both the stretched and the normal case, divider 46px in
   all four. */
.elementor .e-con.brand-lock > .elementor-element.bl-name{display:flex;align-items:center;align-self:stretch}
.elementor .e-con.brand-lock > .elementor-element.bl-name > .elementor-heading-title{flex:0 0 auto;align-self:center;margin-block:auto;height:auto}


/* ============ 56 — Home "Why Choose Us" eyebrow left-aligned; eyebrow colour pinned ============
   (a) hmt-site.css carries `.band .eb{text-align:center}`. Auditing every Elementor document,
   only THREE eyebrows sit inside a `.band` at all: Home "Our Core" (already left via
   `.corewrap .eb`), About Us "Why Choose Us" (already left via `.band-left .eb`), and Home
   "Why Choose Us" — the only one that rule actually centres, and the one the client flagged.
   Its section title beside it is left-aligned, which is what made the mismatch visible.
   Scoped to `.band .band-in > .eb` so the other two are untouched, and stated on the widget,
   its container and the title, mirroring the existing `.band-left .eb` pattern (Elementor
   headings need the alignment on the title, not just the wrapper).

   (b) Eyebrow colour restated at (0,3,0)/(0,4,0). Every colour rule matching
   `.elementor-heading-title` across all 30 enqueued stylesheets and all 15 inline blocks was
   enumerated; the strongest is `.hero .elementor-widget-heading .elementor-heading-title`
   at (0,3,0), and `.eb .elementor-heading-title{color:var(--acc)}` already wins on order.
   Sampling the client's own hero screenshot confirms the eyebrow pixels are rgb(0,160,135) —
   exactly --acc — and a harness of the real cascade computes rgb(0,160,135) for the light-
   section eyebrows too. So they are already the same green; this is belt-and-braces against
   anything not visible in the stylesheets. */
.elementor .band .band-in > .eb,
.elementor .band .band-in > .eb .elementor-widget-container,
.elementor .band .band-in > .eb .elementor-heading-title{text-align:left}
.elementor .eb .elementor-heading-title,
.elementor .eb.elementor-widget-heading .elementor-heading-title{color:var(--acc)}


/* ============ 57 — Home "Why Choose Us" title was indented ============
   Cause: `.band h2{text-align:center;max-width:30ch;margin-inline:auto}` in hmt-site.css. The
   title's BOX is capped at 30ch and centred inside the band, so its left edge sits inboard of
   the eyebrow and the cards — and `text-align:center` nudges the text further. On the client's
   screenshot the eyebrow's first ink is at x=68 and the first card border at x=67, while the
   title's first ink is at x=82: a 14px step that reads as a stray indent.

   Ruled out first: no padding, margin or text-indent on the heading in ANY of the 30 enqueued
   stylesheets or 15 inline blocks (Astra and Elementor both zero it); no leading space in the
   Elementor title value (first byte 0x4d, "M"); and a local render in real Montserrat puts the
   natural side-bearing difference between the eyebrow's "W" and the title's "M" at 3px, not 14.

   Section 56 left-aligned this section's eyebrow, which is what made the title's centring
   visible as a mismatch — both now agree.

   Scoped with `:has(> .eb)` so ONLY a band whose wrap contains an eyebrow is affected. The
   other `.band` on the Home page — "Committed To International Standards" over the
   certification logos — has no eyebrow and is centred by design; it must stay that way.
   `max-width:30ch` is deliberately kept, so the line-length cap and its wrapping behaviour at
   narrow widths are unchanged; only the box alignment moves.

   Harness (hp/bh2c-*.html) with both bands present: title indent 16.4 -> 0 and align
   center -> left, while the certifications title stays at 16.4 / center. */
.elementor .band .band-in:has(> .eb) > .elementor-widget-heading .elementor-heading-title{text-align:left;margin-inline:0}


/* ============ 58 — EDITOR ONLY: restore light-on-dark text in Elementor's preview ============
   Client: in "Edit with Elementor", text that is white on the live site renders navy, making the
   dark sections unreadable and forcing a check against the live page after every change.

   What was established server-side: hmt-site.css and hmt-wp.css DO load in the editor preview
   (simulated the preview request — is_admin() false, preview mode true, both handles queued);
   and NOTHING in Elementor's editor stylesheets, post-15.css or the kit post-10.css declares a
   heading colour at all. So no third-party rule is overriding white with navy — the only
   candidate left is our own base rule `.elementor-widget-heading .elementor-heading-title
   {color:var(--head)}` winning because the light-on-dark rule's ancestor (.hero/.band/.bg-n/…)
   is not matching in the editor's client-built DOM.

   The editor's DOM only exists in the browser, so this is asserted rather than diagnosed: the
   same six dark contexts are restated with the preview's body class in front, taking them from
   (0,3,0) to (0,4,1) — comfortably above anything found anywhere in the stack. Eyebrows are
   restated after, at (0,5,1), so they stay teal rather than being swept white.

   Scoped to `.elementor-editor-active` / `.elementor-editor-preview`, which exist only inside
   the editor's preview iframe: the live site cannot be affected by this section. If the colours
   still come out navy after this, the cause is the ancestor genuinely not matching in the editor
   DOM — which would then need the container classes mirrored into `_css_classes`. */
body.elementor-editor-active .hero .elementor-widget-heading .elementor-heading-title,
body.elementor-editor-active .band .elementor-widget-heading .elementor-heading-title,
body.elementor-editor-active .bg-n .elementor-widget-heading .elementor-heading-title,
body.elementor-editor-active .corecard .elementor-widget-heading .elementor-heading-title,
body.elementor-editor-active .ctab-bx .elementor-widget-heading .elementor-heading-title,
body.elementor-editor-active .ct-r .elementor-widget-heading .elementor-heading-title,
body.elementor-editor-preview .hero .elementor-widget-heading .elementor-heading-title,
body.elementor-editor-preview .band .elementor-widget-heading .elementor-heading-title,
body.elementor-editor-preview .bg-n .elementor-widget-heading .elementor-heading-title,
body.elementor-editor-preview .corecard .elementor-widget-heading .elementor-heading-title,
body.elementor-editor-preview .ctab-bx .elementor-widget-heading .elementor-heading-title,
body.elementor-editor-preview .ct-r .elementor-widget-heading .elementor-heading-title{color:#fff}

body.elementor-editor-active .hero .elementor-widget-text-editor,
body.elementor-editor-active .band .elementor-widget-text-editor,
body.elementor-editor-active .bg-n .elementor-widget-text-editor,
body.elementor-editor-active .corecard .elementor-widget-text-editor,
body.elementor-editor-active .ctab-bx .elementor-widget-text-editor,
body.elementor-editor-active .ct-r .elementor-widget-text-editor,
body.elementor-editor-preview .hero .elementor-widget-text-editor,
body.elementor-editor-preview .band .elementor-widget-text-editor,
body.elementor-editor-preview .bg-n .elementor-widget-text-editor,
body.elementor-editor-preview .corecard .elementor-widget-text-editor,
body.elementor-editor-preview .ctab-bx .elementor-widget-text-editor,
body.elementor-editor-preview .ct-r .elementor-widget-text-editor{color:var(--w60)}

body.elementor-editor-active .eb .elementor-heading-title,
body.elementor-editor-preview .eb .elementor-heading-title{color:var(--acc)}


/* ============ 59 — batch: hero leading, bar gap, header rows, cert cards, map links ============

   (a) HERO LINE SPACING — the real cause is Astra, not our stylesheet. Astra's dynamic inline
   CSS ships `.elementor-widget-heading h1.elementor-heading-title{line-height:1.4em}` at (0,2,1),
   which outranks the artifact's `.hero h1{line-height:1.12}` at (0,1,1). Measured on the client's
   hero screenshot: cap height 42px, line-to-line 84px — a ratio of exactly 1.40, confirming
   Astra's value was the one in force the whole time. Restated at (0,3,1)/(0,4,1).
   NOTE: Astra does the same to h2 (1.3em), h3 (1.3em), h4 (1.2em), h5, h6 — every heading on the
   site is running Astra's leading, not the design's. Only h1 is corrected here because only the
   hero was reported; the rest is flagged to the client as a one-line follow-up.

   (b) ABOUT — gap above the four bars. It came from `.ibx-row{margin-top:clamp(2.5rem,…,3.5rem)}`
   = 40–56px (the two containers themselves have no gap, section 14 zeroes it). Cut to 24–32px.

   (c) HEADER ROWS — new `.hdrow` container puts the section title on the left and its button on
   the right. Used by Why Choose Us and Industries Served, where the button previously sat below
   the cards. Because the heading is no longer a direct child of `.band-in`, sections 56/57 stop
   matching it, so the left-alignment is restated for anything inside `.hdrow`.

   (d) The certifications band title ("Committed To International Standards") is now left-aligned
   too — section 57 deliberately excluded it via `:has(> .eb)`; the client has since asked for the
   left spacing gone, so the rule is restated here without that guard.

   (e) FOOTER ADDRESS is now a link to Google Maps; keep it looking like text, teal on hover.

   (f) `.licard` — the four government-issued licence cards on Compliance now carry the scanned
   certificate above the existing icon box. The card owns the border and the hover lift; the
   inner icon box is stripped of both so the two do not double up. Square image well with
   `object-fit:contain` because the scans are portrait (~340x492) — letterboxing them keeps all
   four cards the same height whatever the document proportions. */

/* (a) */
.elementor .elementor-widget-heading h1.elementor-heading-title{line-height:1.16}
.elementor .hero .elementor-widget-heading h1.elementor-heading-title{line-height:1.12}

/* (b) */
.elementor .e-con.ibx-grid.ibx-row{margin-top:clamp(1.5rem,1rem + 1.5vw,2rem)}

/* (c) */
.elementor .e-con.hdrow{display:flex;flex-direction:row;flex-wrap:wrap;align-items:flex-end;justify-content:space-between;gap:1.5rem 2.5rem;margin-bottom:clamp(2.25rem,1.5rem + 2vw,3.25rem)}
.elementor .e-con.hdrow>.e-con{flex:0 1 auto;min-width:0}
.elementor .e-con.hdrow>.e-con:first-child{flex:1 1 26rem}
.elementor .e-con.hdrow>.e-con.sec-ttl{margin-bottom:0;max-width:none}
.elementor .e-con.hdrow>.e-con.btns{flex:0 0 auto;margin-top:0;justify-content:flex-end}
.elementor .e-con.hdrow .elementor-heading-title{text-align:left;margin-inline:0}
.elementor .e-con.hdrow .eb,
.elementor .e-con.hdrow .eb .elementor-widget-container,
.elementor .e-con.hdrow .eb .elementor-heading-title{text-align:left}
@media(max-width:820px){.elementor .e-con.hdrow{flex-direction:column;align-items:flex-start;justify-content:flex-start}}

/* (d) */
.elementor .band .band-in > .elementor-widget-heading .elementor-heading-title{text-align:left;margin-inline:0}

/* (e) */
.ft .ft-desc a{color:inherit;text-decoration:none;transition:color .2s}
.ft .ft-desc a:hover,.ft .ft-desc a:focus-visible{color:var(--acc)}

/* (f) */
.elementor .e-con.licard{display:flex;flex-direction:column;background:var(--surface);border:1px solid var(--line);padding:0;overflow:hidden;transition:border-color .28s ease,transform .28s var(--ease),box-shadow .28s ease}
.elementor .e-con.licard:hover{border-color:var(--acc);transform:translateY(var(--lift));box-shadow:var(--sh-h)}
.elementor .e-con.licard>.licard-shot{line-height:0;border-bottom:1px solid var(--line);background:var(--xlight)}
.elementor .e-con.licard>.licard-shot img{display:block;width:100%;aspect-ratio:1/1;object-fit:contain;padding:1.1rem;background:var(--xlight)}
.elementor .e-con.licard>.ibx.elementor-widget-icon-box{border:0;background:0 0;box-shadow:none;flex:1 1 auto}
.elementor .e-con.licard>.ibx.elementor-widget-icon-box:hover{border-color:transparent;box-shadow:none;transform:none}

/* 60 — hdrow one-row fix + licard title spacing */
.elementor .e-con.hdrow>.e-con{width:auto}
.elementor .e-con.hdrow>.e-con:first-child{width:auto;flex:1 1 26rem}
.elementor .e-con.hdrow>.e-con.btns{width:auto;flex:0 0 auto;align-self:flex-end}
@media(max-width:820px){.elementor .e-con.hdrow>.e-con{width:100%}.elementor .e-con.hdrow>.e-con.btns{align-self:flex-start}}
.elementor .e-con.licard>.ibx .elementor-icon-box-title{margin-bottom:.6rem}
.elementor .e-con.licard>.ibx .elementor-icon-box-title,.elementor .e-con.licard>.ibx h3.elementor-icon-box-title{margin-block-end:.6rem}

/* 61 — gap tightening + Industries lead measure + Compliance split-head.
   Cause: these block margins (.feat margin-top 3.25rem, .sus-grid margin-top 4.5rem,
   .hdrow/.split-head margin-bottom 3.25rem) were authored for the artifact, whose
   parents had no gap of their own. Elementor's container adds its own row gap on top,
   so every one of these joints is double-spaced. Each rule is scoped by adjacency
   (:has(+ ...)) so the sibling sections the client is happy with stay untouched. */
.elementor .e-con.hdrow:has(+ .e-con.feat){margin-bottom:clamp(1.25rem,.75rem + 1.2vw,2rem)}
.elementor .e-con.hdrow + .e-con.feat{margin-top:0}
.elementor .e-con.sus-row + .e-con.sus-grid{margin-top:clamp(1.5rem,1rem + 1.2vw,2.25rem)}
.elementor .e-con.split-head:has(+ .e-con.jn){margin-bottom:clamp(1rem,.5rem + 1vw,1.5rem)}
.elementor .e-con.split-head + .e-con.jn{margin-top:0}
/* Industries Served: cap the body measure so the row keeps its space-between reading */
.elementor .e-con.hdrow .lead,
.elementor .e-con.hdrow .lead .elementor-widget-container,
.elementor .e-con.hdrow .lead p{max-width:34rem}
/* Compliance framework heading carries an authored <br>; the inherited 16ch cap was
   pushing "Compliance Framework" onto a third line. An authored break means the author
   owns the line count, so drop the cap whenever a <br> is present. */
.elementor .e-con.split-head>.elementor-widget-heading .elementor-heading-title:has(br){max-width:none}
/* ...and right-align its body copy (About's .split-head-r is already right-aligned) */
.elementor .e-con.split-head:not(.split-head-r) .lead .elementor-widget-container,
.elementor .e-con.split-head:not(.split-head-r) .lead p{text-align:right}

/* Between the split-head stack breakpoint (860px) and ~1025px the title column is only
   ~390-445px, where "Compliance Framework" needs ~400px and tips onto a third line.
   Ease the type down across that band only; every other width keeps the full size. */
@media(min-width:861px) and (max-width:1024px){
.elementor .e-con.split-head>.elementor-widget-heading .elementor-heading-title:has(br){font-size:clamp(1.35rem,.85rem + 1.35vw,1.75rem)}
}

/* 62 — About (Home): the photo sets the row height instead of following it.
   .wwa-shot img is aspect-ratio:4/3 at 100% width, so in a 1fr|1fr grid it is ~456px
   tall against a ~380px text column, and align-items:center leaves the photo hanging
   past the eyebrow above and the button below. Taking the photo out of flow inside a
   stretched column makes the TEXT column define the row, and the photo fills it exactly.
   Reverted below 940px, where .wwa stacks to one column and an out-of-flow photo would
   collapse to zero height. */
@media(min-width:941px){
.elementor .e-con.wwa{align-items:stretch}
.elementor .e-con.wwa>.e-con:last-child{position:relative;min-height:0;padding:0}
.elementor .e-con.wwa>.e-con:last-child>.wwa-shot{position:absolute;inset:0;margin:0;padding:0}
.elementor .e-con.wwa>.e-con:last-child>.wwa-shot .elementor-widget-container{height:100%}
.elementor .e-con.wwa>.e-con:last-child>.wwa-shot img{display:block;width:100%;height:100%;aspect-ratio:auto;object-fit:cover}
}

/* ============ 63 — mobile & tablet pass ============
   Elementor breakpoints on this install are the defaults: tablet <=1024, mobile <=767.
   Everything below is inside a max-width query so desktop is untouched. */

/* (a) Sideways drag on mobile. hmt-site.css already had body{overflow-x:hidden}, but that
   only clips the BODY box — the html element still scrolls, which is what lets the page be
   dragged to reveal empty space. overflow-x:clip on html clips without creating a scroll
   container, so position:sticky on the header keeps working (overflow:hidden would break
   it). Clip is the fix regardless of which element is the one overflowing. */
html{overflow-x:clip}
@supports not (overflow-x:clip){html{overflow-x:hidden}}
.elementor-location-header,.elementor-location-footer{max-width:100%}
.elementor .e-con.hdr,.elementor .e-con.ft{max-width:100%}

@media(max-width:1024px){
/* (b) Header: logo | Send An Enquiry | burger, all vertically centred.
   Elementor gives every widget --width:100%, so both the button and the nav widget were
   full-width flex children; width:auto is what lets them sit side by side. */
.elementor .e-con.hdr-in{align-items:center;flex-wrap:nowrap;gap:.7rem;min-height:76px;position:relative}
.elementor .e-con.hdr-in>.logo{order:1;margin-right:auto;align-self:center}
.elementor .e-con.hdr-in>.hm-cta{order:2;width:auto;flex:0 0 auto;align-self:center;margin-block:0}
.elementor .e-con.hdr-in>.hm-nav{order:3;width:auto;flex:0 0 auto;align-self:center;margin-block:0}
.hm-cta .elementor-button{padding:.72rem 1rem;font-size:.75rem;white-space:nowrap;line-height:1.1}
.hm-nav .elementor-menu-toggle,.hm-nav div.elementor-menu-toggle{margin:0}
}
@media(max-width:600px){
.hm-cta .elementor-button{padding:.66rem .8rem;font-size:.6875rem}
.elementor .e-con.hdr-in{gap:.5rem;min-height:70px}
}

/* (c) The burger menu was opening in flow, so it pushed the header taller instead of
   hanging below it. Anchor it to .hdr and take it out of flow. */
.elementor .e-con.hdr{position:relative}
@media(max-width:1024px){
.hm-nav .elementor-nav-menu--dropdown{position:absolute;top:100%;left:0;right:0;width:auto;margin:0;
  max-height:min(72dvh,34rem);overflow-y:auto;overscroll-behavior:contain;
  background:var(--surface);border-top:1px solid var(--line);border-bottom:1px solid var(--line);
  box-shadow:0 26px 44px -26px #19295359;z-index:130;padding:.35rem clamp(.9rem,4vw,1.25rem) .8rem}
.hm-nav .elementor-nav-menu--dropdown .elementor-nav-menu>li>a.elementor-item{padding:.9rem .1rem}
}

/* (d) Why Choose Us / Industries Served: title and button still shared a row on tablet,
   where justify-content:space-between throws them to opposite edges of a narrow screen.
   The stack breakpoint was 820px, which leaves 821-1024 (i.e. tablet) in row mode. Stack
   from 1024 down instead, and drop the row gap so the button sits under the title. */
@media(max-width:1024px){
.elementor .e-con.hdrow{flex-direction:column;flex-wrap:nowrap;gap:.9rem;align-items:flex-start;justify-content:flex-start}
.elementor .e-con.hdrow>.e-con,
.elementor .e-con.hdrow>.e-con:first-child{flex:0 0 auto;width:100%;min-height:0}
.elementor .e-con.hdrow>.e-con.btns{width:auto;flex:0 0 auto;align-self:flex-start;margin-top:0;justify-content:flex-start}
.elementor .e-con.hdrow .lead,
.elementor .e-con.hdrow .lead .elementor-widget-container,
.elementor .e-con.hdrow .lead p{max-width:none}
}

/* (e) Global Presence counters: three across, type scaled for small screens. */
@media(max-width:1024px){
.elementor .e-con.cbar{grid-template-columns:repeat(3,1fr)}
.elementor .e-con.cbar .cbar-item{padding:1.3rem .45rem}
.elementor .e-con.cbar .elementor-counter-number,
.elementor .e-con.cbar .elementor-counter-number-prefix,
.elementor .e-con.cbar .elementor-counter-number-suffix,
.elementor .elementor-widget-counter.cbar-item .elementor-counter-number-wrapper{font-size:clamp(1.375rem,.85rem + 1.7vw,2rem);line-height:1.05}
.elementor .elementor-widget-counter.cbar-item .elementor-counter-title{font-size:clamp(.625rem,.5rem + .45vw,.8125rem);line-height:1.35;margin-top:.3rem;letter-spacing:0}
}

/* (f) Journey year tabs were not the same height. Force every title in a row to stretch,
   with a floor so single-line tabs match whatever the widest one does. */
.elementor .hm-jntabs .e-n-tabs-heading{align-items:stretch;align-content:start}
.elementor .hm-jntabs .e-n-tab-title,
.elementor .hm-jntabs .e-n-tab-title[aria-selected="true"],
.elementor .hm-jntabs .e-n-tab-title:hover{align-self:stretch;height:auto;min-height:3.5rem;box-sizing:border-box;line-height:1.2;align-items:center}

/* (g) Product tabs: no vertical movement on any state. */
.elementor .hm-ptabs .e-n-tab-title,
.elementor .hm-ptabs .e-n-tab-title:hover,
.elementor .hm-ptabs .e-n-tab-title:focus,
.elementor .hm-ptabs .e-n-tab-title:focus-visible,
.elementor .hm-ptabs .e-n-tab-title:active,
.elementor .hm-ptabs .e-n-tab-title[aria-selected="true"],
.elementor .hm-ptabs .e-n-tab-title[aria-selected="false"]:hover{transform:none;translate:none;top:auto;inset-block-start:auto;will-change:auto;animation:none;
  transition:background-color .2s ease,color .2s ease,border-color .2s ease}

/* (h) Compliance. The right-aligned body copy is a desktop composition; at tablet and
   below the block is full width and right-aligned prose reads badly, so revert to left. */
@media(max-width:1024px){
.elementor .e-con.split-head:not(.split-head-r) .lead .elementor-widget-container,
.elementor .e-con.split-head:not(.split-head-r) .lead p{text-align:left}
}
/* The three framework cards centre themselves at <=767px because Elementor's own mobile
   fallback (.elementor-mobile-position-block-start, (0,3,0) with align-items:unset
   !important) stacks the icon above the text and centres it, beating our (0,2,0) rule.
   Matching its weight — including the !important it uses — is the only way past it. */
@media(max-width:767px){
.elementor .sup-hd.elementor-widget-icon-box.elementor-mobile-position-block-start .elementor-icon-box-wrapper{
  flex-direction:row;text-align:left;align-items:flex-start!important;gap:.85rem}
.elementor .sup-hd.elementor-widget-icon-box .elementor-icon-box-title,
.elementor .sup-hd.elementor-widget-icon-box .elementor-icon-box-description,
.elementor .sup-hd.elementor-widget-icon-box .elementor-icon-box-content{text-align:left}
.elementor .sup-hd.elementor-widget-icon-box .elementor-icon-box-icon{margin:0;flex:none}
.elementor .e-con.sup-c .ticks-el .elementor-icon-list-items{text-align:left}
}

/* ============ 64 — mobile & tablet header fit ============
   Cause: section 9 of this file re-declared the header lockup's DESKTOP sizes
   (.logomark-hdr img{height:46px}, .bl-mc img{height:30px}) at the same specificity as
   hmt-site.css but LATER in the cascade, which silently killed the artifact's own
   responsive ladder (46 -> 42 -> 36, 30 -> 22, wordmark 1.12 -> 1rem -> .86rem, and the
   "Malaysia" line dropping out). So on a phone the header still tried to lay out a
   full-size three-part lockup plus a full-size CTA plus the burger in one nowrap row —
   the burger was pushed past the right edge and, since section 63 added overflow-x:clip,
   clipped away entirely rather than merely scrolled off.
   The ladder is restored here at (0,2,1)/(0,3,0) so nothing can pin it back. */

/* --- tablet --- */
@media(max-width:1024px){
.elementor .e-con.hdr-in>.brand-lock{gap:.6rem}
.elementor .e-con.brand-lock>.elementor-element+.elementor-element{padding-left:.6rem}
.elementor .logomark-hdr img{height:38px}
.elementor .bl-mc img{height:24px}
.elementor .bl-name b{font-size:.95rem}
.elementor .bl-name em{font-size:.5rem;letter-spacing:.2em}
}

/* --- mobile --- */
@media(max-width:767px){
.elementor .e-con.hdr-in{gap:.55rem;min-height:68px}
.elementor .e-con.hdr-in>.brand-lock{gap:.45rem;min-width:0}
.elementor .e-con.brand-lock>.elementor-element+.elementor-element{padding-left:.45rem}
.elementor .logomark-hdr img{height:32px}
.elementor .bl-mc img{height:18px}
.elementor .bl-name b{font-size:.8125rem;letter-spacing:0}
.elementor .bl-name em{font-size:.4375rem;letter-spacing:.16em}
.elementor .e-con.brand-lock>.elementor-element.bl-name>.elementor-heading-title{gap:3px}
.hm-cta .elementor-button{padding:.6rem .75rem;font-size:.625rem;letter-spacing:.05em}
.hm-nav div.elementor-menu-toggle{width:38px;height:38px;font-size:20px}
}

/* --- phones (<480px): the Multicore mark is the one element that can go without losing
   the identity (the Harima mark and the HARIMATEC Malaysia wordmark both stay), and
   dropping it buys back ~46px. Above 480 all three stay. --- */
@media(max-width:480px){
.elementor .e-con.brand-lock>.bl-mc{display:none}
.elementor .e-con.hdr-in{gap:.5rem}
.elementor .logomark-hdr img{height:30px}
.hm-cta .elementor-button{padding:.62rem .8rem;font-size:.625rem;letter-spacing:.05em}
}
@media(max-width:365px){
.elementor .e-con.hdr-in{gap:.42rem}
.elementor .bl-name b{font-size:.75rem}
.elementor .logomark-hdr img{height:28px}
.hm-cta .elementor-button{padding:.58rem .68rem;font-size:.59375rem}
.hm-nav div.elementor-menu-toggle{width:36px;height:36px}
}

/* The burger must never be the thing that gets squeezed out. Scoped to <=1024: at desktop
   this widget holds the full horizontal menu and max-content would blow the row apart.
   The lockup keeps flex:0 0 auto — letting it shrink would just truncate the wordmark
   instead of overflowing, which is not an improvement. The size ladder does the fitting. */
@media(max-width:1024px){
.elementor .e-con.hdr-in>.hm-nav{flex:0 0 auto;min-width:max-content}
.elementor .e-con.hdr-in>.brand-lock{flex:0 0 auto;overflow:visible}
}

/* Elementor gives every widget --width:100%; inside the row-flex lockup that makes each
   of the three brand elements demand the full lockup width. Pin them to their content. */
.elementor .e-con.brand-lock>.elementor-element{width:auto;flex:0 0 auto}

/* ============ 65 — header CTA removed, lockup restored, mobile menu height ============ */

/* (a) THE MOBILE MENU OPENED AS A SLIVER. Elementor drives the panel with
     .elementor-nav-menu--toggle .elementor-menu-toggle.elementor-active + .elementor-nav-menu__container
     { max-height: var(--menu-height); transform: scaleY(1) }
   at (0,4,0) — section 63's max-height was only (0,2,0) and never applied. --menu-height is
   written by Elementor's JS from the toggle's position at click time; once the panel became
   position:absolute that measurement stopped describing it, so the panel opened to a sliver.
   Both states are now stated at (0,6,0) so the outcome no longer depends on that variable:
   open is max-height:none (a six-item menu is ~290px, it never needs a cap) and visibility
   carries the hiding, so no computed max-height can leave the panel half-open again. */
@media(max-width:1024px){
.elementor .hm-nav.elementor-nav-menu--toggle .elementor-menu-toggle:not(.elementor-active)+.elementor-nav-menu__container{
  max-height:0;transform:scaleY(0);visibility:hidden;overflow:hidden}
.elementor .hm-nav.elementor-nav-menu--toggle .elementor-menu-toggle.elementor-active+.elementor-nav-menu__container{
  max-height:none;transform:none;visibility:visible;overflow:visible}
.hm-nav .elementor-nav-menu--dropdown .elementor-nav-menu>li+li{border-top:1px solid var(--line)}
.hm-nav .elementor-nav-menu--dropdown .elementor-nav-menu>li>a.elementor-item{display:block;padding:.95rem .15rem;font-size:.9375rem;line-height:1.5;color:var(--head)}
.hm-nav .elementor-nav-menu--dropdown .elementor-nav-menu>li>a.elementor-item.elementor-item-active{color:var(--acc);font-weight:600}
}

/* (b) The Send An Enquiry button is removed from the header template at every breakpoint,
   so the row is logo + burger. That frees enough width to put the Multicore mark back on
   phones and to walk the lockup back up a step. */
@media(max-width:1024px){
.elementor .e-con.hdr-in>.brand-lock{gap:.7rem}
.elementor .e-con.hdr-in>.brand-lock>.elementor-element+.elementor-element{padding-left:.7rem}
.elementor .e-con.hdr-in .logomark-hdr img{height:40px}
.elementor .e-con.hdr-in .bl-mc img{height:26px}
.elementor .e-con.hdr-in .bl-name b{font-size:1rem}
.elementor .e-con.hdr-in .bl-name em{font-size:.5rem;letter-spacing:.2em}
}
@media(max-width:767px){
.elementor .e-con.hdr-in{gap:.6rem;min-height:70px}
.elementor .e-con.hdr-in>.brand-lock{gap:.55rem}
.elementor .e-con.hdr-in>.brand-lock>.elementor-element+.elementor-element{padding-left:.55rem}
.elementor .e-con.hdr-in .logomark-hdr img{height:36px}
.elementor .e-con.hdr-in .bl-mc img{height:22px}
.elementor .e-con.hdr-in .bl-name b{font-size:.875rem;letter-spacing:0}
.elementor .e-con.hdr-in .bl-name em{font-size:.46875rem;letter-spacing:.18em}
}
@media(max-width:480px){
.elementor .e-con.hdr-in .logomark-hdr img{height:34px}
.elementor .e-con.hdr-in .bl-mc img{height:20px}
.elementor .e-con.hdr-in .bl-name b{font-size:.8125rem}
}
@media(max-width:365px){
.elementor .e-con.hdr-in>.brand-lock{gap:.45rem}
.elementor .e-con.hdr-in>.brand-lock>.elementor-element+.elementor-element{padding-left:.45rem}
.elementor .e-con.hdr-in .logomark-hdr img{height:32px}
.elementor .e-con.hdr-in .bl-mc img{height:18px}
.elementor .e-con.hdr-in .bl-name b{font-size:.75rem}
}

/* (c) Section 64 hid the Multicore mark below 480px with a selector that matched
   .brand-lock generally — which is on the FOOTER lockup as well, so it disappeared from
   both. It comes back everywhere; the header now has the room and the footer never
   lacked it. Section 64's other lockup rules were unscoped for the same reason and are
   re-stated here for .ft-lock so the footer keeps its own, larger sizing. */
.elementor .e-con.brand-lock>.bl-mc{display:flex}
@media(max-width:1024px){
.elementor .e-con.ft-lock .logomark-ft img{height:44px}
.elementor .e-con.ft-lock .bl-mc img{height:26px}
.elementor .e-con.ft-lock .bl-name b{font-size:1rem}
.elementor .e-con.ft-lock .bl-name em{font-size:.55rem;letter-spacing:.2em}
}
@media(max-width:767px){
.elementor .e-con.ft-lock{gap:.7rem}
.elementor .e-con.ft-lock>.elementor-element+.elementor-element{padding-left:.7rem}
.elementor .e-con.ft-lock .logomark-ft img{height:40px}
.elementor .e-con.ft-lock .bl-mc img{height:24px}
.elementor .e-con.ft-lock .bl-name b{font-size:.9375rem}
.elementor .e-con.ft-lock .bl-name em{font-size:.5rem;letter-spacing:.18em}
}

/* (d) The header CTA is gone from the template; belt-and-braces so no stray copy of it
   can reappear in the header row. Does not touch the identical button used in page CTAs. */
.elementor-location-header .hm-cta{display:none}

/* ============ 66 — dropdown width, header height, footer accents, tab geometry ============ */

/* (a) THE DROPDOWN WAS A NARROW COLUMN PINNED TO THE RIGHT. Its left:0/right:0 resolved
   against the nav WIDGET (Elementor gives .elementor-widget position:relative), which is
   only as wide as the burger — so the panel was ~50px and every label wrapped. Making the
   widget position:static hands the job to .hdr-in, which section 63 already made relative,
   so the panel spans the header's content width. */
@media(max-width:1024px){
.elementor .e-con.hdr-in>.hm-nav{position:static}
.hm-nav .elementor-nav-menu--dropdown .elementor-nav-menu>li>a.elementor-item{white-space:nowrap}
}

/* (b) More height in the mobile header — it was reading as a thin strip. */
@media(max-width:767px){.elementor .e-con.hdr-in{min-height:78px}}
@media(max-width:480px){.elementor .e-con.hdr-in{min-height:74px}}
@media(max-width:365px){.elementor .e-con.hdr-in{min-height:70px}}

/* (c) Two artifact flourishes read as stray green bars once the layout is one column:
   .ctab-bx::after is a 120x8 teal tab at the bottom-right of the CTA box, and .ft::after
   is a 10px teal strip down the full right edge of the footer. Stacked on a phone they
   sit one above the other against the footer edge. Suppressed at tablet and below;
   desktop, which the client has approved, keeps them. */
@media(max-width:1024px){
.elementor .e-con.ctab-bx:after,.ctab-bx:after,.ctab-bx::after{content:none;display:none}
.elementor .e-con.ft:after,.ft:after,.ft::after{content:none;display:none}
}

/* (d) THE SELECTED TAB SAT SLIGHTLY HIGHER THAN ITS SIBLINGS, and left a gap beneath it
   when the tabs were stacked. Both come from Elementor's accordion-mode pair, which this
   widget carries as a static class (e-n-tabs-mobile is in the rendered markup, not added
   by JS):
     .elementor.elementor .elementor-widget-n-tabs.e-n-tabs-mobile .e-n-tab-title:not(:first-child)
       { margin-block-start: var(--n-tabs-title-gap) }
     .elementor.elementor .elementor-widget-n-tabs.e-n-tabs-mobile .e-n-tab-title[aria-selected=true]
       { margin-block-end: var(--n-tabs-gap) }          <- --n-tabs-gap is 10px
   In a row that bottom margin lifts the selected tab off the baseline by 10px; in a grid
   the top margin pushes every tab but the first down by the same amount — which is the
   "1947 is taller / misaligned" report and the "slightly-up on selected" report, one cause.
   Zeroed at (0,6,0), which is the weight needed to beat .elementor.elementor. */
.elementor.elementor .hm-ptabs.elementor-widget-n-tabs .e-n-tab-title,
.elementor.elementor .hm-ptabs.elementor-widget-n-tabs .e-n-tab-title:not(:first-child),
.elementor.elementor .hm-ptabs.elementor-widget-n-tabs .e-n-tab-title[aria-selected="true"],
.elementor.elementor .hm-ptabs.elementor-widget-n-tabs .e-n-tab-title[aria-selected="false"],
.elementor.elementor .hm-jntabs.elementor-widget-n-tabs .e-n-tab-title,
.elementor.elementor .hm-jntabs.elementor-widget-n-tabs .e-n-tab-title:not(:first-child),
.elementor.elementor .hm-jntabs.elementor-widget-n-tabs .e-n-tab-title[aria-selected="true"],
.elementor.elementor .hm-jntabs.elementor-widget-n-tabs .e-n-tab-title[aria-selected="false"]{
  margin:0;transform:none;translate:none;top:auto;inset-block-start:auto;align-self:stretch}

/* With the margins gone the cells touch, so the separators become real borders again.
   Product tabs: 4 across, 2 across under 760, 1 across under 420. */
@media(max-width:760px) and (min-width:421px){
.elementor .hm-ptabs .e-n-tab-title{border-right:1px solid var(--line)}
.elementor .hm-ptabs .e-n-tab-title:nth-child(2n){border-right:0}
.elementor .hm-ptabs .e-n-tab-title:nth-child(-n+2){border-bottom:1px solid var(--line)}
}
@media(max-width:420px){
.elementor .hm-ptabs .e-n-tab-title{border-right:0;border-bottom:1px solid var(--line)}
.elementor .hm-ptabs .e-n-tab-title:last-child{border-bottom:0}
}
/* Journey tabs: 5 across, 3 across under 640 (2 rows of 3 + 2). */
@media(max-width:640px){
.elementor .hm-jntabs .e-n-tab-title{border-bottom:1px solid var(--line)}
.elementor .hm-jntabs .e-n-tab-title:nth-child(3n){border-right:0}
.elementor .hm-jntabs .e-n-tab-title:nth-last-child(-n+2){border-bottom:0}
}

/* ============ 67 — journey panel: constant height across tabs ============
   Above 820px .jn-panel is two columns with min-height:340px, so every milestone panel is
   already exactly 340px tall. Below 820 it stacks (image over body) and nothing pins the
   body, so the panel grew with the copy: "Today" (172 characters, and a 2-line heading at
   narrow widths) rendered up to 81px taller than "1947" (130 characters), and the whole
   block jumped every time a year was selected.

   A min-height on .jn-body sized to the longest entry fixes it. It has to be a ladder
   rather than one value because the worst case is a function of width — the same copy
   takes more lines as the column narrows — and a single value big enough for a 320px
   screen would leave ~130px of dead space at 820. Each value below was measured, not
   guessed: the tallest of the five real milestones at every width in its band, plus ~9px.
   .jn-body already centres its content, so the slack falls evenly above and below. */
@media(max-width:820px){.elementor .e-con.jn-body{min-height:262px}}
@media(max-width:600px){.elementor .e-con.jn-body{min-height:272px}}
@media(max-width:480px){.elementor .e-con.jn-body{min-height:292px}}
@media(max-width:430px){.elementor .e-con.jn-body{min-height:312px}}
@media(max-width:400px){.elementor .e-con.jn-body{min-height:338px}}
@media(max-width:349px){.elementor .e-con.jn-body{min-height:392px}}

/* ============ 68 — mobile menu: white text on the navy hover / current states ============
   Elementor's own dropdown rule already pairs the dark fill with white text:
     .elementor-nav-menu--dropdown .elementor-item:hover,
     .elementor-nav-menu--dropdown .elementor-item.elementor-item-active,
     .elementor-nav-menu--dropdown .elementor-item.highlighted,
     .elementor-nav-menu--dropdown .elementor-item:focus { background-color:#3f444b; color:#fff }
   but that is only (0,3,0). Section 65 set the resting colour with
   .hm-nav .elementor-nav-menu--dropdown .elementor-nav-menu>li>a.elementor-item{color:var(--head)}
   at (0,4,1), which also won on hover and focus — so the label stayed navy on a navy fill.
   Section 65's active rule then painted the current page teal on that same fill. The
   BACKGROUND is deliberately left alone; only the text colour is restated, at (0,6,1). */
@media(max-width:1024px){
.elementor .hm-nav .elementor-nav-menu--dropdown .elementor-nav-menu>li>a.elementor-item:hover,
.elementor .hm-nav .elementor-nav-menu--dropdown .elementor-nav-menu>li>a.elementor-item:focus,
.elementor .hm-nav .elementor-nav-menu--dropdown .elementor-nav-menu>li>a.elementor-item:focus-visible,
.elementor .hm-nav .elementor-nav-menu--dropdown .elementor-nav-menu>li>a.elementor-item:active,
.elementor .hm-nav .elementor-nav-menu--dropdown .elementor-nav-menu>li>a.elementor-item.highlighted,
.elementor .hm-nav .elementor-nav-menu--dropdown .elementor-nav-menu>li>a.elementor-item.elementor-item-active,
.elementor .hm-nav .elementor-nav-menu--dropdown .elementor-nav-menu>li>a.elementor-item.elementor-item-active:hover,
.elementor .hm-nav .elementor-nav-menu--dropdown .elementor-nav-menu>li>a.elementor-item.elementor-item-active:focus,
.elementor .hm-nav .elementor-nav-menu--dropdown .elementor-nav-menu .elementor-sub-item:hover,
.elementor .hm-nav .elementor-nav-menu--dropdown .elementor-nav-menu .elementor-sub-item.elementor-item-active{color:#fff;fill:#fff}
/* the label and any icon are children of the anchor, so they must follow it */
.elementor .hm-nav .elementor-nav-menu--dropdown .elementor-nav-menu>li>a.elementor-item:hover *,
.elementor .hm-nav .elementor-nav-menu--dropdown .elementor-nav-menu>li>a.elementor-item:focus *,
.elementor .hm-nav .elementor-nav-menu--dropdown .elementor-nav-menu>li>a.elementor-item.highlighted *,
.elementor .hm-nav .elementor-nav-menu--dropdown .elementor-nav-menu>li>a.elementor-item.elementor-item-active *{color:inherit;fill:currentColor}
}

/* ============ 69 — Why Choose Us on cream ============
   The section is a `.band`: a photo at z-index:-2 with a dark green gradient painted over
   it by `.band::before`. Both are removed here and the section takes the cream page tone,
   so it reads like the Sustainability block. A `band-cream` class was added to the
   container on Home so the site's other three `.band` sections (Our Core, Committed To
   International Standards, and Compliance's certification band) are untouched.

   Card hover: on the dark band the cards filled solid teal, which worked because the whole
   section was already light-on-dark. On cream that would flash white text onto #00A087 —
   2.9:1, below the accessible minimum. The cards instead take the same hover this site
   already uses on every light-background card (Compliance's `.sup-c`): teal border, lift
   and shadow, text colours unchanged. */
.elementor .e-con.band.band-cream{background:var(--light)}
.elementor .e-con.band.band-cream::before{background:none}
.elementor .e-con.band.band-cream > .band-img{display:none}

/* headings: navy title, teal eyebrow (restated after the title rule so it survives) */
.elementor .e-con.band.band-cream .elementor-widget-heading .elementor-heading-title{color:var(--head)}
.elementor .e-con.band.band-cream .eb .elementor-heading-title,
.elementor .e-con.band.band-cream .eb.elementor-widget-heading .elementor-heading-title{color:var(--acc)}
.elementor .e-con.band.band-cream .elementor-widget-text-editor,
.elementor .e-con.band.band-cream .elementor-widget-text-editor p{color:var(--body)}

/* the four capability cards */
.elementor .e-con.band.band-cream .feat-c.elementor-widget-icon-box{
  background:var(--surface);border:1px solid var(--line);backdrop-filter:none;-webkit-backdrop-filter:none}
.elementor .e-con.band.band-cream .feat-c.elementor-widget-icon-box .elementor-icon{color:var(--acc)}
.elementor .e-con.band.band-cream .feat-c .elementor-icon-box-title,
.elementor .e-con.band.band-cream .feat-c .elementor-icon-box-title a{color:var(--head)}
.elementor .e-con.band.band-cream .feat-c .elementor-icon-box-description{color:var(--body)}
.elementor .e-con.band.band-cream .feat-c.elementor-widget-icon-box:hover{
  background:var(--surface);border-color:var(--acc);box-shadow:var(--sh-h);transform:translateY(var(--lift))}
.elementor .e-con.band.band-cream .feat-c.elementor-widget-icon-box:hover .elementor-icon,
.elementor .e-con.band.band-cream .feat-c.elementor-widget-icon-box:has(:hover) .elementor-icon{color:var(--acc)}
.elementor .e-con.band.band-cream .feat-c.elementor-widget-icon-box:hover .elementor-icon-box-title,
.elementor .e-con.band.band-cream .feat-c.elementor-widget-icon-box:hover .elementor-icon-box-title a,
.elementor .e-con.band.band-cream .feat-c.elementor-widget-icon-box:has(:hover) .elementor-icon-box-title,
.elementor .e-con.band.band-cream .feat-c.elementor-widget-icon-box:has(:hover) .elementor-icon-box-title a{color:var(--head)}
.elementor .e-con.band.band-cream .feat-c.elementor-widget-icon-box:hover .elementor-icon-box-description{color:var(--body)}

/* Explore More: solid teal on cream, like "Take Me There" on Sustainability */
.elementor .e-con.band.band-cream .hm-btn-o .elementor-button,
.elementor .e-con.band.band-cream .hm-btn .elementor-button,
.elementor .e-con.band.band-cream .hm-btn-l .elementor-button{
  background:var(--acc);border-color:var(--acc);color:#fff}
.elementor .e-con.band.band-cream .hm-btn-o .elementor-button:hover,
.elementor .e-con.band.band-cream .hm-btn .elementor-button:hover,
.elementor .e-con.band.band-cream .hm-btn-l .elementor-button:hover{
  background:var(--acc-h);border-color:var(--acc-h);color:#fff}
.elementor .e-con.band.band-cream .elementor-button:focus-visible{outline:2px solid var(--head);outline-offset:2px}

/* ============ 70 — Why Choose Us icons: recolour the SVG, not its wrapper ============
   Section 69 set `color` on `.elementor-icon` (the <span>), but the icons are Font Awesome
   INLINE SVG (`.e-font-icon-svg`, whose paths are `fill:currentColor`), and hmt-site.css
   carries the artifact rule

       .feat-c svg{width:36px;height:36px;color:#fff;margin:0 auto 1.1rem}

   which sets `color` on the <svg> ITSELF. A colour declared on the element always beats one
   inherited from its parent, so the span turned teal and the glyph stayed white. The colour
   has to be stated on the svg — and `fill` with it, in case the path ever carries a literal
   fill rather than currentColor. */
.elementor .e-con.band.band-cream .feat-c svg,
.elementor .e-con.band.band-cream .feat-c .elementor-icon svg,
.elementor .e-con.band.band-cream .feat-c .elementor-icon svg path,
.elementor .e-con.band.band-cream .feat-c .elementor-icon i,
.elementor .e-con.band.band-cream .feat-c.elementor-widget-icon-box:hover svg,
.elementor .e-con.band.band-cream .feat-c.elementor-widget-icon-box:hover .elementor-icon svg,
.elementor .e-con.band.band-cream .feat-c.elementor-widget-icon-box:hover .elementor-icon svg path,
.elementor .e-con.band.band-cream .feat-c.elementor-widget-icon-box:has(:hover) svg,
.elementor .e-con.band.band-cream .feat-c.elementor-widget-icon-box:has(:hover) .elementor-icon svg path{
  color:var(--acc);fill:var(--acc)}

/* ============ 71 — SOP typography: one family, one scale, ratio leading ============
   Three separate problems, one section.

   (a) TWO FAMILIES. hmt-site.css declares --fd:Montserrat (display) and --fb:Poppins
       (body), and Elementor kit 10 sets font-family:"Poppins" on <body> plus Poppins on
       the Text and Accent global typography slots. The SOP asks for ONE family, chosen
       from its own lists. Montserrat and Poppins both appear on both SOP lists, so either
       is compliant. Montserrat is kept because it is what every heading and the HARIMATEC
       wordmark (.bl-name b, set in var(--fd)) are already approved in — consolidating on
       Poppins would restyle the logo lockup and all 30 headings, consolidating on
       Montserrat changes body copy only.

   (b) LEADING FROZEN AS A LENGTH. The kit sets line-height:1.72em on <body>. A
       line-height WITH a unit is inherited by descendants as the computed LENGTH
       (15.5 x 1.72 = 26.66px), not as a ratio — so a 12px eyebrow and a 33px heading both
       inherited 26.66px of leading. Every unitless value here re-derives per element.
       Astra separately ships, inline in <head>:
         .elementor-widget-heading h1.elementor-heading-title{line-height:1.4em}
         h2 -> 1.3em   h3 -> 1.3em   h4 -> 1.2em   h5 -> 1.2em   h6 -> 1.25em
       at (0,2,1), which outranks the design's own bare-element rules. Restated below at
       (0,3,1) so it wins on specificity and does not depend on sheet order (SpeedyCache
       can reorder).

   (c) SIZES. SOP scale applied to the real document headings and to body copy:
         desktop >=1025   H1 45  H2 38  H3 32  H4 28  H5 24  H6 20  body 18
         tablet  <=1024   H1 40  H2 32  H3 28  H4 24  H5 22  H6 20  body 18
         mobile  <=766    H1 38  H2 32  H3 28  H4 24  H5 22  H6 20  body 16
       (766/1024 are this install's own Elementor breakpoints, not invented ones.)

       NOT applied to component labels, under the SOP's own clause "adjust them according
       to your website's current status". An audit of all 13 Elementor documents found the
       site uses h1, h2, h3 and h4 only — no h5, no h6 — and every single h4 is a card or
       column label already pinned by class between 15px and 18px: .numc h4, .corecard h4,
       .dlc h4, .ft h4, .vmm-c h4, .tl-i h4, .ct-c h4, .sup-hd h4, .icard-b h4, .ibx h4,
       and 30 icon-box titles. Those are UI chrome, not headings; at SOP's 28px the card
       grids would break. Bare h4/h5/h6 still take the SOP scale so anything added later
       complies, and the class-scoped rules (0,1,1) keep winning over it (0,0,1) by design.
       Same reasoning keeps .nb-bx h2 (events-slider card title), .corecard h3,
       .jn-body h3 and .pmodal-panel h3 at their component sizes. */

/* --- 71.1  one family ------------------------------------------------------------- */
html:root{
  --fd:'Montserrat','Helvetica Neue',Helvetica,Arial,sans-serif;
  --fb:'Montserrat','Helvetica Neue',Helvetica,Arial,sans-serif}
body.elementor-kit-10{font-family:var(--fb)}

/* --- 71.2  leading as a ratio ------------------------------------------------------ */
body.elementor-kit-10{line-height:1.72}
h1,h2,h3,h4,h5,h6{line-height:1.22}
h1{line-height:1.16}
.elementor-widget.elementor-widget-heading h1.elementor-heading-title{line-height:1.16}
.elementor-widget.elementor-widget-heading h2.elementor-heading-title,
.elementor-widget.elementor-widget-heading h3.elementor-heading-title,
.elementor-widget.elementor-widget-heading h4.elementor-heading-title,
.elementor-widget.elementor-widget-heading h5.elementor-heading-title,
.elementor-widget.elementor-widget-heading h6.elementor-heading-title{line-height:1.22}

/* --- 71.3  SOP scale, desktop ------------------------------------------------------ */
h1{font-size:45px}
h2{font-size:38px}
h3{font-size:32px}
h4{font-size:28px}
h5{font-size:24px}
h6{font-size:20px}
.hero h1,.ph-card h1{font-size:45px}
.band h2{font-size:38px}
body.elementor-kit-10{font-size:18px}
.lead{font-size:18px}

/* --- 71.4  SOP scale, tablet ------------------------------------------------------- */
@media(max-width:1024px){
  h1{font-size:40px}
  h2{font-size:32px}
  h3{font-size:28px}
  h4{font-size:24px}
  h5{font-size:22px}
  h6{font-size:20px}
  .hero h1,.ph-card h1{font-size:40px}
  .band h2{font-size:32px}
  body.elementor-kit-10{font-size:18px}
  .lead{font-size:18px}
}

/* --- 71.5  SOP scale, mobile ------------------------------------------------------- */
@media(max-width:766px){
  h1{font-size:38px}
  h2{font-size:32px}
  h3{font-size:28px}
  h4{font-size:24px}
  h5{font-size:22px}
  h6{font-size:20px}
  .hero h1,.ph-card h1{font-size:38px}
  .band h2{font-size:32px}
  body.elementor-kit-10{font-size:16px}
  .lead{font-size:16px}
}

/* ============ 72 — eyebrow-to-title spacing, matched to the events slider ============
   Client's reference is the homepage events slider.

   FIRST ATTEMPT FAILED AND IT IS WORTH RECORDING WHY. The obvious rule —
   `.eb{margin-bottom:.3rem}` at (0,1,0) — never applied, because Elementor ships

       .e-con .elementor-widget.elementor-widget{margin-block-end:0}     (0,3,0)

   which zeroes the bottom margin of EVERY widget inside a container. Two consequences:

   (1) the artifact's own `.eb{margin-bottom:.9rem}` has never applied on this site either,
       so the eyebrow-to-title gap has always been pure line-box leading, never a margin; and
   (2) any rule that wants to set it must beat (0,3,0) AND set `margin-block-end`, since that
       is the property actually holding the zero. `margin-bottom` alone at lower weight loses
       even though the two resolve to the same physical edge.

   THE SLIDER DOES NOT USE A WIDGET MARGIN AT ALL, which is why it looks different. Its
   eyebrow sits inside a CONTAINER —
       .e-con.nb-top{display:flex;align-items:center;min-height:30px;margin-bottom:.15rem}
   — and containers are not touched by the rule above. So its gap is the centring slack
   inside that 30px row (the .eb line box is 20.64px, leaving 4.68px below) plus the
   container's own 2.4px: 7.6px of box gap, where every section title has had 0.

   MATCHED ON INK, NOT ON BOXES. What the eye judges is last pixel of the tag to first pixel
   of the title: box gap + half-leading under the tag + half-leading and ascent gap over the
   title. The titles differ (slider 28px, section titles 38px desktop / 32px at 1024 and
   below), so the same box gap does not give the same look. Measured in real Montserrat, in a
   fixture carrying the Elementor rules above and the real widget markup, with the eyebrow
   measured in its rendered UPPERCASE form:

     slider reference ............................. box  7.64px   ink  20.03px   (28px title)
     every section title, before .................. box  0.00px   ink  15.49px   (38px title)
     .3rem   with a 38px title .................... box  4.80px   ink  20.28px   <- desktop
     .45rem  with a 32px title .................... box  7.19px   ink  20.01px   <- <=1024

   Two values, not one: the ascent gap over the title shrinks with the title, so a single
   margin leaves one breakpoint 2.4px tight. Swept and rejected: .15/.2/.25/.35rem at 38px
   (17.9-21.1) and .3/.4/.5/.55rem at 32px (17.6-21.6).

   `.nb-top` is excluded so the reference itself is not moved. Home's "Our Core" eyebrow is
   NOT excluded: its authored `.corecard .eb{margin-bottom:.15rem}` was dead for the same
   reason as everything else, so it takes the same treatment rather than being the one tag
   left flush against its title. All 21 eyebrow widgets were enumerated from _elementor_data
   first; none carries a per-widget margin in Elementor, so nothing here is being fought.

   Hero note: the one eyebrow that sits over an h1 rather than an h2 (Home hero, 45px) lands
   at 22.05px instead of 20.03px. Left alone — a 2px difference under a display headline is
   not worth a third breakpoint. */
.elementor .e-con:not(.nb-top) > .elementor-widget.eb{margin-block-end:.3rem;margin-bottom:.3rem}
@media(max-width:1024px){
  .elementor .e-con:not(.nb-top) > .elementor-widget.eb{margin-block-end:.45rem;margin-bottom:.45rem}
}

/* ============ 73 — title-to-body spacing (client-selected 30px) ============
   §72 matched tag-to-title to the events slider. This is the second joint. The slider's own
   title-to-body gap measures 40.3px; the client compared 40 / 30 / 20 as rendered proofs,
   tested 20 then 30 live on the hero, and chose **30px** for the whole site.

   SAME ROOT CAUSE AS §72, IN TWO MORE PLACES. Elementor's
   `.e-con .elementor-widget.elementor-widget{margin-block-end:0}` (0,3,0) kills every widget's
   bottom margin, and `.elementor-widget-heading .elementor-heading-title{margin:0}` (0,2,0)
   kills the heading element's. So two more authored rules have never done anything:
       .cathd h2{margin-bottom:.5rem}                                 (0,1,1) — dead
       .band-lead .elementor-widget-container{margin:1.15rem auto 0}  — dead, and the
           text-editor widget has no .elementor-widget-container in Elementor 4.x anyway
   The only thing that has ever held this gap open is `.mt1{margin-top:1rem}` on the body
   widget — a margin-TOP, which nothing zeroes. Hence a flat 16px under every title regardless
   of the title's size, and nothing at all where .mt1 was absent.

   FOUR VALUES, NOT ONE, because the visible gap is
       box gap + the descent space under the title + the ascent space over the body
   and both of those vary. The per-context constant, measured:
       .lead / .cathd  7.18px   (38px title at line-height 1.22, 15px body)
       .ctab-bx        6.78px   (same title, 14px body)
       .hero           3.68px   (45px h1 at line-height **1.12** — tighter leading, so much
                                 less descent space under its last line)
   That last one is why the hero needs 1.645rem where a section title needs 1.425rem for the
   same 30px. Values below were measured, not derived:

     context     shipped      -> visible     candidates swept
     .lead       1.425rem     -> 29.98px     1.4 = 29.57 · 1.45 = 30.37 · @32px title = 30.31
     .cathd      1.425rem     -> 29.98px     1.4 = 29.57 · 1.45 = 30.37
     .ctab-bx    1.45rem      -> 29.97px     1.425 = 29.58 · 1.475 = 30.37
     .hero       1.645rem     -> 29.99px     1.6 = 29.28 · 1.64 = 29.92 · 1.7 = 30.87

   One value per context rather than per breakpoint: dropping the title from 38px to 32px at
   1024 moves the gap 0.33px, which is not worth a media query.

   FOR REFERENCE, the other two rungs of the ladder, all measured, should the client revisit:
     20px:  .lead 0.8rem   · .cathd 0.8rem   · .ctab-bx 0.825rem · .hero 1.02rem
     40px:  .lead 2.05rem  · .cathd 2.05rem  · .ctab-bx 2.1rem   · .hero 2.3rem   (slider-matched)

   NOT INCLUDED, deliberately:
   - `.split-head` — Compliance and About put the title and body SIDE BY SIDE in one row, with
     the body right-aligned, which the client asked for earlier. There is no title-above-body
     joint there to match, so it is excluded by :not().
   - Card and footer copy (`.dlc-note`, `.ft-desc`, `.coreq`, `.vmm-c p`, `.tl-i p`, `.ibx p`)
     — component chrome inside cards, not a section's body copy.

   Written at (0,4,1)/(0,5,0) because everything here has to beat rules that already exist at
   (0,1,0)-(0,1,1), and because on this site anything weaker than (0,4,0) on a widget margin is
   silently dead. */
.elementor .e-con:not(.split-head) > .elementor-widget.lead{margin-block-start:1.425rem;margin-top:1.425rem}
.elementor .e-con.cathd > .elementor-widget-text-editor > p{margin-top:1.425rem}
.elementor .e-con.ctab-bx > .elementor-widget-text-editor > p{margin-top:1.45rem}
.elementor .e-con.hero-copy > .elementor-widget-text-editor > p{margin-top:1.645rem}

/* ============ 74 — Phase 2: one-line section titles ============
   Client asked for four long titles to sit on one line. Measured first, and the finding
   changed the fix: **the viewport was never the constraint — the artifact's `ch` caps were.**
   They were authored against the old 33px h2 and are too tight now that §71 put headings at
   the SOP's 38px. Available width vs allowed width, at 1440:

     Certifications & Management Systems ....... needs 732px, allowed 619px  (.band-left h2 24ch)
                                                 while 1280px sat unused
     Government-Issued Manufacturing Auth. ..... needs 965px, allowed 715px  (.sec-ttl 60ch)
     Manufacturing With Sustainability In Mind . needs 812px, allowed 715px  (.sec-ttl 60ch)
     The Evolution Of Harimatec Malaysia ....... needs 703px, allowed 413px  (.split-head 16ch)

   RAISING .sec-ttl WOULD HAVE WIDENED THE BODY COPY as a side effect: the 60ch cap was
   clipping `.lead` (own cap 68ch = 810px) down to 715px, so lifting it moved the reading
   measure from 715 to 810px — a change nobody asked for. The 60ch is therefore handed to
   `.lead` itself, which is what it was actually guarding. Measured: 715px before, 715px
   after, at every width.

   THE JOURNEY ROW went through three rounds and ended up restructured rather than tuned.
   Its eyebrow sits in `.wrap`, OUTSIDE the grid, and the grid carried `align-items:end`, so
   the row's height came from the three-line intro on the right and the one-line title was
   pushed to the BOTTOM of an 81px row — a measured 54.9px eyebrow-to-title gap against
   20.3px everywhere else. The margin was correct the whole time; the grid was stretching the
   space underneath it. Baseline-aligning the two columns fixed that, but left the intro at
   three lines, and it could not be two: at 15px that sentence needs 530px, while the intro
   column can never exceed 495px (the title beside it needs 703px and the row only has
   1216px to share — 1233px required). No column rebalancing could produce it.

   So the client chose to STACK the row instead. `.split-head-r` is now a single column at
   every width: eyebrow, title, intro, all left-aligned. Both halves then get the full
   measure, which is strictly better than the two-column version they replaced:
       title  1 line from 1280px  ->  1 line from 767px
       intro  3 lines everywhere  ->  1 line from 1100px
   `row-gap:0.74rem` gives a measured 20.0px title-to-intro gap at every width. This is the
   ONE section that does not take §73's site-wide 30px: at 1.36rem it measured 29.9px, exactly
   in line with the rest, and the client still read it as loose — because the intro here is a
   single ~1040px line under a 703px title, so there is far more horizontal space in play than
   in a normal stacked block and the same vertical gap looks bigger. Tightened on the client's
   instruction, for this section only. 30px here is `row-gap:1.36rem` if it is ever restored.
   The intro runs to ~1040px on one line — a long measure for body copy, but it is a single
   standfirst sentence under a display title, not a paragraph.

   Compliance's `.split-head` keeps its two columns, its right-aligned intro and its
   `align-items:end`: it has no eyebrow above it and the client has approved it as it stands.

   THE COMPLIANCE TITLE carries an authored <br>, so TWO lines is its correct state. It was
   rendering THREE at 1025px (the band §71's rescale opened up, above the old eased query's
   1024px ceiling), at 821-860px (below its 861px floor), and at 390px. Both ramps below are
   sized so "Compliance Framework" fits the column at every width in the band.

   VERIFIED — rendered line count at 15 viewport widths per title:

     title                     before                          after
     Sustainability            2 lines >=1025                  1 line 767-1440
     Certifications            2 lines everywhere              1 line 767-1440
     Government-Issued         2 everywhere, 3 on phones       1 line 861-1440
     Journey title             2 everywhere, 3-4 on phones     1 line 767-1440
     Journey intro             3 lines everywhere              1 line 1100-1440, 2 lines 640-1025
     Compliance Framework      3 lines at 1025, 860, 821, 390  2 lines at every width

   Titles still wrap on phones, which is deliberate: forcing one line at 390px would mean
   unreadable type. */

/* (a) section-title measure: cap the body copy, not the block */
.elementor .e-con.sec-ttl{max-width:62rem}
.elementor .e-con.sec-ttl > .elementor-widget.lead{max-width:60ch}

/* (b) dark-band title measure */
.elementor .band-left h2,
.elementor .e-con.band-left > .elementor-widget-heading .elementor-heading-title{max-width:30ch}

/* (c) About Journey: stacked, full measure for both, intro on one line */
.elementor .e-con.split-head.split-head-r{grid-template-columns:1fr;align-items:start;row-gap:0.74rem}
.elementor .e-con.split-head-r > .elementor-widget-heading .elementor-heading-title{max-width:none}
.elementor .e-con.split-head-r > .elementor-widget.lead{max-width:none;justify-self:start}
.elementor .e-con.split-head-r > .elementor-widget.lead p{max-width:none;text-align:left}

/* (d) Compliance's authored-<br> title: hold it at two lines, never three */
@media(min-width:821px) and (max-width:1060px){
  .elementor .e-con.split-head > .elementor-widget-heading .elementor-heading-title:has(br){
    font-size:clamp(28px,4.184vw - 6.35px,38px)}
}
@media(max-width:414px){
  .elementor .e-con.split-head > .elementor-widget-heading .elementor-heading-title:has(br){
    font-size:clamp(22px,8.29vw - 2.32px,32px)}
}

/* ============ 76 — Vision / Mission / Core Values: title-to-body gap ============
   SPACING POLICY, as set by the client: **30px is the default** for title-to-body across the
   site (§73). Individual blocks may drop to **20px** where the surrounding layout makes 30
   read as loose or where the block is tight and 30 would be too much. Two exceptions so far:
     §74(c) About Journey ...... 20px, because a ~1040px one-line intro under a 703px title
                                 puts so much horizontal space in play that 29.9px read loose
     §76 (this) Vision/Mission . 20px, because these are compact cards, not section blocks

   THESE ARE ICON-BOXES, NOT A HEADING PLUS A TEXT WIDGET, so §73 never touched them — and
   their title and description sit inside one `.elementor-icon-box-content` block where BOTH
   carry `margin:0`. The wrapper's `gap:.6rem` separates the ICON from the content, not the
   title from the description. So the gap has been **zero box, 10.8px of pure leading** — which
   is what the client saw as "too close".

   Measured on the real icon-box markup, sweeping the title's bottom margin:
     0        -> 10.8px ink   (current)
     .55rem   -> 19.6px
     **.575rem -> 20.0px**    <- shipped
     .6rem    -> 20.4px
   (An earlier sweep of 8-16px is in the harness; the values above are the fine pass.)

   Set on the TITLE's margin rather than the wrapper's `gap`, because the gap also controls
   icon-to-title and the client asked only for title-to-body. (0,4,0) to beat
   `.vmm-c .elementor-icon-box-title{margin:0}` at (0,2,0).

   NOT applied to the site's other icon-box card sets — `.feat-c` (Why Choose Us on Home and
   About), `.ct-c` (contact cards), `.ibx`, `.sup-hd`, `.icard-lbl` — which all have the same
   zero box gap and will read equally tight. Flagged to the client rather than changed unasked;
   each needs its own value since their title and body sizes differ. */
.elementor .vmm-c.elementor-widget-icon-box .elementor-icon-box-title{margin-block-end:.575rem}

/* ============ 77 — five per-section copy-fit adjustments ============
   Client, one batch. Four are measure caps; (1) also corrects a bug in my own §72/§73.

   (1) CTA BAND. Asked for 20px title-to-body. Measuring showed BOTH gaps were wrong live:
       tag->title 29.9px (§72's value is 20.3) and title->body 39.6px (§73 set 30).
       Cause: `.elementor .e-con.ctab-bx{…gap:.6rem}` puts a 9.6px flex gap between EVERY child
       of the CTA box, on top of the widget margins §72/§73 set. Those fixtures reproduced the
       widget markup but not this container's gap, so both shipped 9.6px loose. Corrected by
       subtracting it: eyebrow -.3rem -> 20.3px, body p .225rem -> 20.0px.
       Swept .2/.225/.25rem = 19.6/20.0/20.4px.

   (2) ABOUT "Why Choose Us" — line 2 to start "Harimatec Malaysia to support…". Done with a
       measure cap, not an authored <br>: line 1 is 1037px and the next word is ~80px, so any
       cap in 1037-1115px forces the break there. 66rem = 1056px. Verified at 1100/1200/1280/
       1440. Below ~1080 the container is narrower and it wraps naturally — which is why a <br>
       was avoided.

   (3) COMPLIANCE "Certifications & Management Systems" — line 2 to start "occupational health
       and safety…". Line 1 is 1070px, next word ~95px, window 1070-1160px. 69rem = 1104px.
       Verified 1200-1440; at 1100 the container is only 1060px so the break moves up to
       "responsibility," — still two lines, unavoidable without shrinking the type.

   (4) COMPLIANCE "Government-Issued…" — measure to end at the third licence card. Cards are
       `repeat(auto-fit,minmax(250px,1fr))` with a 16px gap, so with four across the third
       card's right edge is 0.75 x wrap - 0.25 x gap. Verified: the paragraph's right edge
       lands on the card's right edge to the pixel at every width from 1088 up. Scoped to
       min-width:1088px because below that the grid drops out of four columns.
       **This does NOT also give two lines** — the sentence is 1901px and the cap is 956px at
       1440, so it takes three. Two lines needs a cap of ~1000px (which overshoots the card by
       44px) or ~20 characters trimmed. Flagged to the client; the cap is what was asked for.

   (5) SUSTAINABILITY "Manufacturing With Sustainability In Mind" — one line. The sentence is
       898px and §74(a) capped this widget at 60ch (715px). Cap lifted for this widget only;
       `.sec-ttl` is 992px, so one line holds from ~940px up.

   (4) and (5) are addressed by page id: each is the only `.sec-ttl > .lead` on its page, which
   is cheaper than adding a class to the page data for two one-off rules. */

/* (1) */
.elementor .e-con.ctab-bx:not(.nb-top) > .elementor-widget.eb{margin-block-end:-.3rem;margin-bottom:-.3rem}
.elementor .e-con.ctab-bx > .elementor-widget-text-editor > p{margin-top:.225rem}
/* (2) */
.elementor .e-con.band-left > .elementor-widget.lead.band-lead,
.elementor .e-con.band-left > .elementor-widget.lead.band-lead p{max-width:66rem}
/* (3) */
.elementor .e-con.band-left > .elementor-widget.lead.band-lead-left,
.elementor .e-con.band-left > .elementor-widget.lead.band-lead-left p{max-width:69rem}
/* (4) */
@media(min-width:1088px){
  body.page-id-62 .elementor .e-con.sec-ttl > .elementor-widget.lead{
    max-width:calc(0.75 * min(100vw - 2.5rem, 1280px) - 4px)}
}
/* (5) */
body.page-id-59 .elementor .e-con.sec-ttl > .elementor-widget.lead{max-width:none}

/* ============ 78 — revised break points (supersedes parts of §77) ============
   Client refined three of §77's breaks and asked for a fourth gap change.

   (1) ABOUT "Why Choose Us" — line 2 must now start at "and a diverse product portfolio…".
       A measure cap CANNOT do this. Line 1 is 740px, line 1 + the next word is 773px, but
       line 2 is 960px — so the cap would have to be both >=960 (to keep line 2 whole) and
       <773 (to force the break). An authored <br> is the only way once line 2 is LONGER than
       line 1. Added to the page content (backup `hmt_p61_bk_wcu`) and hidden below 1000px so
       phones wrap naturally rather than showing one short line above a long one.
       §77's 66rem cap stays — line 2 needs 960px of room.

   (2) COMPLIANCE "Certifications" — line 2 now starts at "environmental responsibility,".
       Line 1 850px, line 1 + next word 964px, line 2 804px, so the window is 850-963px.
       56rem = 896px. (§77's 69rem put the break one phrase later.)

   (3) COMPLIANCE "Government-Issued" — TWO LINES NOW TAKES PRIORITY over the card alignment.
       Measured threshold: 975px = 3 lines, **980px = 2 lines**. §77's card-aligned cap was
       956px at 1440, which is exactly why it took three. `min(980px,100%)` gives two lines
       from 1025px up. COST, stated plainly: at 1440 the paragraph now ends 36px past the third
       card's right edge, about 20px into the fourth column. Getting both at once needs roughly
       six characters trimmed from the sentence; no copy change was asked for, so line count wins.

   (4) SUSTAINABILITY — title-to-body 30px -> 20px, per the client's "30 default, 20 where it
       reads better" policy. .7375rem = 20.0px measured (.72/.75rem = 19.7/20.2). */
@media(max-width:1000px){
  .elementor .e-con.band-left > .elementor-widget.lead.band-lead br{display:none}
}
.elementor .e-con.band-left > .elementor-widget.lead.band-lead-left,
.elementor .e-con.band-left > .elementor-widget.lead.band-lead-left p{max-width:56rem}
body.page-id-62 .elementor .e-con.sec-ttl > .elementor-widget.lead{max-width:min(980px,100%)}
body.page-id-59 .elementor .e-con.sec-ttl > .elementor-widget.lead{margin-top:.7375rem}

/* ===== 79. PHASE 3 (v3) =====
   Close button only. Everything about the banner is now set natively in Elementor:
     .ph-img container  -> Layout > Min Height (mobile) = 480px
     .ph-shot image     -> Style > Width 100%, Height 100%, Object Fit: Cover, Position: Center
     home .hero         -> Layout > Min Height (mobile) = 420px
   Page 58's banner image was the odd one out: its image widget had NO css class, so it never
   picked up the .ph-shot height chain and rendered at natural height, leaving the container's
   navy background showing below it. It now carries ph-shot plus the native cover settings.

   The product lightbox is hand-authored markup inside a text-editor widget, not an Elementor
   widget, so .pmodal-x has no Style tab. This rule is the only place these colours can live.
   White button, navy x at rest; teal on hover. (0,3,0) to clear the earlier (0,1,0)/(0,2,0). */

body > .pmodal .pmodal-x,
.elementor .pmodal .pmodal-x{background:#fff;border-color:var(--line);color:var(--head)}
body > .pmodal .pmodal-x:hover,
.elementor .pmodal .pmodal-x:hover,
body > .pmodal .pmodal-x:focus-visible,
.elementor .pmodal .pmodal-x:focus-visible{background:var(--acc);border-color:var(--acc);color:#fff}
body > .pmodal .pmodal-x svg,
.elementor .pmodal .pmodal-x svg{fill:currentColor;stroke:currentColor}

/* ===== 80. HERO IMAGE FULL HEIGHT (client-authorised hardcode) =====
   .hero-in is a grid with padding-block:clamp(3.5rem,2rem + 6vw,6.5em) at (0,3,0), and
   .hero-fig is a grid item inside it, so it cannot reach the hero's top and bottom edges while
   that padding stands. No native control beats (0,3,0), and cancelling it with a negative
   margin failed: the clamp resolves against a different font/root size on .hero-fig than on
   .hero-in, leaving a stubborn ~9-10px at each edge at every width.
   So the padding is moved off the grid instead and onto the copy column, which is what it was
   really spacing. The grid row then equals the full hero height and the figure simply
   stretches into it -- no arithmetic to get wrong.
   Vertical bleed only: the grid column is untouched, so width and horizontal position are
   exactly as before. */



.elementor .e-con.hero-fig > .elementor-widget-image,
.elementor .e-con.hero-fig > .elementor-widget-image .elementor-widget-container,
.elementor .e-con.hero-fig > .elementor-widget-image figure{height:100%;width:100%;margin:0}
.elementor .e-con.hero-fig > .elementor-widget-image img{width:100%;object-fit:cover;display:block}


/* ===== 82. LIGHTBOX POSITION FOR LOGGED-IN USERS =====
   Elementor ships:  body.admin-bar .dialog-type-lightbox{height:100vh;position:sticky}
   The base rule is position:fixed. Switching it to sticky with no top offset makes it fall
   back to its normal-flow position, and the lightbox is appended at the END of <body> -- so it
   renders at the bottom of the document instead of over the viewport. That is exactly the
   'does not pop up where my screen is' symptom, and because the site is still behind Coming
   Soon every client view is logged-in, so the rule fires every time.
   Restores fixed positioning, full height. NOTE: this is only the no-JS fallback now --
   hmt_lightbox_pin() re-parents the lightbox to <html>, so this selector (which needs it inside
   <body>) no longer matches on a normal render. Logged-out visitors were never affected. Not fixable natively -- this is Elementor's own
   stylesheet. */
body.admin-bar .dialog-type-lightbox{
  position:fixed;
  top:0;
  bottom:0;
  height:100vh;
}
body.admin-bar .dialog-lightbox-widget{height:100vh}
@media screen and (max-width:782px){
  /* below 783px the WP admin bar is absolutely positioned and scrolls away, so no inset */
  body.admin-bar .dialog-type-lightbox{top:0;height:100vh}
  body.admin-bar .dialog-lightbox-widget{height:100vh}
}

/* ===== 83. LIGHTBOX PINNED TO THE VIEWPORT =====
   Works with hmt_lightbox_pin() in hmt-core.php, which re-parents the lightbox to <html> so no
   transformed ancestor inside <body> can capture its position:fixed. Once it is out there the
   inset is stated explicitly rather than relying on Elementor's bottom:0 + height:100%.
   The scrim covers the FULL screen, admin bar included -- z-index 100000 clears the toolbar's
   99999. An earlier version inset the top by 32px to hold the bar clear, which left a visible
   strip of the page above the overlay; the client wanted it edge to edge.
   The script still mirrors body.admin-bar onto <html> as .hmt-adminbar; nothing consumes it now,
   but it is left in place in case an inset is ever wanted again. */
.hmt-lb-pinned{
  position:fixed !important;
  top:0 !important; right:0 !important; bottom:0 !important; left:0 !important;
  width:auto !important; height:auto !important;
  margin:0 !important;
  z-index:100000 !important;
}
/* No admin-bar inset: the scrim is meant to cover the whole screen, and z-index 100000
   clears the WP admin bar's 99999. Leaving a 32px inset showed a strip of the page above the
   overlay. */

/* --- 84. Sustainability: pillar hover -> stage image, rewritten for the 4c structure ---
   The original pair was keyed to `.sus-wrap>.numgrid ... ~ .sus-stage`, which depended on three
   things Phase 4c changed: the wrapper's `sus-wrap` class (removed), the grid's `numgrid` class
   (removed again when the grid went native), and the tabs PRECEDING the stage so `~` could reach
   it. 4c reordered the children so the stage comes first, which means no sibling combinator can
   ever reach it from the tabs -- the effect had been dead since then, not merely mis-scoped.
   Confirmed before fixing: hovering pillars 2-4 left the stage at opacity [1,0,0,0].
   Hung off the shared parent with :has() instead, which reads in both directions.
   Specificity: hide (0,6,0), show (0,8,0); the resting
   `.sus-stage>.elementor-widget-image:first-child` is (0,3,0), so both outrank it and the
   first image still shows at rest. Elementor has no native cross-element hover control, so this
   is CSS by necessity -- client authorised the exception. */
.elementor .e-con:has(> .sus-hover:hover) > .sus-stage > .elementor-widget-image{opacity:0}
.elementor .e-con:has(> .sus-hover > .numc:nth-child(1):hover) > .sus-stage > .elementor-widget-image:nth-child(1),
.elementor .e-con:has(> .sus-hover > .numc:nth-child(2):hover) > .sus-stage > .elementor-widget-image:nth-child(2),
.elementor .e-con:has(> .sus-hover > .numc:nth-child(3):hover) > .sus-stage > .elementor-widget-image:nth-child(3),
.elementor .e-con:has(> .sus-hover > .numc:nth-child(4):hover) > .sus-stage > .elementor-widget-image:nth-child(4){opacity:1}

/* --- 85. Contact map band ---------------------------------------------------------
   The aerial photo that stood in for a map above the footer is replaced by Elementor's
   native Google Maps widget (keyless embed; no API key on this install, so it uses the
   maps.google.com/output=embed URL). Height is now the widget's OWN responsive control
   (380/320/260), so the three hardcoded rules that sized the old band and stretched the
   image inside it -- `.e-con.ct-map` and the two `.ct-map-shot` rules -- are removed rather
   than left dead. The container keeps `.fig` for the full-bleed frame. Verified `ct-map`
   and `ct-map-shot` appear nowhere else: the only other posts matching were revisions
   237/238/239 of page 63 itself. */

/* --- 86. Hero grid is now NATIVE (supersedes the layout half of section 80) --------
   Client: the hero photo sat ~65px narrower on its left than the events-slider photo.
   Cause, measured: `.hero-in` was `1.15fr .85fr` with a 3rem gap, so the image column began at
   (1.15/2)x(W-48)+48 = W*0.575+20.4 -> 756px in a 1280 wrap, while `.nb-box` is `.54fr .46fr`
   with NO gap, so its image begins at 0.54*W = 691px. A 65px difference by construction.
   No native control could fix it while `.hero-in` stood: the class rule is (0,3,0) and
   Elementor's grid kit rule `.e-con.e-grid` is only (0,2,0), so every native value lost.
   So the container was converted to a real Elementor grid and the class dropped:
     columns  calc(0.54 * 100% - 3rem) 1fr   <- image column starts at exactly 0.54 x wrap,
                                                 the same construction as .nb-box
     gap 48px, align-items center, 1 column on tablet and mobile
   The three declarations section 80 needed are now native too: hero-in padding-block 0 is the
   container's own padding, the copy column carries the clamp as a custom-unit padding, and the
   figure uses the native align-self:stretch. All five .hero-in rules are therefore DELETED, not
   left dead -- this is a net REMOVAL of hardcode, not an addition.
   Known behaviour change, deliberate: the hero used to stack at 980px, a width that is not an
   Elementor breakpoint. It now stacks at the tablet breakpoint (1024px), which is where
   Industries Served and the Global Presence bar already stack. One stack point, not two.
   `.hero-in` appeared only on page 15 (every other DB hit was a revision of 15). */

/* --- 87. Page gutters on tablet and mobile (client SOP 2.1) ------------------------
   Client: on phones and tablets the content sits almost against the screen edge. SOP table:
     tablet  left/right 40    mobile  left/right 20    (desktop left alone - not requested)
   Every section on every page puts its content in a `.wrap`, and `.wrap` sets the gutter through
   its WIDTH, not padding: width:min(100% - 2.5rem, var(--maxw)) = 20px a side, with a
   max-width:640px override that tightened it to 1.75rem = 14px a side.

   Why this is not done per container in the editor: a native container width emits at
   `.elementor-N .elementor-element.elementor-element-XXX` = (0,3,0), and `.elementor .e-con.wrap`
   is ALSO (0,3,0). hmt-wp.css is enqueued after every post-N.css (verified in the rendered
   document: the .wrap rule sits ~134k bytes after the post-15 block), so the tie goes to the
   class and the native value loses at EVERY breakpoint. Setting it on ~33 containers would have
   produced 33 dead values. Changing the one rule they all already use is the only mechanism that
   works, and it keeps a single source of truth -- `--maxw` still governs the max width.

   The 640px override is DELETED rather than overridden: at <=640 the gutter was 14px a side and
   the SOP asks for 20, which is exactly what the base rule already gives. One less breakpoint.
   Tablet is scoped to Elementor's own tablet band so it lines up with every other responsive
   value on the site. */
@media(min-width:767px) and (max-width:1024px){.elementor .e-con.wrap{width:min(100% - 5rem,var(--maxw))}}

/* --- 88. Hero corner bar removed + SOP vertical padding (tablet/mobile) ------------
   (a) hmt-site.css draws a 120x12 teal tab at the bottom-right of the hero photo via
       `.hero-fig::after`. Same ornament the client already had removed from the announcement
       photo in section 30, and from the Sustainability stage. Suppressed the same way rather
       than edited out of hmt-site.css, so the artifact sheet stays a faithful copy of the
       approved design and this is revertible by deleting one block. Section 80's
       `.hero-fig::after{bottom:0}` (which had pulled the bar up from bottom:-12px so it sat ON
       the photo) is deleted with it -- it has nothing left to position.
   (b) Client SOP 2.1 vertical padding, tablet and mobile only (desktop untouched, not asked).
       Sections are padded by `.sec{padding:clamp(3.25rem,2rem + 4.5vw,6em) 0}` in hmt-site.css,
       which gives ~66-78px on tablet and ~52-66px on mobile. SOP asks for 80 and 40.
       Restated at (0,3,0) so it beats the artifact's (0,1,0) rule regardless of sheet order,
       and as padding-BLOCK only so the horizontal 0 (and section 87's gutters) are untouched.
       `.sec-sm` follows the same table -- it is the same kind of section, just tighter. */
.elementor .e-con.hero-fig::after{display:none;content:none}
@media(min-width:767px) and (max-width:1024px){
  .elementor .e-con.sec,.elementor .e-con.sec-sm{padding-block:80px}
}
@media(max-width:766px){
  .elementor .e-con.sec,.elementor .e-con.sec-sm{padding-block:40px}
}

/* --- 89. Hero photo visible on tablet and mobile ----------------------------------
   Client: the hero image does not show on phone/tablet. Pre-existing, not a regression:
   the approved artifact deliberately hid it below 980px --
     hmt-site.css  @media(max-width:980px){.hero-in{grid-template-columns:1fr;gap:2.25rem}.hero-fig{display:none}}
   and hmt-wp.css carried a second copy of the same `.hero-fig{display:none}`. The duplicate is
   DELETED here; the artifact's own copy is left in place (that sheet stays a faithful record of
   the approved design) and overridden at (0,3,0), which beats its (0,1,0) regardless of order.
   The `.hero-in` half of that artifact rule is already inert -- section 86 removed the class.

   Un-hiding alone was not enough, and the harness is why: with the stacked grid at
   `repeat(2, 1fr)` both rows equalise, and the photo's row took its natural 4:3 height, so the
   hero grew to 1464px at 1024 and 738px at 390. The row template is now native
   `auto 320px` (tablet) / `auto 240px` (mobile) -- copy sizes to its content, photo gets a fixed
   band it can cover. Measured after: hero 641-671px on tablet, 541-633px on mobile. */
@media(max-width:980px){.elementor .e-con.hero-fig{display:block}}

/* --- 90. CTA band on tablet: one-line title, full-measure body --------------------
   Client: on tablet the CTA title should sit on one line and the body should fill the box.
   TWO separate causes, and neither is the container width:
     `.ctab-bx h2{max-width:19ch}` and `.ctab-bx p{max-width:52ch}` (hmt-site.css, (0,1,1)).
   The title is 30 characters, so a 19ch cap can NEVER hold it on one line at any font size --
   `ch` scales WITH the type, so shrinking the heading would not have helped. The cap had to go.
   Elementor has no max-width control on the heading or text-editor inner elements (only on the
   widget wrapper, which the h2/p cap sits inside), so this cannot be done from the editor --
   restated here at (0,3,1) instead, scoped to the tablet band only so desktop keeps its measure.

   The `.ctab` stack point also moved 900px -> 1024px. Between 901 and 1024 the band was still two
   columns, leaving the copy box ~350px of inner width -- the title could not fit on one line there
   however the caps were set. 1024 is Elementor's tablet breakpoint and now the site's single stack
   point (hero  and Industries Served already moved there), so this removes a stray third one. */
@media(min-width:767px) and (max-width:1024px){
  .elementor .e-con.ctab-bx h2{max-width:none}
  .elementor .e-con.ctab-bx p{max-width:none}
}

/* --- 91. Hamburger menu: teal highlight, bled to the panel edges -------------------
   Client: make the highlight teal, keep the white text, run it to the left and right edges.
   Measured first (measure/menu.js, menu open via .elementor-active on the toggle, at 900/768/390):
     active item background = rgb(63,68,75) -- Elementor's OWN default, not ours:
       `.elementor-nav-menu--dropdown .elementor-item.elementor-item-active{background-color:#3f444b;color:#fff}`
     text was ALREADY white (a section-65 rule outranks the teal-text rule above it), so only the
     background needed changing -- done NATIVELY on the widget, which emits at (0,5,0) and clears
     Elementor's (0,2,0). No CSS needed for the colour.
   The inset was NOT item padding (that is only .15rem): at 768 the panel measured l=18 r=750 while
   the link measured l=36 r=732, an 18.24px gap each side, and it comes from section 65's
     `.hm-nav .elementor-nav-menu--dropdown{padding:.35rem clamp(.9rem,4vw,1.25rem) .8rem}`.
   (18.24px, not 20px, because Astra ships html{font-size:91.2%} below 921px -- so 1.25rem = 18.24.)
   Zeroing that panel padding would have bled the ITEM DIVIDERS to the edges too, which the client
   did not ask for. So the bleed is applied to the ACTIVE ITEM ONLY: a negative inline margin equal
   to the panel padding, with the same amount added back as padding so the label does not move.
   Everything else in the panel -- dividers, resting items, spacing -- is untouched. */
/* 91b — the same bleed on hover/focus/pressed, so tapping looks identical to selected */
@media(max-width:1024px){
  .hm-nav .elementor-nav-menu--dropdown .elementor-nav-menu>li>a.elementor-item.elementor-item-active,
  .hm-nav .elementor-nav-menu--dropdown .elementor-nav-menu>li>a.elementor-item:hover,
  .hm-nav .elementor-nav-menu--dropdown .elementor-nav-menu>li>a.elementor-item:focus,
  .hm-nav .elementor-nav-menu--dropdown .elementor-nav-menu>li>a.elementor-item.highlighted{
    margin-inline:calc(-1 * clamp(.9rem,4vw,1.25rem));
    padding-inline:calc(clamp(.9rem,4vw,1.25rem) + .15rem)}
}


/* --- 93. Anchor targets clear the sticky header (menu dropdowns, Sept 2026) --------
   The dropdown items added to the main menu are in-page anchors (/about/#who-we-are,
   /compliance/#certifications, and so on). The header is sticky
   (.elementor-location-header{position:sticky;top:0}), so a native hash jump lands the
   section's top edge underneath it and the heading is hidden.

   scroll-margin-top on the anchored element is the correct fix -- it only affects
   scroll-into-view, never layout, so nothing on any page moves. Elementor has no control
   for it, which is why it lives here. Scoped to containers carrying an id, which is
   exactly the set the menu links at.

   Offsets track the header's own min-height in section 66 (76px base, 78/74/70/68 down
   the breakpoints) plus roughly 20px of breathing room. One variable, so it is a
   one-line change if the header height is ever retuned. */
:root{--hmt-anchor-offset:96px}
@media(max-width:1024px){:root{--hmt-anchor-offset:98px}}
@media(max-width:766px){:root{--hmt-anchor-offset:90px}}
.elementor .e-con[id]{scroll-margin-top:var(--hmt-anchor-offset)}

/* 93(b) Astra filters an empty <span class="dropdown-menu-toggle ast-header-navigation-arrow">
   into every menu link that has children. Its own styling is scoped to
   `#ast-desktop-header .main-header-menu`, which never matches inside the Elementor nav
   widget -- so in our header it paints nothing, yet still takes a keyboard tab stop as a
   role="button" with no visible affordance. Elementor's own caret (span.sub-arrow, rendered
   as an inline SVG) is the one the user sees, so Astra's is removed. `.sub-arrow` is
   deliberately left alone: Elementor's mobile dropdown toggles submenus on it. */
.hm-nav .elementor-nav-menu .ast-header-navigation-arrow{display:none}


/* --- 94. Journey year strip fills its row whatever the tab count -------------------
   Section 33 pinned the strip to `repeat(5,1fr)` because there were five milestones. Two
   were retired in September, so three tabs sat in a five-column grid and left two dead
   cells on the right. A column count should never be a function of how much content
   happens to exist today.

   `repeat(auto-fit, minmax(X,1fr))` collapses the empty repeated tracks and lets the
   remaining ones absorb the freed width, so N tabs always produce N equal columns that
   fill the row -- and once N outgrows the row they wrap instead of squashing. Adding or
   retiring a milestone now needs no CSS change at all.

   Separators move from per-cell borders to a 1px grid gap showing the heading's own
   background. The old edge rules keyed off `:nth-child(3n)` and `:nth-last-child(-n+2)`,
   which only drew correct edges for the five-in-three-columns case; with a variable column
   count there is no nth- expression that can be right, whereas a gap is correct by
   construction for every count and every wrap.

   Left on `.hm-ptabs` (the Products strip) deliberately: it has exactly four categories,
   which is a fixed taxonomy rather than editable content, and its 4/2/1 wrap has tuned
   border rules that this technique would need re-tested against. */
.elementor .hm-jntabs .e-n-tabs-heading{
  grid-template-columns:repeat(auto-fit,minmax(7rem,1fr));
  background:var(--line);
  gap:1px;
  border-top:1px solid var(--line)}
.elementor .hm-jntabs .e-n-tab-title{
  background:var(--surface);
  border-right:0;
  border-bottom:0}
.elementor .hm-jntabs .e-n-tab-title:nth-child(3n),
.elementor .hm-jntabs .e-n-tab-title:nth-last-child(-n+2),
.elementor .hm-jntabs .e-n-tab-title:last-child{
  border-right:0;
  border-bottom:0}
@media(max-width:1024px){
  .elementor .hm-jntabs .e-n-tabs-heading{grid-template-columns:repeat(auto-fit,minmax(6rem,1fr))}
}
@media(max-width:766px){
  .elementor .hm-jntabs .e-n-tabs-heading{grid-template-columns:repeat(auto-fit,minmax(5rem,1fr))}
}


/* --- 95. Progressive reveal: show the first N cards, a button expands the rest -------
   Client asked for the Code of Conduct to open short and expand on request: four of the
   ten principles on desktop and tablet, three on phones. Measured first -- stacked, the
   full list runs 3,400px on a 390px phone (about four screens), 2,000px at 820px and
   1,630px at 1024px.

   A carousel was considered and rejected: card heights range 217-553px on a phone, and a
   carousel gives every slide the height of the tallest, so the short principles would
   carry ~340px of dead space on every view -- and a code of conduct is reference content
   that should not sit behind nine swipes.

   Deliberately built as progressive enhancement. The collapsed state is applied by
   JavaScript, never in the markup, so with scripting unavailable every principle is
   visible and the button never appears. Nothing is removed from the DOM either way, so
   find-in-page and search engines always see all ten. Print shows the full list.

   The counts are read from `data-reveal` / `data-reveal-mobile` on the grid, set through
   Elementor Pro's Custom Attributes -- so the client can change four to six, or three to
   five, in the builder without touching this file. Reusable on any container: add the
   `hmt-reveal` class plus the attributes, and a button carrying `hmt-reveal-btn`. */
.hmt-reveal > .is-reveal-hidden{display:none}
.elementor .elementor-widget.hmt-reveal-btn{display:none}
.elementor .elementor-widget.hmt-reveal-btn.is-reveal-ready{display:block}
.elementor .elementor-widget.hmt-reveal-btn .elementor-button{cursor:pointer}
@media print{
  .hmt-reveal > .is-reveal-hidden{display:block}
  .elementor .elementor-widget.hmt-reveal-btn,
  .elementor .elementor-widget.hmt-reveal-btn.is-reveal-ready{display:none}
}


/* --- 96. Compliance page header: card straddles the banner and the green band -------
   The header puts a 640px card over the banner, pulled up 96px (`.ph-card`
   margin-top:-96px). The banner image is a fixed clamp(200px,14vw + 130px,290px) and the
   card is taller than the 96px it borrows, so the card hangs below the image. That overhang
   IS the design -- on every other page a white or cream section follows, so it reads as the
   card sitting between the banner and the page. On Compliance the next section is the dark
   Certifications band, which used to begin below the overhang and left a white bar.

   Two earlier attempts and why they were wrong:

   1. Stretching the image to fill the whole header removed the white, but pinned the card
      wholly inside the banner with its bottom flush to the band -- not how the other six
      headers read.
   2. Pulling the band up by a measured overhang (123 / 117 / 114px) straddled correctly but
      left a few pixels of white, because the real card is slightly taller than those
      constants: Elementor's divider widget and the paragraph margins inside the text
      widgets add height that a hand calculation does not capture.

   So the number is removed from the equation entirely. The wrap holding the card is taken
   out of flow and pinned at `top: <the image's own height>`, which makes the header exactly
   as tall as its image -- so the band ALWAYS starts precisely at the image's bottom edge and
   a gap is impossible whatever the card's height. The card keeps its -96px and simply
   overhangs into the band.

   The band's extra top padding is only clearance for that overhang, so an approximate value
   is harmless here: too small merely tightens the gap under the card, it can never reopen
   the white bar.

   Verified at 1440, 1024 and 390, and again with a deliberately 42px-taller card:
   band top == image bottom and white gap == 0 in all six cases, card straddles in all six,
   heading clearance 112 / 98 / 73px normally and still 70 / 55 / 30px in the taller case.

   Scoped to this page on purpose: the overhang exists on all six headers but is invisible
   wherever a light section follows. Any page that puts a dark section directly under its
   banner needs these same two rules. */
body.page-id-62 .elementor .e-con.ph > .e-con.wrap{
  position:absolute;
  left:0;
  right:0;
  z-index:3;
  top:clamp(200px,14vw + 130px,290px)}
body.page-id-62 .elementor .e-con.band > .e-con.band-in{
  padding-top:calc(clamp(4rem,2.5rem + 5vw,7em) + 123px)}


/* --- 97. Homepage slider: product ranges instead of announcements (Sept 2026) -------
   The "What's Happening" slider now carries the four product categories rather than public
   holidays, at the client's request, until there is real Harimatec news to run.

   `.nb-fig` was built for photographs: a dark bottom scrim (`:before`) so the white overlay
   text stays readable against a busy image. The slides are now product packshots composed
   on white (1100x733, product centred at 86% of the height, so nothing is cropped at either
   breakpoint). A dark gradient washing up a clean white product shot reads as dirt, so the
   scrim comes off and the overlay text — now the product code, e.g. "MF 210" — goes navy.

   The overlay title that used to sit on the photo (`.nb-greet`) is gone: on a packshot it
   duplicated the slide's own title. It is hidden with Elementor's own Advanced > Responsive
   toggles on container 9ef9f34 in listing template 162, not with CSS, so bringing it back is
   three switches in the builder. Its colour rule is therefore removed from here.

   Reverting to news: delete this block to restore the scrim, and clear those three toggles. */
.elementor .e-con.nb-fig:before{background:none}

/* ============ 98 — Download Centre: the document cards (Sept 2026) ============
   The page runs the same nested-tabs strip as Products — it carries .hm-ptabs, so the tab
   chrome is shared and nothing about it is restated here — with one JetEngine listing grid
   per range, each pointed at a saved Query Builder query.

   Each document renders as the page's original download card (.dlc, §earlier) with a
   Download button added. The card's own layout is native on the containers, per the Round 4
   rule; only the bits .dlc cannot express are below, all keyed to the .dlc-file variant so
   the base card is untouched:

     - .dlc sets `gap:0`, which a native flex gap cannot beat (it lands at (0,3,0) against
       Elementor's own (0,1,0) --gap). The variant restates it one class deeper.
     - the image frame is 4:3 rather than 16:9 because the product packshots are square, and
       `object-fit:contain` on white so a packshot is never cropped.
     - JetEngine's Dynamic Link renders a plain <a>, not Elementor's .elementor-button, so
       the .hm-btn skin is restated for that one selector.

   `display` is deliberately NOT declared on .dlc-file, .fig, .dl-meta or the panels. At
   (0,3,0) it would out-specify Elementor's own .elementor-hidden-* rules and silently
   disable the Responsive hide toggles on those containers — see §29 and Round 6. */
.elementor .e-con.dlpanel{width:100%}
.dlgrid .jet-listing-grid__items{gap:1.25rem}

.elementor .e-con.dlc.dlc-file{gap:.55rem}
.elementor .e-con.dlc.dlc-file > .fig{aspect-ratio:4/3;background:#fff;overflow:hidden}
/* The existing .fig rules size Elementor's own image widget. This card uses JetEngine's
   dynamic image, so the same height chain has to be restated for it: without a definite
   height on every box between .fig and the <img>, the image's `height:100%` resolves to auto
   and the packshot's intrinsic 1:1 ratio pushes the frame back to square, overriding the
   aspect-ratio. Measured 398x299 at 1440, 480x360 at 1024, 348x261 at 390 with the packshot
   whole in every case. */
.dlc-file > .fig > .elementor-widget,
.dlc-file > .fig .jet-listing-dynamic-image,
.dlc-file > .fig .jet-listing-dynamic-image__figure{height:100%;width:100%;margin:0;min-height:0}

.dl-type .jet-listing-dynamic-field__content{font-family:var(--fb);font-size:.6875rem;font-weight:700;letter-spacing:.1em;text-transform:uppercase;color:var(--acc)}
.dl-title .jet-listing-dynamic-field__content{font-family:var(--fd);font-size:1.0625rem;font-weight:600;line-height:1.35;color:var(--head);margin:0}
.dl-size .jet-listing-dynamic-field__content,.dl-rev .jet-listing-dynamic-field__content{font-family:var(--fb);font-size:.8125rem;color:var(--body)}

.dlc-file .dl-get{margin-top:auto;padding-top:.55rem}
.dl-get .jet-listing-dynamic-link__link{display:inline-flex;align-items:center;justify-content:center;width:100%;font-family:var(--fb);font-size:.75rem;font-weight:600;letter-spacing:.09em;text-transform:uppercase;padding:.8rem 1.4rem;border-radius:0;border:1px solid var(--acc);background:var(--acc);color:#fff;text-decoration:none;white-space:nowrap;transition:background .2s,color .2s,border-color .2s}
.dl-get .jet-listing-dynamic-link__link:hover{background:var(--navy);border-color:var(--navy);color:#fff}

.dlgrid .jet-listing-not-found{font-family:var(--fb);font-size:.9375rem;color:var(--body);padding:2.25rem 0;border-block-start:1px solid var(--line)}
