/* =========================================================================
   THE TWO TYPEFACES, SERVED FROM THIS SERVER
   =========================================================================
   These were <link>s to fonts.googleapis.com until this build. Three things
   were wrong with that and only one of them is about privacy:

   1. It is a CDN, and this project does not load anything from one.
   2. Every catalog page made two DNS lookups and two TLS handshakes to a
      third party before it could draw a heading, on a connection nobody
      here controls. When Google is slow, the catalog is slow.
   3. A visitor's IP address and the page they are on were sent to Google on
      every single view, from a page that carries a company's own branding.

   Both families are the same files Google serves — Inter and Playfair
   Display are both under the SIL Open Font License, and both are shipped by
   their own maintainers on npm. The licences are next to the files in
   /fonts, which is what that licence asks for.

   Latin only, and only the weights this stylesheet actually asks for.
   Loading the Cyrillic and Vietnamese subsets of five weights would be
   nine tenths of a megabyte to draw a page that is in English.

   Paths are RELATIVE, so this works whether the site is at the root of a
   domain or inside a folder. font-display:swap so the text is readable in
   the fallback face while the real one arrives, rather than invisible.
   ========================================================================= */
@font-face{font-family:'Inter';font-style:normal;font-weight:400;font-display:swap;
  src:url(../../fonts/inter-400.woff2) format('woff2')}
@font-face{font-family:'Inter';font-style:normal;font-weight:500;font-display:swap;
  src:url(../../fonts/inter-500.woff2) format('woff2')}
@font-face{font-family:'Inter';font-style:normal;font-weight:600;font-display:swap;
  src:url(../../fonts/inter-600.woff2) format('woff2')}
@font-face{font-family:'Inter';font-style:normal;font-weight:700;font-display:swap;
  src:url(../../fonts/inter-700.woff2) format('woff2')}
@font-face{font-family:'Inter';font-style:normal;font-weight:800;font-display:swap;
  src:url(../../fonts/inter-800.woff2) format('woff2')}
@font-face{font-family:'Playfair Display';font-style:normal;font-weight:600;font-display:swap;
  src:url(../../fonts/playfair-600.woff2) format('woff2')}
@font-face{font-family:'Playfair Display';font-style:normal;font-weight:700;font-display:swap;
  src:url(../../fonts/playfair-700.woff2) format('woff2')}
@font-face{font-family:'Playfair Display';font-style:italic;font-weight:700;font-display:swap;
  src:url(../../fonts/playfair-700-italic.woff2) format('woff2')}

/* =========================================================================
   THIRD PARTY MANUFACTURING — CATALOG
   =========================================================================
   The company catalog for the "thirdparty" template.

   Self-contained on purpose. This file is not part of the Vite bundle and
   shares nothing with the marketplace stylesheet: a catalog is a company's
   own shop window, it is opened in its own window from a listing, and the
   two templates are meant to be able to diverge without either of them
   dragging the other along. That is why the design tokens and the button
   set are copied in below rather than imported.

   Palette: the company's own, from `users.color`. Five are defined; the
   default for this template is green.

   Everything is scoped under .mspage so nothing here can reach any other
   page even if this file is ever loaded somewhere it should not be.
   ========================================================================= */

/* --- design tokens, reset and buttons ---------------------------------
   Copied from the marketplace stylesheet so the two look like one
   company even though they share no file. --------------------------- */
:root{
  --blue-900:#062b57; --blue-800:#083a72; --blue-700:#0a4a8f; --blue-600:#0d5eaf;
  --blue-500:#1a76d2; --blue-100:#e5f0fb; --blue-50:#f2f8fd;
  --accent:#e8720c; --accent-600:#cf6209; --accent-50:#fdf3ea;
  --green:#0e8f5c; --green-50:#e6f6ee; --wa:#22c55e;
  --ink:#0f1e33; --body:#41506a; --muted:#6f7d90; --faint:#9aa7b8;
  --line:#e4e9f0; --hair:#eef1f6;
  --grey:#ececec; --surface:#fff;
  --wrap:1200px;
  --sans:Inter,-apple-system,"Segoe UI",Roboto,sans-serif;
  --serif:"Playfair Display",Georgia,serif;

  /* Sort markers as inline SVG masks: no icon font, no extra request, and
     they take their colour from the header text they sit in. */
  --ms-sort:url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 8 12"><path d="M4 0 7 4H1z"/><path d="M4 12 1 8h6z"/></svg>');
  --ms-up:url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 8 12"><path d="M4 2 7.2 7H.8z"/></svg>');
  --ms-down:url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 8 12"><path d="M4 10 .8 5h6.4z"/></svg>');
  --sh-1:0 1px 3px rgba(15,30,51,.06);
  --sh-2:0 6px 22px rgba(15,30,51,.09);
  --sh-3:0 18px 46px rgba(15,30,51,.14);
}
*,*::before,*::after{box-sizing:border-box}
body{margin:0;overflow-x:hidden;font-family:var(--sans);color:var(--body);background:#fff;
  font-size:15.5px;line-height:1.65;-webkit-font-smoothing:antialiased}
img{max-width:100%;display:block}
a{text-decoration:none;color:var(--blue-600)}
h1,h2,h3,h4{margin:0;color:var(--ink);line-height:1.2}
p{margin:0 0 1rem}
ul{margin:0;padding:0;list-style:none}
.wrap{max-width:var(--wrap);margin:0 auto;padding:0 24px}
.sec{padding:70px 0}
.sec.grey{background:var(--grey)}
.sec.tight{padding:46px 0}
.mw0{min-width:0}
.i{width:1em;height:1em;fill:none;stroke:currentColor;stroke-width:1.85;stroke-linecap:round;stroke-linejoin:round;flex:none}
/* The site's icon component renders class="i", this stylesheet was
   written against `.i`, and they are the same thing. Aliased rather
   than renamed so the catalog can go on using <x-web::icon> — one
   icon component for the whole site, already tested, already
   accessible. */
.i{width:1em;height:1em;fill:none;stroke:currentColor;stroke-width:1.85;stroke-linecap:round;stroke-linejoin:round;flex:none}

.btn{display:inline-flex;align-items:center;justify-content:center;gap:9px;border:1.5px solid transparent;
  border-radius:8px;padding:13px 24px;font-weight:650;font-size:.92rem;cursor:pointer;transition:.18s;white-space:nowrap}
.btn-acc{background:var(--accent);color:#fff}
.btn-acc:hover{background:var(--accent-600)}
.btn-blue{background:var(--blue-600);color:#fff}
.btn-blue:hover{background:var(--blue-700)}
.btn-out{background:#fff;border-color:var(--line);color:var(--ink)}
.btn-out:hover{border-color:var(--blue-600);color:var(--blue-700)}
.btn-ghost{background:rgba(255,255,255,.12);border-color:rgba(255,255,255,.4);color:#fff}
.btn-ghost:hover{background:rgba(255,255,255,.22)}
.btn-sm{padding:9px 17px;font-size:.85rem}
.btn-pill{border-radius:999px}

/* ===== the section heading treatment from the reference ===== */
.eyebrow{display:inline-flex;align-items:center;gap:8px;font-size:.72rem;font-weight:800;letter-spacing:.16em;
  text-transform:uppercase;color:var(--blue-700);background:var(--blue-100);padding:8px 18px;border-radius:999px}
.sechead{text-align:center;max-width:760px;margin:0 auto 44px}
.sechead h2{font-family:var(--serif);font-weight:700;font-size:clamp(1.8rem,1.2rem + 2.2vw,2.8rem);
  margin:18px 0 12px;letter-spacing:-.01em}
.sechead h2 em{font-style:italic;color:var(--blue-600)}
.sechead p{color:var(--muted);font-size:1rem;margin:0}

/* =========================================================================
   THE COMPANY CATALOG — a microsite, scoped under .mspage
   =========================================================================
   Every other page built so far wears the marketplace's chrome. This one
   deliberately does not: it is the company's own shop window, reached by
   clicking a company name, and it opens in its own window. So it carries
   the company's header, the company's colour and the company's footer.

   What keeps it honest is the strip above the header and the badge in the
   footer: both say, plainly, that this page is part of RedNirus Mart and
   both link back. A visitor is never left wondering whose site they are on,
   and the marketplace's phone number is the only number anywhere on it.

   Class names all start `ms-` (microsite). Everything is scoped under
   .mspage so none of it can reach the marketplace pages, which share this
   stylesheet's tokens but nothing else.
   ========================================================================= */

/* --- the company's colour ------------------------------------------------
   `users.color` on the legacy database holds colourv2 … colourv5. That is
   what these five palettes are: one custom property, set on the wrapper,
   that every accent in the page reads from. A company changes its colour
   and nothing else on the page has to know.                              */
.mspage{--ms:#0e8f5c;--ms-d:#075c3b;--ms-l:#e6f6ee;--ms-ink:#062f1f}
.mspage.ms-c1{--ms:#0d5eaf;--ms-d:#083a72;--ms-l:#e5f0fb;--ms-ink:#0a2340}
.mspage.ms-c2{--ms:#0e8f5c;--ms-d:#075c3b;--ms-l:#e6f6ee;--ms-ink:#062f1f}
.mspage.ms-c3{--ms:#9a3412;--ms-d:#6b2409;--ms-l:#fdf0e8;--ms-ink:#3d1405}
.mspage.ms-c4{--ms:#5b21b6;--ms-d:#3f157f;--ms-l:#f1ebfd;--ms-ink:#25084f}
.mspage.ms-c5{--ms:#0f766e;--ms-d:#0a524c;--ms-l:#e6f5f3;--ms-ink:#04302c}

.mspage{background:#fff}
.mspage section{scroll-margin-top:132px}

/* --- the marketplace strip ----------------------------------------------
   Thin, dark, always first. It is the only thing on the page that is ours
   rather than theirs, and it exists so nobody mistakes a company microsite
   for an endorsement — or for a site that can take their money.          */
.mspage .ms-strip{background:#03102a;color:#a9c2dd;font-size:.76rem}
.mspage .ms-strip .wrap{display:flex;align-items:center;gap:14px;height:34px}
.mspage .ms-strip a{color:#cfe0f2;font-weight:600}
.mspage .ms-strip a:hover{color:#fff;text-decoration:underline}
.mspage .ms-strip .ms-back{margin-left:auto;display:inline-flex;align-items:center;gap:7px}
.mspage .ms-strip b{color:#fff;font-weight:700}
.mspage .ms-strip .ms-vrf{display:inline-flex;align-items:center;gap:6px;background:rgba(34,197,94,.16);
  border:1px solid rgba(34,197,94,.4);color:#7ee2a8;padding:2px 10px;border-radius:999px;font-weight:700}

/* --- the company header --------------------------------------------------
   Sticky, one row, white. Same 74px rhythm as the marketplace header so a
   visitor moving between the two does not feel the page jump.            */
.mspage .ms-hdr{position:sticky;top:0;z-index:60;background:#fff;border-bottom:1px solid var(--line);
  box-shadow:0 1px 0 rgba(15,30,51,.04)}
.mspage .ms-hrow{display:flex;align-items:center;gap:18px;height:74px}
.mspage .ms-brand{display:flex;align-items:center;gap:12px;flex:none;color:var(--ink)}
.mspage .ms-mark{position:relative;overflow:hidden;
  width:46px;height:46px;border-radius:12px;display:grid;place-items:center;flex:none;
  color:#fff;font-weight:800;font-size:1rem;letter-spacing:.02em;
  background:linear-gradient(140deg,var(--ms),var(--ms-d))}
/*
| The company's own logo, over its initials.
|
| The initials stay in the markup underneath, so a logo whose file has gone
| missing since the page was cached drops away on error and leaves the
| square it has always had rather than a broken-image glyph in the header.
| contain and a white ground, because a logo is artwork with its own
| margins and most of them are drawn for white.
*/
.mspage .ms-mark img{position:absolute;inset:0;width:100%;height:100%;object-fit:contain;
  padding:5px;background:#fff}
/* Named classes, not `.ms-brand span`.
   The descendant version also matched .ms-mark — which is a span, and which
   sits on the company's own colour — so the initials were painted in that
   same colour on top of it and the logo tile rendered as an empty blue
   square on every page of the site. */
.mspage .ms-bt{display:block}
.mspage .ms-brand b{display:block;font-size:1.1rem;font-weight:800;letter-spacing:-.02em;line-height:1.15}
.mspage .ms-sub{display:block;font-size:.66rem;font-weight:700;letter-spacing:.12em;
  text-transform:uppercase;color:var(--ms);white-space:nowrap}

.mspage .ms-nav{display:flex;align-items:center;gap:4px;margin-left:auto;min-width:0}
.mspage .ms-nav a{padding:9px 13px;border-radius:8px;font-size:.9rem;font-weight:600;color:var(--body);white-space:nowrap}
.mspage .ms-nav a:hover{background:var(--ms-l);color:var(--ms-d)}
.mspage .ms-nav a.on{color:var(--ms-d);background:var(--ms-l)}

.mspage .ms-act{display:flex;align-items:center;gap:9px;flex:none}
.mspage .ms-act .btn{padding:11px 18px;font-size:.87rem}
.mspage .ms-call{background:var(--ms);color:#fff;border-color:var(--ms)}
.mspage .ms-call:hover{background:var(--ms-d);border-color:var(--ms-d)}
.mspage .ms-burger{display:none;width:44px;height:44px;border-radius:10px;border:1px solid var(--line);
  background:#fff;color:var(--ink);cursor:pointer;place-items:center;font-size:1.15rem}

/* --- hero ----------------------------------------------------------------
   Two columns: the pitch, and the form. The form is in the hero rather
   than at the foot of the page because an enquiry is the only thing this
   page is for, and a distributor who has to scroll to find it often does
   not.                                                                   */
.mspage .ms-hero{position:relative;overflow:hidden;color:#fff;padding:58px 0 64px;
  background:linear-gradient(135deg,var(--ms-ink),var(--ms-d) 52%,var(--ms))}
/*
| The company's own banner behind the hero, when it has one.
|
| Behind, not instead of: the hero carries white headings, the enquiry form
| and the certification eyebrow, and a photograph straight under white text
| is unreadable. The banner sits at the back with the brand gradient laid
| over it at .82, which keeps the company's own artwork recognisable and
| every word on top of it legible. Without a banner nothing changes.
*/
.mspage .ms-hero-bg{position:absolute;inset:0;z-index:0}
.mspage .ms-hero-bg img{width:100%;height:100%;object-fit:cover;display:block}
.mspage .ms-hero-bg::after{content:"";position:absolute;inset:0;
  background:linear-gradient(135deg,var(--ms-ink),var(--ms-d) 52%,var(--ms));opacity:.82}
.mspage .ms-hero::after{content:"";position:absolute;inset:0;pointer-events:none;
  background:radial-gradient(720px 320px at 88% -8%,rgba(255,255,255,.14),transparent 70%)}
.mspage .ms-hero .wrap{position:relative;z-index:1}
.mspage .ms-hero-g{display:grid;grid-template-columns:minmax(0,1fr) 400px;gap:44px;align-items:start}

.mspage .ms-eyeb{display:inline-flex;align-items:center;gap:8px;font-size:.7rem;font-weight:800;
  letter-spacing:.16em;text-transform:uppercase;color:#fff;background:rgba(255,255,255,.16);
  border:1px solid rgba(255,255,255,.28);padding:7px 16px;border-radius:999px}
.mspage .ms-hero h1{font-family:var(--serif);font-weight:700;color:#fff;margin:18px 0 14px;
  font-size:clamp(1.85rem,1.15rem + 2.5vw,2.85rem);letter-spacing:-.015em}
.mspage .ms-hero h1 em{font-style:italic;color:#ffd9a8}
.mspage .ms-lede{color:#cfe0f2;font-size:1.02rem;margin:0 0 22px;max-width:60ch}

.mspage .ms-usp{display:flex;flex-wrap:wrap;gap:9px;margin:0 0 24px}
.mspage .ms-usp li{display:inline-flex;align-items:center;gap:8px;font-size:.85rem;font-weight:600;color:#fff;
  background:rgba(255,255,255,.11);border:1px solid rgba(255,255,255,.22);padding:8px 14px;border-radius:999px}
.mspage .ms-usp .i{color:#7ee2a8}

.mspage .ms-hbtn{display:flex;flex-wrap:wrap;gap:11px}

/* the enquiry card ------------------------------------------------------- */
.mspage .ms-form{background:#fff;border-radius:16px;box-shadow:var(--sh-3);overflow:hidden}
.mspage .ms-form-h{padding:17px 22px;background:var(--accent);color:#fff}
.mspage .ms-form-h b{display:block;color:#fff;font-size:1.02rem;font-weight:800}
.mspage .ms-form-h span{display:block;font-size:.79rem;color:#ffe9d3;margin-top:2px}
.mspage .ms-form-b{padding:18px 22px 22px}
.mspage .ms-fgrid{display:grid;grid-template-columns:1fr 1fr;gap:12px}
.mspage .ms-fld{display:flex;flex-direction:column;gap:5px;min-width:0}
.mspage .ms-fld.ms-w{grid-column:1/-1}
.mspage .ms-fld label{font-size:.74rem;font-weight:700;color:var(--ink);letter-spacing:.01em}
.mspage .ms-fld label i{color:#d33;font-style:normal}
.mspage .ms-fld input,.mspage .ms-fld select,.mspage .ms-fld textarea{
  width:100%;border:1.5px solid var(--line);border-radius:9px;padding:11px 13px;font:inherit;
  font-size:.9rem;color:var(--ink);background:#fff;transition:.15s}
.mspage .ms-fld textarea{resize:vertical;min-height:76px}
.mspage .ms-fld input:focus,.mspage .ms-fld select:focus,.mspage .ms-fld textarea:focus{
  outline:none;border-color:var(--ms);box-shadow:0 0 0 3px var(--ms-l)}
.mspage .ms-fld input::placeholder,.mspage .ms-fld textarea::placeholder{color:var(--faint)}
/* The honeypot. Not display:none — some bots skip hidden inputs on
   purpose. Clipped to nothing and untabbable is invisible to a person and
   perfectly fillable by a script, which is the whole point.

   Clipped rather than pushed to left:-9999px: an element parked off the
   left edge is still an element outside the viewport, and every
   responsive check on this page would report it as one. */
.mspage .ms-hp{position:absolute;width:1px;height:1px;padding:0;margin:-1px;border:0;
  overflow:hidden;clip-path:inset(50%);white-space:nowrap}
/* The input as well as the wrapper. A default-sized text box inside a 1px
   overflow:hidden wrapper is invisible but still a 180x30 element, and the
   only thing that makes it un-clickable is the clip — which is one CSS
   file away from not being there. */
.mspage .ms-hp input,.mspage .ms-hp label{width:1px;height:1px;padding:0;border:0;
  font-size:1px;line-height:1;display:block}
.mspage .ms-form .btn{width:100%;margin-top:14px}
.mspage .ms-fine{display:flex;align-items:center;justify-content:center;gap:7px;margin:12px 0 0;
  font-size:.74rem;color:var(--muted);text-align:center}

/* --- what the port added over the approved mockup -------------------------
   The mockup drew a placeholder where the photo goes and had no server to
   validate against. These are the three things a real form and a real
   photograph need, and nothing else changed. */

/* The company's own photograph, or this template's placeholder. Cover, not
   contain: a 4:3 frame with a 16:9 photo letterboxed inside it reads as a
   broken image rather than as a design. */
.mspage .ms-shot img{width:100%;height:100%;object-fit:cover;display:block}

/* A validation message, under the field it belongs to. */
.mspage .ms-err{font-size:.76rem;font-weight:650;color:#c0392b}

/* Sent. Deliberately not a toast: the person has finished, and the page
   should say so where they were looking rather than in a corner. */
.mspage .ms-sent{text-align:center;padding:18px 6px}
.mspage .ms-sent b{display:block;color:var(--ink);font-size:1.02rem;margin-bottom:6px}
.mspage .ms-sent p{margin:0;font-size:.88rem;color:var(--muted);line-height:1.6}

/* --- the moving strip of claims -----------------------------------------
   Paused on hover and by prefers-reduced-motion, because a line of text
   that will not hold still is unreadable to some people and merely
   annoying to everybody else.                                            */
.mspage .ms-marq{background:var(--ms-l);border-block:1px solid var(--line);overflow:hidden;padding:11px 0}
.mspage .ms-marq-t{display:flex;gap:38px;width:max-content;animation:ms-slide 34s linear infinite}
.mspage .ms-marq:hover .ms-marq-t{animation-play-state:paused}
.mspage .ms-marq-t span{display:inline-flex;align-items:center;gap:9px;font-size:.85rem;font-weight:700;
  color:var(--ms-d);white-space:nowrap}
.mspage .ms-marq-t .i{color:var(--ms)}
@keyframes ms-slide{from{transform:translateX(0)}to{transform:translateX(-50%)}}
@media (prefers-reduced-motion:reduce){
  .mspage .ms-marq-t{animation:none;width:100%;flex-wrap:wrap;justify-content:center;gap:14px 26px}
}

/* --- about --------------------------------------------------------------- */
.mspage .ms-about-g{display:grid;grid-template-columns:minmax(0,470px) minmax(0,1fr);gap:52px;align-items:center}
/* The badge overhangs the photo, so the photo cannot be the thing that
   clips its own overflow. .ms-shotw is that wrapper — without it
   `overflow:hidden` on the picture ate the right-hand half of the years
   badge and the page still looked deliberate. */
.mspage .ms-shotw{position:relative}
.mspage .ms-shot{border-radius:18px;overflow:hidden;box-shadow:var(--sh-2);
  aspect-ratio:4/3;display:grid;place-items:center;color:#fff;text-align:center;padding:24px;
  background:linear-gradient(140deg,var(--ms-d),var(--ms))}
.mspage .ms-shot .i{font-size:3.4rem;opacity:.5}
.mspage .ms-yrs{position:absolute;right:-14px;bottom:22px;background:var(--accent);color:#fff;
  border-radius:14px;padding:14px 20px;box-shadow:var(--sh-2);text-align:center;line-height:1.1}
.mspage .ms-yrs b{display:block;color:#fff;font-size:1.7rem;font-weight:800}
.mspage .ms-yrs span{display:block;font-size:.6rem;font-weight:800;letter-spacing:.13em;text-transform:uppercase;color:#ffe9d3}

.mspage .ms-h2{font-family:var(--serif);font-weight:700;letter-spacing:-.012em;
  font-size:clamp(1.6rem,1.1rem + 1.8vw,2.35rem);margin:16px 0 14px}
.mspage .ms-h2 em{font-style:italic;color:var(--ms)}
.mspage .ms-p{color:var(--body);margin:0 0 14px}

.mspage .ms-feat{display:grid;gap:14px;margin-top:24px}
.mspage .ms-feat li{display:flex;gap:14px;align-items:flex-start}
.mspage .ms-feat i{flex:none;width:42px;height:42px;border-radius:11px;display:grid;place-items:center;
  background:var(--ms-l);color:var(--ms-d);font-size:1.15rem;font-style:normal}
.mspage .ms-feat b{display:block;font-size:.95rem;color:var(--ink);font-weight:700}
.mspage .ms-feat p{margin:2px 0 0;font-size:.87rem;color:var(--muted);line-height:1.55}

/* --- the numbers band ----------------------------------------------------
   Only figures the company actually gave us. A cell with nothing behind it
   is not rendered at all, rather than printed as a zero — "0 franchise
   partners" on a company's own shop window is worse than silence.        */
.mspage .ms-band{color:#fff;padding:44px 0;background:linear-gradient(120deg,var(--ms-d),var(--ms))}
.mspage .ms-band-g{display:grid;grid-template-columns:repeat(var(--cells,4),1fr);gap:20px;text-align:center}
.mspage .ms-stat b{display:block;font-family:var(--serif);font-weight:700;color:#fff;
  font-size:clamp(1.7rem,1.2rem + 1.6vw,2.5rem);line-height:1.1}
.mspage .ms-stat span{display:block;font-size:.78rem;font-weight:700;letter-spacing:.11em;
  text-transform:uppercase;color:#cfe0f2;margin-top:6px}
.mspage .ms-band-g > div + div{border-left:1px solid rgba(255,255,255,.16)}

/* --- product / capability cards ------------------------------------------ */
.mspage .ms-cards{display:grid;grid-template-columns:repeat(auto-fill,minmax(280px,1fr));gap:20px}
.mspage .ms-card{border:1px solid var(--line);border-radius:14px;background:#fff;overflow:hidden;
  display:flex;flex-direction:column;transition:.18s}
.mspage .ms-card:hover{border-color:var(--ms);box-shadow:var(--sh-2);transform:translateY(-3px)}
.mspage .ms-card-h{display:flex;align-items:center;gap:12px;padding:16px 18px;background:var(--ms-l);
  border-bottom:1px solid var(--line)}
.mspage .ms-card-h i{flex:none;width:40px;height:40px;border-radius:10px;display:grid;place-items:center;
  background:#fff;color:var(--ms);font-size:1.15rem;font-style:normal;box-shadow:var(--sh-1)}
.mspage .ms-card-h b{font-size:.98rem;color:var(--ink);font-weight:750;line-height:1.25}
/*
| The listing's photograph, above its text.
|
| A fixed aspect ratio rather than a height, so a row of cards lines up
| whatever shape the uploaded image is; cover, because these are photographs
| of products and packaging, not logos, and letterboxing them leaves grey
| bars down the side of every card.
*/
.mspage .ms-card-img{aspect-ratio:16/9;background:var(--ms-l);border-block:1px solid var(--line);
  overflow:hidden}
.mspage .ms-card-img img{width:100%;height:100%;object-fit:cover;display:block}
.mspage .ms-card-b{padding:16px 18px;flex:1}
.mspage .ms-card-b p{font-size:.87rem;color:var(--muted);margin:0 0 12px;line-height:1.55}
.mspage .ms-pills{display:flex;flex-wrap:wrap;gap:6px}
.mspage .ms-pills span{font-size:.73rem;font-weight:700;color:var(--ms-d);background:var(--ms-l);
  border:1px solid color-mix(in srgb,var(--ms) 22%,#fff);padding:4px 10px;border-radius:999px}
.mspage .ms-card-f{padding:0 18px 16px}
.mspage .ms-card-f .btn{width:100%}
.mspage .ms-badge{display:inline-flex;align-items:center;gap:6px;font-size:.68rem;font-weight:800;
  letter-spacing:.09em;text-transform:uppercase;color:#fff;background:var(--green);
  padding:4px 10px;border-radius:999px;margin-left:auto;flex:none}

/* --- the dark capability section ----------------------------------------- */
.mspage .ms-dark{background:var(--ms-ink);color:#cfe0f2;padding:70px 0}
.mspage .ms-dark .ms-h2{color:#fff}
.mspage .ms-dark .ms-h2 em{color:#ffd9a8}
.mspage .ms-head{text-align:center;max-width:780px;margin:0 auto 40px}
.mspage .ms-head p{margin:0;color:var(--muted);font-size:1rem}
.mspage .ms-dark .ms-head p{color:#a9c2dd}
.mspage .ms-tiles{display:grid;grid-template-columns:repeat(4,1fr);gap:18px}
.mspage .ms-tile{background:rgba(255,255,255,.055);border:1px solid rgba(255,255,255,.12);
  border-radius:14px;padding:22px 20px;transition:.18s}
.mspage .ms-tile:hover{background:rgba(255,255,255,.1);border-color:rgba(255,255,255,.28);transform:translateY(-3px)}
.mspage .ms-tile i{display:grid;place-items:center;width:46px;height:46px;border-radius:12px;font-style:normal;
  font-size:1.25rem;color:#fff;background:linear-gradient(140deg,var(--ms),var(--ms-d));margin-bottom:14px}
.mspage .ms-tile b{display:block;color:#fff;font-size:.98rem;font-weight:750;margin-bottom:6px}
.mspage .ms-tile p{margin:0;font-size:.85rem;color:#a9c2dd;line-height:1.55}

/* --- why us | how to start ----------------------------------------------- */
.mspage .ms-two{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:44px;align-items:start}
.mspage .ms-why{display:grid;gap:12px}
.mspage .ms-why li{display:flex;gap:13px;align-items:flex-start;background:#fff;border:1px solid var(--line);
  border-radius:12px;padding:15px 17px}
.mspage .ms-why .i{flex:none;color:var(--green);font-size:1.15rem;margin-top:2px}
.mspage .ms-why p{margin:2px 0 0;font-size:.86rem;color:var(--muted);line-height:1.55}

.mspage .ms-steps{position:relative;display:grid;gap:0;counter-reset:ms-n}
.mspage .ms-step{position:relative;padding:0 0 26px 58px}
.mspage .ms-step::before{counter-increment:ms-n;content:counter(ms-n);position:absolute;left:0;top:0;
  width:38px;height:38px;border-radius:50%;display:grid;place-items:center;font-weight:800;font-size:.95rem;
  color:#fff;background:var(--ms)}
.mspage .ms-step::after{content:"";position:absolute;left:18.5px;top:44px;bottom:6px;width:2px;background:var(--line)}
.mspage .ms-step:last-child{padding-bottom:0}
.mspage .ms-step:last-child::after{display:none}
.mspage .ms-step b{display:block;color:var(--ink);font-size:.98rem;font-weight:750;padding-top:7px}
.mspage .ms-step p{margin:4px 0 0;font-size:.87rem;color:var(--muted);line-height:1.6}

/* --- the closing enquiry -------------------------------------------------- */
/* The company's own tint, not the marketplace's blue — on the green
   template a blue band here was the one thing on the page that still
   looked like somebody else's site. */
.mspage .ms-cta{padding:66px 0;background:var(--ms-l);border-top:1px solid var(--line)}
.mspage .ms-cta-g{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,520px);gap:46px;align-items:center}
.mspage .ms-cta .ms-form{box-shadow:var(--sh-2)}
.mspage .ms-contact{display:grid;gap:12px;margin-top:22px}
.mspage .ms-contact li{display:flex;gap:13px;align-items:flex-start;font-size:.9rem;color:var(--body)}
.mspage .ms-contact .i{flex:none;color:var(--ms);font-size:1.1rem;margin-top:3px}
.mspage .ms-contact b{display:block;color:var(--ink);font-weight:700}
.mspage .ms-link{color:var(--ms);text-decoration:underline;text-underline-offset:3px}
.mspage .ms-link:hover{color:var(--ms-d)}

/* --- the company footer ---------------------------------------------------
   Its own, dark, in the company's colour — and carrying the member badge
   that links back to the marketplace.                                    */
.mspage .ms-ftr{background:var(--ms-ink);color:#a9c2dd;padding:54px 0 0}
.mspage .ms-fcols{display:grid;grid-template-columns:1.5fr 1fr 1fr 1.3fr;gap:34px;padding-bottom:38px}
.mspage .ms-ftr h4{color:#fff;font-size:.82rem;font-weight:800;letter-spacing:.12em;text-transform:uppercase;
  margin:0 0 16px}
.mspage .ms-ftr p{font-size:.87rem;line-height:1.65;color:#a9c2dd}
.mspage .ms-ftr a{color:#a9c2dd;font-size:.88rem}
.mspage .ms-ftr a:hover{color:#fff}
/*
| Footer list rows: icon on the left, text beside it, and a SECOND LINE THAT
| LINES UP WITH THE FIRST.
|
| These rows were inline. A label long enough to wrap — "Pharma Tablet
| Manufacturing Company" is, in a footer column — put its second line back at
| the left edge, underneath the chevron, so the column read as a ragged block
| rather than a list. The icon sat on the text baseline too, which is the same
| defect the main site's contact strip had.
|
| Two shapes share these rules. In Product Categories the icon is INSIDE the
| anchor; in Get in touch it is a sibling of it. Both are made flex rows, so
| both behave the same way.
|
| align-items:flex-start, not center: on a row that wraps to two lines,
| centring pushes the icon halfway down the block instead of keeping it beside
| the first line, which is where it belongs.
*/
.mspage .ms-fcol li{margin-bottom:9px;display:flex;align-items:flex-start;gap:8px}
.mspage .ms-fcol li > a{display:inline-flex;align-items:flex-start;gap:8px}
.mspage .ms-fcol .i{color:var(--ms);flex:none;margin-top:.22em}
.mspage .ms-ftr .ms-brand b{color:#fff}
.mspage .ms-ftr .ms-sub{color:#fff}
.mspage .ms-ftr .ms-brand{margin-bottom:16px}
.mspage .ms-member{display:inline-flex;align-items:center;gap:11px;background:rgba(255,255,255,.07);
  border:1px solid rgba(255,255,255,.18);border-radius:12px;padding:11px 15px;margin-top:16px}
.mspage .ms-member .ms-mark{width:36px;height:36px;border-radius:9px;font-size:.72rem;
  background:linear-gradient(140deg,var(--blue-600),var(--blue-800))}
.mspage .ms-member b{display:block;color:#fff;font-size:.85rem;font-weight:750;line-height:1.2}
.mspage .ms-member .ms-sub{font-size:.7rem;color:#a9c2dd;letter-spacing:0;text-transform:none;
  font-weight:600;white-space:normal}
.mspage .ms-member .ms-mark .i{font-size:.95rem}
.mspage .ms-fbot{border-top:1px solid rgba(255,255,255,.12);padding:16px 0;display:flex;flex-wrap:wrap;
  gap:12px;align-items:center;justify-content:space-between;font-size:.8rem}
/* The build marker — quiet, but on the page, because "is this the new build?"
   is a question that arrives as a screenshot. */

/* --- the fixed CTA — mail, call, WhatsApp --------------------------------
   One component, two shapes. A vertical rail against the right edge on a
   desktop; the bar across the bottom of a phone. Same markup either way,
   so the three destinations cannot drift apart between them.

   All three are the marketplace's, never the company's. On a desktop each
   button is a 52px circle that opens out to its label on hover or keyboard
   focus — it opens LEFTWARDS, away from the edge, so it can never push the
   page sideways.                                                        */
.mspage .ms-fix{position:fixed;right:16px;top:50%;transform:translateY(-50%);z-index:75;
  display:grid;gap:10px;justify-items:end}
/*
 | The label is absolutely positioned to the LEFT of the icon, not laid out
 | after it in a flex row.
 |
 | Laid out in normal flow inside a 52px pill with overflow:hidden, the
 | label's box still extends to the right of the pill — clipped from view,
 | but 70px past the right edge of the window as far as every measurement
 | is concerned. Anchored to the pill's right edge and drawn leftwards, it
 | is inside the window whether it is showing or not.
 */
.mspage .ms-fb{position:relative;display:block;width:52px;height:52px;border-radius:999px;
  color:#fff;font-weight:700;font-size:.86rem;overflow:hidden;
  box-shadow:0 8px 22px rgba(15,30,51,.22);transition:width .22s ease,background .18s}
.mspage .ms-fb .i{position:absolute;right:16px;top:50%;transform:translateY(-50%);font-size:1.28rem}
/* right:52px is the pill's own collapsed width, so the label sits exactly
   at its left edge and is fully clipped. At 46px the last six pixels of
   every label showed through as a stray letter beside the icon. */
.mspage .ms-fb .ms-lbl{position:absolute;right:54px;top:50%;transform:translateY(-50%);white-space:nowrap}
.mspage .ms-fb:hover,.mspage .ms-fb:focus-visible{width:172px}
.mspage .ms-fmail{background:var(--accent)}
.mspage .ms-fmail:hover{background:var(--accent-600)}
.mspage .ms-fcall{background:var(--ms)}
.mspage .ms-fcall:hover{background:var(--ms-d)}
.mspage .ms-fwa{background:var(--wa)}
.mspage .ms-fwa:hover{background:#16a34a}
@media (prefers-reduced-motion:reduce){.mspage .ms-fb{transition:none}}

/* --- the enquiry popup ---------------------------------------------------
   "Send enquiry" and the mail button open this rather than jumping to the
   bottom of the page or to a mail client. It holds the SAME form the page
   already shows — one set of questions, so every lead is comparable.    */
.mspage .ms-modal{position:fixed;inset:0;z-index:95;display:grid;place-items:center;
  padding:20px 16px;background:rgba(3,16,42,.62);backdrop-filter:blur(2px);overflow-y:auto}
.mspage .ms-modal[hidden]{display:none}
.mspage .ms-mcard{width:min(560px,100%);max-height:calc(100vh - 40px);overflow-y:auto;
  border-radius:16px;box-shadow:var(--sh-3);animation:ms-pop .2s ease-out}
/* 100vh on a phone is the window WITHOUT the browser's own bars, so the
   last field of a tall form sits under the address bar and cannot be
   reached. dvh is the visible height, and it changes as the bars slide. */
@supports (height:100dvh){.mspage .ms-mcard{max-height:calc(100dvh - 40px)}}
@keyframes ms-pop{from{transform:translateY(10px) scale(.98);opacity:0}to{transform:none;opacity:1}}
@media (prefers-reduced-motion:reduce){.mspage .ms-mcard{animation:none}}
/* The card is the scroll container, so the header sticks to the top of it
   and the close button never scrolls out of reach. */
.mspage .ms-mcard .ms-form{border-radius:16px;box-shadow:none;overflow:visible}
.mspage .ms-mcard .ms-form-h{position:sticky;top:0;z-index:2;display:flex;align-items:center;gap:12px;
  border-radius:16px 16px 0 0}
.mspage .ms-mx{flex:none;width:38px;height:38px;border-radius:50%;border:0;cursor:pointer;
  display:grid;place-items:center;font-size:1.05rem;color:#fff;background:rgba(255,255,255,.22)}
.mspage .ms-mx:hover{background:rgba(255,255,255,.38)}

/* --- the menu the burger opens -------------------------------------------
   A full-height panel from the right, over a dimmed page. It carries the
   whole nav plus the three things somebody on a phone actually wants:
   enquire, call, WhatsApp.                                              */
.mspage .ms-drawer{position:fixed;inset:0;z-index:90;display:flex;justify-content:flex-end;
  background:rgba(3,16,42,.55);backdrop-filter:blur(2px)}
.mspage .ms-drawer[hidden]{display:none}
.mspage .ms-dpanel{width:min(340px,88vw);height:100%;background:#fff;display:flex;flex-direction:column;
  box-shadow:-18px 0 46px rgba(15,30,51,.28);animation:ms-in .22s ease-out}
@keyframes ms-in{from{transform:translateX(18px);opacity:.4}to{transform:none;opacity:1}}
@media (prefers-reduced-motion:reduce){.mspage .ms-dpanel{animation:none}}
.mspage .ms-dhead{display:flex;align-items:center;gap:12px;padding:14px 16px;border-bottom:1px solid var(--line)}
.mspage .ms-dhead .ms-brand{min-width:0;flex:1}
.mspage .ms-x{flex:none;width:44px;height:44px;border-radius:10px;border:1px solid var(--line);
  background:#fff;color:var(--ink);cursor:pointer;display:grid;place-items:center;font-size:1.1rem}
.mspage .ms-x:hover{border-color:var(--ms);color:var(--ms)}
.mspage .ms-dnav{flex:1;overflow-y:auto;padding:10px 12px}
.mspage .ms-dnav a{display:flex;align-items:center;gap:10px;padding:13px 14px;border-radius:10px;
  font-size:.98rem;font-weight:650;color:var(--ink);min-height:48px}
.mspage .ms-dnav a:hover,.mspage .ms-dnav a:focus-visible{background:var(--ms-l);color:var(--ms-d)}
.mspage .ms-dnav .i{color:var(--ms)}
.mspage .ms-dact{display:grid;gap:9px;padding:14px 16px;border-top:1px solid var(--line);background:var(--ms-l)}
.mspage .ms-dact .btn{width:100%;min-height:48px}
.mspage .ms-dact .ms-fine{margin:2px 0 0}

/* =======================================================================
   RESPONSIVE — every selector below is scoped .mspage on purpose.
   An unscoped `.ms-hero-g` inside a media query loses to `.mspage
   .ms-hero-g` on specificity and never applies. That exact mistake made
   the category listing column 0px wide on a phone, live, for a week.
   ======================================================================= */
/* The number spelled out inside the Call button is 17 characters of
   nowrap. With six nav items beside it the header row was 46px wider than
   a 1152px viewport — which is what a 1440px screen at 125% scaling
   actually is, and that is the commonest desktop there is. */
@media (max-width:1279.98px){
  .mspage .ms-nav a{padding:9px 10px;font-size:.87rem}
  .mspage .ms-act .btn{padding:11px 15px}
}

/* The hero keeps two columns well past the point the old rule gave up on
   them. It used to stack at 1100 and cap the form at 520px, which left the
   whole right-hand half of a tablet empty — the single loudest way for a
   page to read as "desktop layout, shrunk". */
@media (max-width:1199.98px){
  .mspage .ms-hero-g{grid-template-columns:minmax(0,1fr) 340px;gap:30px}
  .mspage .ms-cta-g{grid-template-columns:minmax(0,1fr) minmax(0,420px);gap:32px}
}

@media (max-width:1099.98px){
  .mspage .ms-tiles{grid-template-columns:repeat(2,1fr)}
  /* Narrower, not stacked. Stacking here put a 540px-tall picture between
     the visitor and the first sentence about the company. */
  .mspage .ms-about-g{grid-template-columns:minmax(0,330px) minmax(0,1fr);gap:30px;align-items:start}
  .mspage .ms-yrs{right:14px}
  .mspage .ms-fcols{grid-template-columns:1fr 1fr;gap:30px}
}

@media (max-width:991.98px){
  .mspage .ms-nav{display:none}
  .mspage .ms-burger{display:grid}
  .mspage .ms-act .ms-enq{display:none}
  .mspage .ms-two{grid-template-columns:1fr;gap:36px}
}

/* Below this the two-column hero genuinely has no room, so it stacks — and
   the form takes the full width of the container rather than sitting in a
   520px box with half the screen blank beside it. */
@media (max-width:899.98px){
  .mspage .ms-hero-g{grid-template-columns:1fr;gap:28px}
  .mspage .ms-cta-g{grid-template-columns:1fr;gap:28px}
  .mspage .ms-form{max-width:none}
  .mspage .ms-about-g{grid-template-columns:1fr;gap:28px}
  /* Centred once it is stacked, so it does not sit in the left half of a
     tablet with nothing beside it. */
  .mspage .ms-shotw{max-width:540px;margin-inline:auto}
  .mspage .ms-band-g{grid-template-columns:repeat(min(var(--cells,4),2),1fr);gap:26px 12px}
  .mspage .ms-band-g > div + div{border-left:0}
  .mspage .ms-band-g > div:nth-child(2n){border-left:1px solid rgba(255,255,255,.16)}
}

@media (max-width:767.98px){
  .mspage .ms-hero{padding:40px 0 46px}
  .mspage .ms-dark,.mspage .ms-cta{padding:52px 0}
  .mspage .ms-strip .wrap{height:auto;padding-block:7px;flex-wrap:wrap;gap:8px 12px;font-size:.72rem}
  .mspage .ms-strip .ms-back{margin-left:0}
  /* The header is shorter here and the strip is two lines, so the anchor
     offset that keeps a heading clear of the sticky bar changes with it. */
  .mspage section{scroll-margin-top:108px}
  /* Room for the fixed bar, so the footer's last line is reachable. */
  .mspage .ms-ftr{padding-bottom:74px}
  /* The rail becomes the bar. A hover-to-expand pill is useless on a
     touch screen, so here every label is simply shown. */
  .mspage .ms-fix{left:0;right:0;bottom:0;top:auto;transform:none;z-index:70;
    display:flex;gap:8px;justify-items:stretch;
    padding:9px 12px calc(9px + env(safe-area-inset-bottom));
    background:#fff;border-top:1px solid var(--line);box-shadow:0 -6px 22px rgba(15,30,51,.12)}
  /* flex:1 alone will not shrink a button below the width of its own
     label, and three nowrap labels do not fit a 320px phone — the third
     button hung 49px off the right edge. */
  .mspage .ms-fb{flex:1 1 0;min-width:0;width:auto;height:46px;padding:0 8px;border-radius:10px;
    display:flex;align-items:center;justify-content:center;gap:7px;font-size:.85rem;box-shadow:none}
  .mspage .ms-fb:hover,.mspage .ms-fb:focus-visible{width:auto}
  .mspage .ms-fb .i{position:static;transform:none;font-size:1.1rem}
  .mspage .ms-fb .ms-lbl{position:static;transform:none;overflow:hidden;text-overflow:ellipsis}
}

@media (max-width:575.98px){
  .mspage .ms-hrow{height:64px;gap:10px}
  .mspage .ms-mark{width:40px;height:40px;font-size:.9rem}
  /* The company name is the one thing here that has no maximum length.
     "Aurexa Formulations" pushed the burger 59px off the right edge of a
     390px phone; flex:none on the brand meant it never gave any ground. */
  .mspage .ms-brand{flex:1 1 auto;min-width:0}
  .mspage .ms-brand b{font-size:.98rem;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
  .mspage .ms-brand .ms-sub{overflow:hidden;text-overflow:ellipsis}
  /* The call button leaves the header on a phone. It has not gone away —
     it is in the fixed bar at the bottom of the screen, permanently, which
     is a better place for it than a bar you have to scroll back up to. */
  .mspage .ms-act .ms-call{display:none}
  .mspage .sec{padding:46px 0}
  .mspage .ms-fgrid{grid-template-columns:1fr}
  .mspage .ms-cards{grid-template-columns:1fr}
  .mspage .ms-tiles{grid-template-columns:1fr}
  .mspage .ms-fcols{grid-template-columns:1fr}
  .mspage .ms-form-b{padding:16px 16px 18px}
  .mspage .ms-form-h{padding:15px 16px}
  .mspage .ms-yrs{right:12px;bottom:12px;padding:11px 15px}
  .mspage .ms-yrs b{font-size:1.4rem}
  .mspage .ms-hbtn .btn{width:100%}
  .mspage .ms-fbot{justify-content:center;text-align:center}
}

/* Small phones — 320 to 420px. */
@media (max-width:419.98px){
  .mspage .wrap{padding:0 16px}
  /* The product-count badge and the category name are two things on one
     line; below 420px they are two lines. */
  .mspage .ms-card-h{flex-wrap:wrap}
  .mspage .ms-badge{margin-left:52px}
  .mspage .ms-usp li{font-size:.8rem;padding:7px 12px}
  .mspage .ms-step{padding-left:50px}
}

/* Only on the narrowest phones does a label give way to its icon. Three
   labels fit a 360px bar; they do not fit a 320px one. */
@media (max-width:359.98px){
  .mspage .ms-fwa{flex:0 0 52px;padding:0}
  .mspage .ms-fwa .ms-lbl{display:none}
}

/* =========================================================================
   THE CATALOG'S OWN PAGES
   =========================================================================
   /{company}/about-us, /services, /products, /product-ranges, /contact-us
   and /products/{product}. Everything above this line is the catalog page
   itself; everything below is what the pages hung off it need.
   ========================================================================= */

/* --- the band under the header: where you are, and the way back --------- */
.mspage .ms-phead{background:var(--ms-l);border-bottom:1px solid var(--line);padding:26px 0 30px}
.mspage .ms-crumbs{display:flex;align-items:center;gap:8px;font-size:.8rem;color:var(--muted);
  overflow-x:auto;white-space:nowrap;scrollbar-width:none}
.mspage .ms-crumbs::-webkit-scrollbar{display:none}
.mspage .ms-crumbs a{color:var(--ms-d);font-weight:600}
.mspage .ms-crumbs a:hover{text-decoration:underline;text-underline-offset:3px}
.mspage .ms-crumbs .i{color:var(--faint);width:.8em;height:.8em}
.mspage .ms-crumbs b{color:var(--ink);font-weight:700}
.mspage .ms-ph-t{font-family:var(--serif);font-weight:700;letter-spacing:-.012em;margin:10px 0 0;
  font-size:clamp(1.5rem,1.1rem + 1.6vw,2.2rem)}

.mspage .ms-count{font-size:.88rem;color:var(--muted);margin:0 0 22px}

/* Nothing here yet — said plainly, in the place the list would have been,
   rather than as a heading over blank space. */
.mspage .ms-empty{display:flex;gap:12px;align-items:flex-start;background:var(--ms-l);
  border:1px solid var(--line);border-radius:12px;padding:20px 22px;margin:0;
  font-size:.92rem;color:var(--body)}
.mspage .ms-empty .i{flex:none;color:var(--ms);font-size:1.2rem;margin-top:2px}

/* --- the range filter on /products -------------------------------------- */
.mspage .ms-filter{display:flex;flex-wrap:wrap;gap:8px;margin:0 0 26px}
.mspage .ms-filter a{display:inline-flex;align-items:center;gap:7px;padding:8px 15px;border-radius:999px;
  font-size:.84rem;font-weight:650;color:var(--body);background:#fff;border:1px solid var(--line)}
.mspage .ms-filter a:hover{border-color:var(--ms);color:var(--ms-d)}
.mspage .ms-filter a.on{background:var(--ms);border-color:var(--ms);color:#fff}
.mspage .ms-filter a span{font-size:.74rem;font-weight:700;opacity:.75}

/* --- the product grid ---------------------------------------------------
   Its own card, not .ms-card. A product card is mostly picture and has a
   quote button pinned to the bottom; the category card is mostly text and
   has a badge in its header. Two shapes, two classes — reusing one for the
   other is how a grid ends up with a badge slot nothing fills. */
.mspage .ms-plist{display:grid;grid-template-columns:repeat(auto-fill,minmax(220px,1fr));gap:18px}
.mspage .ms-pcard{display:flex;flex-direction:column;border:1px solid var(--line);border-radius:14px;
  background:#fff;overflow:hidden;transition:.18s}
.mspage .ms-pcard:hover{border-color:var(--ms);box-shadow:var(--sh-2);transform:translateY(-3px)}
.mspage .ms-pcard-s{display:grid;place-items:center;aspect-ratio:4/3;background:var(--ms-l);
  color:var(--ms);font-size:2.6rem;overflow:hidden}
.mspage .ms-pcard-s img{width:100%;height:100%;object-fit:cover}
.mspage .ms-pcard-b{padding:14px 16px;flex:1}
.mspage .ms-pcard-b b{display:block;font-size:.94rem;font-weight:750;line-height:1.3;color:var(--ink)}
.mspage .ms-pcard-b b a{color:inherit}
.mspage .ms-pcard-b b a:hover{color:var(--ms-d)}
.mspage .ms-pcard-b p{margin:6px 0 0;font-size:.8rem;color:var(--muted);line-height:1.5}
.mspage .ms-pmeta{display:flex;flex-wrap:wrap;gap:6px;margin-top:10px}
.mspage .ms-pmeta span{font-size:.7rem;font-weight:700;color:var(--ms-d);background:var(--ms-l);
  padding:3px 9px;border-radius:999px}
.mspage .ms-pcard-f{display:flex;align-items:center;justify-content:center;gap:8px;padding:11px 16px;
  border-top:1px solid var(--line);font-size:.84rem;font-weight:700;color:var(--ms-d);
  background:#fff;min-height:44px}
.mspage .ms-pcard-f:hover{background:var(--ms-l)}

/* --- one product -------------------------------------------------------- */
/*
 | The product page's own rules are at the foot of this file, under
 | "PRODUCT PAGE". What used to be here — .ms-prod, .ms-prodshot, .ms-comp
 | and .ms-spec — went with the markup that used them: the page is a split
 | hero and four sections now, not a picture beside a definition list. Left
 | in place they would have been four more rules addressing nothing, which
 | is the exact thing the guard in CatalogPageTest exists to catch.
 */

/* --- the pager, which the framework renders as Bootstrap 5 -------------- */
.mspage .pagination{display:flex;flex-wrap:wrap;gap:6px;list-style:none;padding:0;margin:32px 0 0;
  justify-content:center}
.mspage .page-item .page-link{display:grid;place-items:center;min-width:40px;height:40px;padding:0 12px;
  border-radius:9px;border:1px solid var(--line);background:#fff;color:var(--body);
  font-size:.88rem;font-weight:650}
.mspage .page-item .page-link:hover{border-color:var(--ms);color:var(--ms-d)}
.mspage .page-item.active .page-link{background:var(--ms);border-color:var(--ms);color:#fff}
.mspage .page-item.disabled .page-link{opacity:.45}

@media (max-width:575.98px){
  .mspage .ms-plist{grid-template-columns:repeat(auto-fill,minmax(150px,1fr));gap:12px}
  .mspage .ms-pcard-b{padding:12px}
  .mspage .ms-phead{padding:20px 0 22px}
}

/* =========================================================================
   PRODUCT RANGE PAGE — the whole catalogue as one table
   =========================================================================
   The list a distributor actually reads, with the search, the sorting and
   the paging that make a long one usable. All of it runs on rows that are
   already in the document — see catalog.js — so this styles a table that
   works before a line of script does.
   ========================================================================= */
.mspage .ms-rangewrap{display:grid;grid-template-columns:minmax(0,1fr) 340px;gap:22px;align-items:start}

.mspage .ms-tablecard{background:#fff;border:1px solid var(--line);border-radius:14px;
  box-shadow:var(--sh-2);overflow:hidden}

/* the bar above the table */
.mspage .ms-tbar{display:flex;align-items:center;justify-content:space-between;gap:14px;
  flex-wrap:wrap;padding:16px 18px}
.mspage .ms-tbar label{font-size:.84rem;color:var(--body);font-weight:600;
  display:inline-flex;align-items:center;gap:8px}
.mspage .ms-tbar select,.mspage .ms-tbar input{font:inherit;font-size:.84rem;color:var(--ink);
  border:1px solid var(--line);border-radius:8px;padding:7px 10px;background:#fff}
.mspage .ms-tbar select{padding-right:26px}
.mspage .ms-tbar input{min-width:200px}
.mspage .ms-tbar input:focus,.mspage .ms-tbar select:focus{outline:2px solid var(--ms);outline-offset:1px}

/*
| The table scrolls inside its own box, never the page.
|
| Composition is the one column with no length limit — some of these run to
| ninety characters — and a table that widens the document gives every page
| on the site a horizontal scrollbar on a phone.
*/
.mspage .ms-tscroll{overflow-x:auto;-webkit-overflow-scrolling:touch}

.mspage .ms-ptable{width:100%;border-collapse:collapse;font-size:.86rem;min-width:640px}
.mspage .ms-ptable th{background:var(--ms);color:#fff;text-align:left;font-weight:700;
  white-space:nowrap;padding:0;position:sticky;top:0;z-index:1}
/*
| The button is what carries the padding and the click.
|
| A <th> with a click handler is not reachable from a keyboard and reads as
| static text to a screen reader; a real button inside it is both, and
| stretching it to fill the cell keeps the whole header clickable.
*/
.mspage .ms-ptable th button{all:unset;box-sizing:border-box;display:flex;align-items:center;gap:7px;
  width:100%;padding:13px 14px;cursor:pointer;font:inherit;color:inherit}
.mspage .ms-ptable th button:focus-visible{outline:2px solid #fff;outline-offset:-3px}
.mspage .ms-ptable th button:hover{background:rgba(255,255,255,.1)}

/* The sort marker: both arrows at rest, one of them once the column is
   sorted, so a sortable column looks sortable before it is used. */
.mspage .ms-ptable th i{flex:none;width:8px;height:12px;opacity:.5;
  background:currentColor;
  -webkit-mask:var(--ms-sort) center/8px 12px no-repeat;
  mask:var(--ms-sort) center/8px 12px no-repeat}
.mspage .ms-ptable th[data-dir] i{opacity:1}
.mspage .ms-ptable th[data-dir=asc] i{-webkit-mask-image:var(--ms-up);mask-image:var(--ms-up)}
.mspage .ms-ptable th[data-dir=desc] i{-webkit-mask-image:var(--ms-down);mask-image:var(--ms-down)}

.mspage .ms-ptable td{padding:13px 14px;border-bottom:1px solid var(--line);vertical-align:middle}
.mspage .ms-ptable tbody tr:nth-child(odd) td{background:#f7f9fc}
.mspage .ms-ptable tbody tr:hover td{background:var(--ms-l)}
.mspage .ms-pt-n{font-weight:750;color:var(--ink);white-space:nowrap}
.mspage .ms-pt-n a{color:inherit}
.mspage .ms-pt-n a:hover{color:var(--ms);text-decoration:underline;text-underline-offset:3px}
.mspage .ms-pt-c{color:var(--body);min-width:260px}
.mspage .ms-pt-p{color:var(--muted);white-space:nowrap}
.mspage .ms-dash{color:var(--faint)}
.mspage .ms-ptable .ms-tag{display:inline-block;background:var(--ms-l);color:var(--ms);
  font-size:.74rem;font-weight:700;padding:5px 12px;border-radius:99px;white-space:nowrap}

/* the bar under it */
.mspage .ms-tfoot{display:flex;align-items:center;justify-content:space-between;gap:14px;
  flex-wrap:wrap;padding:15px 18px;border-top:1px solid var(--line)}
.mspage .ms-tfoot p{margin:0;font-size:.82rem;color:var(--muted)}
.mspage .ms-tpager{display:flex;gap:6px;flex-wrap:wrap}
.mspage .ms-tpager button{font:inherit;font-size:.82rem;font-weight:650;color:var(--body);
  background:#fff;border:1px solid var(--line);border-radius:8px;padding:7px 12px;cursor:pointer}
.mspage .ms-tpager button:hover:not(:disabled){border-color:var(--ms);color:var(--ms)}
.mspage .ms-tpager button.on{background:var(--ms);border-color:var(--ms);color:#fff}
.mspage .ms-tpager button:disabled{opacity:.45;cursor:default}
.mspage .ms-tpager span{padding:7px 4px;color:var(--faint);font-size:.82rem}
.mspage .ms-tnote{margin:0;padding:13px 18px;border-top:1px solid var(--line);background:var(--accent-50);
  font-size:.82rem;color:var(--body);display:flex;align-items:center;gap:9px}
.mspage .ms-tnote .i{color:var(--accent);flex:none}

/* ---- the rail ---------------------------------------------------------- */
.mspage .ms-rangerail{display:grid;gap:18px;position:sticky;top:88px}
.mspage .ms-rbox{background:#fff;border:1px solid var(--line);border-radius:14px;
  overflow:hidden;box-shadow:var(--sh-1)}
.mspage .ms-rbox > h2{margin:0;background:var(--ms);color:#fff;font-size:1rem;font-weight:750;
  padding:14px 18px}

.mspage .ms-rlist{padding:8px}
.mspage .ms-rlist label{display:flex;align-items:center;gap:10px;padding:10px 12px;border-radius:9px;
  font-size:.86rem;color:var(--body);cursor:pointer}
.mspage .ms-rlist label:hover{background:var(--ms-l)}
.mspage .ms-rlist label span{flex:1;min-width:0}
.mspage .ms-rlist label b{font-size:.74rem;font-weight:700;color:var(--muted);
  background:var(--ms-l);padding:3px 9px;border-radius:99px;flex:none}
.mspage .ms-rlist input{accent-color:var(--ms);flex:none;width:16px;height:16px}
/* :has, with a plain fallback: the row is readable either way, and where it
   is supported the whole row shows which range is on rather than a 16px
   dot doing it alone. */
.mspage .ms-rlist label:has(input:checked){background:var(--ms-l);color:var(--ms-ink);font-weight:700}
.mspage .ms-rlist label:has(input:checked) b{background:var(--ms);color:#fff}

/* The enquiry form drops its own chrome inside the rail box, which already
   has a heading and a border of its own. */
.mspage .ms-rform .ms-form{border:0;border-radius:0;box-shadow:none}
.mspage .ms-rform .ms-form-h{display:none}

@media (max-width:991.98px){
  .mspage .ms-rangewrap{grid-template-columns:1fr}
  .mspage .ms-rangerail{position:static}
}
@media (max-width:575.98px){
  .mspage .ms-tbar{padding:13px 14px}
  .mspage .ms-tbar input{min-width:0;width:100%}
  .mspage .ms-tbar .ms-tsearch{flex:1 1 100%}
  .mspage .ms-tfoot{padding:13px 14px;justify-content:center;text-align:center}
  .mspage .ms-tpager{justify-content:center;width:100%}
}

/* =========================================================================
   PRODUCT PAGE
   =========================================================================
   What is in it, who makes it, and can I have the territory — in that
   order, above the fold. Everything else on the page comes after.
   ========================================================================= */
.mspage .ms-psec{padding-top:34px}
.mspage .ms-pdetail{display:grid;grid-template-columns:minmax(0,460px) minmax(0,1fr);gap:40px;
  align-items:start}

/* ---- the picture ------------------------------------------------------- */
.mspage .ms-pgal-m{position:relative;border:1px solid var(--line);border-radius:16px;
  background:var(--ms-l);padding:26px;min-height:340px;display:grid;place-items:center;
  overflow:hidden}
.mspage .ms-pgal-m img{max-width:100%;max-height:420px;object-fit:contain;border-radius:10px;display:block}

/* The two certification flags, stacked in the corner. Absolute so they sit
   over the photograph rather than pushing it down the panel. */
.mspage .ms-pflags{position:absolute;top:16px;left:16px;z-index:1;display:grid;gap:8px;justify-items:start}
.mspage .ms-pflag{display:inline-flex;align-items:center;gap:7px;background:#fff;
  font-size:.74rem;font-weight:750;color:var(--ms);border:1px solid #cfe2f6;
  padding:6px 13px;border-radius:99px;box-shadow:var(--sh-1)}
.mspage .ms-pflag.ok{color:var(--green);border-color:#bfe6d3;background:var(--green-50)}
.mspage .ms-pflag .i{width:.95em;height:.95em}

/* No photograph — said, not implied. */
.mspage .ms-pcoming{display:grid;justify-items:center;gap:8px;text-align:center;color:var(--ms);padding:30px 10px}
.mspage .ms-pcoming .i{width:52px;height:52px;opacity:.45}
.mspage .ms-pcoming b{font-size:.98rem;color:var(--ms-ink)}
.mspage .ms-pcoming span{font-size:.83rem;color:var(--muted)}

.mspage .ms-pthumbs{display:flex;gap:10px;margin-top:14px;flex-wrap:wrap}
.mspage .ms-pthumbs button{all:unset;box-sizing:border-box;cursor:pointer;width:84px;height:84px;
  border:1px solid var(--line);border-radius:11px;overflow:hidden;background:#fff;display:grid;
  place-items:center;padding:6px}
.mspage .ms-pthumbs button.on{border-color:var(--ms);box-shadow:0 0 0 2px var(--ms-l)}
.mspage .ms-pthumbs img{max-width:100%;max-height:100%;object-fit:contain}

/* ---- the facts --------------------------------------------------------- */
.mspage .ms-pchip{display:inline-flex;align-items:center;gap:8px;background:var(--green-50);
  color:var(--green);font-size:.7rem;font-weight:800;letter-spacing:.08em;text-transform:uppercase;
  padding:7px 15px;border-radius:99px}
.mspage .ms-pname{font-size:clamp(1.9rem,1.3rem + 2.1vw,2.9rem);font-weight:800;color:var(--ms);
  letter-spacing:-.02em;line-height:1.1;margin:14px 0 6px;overflow-wrap:anywhere}
.mspage .ms-pmaker{color:var(--body);font-size:.95rem;margin:0 0 20px}
.mspage .ms-pmaker a{font-weight:750;color:var(--ms)}
.mspage .ms-pmaker a:hover{text-decoration:underline;text-underline-offset:3px}

.mspage .ms-pfacts{display:grid;grid-template-columns:repeat(auto-fit,minmax(240px,1fr));gap:14px}
.mspage .ms-pfacts > div{border:1px solid var(--line);border-radius:12px;background:#fbfcfe;padding:14px 16px;
  min-width:0}
.mspage .ms-pfacts span{display:flex;align-items:center;gap:7px;font-size:.68rem;font-weight:800;
  letter-spacing:.07em;text-transform:uppercase;color:var(--muted);margin-bottom:7px}
.mspage .ms-pfacts span .i{color:var(--ms);width:.95em;height:.95em}
.mspage .ms-pfacts b{display:block;font-size:.98rem;color:var(--ink);font-weight:700;overflow-wrap:anywhere}
.mspage .ms-pfacts b.acc{color:var(--ms);font-weight:800}

.mspage .ms-pcerts{display:flex;flex-wrap:wrap;gap:9px;margin-top:18px}
.mspage .ms-pcerts span{display:inline-flex;align-items:center;gap:7px;font-size:.76rem;font-weight:700;
  color:var(--green);background:var(--green-50);border:1px solid #cbe9d9;padding:6px 13px;border-radius:99px}
.mspage .ms-pcerts i{width:7px;height:7px;border-radius:50%;background:currentColor;flex:none}
.mspage .ms-pcerts .ship{color:var(--ms);background:var(--ms-l);border-color:#cfe2f6}
.mspage .ms-pcerts .ship .i{width:.95em;height:.95em}

/* The call to action. Solid brand, because it is the one block on the page
   that is asking for something rather than telling. */
.mspage .ms-pcta{margin-top:22px;border-radius:14px;padding:20px 22px;color:#fff;
  background:linear-gradient(135deg,var(--ms),var(--ms-d))}
.mspage .ms-pcta b{display:flex;align-items:center;gap:9px;font-size:1rem;font-weight:750}
.mspage .ms-pcta p{margin:8px 0 16px;font-size:.88rem;color:rgba(255,255,255,.86)}
.mspage .ms-pcta-b{display:flex;gap:11px;flex-wrap:wrap}
.mspage .ms-pcta-b .btn{flex:1 1 200px;justify-content:center;background:#fff;color:var(--ms-ink);
  border-color:#fff}
.mspage .ms-pcta-b .btn:hover{background:#eef4fb;color:var(--ms-d)}
.mspage .ms-pcta-b .ms-pwa{background:var(--wa);border-color:var(--wa);color:#fff}
.mspage .ms-pcta-b .ms-pwa:hover{background:#16a34a;color:#fff}

.mspage .ms-phours{display:flex;flex-wrap:wrap;gap:8px 22px;margin:18px 0 0;padding:13px 16px;
  border-radius:11px;background:var(--green-50);border:1px solid #cbe9d9;
  font-size:.84rem;font-weight:650;color:var(--green)}
.mspage .ms-phours span{display:inline-flex;align-items:center;gap:8px;min-width:0}
.mspage .ms-phours .i{flex:none}

/* ---- the specification table ------------------------------------------- */
.mspage .ms-spectable th{background:var(--ms-l);color:var(--ms-ink);width:230px;
  padding:13px 16px;font-weight:750;white-space:nowrap;position:static}
.mspage .ms-spectable td{color:var(--body)}
.mspage .ms-spectable tbody tr:nth-child(odd) td{background:#fff}
.mspage .ms-spectable tbody tr:hover td{background:#fbfcfe}

/* ---- the enquiry band --------------------------------------------------- */
.mspage .ms-penq{background:linear-gradient(135deg,var(--ms-ink),var(--ms-d) 60%,var(--ms));color:#fff}
.mspage .ms-penq .eyebrow{background:rgba(255,255,255,.16);color:#fff}
.mspage .ms-penq .ms-h2{color:#fff}
.mspage .ms-penq .ms-p{color:rgba(255,255,255,.84)}
.mspage .ms-penq-g{display:grid;grid-template-columns:minmax(0,1fr) 420px;gap:44px;align-items:start}
.mspage .ms-penq .ms-usp{display:grid;gap:9px;margin-top:20px}
.mspage .ms-penq .ms-usp li{display:flex;align-items:center;gap:9px;font-size:.88rem;
  color:rgba(255,255,255,.9)}
.mspage .ms-penq .ms-usp .i{color:#7ee2a8;flex:none}

@media (max-width:991.98px){
  .mspage .ms-pdetail{grid-template-columns:1fr;gap:26px}
  .mspage .ms-penq-g{grid-template-columns:1fr;gap:26px}
}
@media (max-width:575.98px){
  .mspage .ms-pgal-m{padding:18px;min-height:250px}
  .mspage .ms-pflags{top:12px;left:12px}
  .mspage .ms-pcta{padding:17px 16px}
  .mspage .ms-pcta-b .btn{flex:1 1 100%}
  .mspage .ms-spectable th{width:auto;min-width:140px;white-space:normal}
}

/*
| The franchise-terms tiles on the product page.
|
| Its own class, not .ms-tile. That one is built for the dark band on the
| catalog home — white heading, pale blue body — and dropped onto a white
| section its heading is white on white: the tiles rendered as an icon and a
| ghost of a paragraph, with the title simply not there.
*/
.mspage .ms-ptiles{display:grid;grid-template-columns:repeat(3,1fr);gap:18px}
.mspage .ms-ptile{background:#fff;border:1px solid var(--line);border-radius:14px;padding:20px;
  box-shadow:var(--sh-1);transition:box-shadow .18s,transform .18s,border-color .18s}
.mspage .ms-ptile:hover{box-shadow:var(--sh-2);transform:translateY(-3px);border-color:#cfe2f6}
.mspage .ms-ptile i{display:grid;place-items:center;width:46px;height:46px;border-radius:12px;
  font-style:normal;background:var(--ms-l);color:var(--ms);margin-bottom:13px}
.mspage .ms-ptile i .i{width:22px;height:22px}
.mspage .ms-ptile b{display:block;color:var(--ms-ink);font-size:.98rem;font-weight:750;margin-bottom:6px}
.mspage .ms-ptile p{margin:0;font-size:.85rem;color:var(--body);line-height:1.55}

@media (max-width:900px){.mspage .ms-ptiles{grid-template-columns:repeat(2,1fr)}}
@media (max-width:575.98px){.mspage .ms-ptiles{grid-template-columns:1fr}}


/* ---- LOAD MORE ------------------------------------------------------------
   A catalogue is a shop window, and nobody clicks to page 7 of one. The
   button asks the server for the next page and appends the cards; the
   numbered pager below it stays in the markup for crawlers and for anyone
   with JavaScript off, and the script hides it the moment it takes over.

   The pager also gets real styling here for the first time. It had none —
   this file never carried a `.pager` rule, so on a catalogue it drew as a
   row of bare blue links, which is most of what was wrong with it.        */
.mspage .ms-more{display:flex;flex-direction:column;align-items:center;gap:10px;margin:26px 0 0}
.mspage .ms-more [data-catload]{min-width:230px;padding:13px 26px;font-weight:700}
.mspage .ms-more [data-catload] svg{width:16px;height:16px}
.mspage .ms-more [data-catload][aria-busy="true"]{opacity:.6;cursor:progress}
.mspage .ms-more-end{margin:0;color:var(--muted);font-size:.88rem;text-align:center}
.mspage .ms-more-end[hidden]{display:none}

.mspage .pager{display:flex;gap:6px;align-items:center;justify-content:center;margin:6px 0 0;flex-wrap:wrap}
.mspage .pager a,.mspage .pager span{min-width:38px;height:38px;padding:0 12px;border:1px solid var(--line);
  background:#fff;border-radius:9px;display:inline-flex;align-items:center;justify-content:center;
  font-size:.9rem;font-weight:650;color:var(--body);text-decoration:none}
.mspage .pager a:hover{border-color:var(--ms);color:var(--ms)}
.mspage .pager .on{background:var(--ms);border-color:var(--ms);color:#fff}
.mspage .pager .gap{border:0;background:none;color:var(--faint);min-width:0;padding:0 4px}
.mspage .pager[hidden]{display:none}
