/* QZ Infomatics — rules written for the WordPress build.
   Everything in base/header/footer/float/components is generated from the static
   demo by scratchpad/split_theme_css.py and is overwritten on every regeneration.
   Anything hand-written belongs here, where the generator cannot reach it.
   Loaded last, so it also wins any tie against the generated files. */

/* ---- Elementor wrappers ----
   A widget arrives inside .e-con > .elementor-widget > .elementor-widget-container.
   Our sections are full-bleed and own their own .wrap, so those three boxes must
   contribute no width, padding, margin or flex behaviour of their own. */
.elementor .e-con,
.elementor .e-con-inner{--content-width:100%;--padding-top:0;--padding-right:0;--padding-bottom:0;--padding-left:0;--gap:0px;--row-gap:0px;--column-gap:0px;max-width:100%;width:100%}
.qz-widget{width:100%;max-width:100%;margin:0;padding:0}
.qz-widget>.elementor-widget-container{height:auto;margin:0;padding:0}
.qz-widget>.elementor-widget-container>section{width:100%}

/* ------------------------------------------------------------------ *
 * Source order the split lost.
 *
 * The demo is one stylesheet; the theme is six. Rules of equal
 * specificity are decided by source order, and splitting them across
 * files reorders them. Both of these lost that way — the hero image
 * came out a third taller than the design, and mobile sections 10px
 * tighter. Re-asserting the demo's winner here, last, restores it.
 *
 * `node scratchpad/cascadeCheck.js <static.html> <width>` resolves both
 * stylesheets against the real DOM and proves there are no others.
 * ------------------------------------------------------------------ */
.imgph{aspect-ratio:16/9;margin:0 0 20px}
/* and the rules the demo places after it, in the same order, so re-asserting
   the base above does not steal their override back */
.pc__img{margin:0;width:100%;height:100%;aspect-ratio:auto;border-radius:0;background:var(--white)}
.cap__img{margin:0;width:100%;aspect-ratio:4/3;border-radius:var(--r)}
.idd__img{margin:0;width:100%;aspect-ratio:4/3;border-radius:var(--r);background:rgba(23,132,126,.07);box-shadow:0 30px 66px -44px rgba(14,27,30,.4)}
/* A band showing a logo sits it on white with a hairline; a band showing a
   photograph tints the box behind it. Both pages wrote `.idd__img`, so the
   difference is scoped by the modifier the markup already carries. */
.idd__img.has-logo{background:var(--white);border:1px solid var(--line);box-shadow:none}
@media (max-width:1080px){
.idd__img{aspect-ratio:16/9}
}
@media (max-width:640px){
.sect{padding:66px 0}
.hero__img{aspect-ratio:3/2}
.logoph{height:auto}
}

/* Two sections of the same tone that read as one block: the lower one drops its
   top padding so the gap between them is a single rhythm, not a double one.
   After the block above, which re-asserts .sect at the same specificity. */
.sect--flush{padding-top:0}

/* ------------------------------------------------------------------ *
 * Cross-page class collisions.
 *
 * Merging 26 page stylesheets brings some classes in twice with two
 * different intents, and source order then decides silently. Scope them
 * by section tone instead, which is the rule the design already follows:
 * tinted cards on a white section, white cards on a tinted one.
 * ------------------------------------------------------------------ */
/* The careers page tints its role facts; the legal pages set the same chip on
   white. Scoped by the section each one actually appears in. */
.jobs .job__m span{background:var(--teal-soft)}

.sect--wash .comp__i{background:var(--grad-card)}
.sect--grad .comp__i{background:var(--white)}

/* ------------------------------------------------------------------ *
 * Cards that do not follow the section rule.
 *
 * The four hub pages invert it: tinted accreditation cards on a tinted
 * section, white onward-link cards on a white one. Rather than let the
 * merged stylesheet pick a winner, the widget says which it wants.
 * ------------------------------------------------------------------ */
.comp.cards--white .comp__i,
.rel.cards--white a{background:var(--white)}
.comp.cards--tinted .comp__i,
.rel.cards--tinted a{background:var(--grad-card)}

/* Six pages set the article heading at 2.85rem and the calculator alone at
   2.7rem; the merge kept the calculator's. Restore the common one and let that
   page opt down. */
.hero__kw--art{font-size:clamp(1.85rem,4vw,2.85rem)}
.hero__kw--art.hero__kw--sm{font-size:clamp(1.85rem,4vw,2.7rem)}

/* The case study pages set their chips as bordered pills; the author pages
   leave the same markup as plain links. Merging the two stylesheets applied the
   pill everywhere, so the widget now says which it wants. */
.chips a{background:none;border:0;color:inherit;padding:0;border-radius:0;font-size:inherit;font-weight:inherit}
.chips--pill a{background:var(--white);border:1px solid var(--line);color:var(--ink);padding:7px 15px;
  border-radius:100px;font-size:.79rem;font-weight:600}


/* The key-facts list inside an article sets its own type; the merge left the
   generic .prose dt/dd winning over it. */
.prose dl.kf,.kf{gap:1px;margin:0 0 28px}
.kf dt{font-size:.64rem;color:var(--muted)}
.kf dd{font-size:.9rem;color:var(--ink)}

/* The author bio paragraph is also the page's answer block, and the design lets
   the answer's size win. The merge had reversed them. */
.ai-summary{font-size:1.06rem}

/* The careers page tightens the job actions on a phone. A second copy of
   .job__a from another page's sheet lands after that media query in the merge
   and takes the gap back to the desktop value. */
@media (max-width:640px){.job__a{gap:10px}}

/* The jump rail's column count and minimum stop width are per page, so the
   widget passes them as custom properties. Written as a finished
   grid-template-columns inline they beat the 1080px media query, and the rail
   squashed on a phone instead of scrolling. */
.isel__in{grid-template-columns:repeat(var(--isel-cols,4),minmax(0,1fr))}
@media (max-width:1080px){
  .isel__in{grid-template-columns:repeat(var(--isel-cols,4),minmax(var(--isel-min,170px),1fr))}
}

/* The jump rail is sticky in the demo because <nav class="isel"> sits directly
   under <main>, so it can travel the whole page. As a widget it is the only
   child of its own Elementor container, and a sticky element can only move
   inside its parent's box -- a box exactly its own height, so it never pinned.
   Move the stickiness up to that container, which IS a direct child of the page
   wrapper. .isel keeps position:sticky so the design and the render still agree;
   nested inside a pinned parent it simply has nowhere left to travel.
   Done in CSS rather than by tagging the container: a container carrying a class
   of ours stops being scaffolding the structure audit can flatten away. */
.e-con:has(> .elementor-widget-qz_jump_rail){
  position:sticky;top:var(--hdr-h,72px);z-index:60}

/* Centred hero, centred actions. Opt-in per page via the hero's "Centre the
   buttons and proof" switch, because two dozen approved pages use a centred
   hero with left-aligned buttons and those are signed off as they are. */
.hero__cta--ctr{justify-content:center}
.hero__pf--ctr{justify-content:center;text-align:center}

/* Inline call to action, for part-way through a long guide.
   The approved article design has .note for a quiet callout and .aside__cta for
   the sidebar card, but nothing for mid-article. This borrows the sidebar
   card's teal so it reads as an invitation rather than another note, and lays
   it out along the line rather than down it, because in the middle of a guide
   it should interrupt the reader for one line and no more. */
.prose .midcta{background:var(--grad-btn);border-radius:var(--r);color:#fff;
  padding:22px 24px;margin:34px 0;display:grid;grid-template-columns:minmax(0,1fr) auto;
  gap:10px 22px;align-items:center}
.prose .midcta b{font-family:var(--main-font);font-size:1.02rem;font-weight:600;
  color:#fff;display:block;margin-bottom:4px}
.prose .midcta__t span{display:block;font-size:.88rem;line-height:1.55;
  color:rgba(255,255,255,.88);max-width:62ch}
.prose .midcta__a > a:not(.btn){white-space:nowrap;background:#fff;color:var(--ink);
  font-weight:600;font-size:.86rem;text-decoration:none;border-radius:100px;
  padding:11px 20px;display:inline-flex;align-items:center;gap:8px;
  transition:transform .18s,box-shadow .18s}
.prose .midcta__a > a:not(.btn):hover{transform:translateY(-2px);box-shadow:0 16px 30px -18px rgba(0,0,0,.5)}

@media (max-width:640px){
  .prose .midcta{grid-template-columns:minmax(0,1fr)}
  .prose .midcta a{justify-self:start}
}

/* A theme button dropped into prose. .prose a underlines and re-colours every
   link, which is right for a link in a sentence and wrong for a button, so the
   button's own colours are restored here rather than in each place one is used. */
.prose a.btn{text-decoration:none;font-weight:600}
.prose a.btn--primary{color:#fff}
.prose a.btn--ghost{color:var(--ink)}

/* Inline CTA, second style: a full-width invitation on the soft gradient,
   centred, with the site's own buttons rather than a pill of its own. Where
   variant 1 interrupts a guide for one line, this one is a pause -- it takes
   the full measure of the column and asks properly. */
.prose .midcta--02{background:var(--grad-card);color:var(--ink);
  grid-template-columns:minmax(0,1fr);justify-items:center;text-align:center;
  padding:46px 34px;gap:0}
.prose .midcta--02 b{font-family:var(--main-font);font-size:clamp(1.5rem,3vw,2.05rem);
  line-height:1.2;color:var(--head);margin-bottom:14px}
.prose .midcta--02 .midcta__t span{color:var(--body);font-size:1rem;line-height:1.65;
  max-width:56ch;margin-inline:auto}
.prose .midcta--02 .midcta__a{display:flex;flex-wrap:wrap;gap:12px;
  justify-content:center;margin-top:26px}

@media (max-width:640px){
  .prose .midcta--02{padding:34px 22px}
  .prose .midcta--02 .midcta__a{width:100%}
  .prose .midcta--02 .midcta__a .btn{width:100%;justify-content:space-between}
}

/* Article images.
   base.css caps width at 100% but never releases the height, so an image whose
   markup says height="720" keeps drawing 720px tall inside an 800px column and
   squashes. height:auto is the whole fix: the width and height attributes stay
   in the HTML, where the browser uses them to reserve the right space before
   the file arrives, and the aspect ratio is honoured once it does. */
.prose img{height:auto}
.prose figure{margin:30px 0}
.prose figure img{width:100%;border-radius:var(--r);border:1px solid var(--line)}
.prose figcaption{font-size:.8rem;color:var(--muted);margin:9px 0 0;text-align:center}

/* ---------------------------------------------------------------------------
   Phone field: country code and number read as one control

   The picker and the number were two bordered inputs sitting side by side,
   which looked like two questions. One border goes on the wrapper, the parts
   inside lose theirs, and a divider separates them.
   --------------------------------------------------------------------------- */
.telfield{gap:0;border:1px solid rgba(255,255,255,.18);border-radius:100px;
  background:rgba(255,255,255,.06);transition:border-color .2s}
.telfield:focus-within{border-color:var(--teal-l)}
.telfield .inp,
.telfield .ccbtn{border:0;background:transparent;border-radius:0}
.telfield .inp:focus,
.telfield .ccbtn:focus{outline:none;box-shadow:none}
.telfield .ccpick::after{content:"";position:absolute;top:9px;bottom:9px;right:0;
  width:1px;background:rgba(255,255,255,.18)}
.telfield .ccbtn{padding-right:14px}
.telfield>.inp:last-child{padding-left:14px;border-radius:0 100px 100px 0}
.telfield .telcc{border-radius:100px 0 0 100px}

/* On the light sections the divider has to follow the light border colour. */
.cta-light .telfield,
.fit-light .telfield{border-color:var(--line);background:var(--white)}
.cta-light .telfield .ccpick::after,
.fit-light .telfield .ccpick::after{background:var(--line)}

/* The whole point of the anchor: land below the sticky header, not under it. */
#demo{scroll-margin-top:calc(var(--hdr-h,72px) + 16px)}

@media(max-width:640px){
  /* Stacking the picker above the number would break the single-field look,
     so it stays one row on small screens and the picker gets narrower. */
  .telfield{flex-direction:row;gap:0}
  .telfield .ccpick,.telfield .ccbtn{width:auto}
  .telfield .ccbtn{padding-left:14px;padding-right:10px}
}

/* ---------------------------------------------------------------------------
   Resource card: featured image behind the colour band

   The band was decoration only. With a post behind the card it can carry the
   article's featured image, with the same gradient laid over it so the rail
   keeps its colour. Only cards that have an image change shape -- the
   hand-written rails on /solutions/ and /industries/ keep their 132px band.
   --------------------------------------------------------------------------- */
.rc__t--img{aspect-ratio:16/9;height:auto}          /* same crop as the blog listing */
.rc__t--img img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;z-index:0}
.rc__t--img::after{content:"";position:absolute;inset:0;z-index:1;
  background:linear-gradient(150deg,var(--ink-2),#0E3A3B);opacity:.7}
.rc__t--img::before{z-index:2}                      /* the arc pattern sits over the tint */
.rc__t--img span{z-index:3}

/* ---------------------------------------------------------------------------
   Archive pagination

   Category archives had no template at all until now, so nothing here was
   styled. The cards reuse .bgrid and .bc from the blog hub; only the page
   links are new.
   --------------------------------------------------------------------------- */
.apg{display:flex;gap:8px;justify-content:center;align-items:center;margin-top:44px;flex-wrap:wrap}
.apg .page-numbers{display:grid;place-items:center;min-width:40px;height:40px;padding:0 12px;
  border:1px solid var(--line);border-radius:100px;background:var(--white);
  font-size:.9rem;font-weight:600;color:var(--ink);text-decoration:none;transition:border-color .2s,color .2s}
.apg .page-numbers:hover{border-color:var(--teal);color:var(--teal)}
.apg .page-numbers.current{background:var(--grad-btn);border-color:transparent;color:#fff}
.apg .dots{border:0;background:transparent}

/* The "last verified" line follows its hero.
   .legal__d was written for the legal pages, whose heroes are centred. In a
   split hero the same line sits above a left-aligned column and centring it
   reads as a mistake, so align it with the heading it belongs to. */
.hero:has(.hero__g) .legal__d{text-align:left}

/* ---------------------------------------------------------------------------
   Leadership row: three across, then two centred underneath

   .ppl is a centred flex wrap, so how many fit per row is decided by the width
   available. At 1284px the 254px cards fit four across, which left the fifth
   person alone on a row of their own. Capping the row rather than resizing the
   cards keeps the portraits the same size as the consulting team below and
   leaves the narrower breakpoints exactly as they were: three cards plus their
   gaps need 822px, four need 1106px.
   --------------------------------------------------------------------------- */
.ppl--lead{max-width:920px;margin-left:auto;margin-right:auto}
@media(min-width:641px){.ppl--lead .ppl__c{flex:0 1 280px}}   /* room around a 248px portrait */

/* Portraits, once a photograph is supplied.
   The frame keeps its gradient ring and its size; the picture fills it and is
   cropped to the circle (or to the rounded square the wider team rows use).
   The ring is drawn on the border, so the image has to sit inside the padding
   box rather than over it. */
.ppl__ph.has-img,
.aut__av.has-img{display:block;overflow:hidden;
  background-image:var(--grad-btn);background-clip:border-box}
.ppl__ph.has-img img,
.aut__av.has-img img{width:100%;height:100%;object-fit:cover;border-radius:inherit;display:block}

/* Leadership portraits read 30px larger than the consulting rows below. */
@media(min-width:641px){
  .ppl--lead .ppl__ph{width:248px;height:248px}
  .ppl--lead .ppl__ph svg{width:76px;height:76px}

  /* The consulting rows below, 30px larger again. */
  .ppl--team .ppl__ph{width:180px;height:180px}
  .ppl--team .ppl__ph svg{width:55px;height:55px}
}

/* Client marquee: a logo in place of a name. Height-capped so every mark sits
   on the same line, in their own colours. */
.mq .mq__logo{display:flex;align-items:center;height:60px;opacity:1}
.mq .mq__logo:hover{opacity:1}
.mq .mq__logo img{height:100%;width:auto;max-width:200px;object-fit:contain}

/* Testimonial tabs: rest on a near-white, active on the light card gradient
   with ink text and a dark caret (the demo used the button gradient). */
.tw__tab{background:rgb(250,250,250)}
.tw__tab.on{background:var(--grad-card);color:var(--ink)}
.tw__tab.on::before{border-top-color:var(--ink)}

/* Testimonials: body centred as in the client mock; the media column drops
   when a panel has neither a video nor a photo. A video plays in a lightbox. */
.tw__top{grid-template-columns:.4fr 1fr;align-items:center}
.tw__top--solo{grid-template-columns:1fr}
.tw__b{align-items:center;text-align:center}
.tw__top--solo .tw__b{max-width:62ch;margin:0 auto}
.tw__q{text-align:center}
.tw__by b,.tw__by span{text-align:left}
.tw__go{align-self:center}
.tw__logo--img{display:flex;justify-content:center;margin-bottom:22px}
.tw__logo--img img{height:60px;width:auto;max-width:220px;object-fit:contain}
.tw__v{aspect-ratio:1;background-size:cover;background-position:center}
.tw__v[style]::after{background:rgba(14,27,30,.12)}
.tw__ph{aspect-ratio:1;border-radius:var(--r);overflow:hidden}
.tw__ph img{width:100%;height:100%;object-fit:cover;display:block}
@media(max-width:900px){.tw__top{grid-template-columns:1fr}.tw__v,.tw__ph{max-width:320px;margin:0 auto}}

.vlb{position:fixed;inset:0;z-index:2000;background:rgba(6,14,16,.86);display:grid;place-items:center;padding:24px;
  opacity:0;transition:opacity .2s}
.vlb.on{opacity:1}
.vlb video{width:auto;height:auto;max-width:min(960px,100%);max-height:85vh;border-radius:var(--r);background:#000;box-shadow:0 40px 80px -30px rgba(0,0,0,.8)}
.vlb__x{position:absolute;top:18px;right:22px;width:44px;height:44px;border-radius:50%;border:0;cursor:pointer;
  background:rgba(255,255,255,.14);color:#fff;font-size:1.4rem;line-height:1;display:grid;place-items:center}
.vlb__x:hover{background:rgba(255,255,255,.28)}

/* Lead forms: field errors, the thank-you card, the no-JS error line. */
.inp--bad{border-color:#d0463b!important;box-shadow:0 0 0 3px rgba(208,70,59,.15)}
.inp--bad::placeholder{color:#d0463b}
.lead__err{color:#b32d2e;font-size:.92rem;margin:0 0 10px}
.lead__ok{padding:28px 22px;text-align:center;border-radius:var(--r);background:var(--grad-card)}
.lead__ok b{display:block;font-size:1.2rem;color:var(--ink);margin-bottom:8px;letter-spacing:-.02em}
.lead__ok p{margin:0;color:var(--muted)}
.lead--sent{display:block}
.ffform.lead--sent{grid-template-columns:1fr}

/* Hero logo card: the mark sits on white with generous padding. 20px less
   padding on every side than the original 18%/20%, then 25px less again: the
   frame keeps its size, the mark inside it grows 90px in total. */
.hero__img--logo img{object-fit:contain;background:#fff;padding:calc(18% - 45px) calc(20% - 45px)}

/* Coverage bands: an optional paragraph and chip row per band, for pages that
   describe an area in prose rather than a tick list. */
.cap__p{color:var(--body);line-height:1.65;margin:0 0 18px;max-width:52ch}
.cap__chips{margin:6px 0 4px}
.cap__chips span{background:var(--ink);color:#fff;border-color:var(--ink);font-weight:600}

/* Hero with a background photo instead of the gradient. The wash is a
   pseudo-element so the photo stays a plain background-image (editable in
   the panel) and the copy sits above it. */
.hero--photo{background-size:cover;background-position:center;background-repeat:no-repeat}
.hero--photo::before{background:none}
.hero--photo::after{content:"";position:absolute;inset:0;pointer-events:none;z-index:0}
.hero--photo-light::after{background:linear-gradient(104deg,rgba(255,255,255,.92) 0%,rgba(255,255,255,.82) 45%,rgba(255,255,255,.62) 100%)}
.hero--photo-dark::after{background:linear-gradient(104deg,rgba(14,27,30,.86) 0%,rgba(14,27,30,.72) 50%,rgba(14,27,30,.55) 100%)}
.hero--photo>.wrap{position:relative;z-index:1}
.hero--photo-dark,.hero--photo-dark h1,.hero--photo-dark .hero__kw,.hero--photo-dark .hero__sub,.hero--photo-dark .hero__pf span,.hero--photo-dark .crumbs a,.hero--photo-dark .crumbs,.hero--photo-dark .hero__eyebrow,.hero--photo-dark .eyebrow{color:#fff}
.hero--photo-dark .hero__kw em{color:var(--lime,#c8e86b)}
.hero--photo-dark .btn--ghost{color:#fff;border-color:rgba(255,255,255,.5)}
.hero--photo-dark .hero__pf{border-top-color:rgba(255,255,255,.25)}
.hero--photo-dark .hero__h2,.hero--photo-dark .hero__h2 em,.hero--photo-dark .hero__l,.hero--photo-dark .legal__d,.hero--photo-dark .hero__sub{color:#fff}
.hero--photo-dark .hero__h2 em{color:var(--lime,#c8e86b)}

/* Platform stack as a static two-across grid: every card visible, no scroll
   choreography. The logo sits on the title row, opposite the name. */
.stack--grid{height:auto;padding:88px 0 80px}
.stack--grid .stack__hd{grid-template-columns:1fr;margin-bottom:34px}
.pgrid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:22px}
.pgrid .pc{position:relative;inset:auto;opacity:1;transform:none;pointer-events:auto;grid-template-columns:1fr;transition:transform .2s,box-shadow .2s}
.pgrid .pc:hover{transform:translateY(-3px);box-shadow:0 22px 50px -30px rgba(14,27,30,.3)}
.pgrid .pc__cta{gap:26px;align-items:center}
.pgrid .pc__hd{gap:15px}
.pgrid .pc__hd h3{flex:1;min-width:0;font-size:1.4rem}
.pgrid .pc__logo{flex:0 0 auto;margin:-14px 0 -14px auto;height:84px;width:170px;display:flex;align-items:center;justify-content:flex-end}
.pgrid .pc__logo img{max-height:84px;max-width:170px;width:auto;height:auto;object-fit:contain}
@media(max-width:900px){.pgrid{grid-template-columns:1fr}}
@media(max-width:640px){.pgrid .pc__logo{width:96px;height:36px}.pgrid .pc__logo img{max-height:36px;max-width:96px}}

/* Section headings are centred everywhere, and the section h2 is a fixed
   36px. The hero keeps its own sizes; the split hero keeps its left column. */
h2{font-size:36px}
.head{margin-inline:auto;text-align:center}
.head p,.head h2,.head h1,.head h3{margin-inline:auto}
.head .eyebrow,.eyebrow{justify-content:center}
.head .eyebrow{display:inline-flex}
.car__hd{flex-direction:column;align-items:center;gap:20px}
.car__hd .head{margin-inline:auto}
.car__hd .car__nav{margin-left:0}
.stack__hd{grid-template-columns:1fr;text-align:center}
.stack__hd h2{margin-inline:auto}
.stack__hd p{margin-inline:auto}
.stack__ct{margin-inline:auto}
.hero .head{text-align:inherit}
@media(max-width:640px){h2{font-size:30px}}
/* the three sections with their own header markup */
.rhd{grid-template-columns:1fr;justify-items:center;text-align:center;gap:22px}
.rhd>div{text-align:center}
.rhd .rsel{width:100%;max-width:360px}
.shift__top{flex-direction:column;align-items:center;text-align:center}
.shift__top h2{max-width:none;font-size:36px}
.shift__top p{margin-inline:auto}
.proc-eyebrow,.sect>.wrap>.eyebrow{display:flex;justify-content:center;width:100%}
.stack--grid .stack__hd,.stack__hd>div{text-align:center}
.head h2[style]{font-size:36px!important}   /* the "a shade smaller" switch no longer applies */
