/* ============================================================
   CLEANOVA — cleanova.org
   Editorial Science. DESIGN.md v1.1 / tokens.css v1.1.
   Written in LOGICAL properties throughout so /ar mirrors
   from dir="rtl" alone. No physical left/right anywhere.
   ============================================================ */

@font-face{font-family:'Archivo';src:url(fonts/Archivo-400.woff2) format('woff2');font-weight:400;font-display:swap}
@font-face{font-family:'Archivo';src:url(fonts/Archivo-500.woff2) format('woff2');font-weight:500;font-display:swap}
@font-face{font-family:'Archivo';src:url(fonts/Archivo-600.woff2) format('woff2');font-weight:600;font-display:swap}
@font-face{font-family:'Archivo';src:url(fonts/Archivo-700.woff2) format('woff2');font-weight:700;font-display:swap}
@font-face{font-family:'Lama Sans';src:url(fonts/LamaSans-Regular.woff2) format('woff2');font-weight:400;font-display:swap}
@font-face{font-family:'Lama Sans';src:url(fonts/LamaSans-Medium.woff2) format('woff2');font-weight:500;font-display:swap}
@font-face{font-family:'Lama Sans';src:url(fonts/LamaSans-Bold.woff2) format('woff2');font-weight:700;font-display:swap}

:root{
  --paper:#F9F8F4; --panel:#F1EEE6; --ink:#1A1A1A; --ink-soft:#31302B;
  --ink-muted:#656158; --ink-faint:#6A6559;  /* A8 raised faint from #8A8474 (3.51:1). A17 retunes BOTH against the measured
     darkest ground pixel (231,230,226): muted 4.99:1, faint 4.64:1, and faint stays
     lighter than muted - an earlier pass inverted that ordering. */ --blue:#2C5FBF;
  --hairline:#D8D3C6; --hover:#F3F1EA; --dots:#B9B3A2;
  --on-ink:#F9F8F4; --muted-on-ink:#B8B2A3; --rule-on-ink:#3A382F;
  --alert:#A33A2A;

  /* Tonal layering, the method Stripe's own system uses instead of blur or glass:
     depth comes from ground tint shifts, never from elevation. --wash is a SOLID
     mix of the family colour into paper, not a gradient. 10% is the deepest tint
     that keeps a caption at AA once the caption steps from faint to muted. */
  /* Stage 3: ink strength for the engraved grounds, tuned in one place. */
  --tex-ink:.30;
  /* page-wide grounds. Deliberately quiet: these sit under every muted label
     on the site, so they buy atmosphere, not attention. */
  --ground-ink:.05; --grain-ink:.03; --grid-ink:.045;
  --wash-mix:10%;
  --wash-hover:15%;
  --deep:#EFEDE6;   /* fourth neutral step, warm-tinted per LOCKED s2 */

  /* Family colours — A2c. Print inks, now also used as range identity on
     screen, always as a GROUND with reversed type, never as text on paper. */
  --fam-C:#2C6FB5; --fam-C-on:#F9F8F4;   /* 4.88:1 */
  --fam-N:#E8A020; --fam-N-on:#1A1A1A;   /* 7.86:1 */
  --fam-E:#8A5AA8; --fam-E-on:#F9F8F4;   /* 4.81:1 */
  --fam-F:#1F8A4C; --fam-F-on:#F9F8F4;   /* 4.12:1, large type only */

  /* Both stacks must cover BOTH scripts. Archivo carries 0 Arabic glyphs, so a
     mixed value like "5 لتر × 4" set in --latin rendered its digits in Archivo and
     dropped the Arabic word to an OS font. Font matching is per-glyph, so listing
     the other face second fixes it without changing anything already correct. */
  --latin:'Archivo','Lama Sans','Helvetica Neue',Helvetica,Arial,sans-serif;
  --arabic:'Lama Sans','Archivo','Noto Kufi Arabic',sans-serif;
  --ar-display:.78; --ar-text:.92;

  --gutter:44px; --maxw:1280px;
}

*{box-sizing:border-box}
html{-webkit-text-size-adjust:100%;background:var(--paper)}
/* Ground stack. html paints the paper; these two fixed layers sit above it and
   below all content, so no band is ever bare white and nothing moves on scroll. */
body::before,body::after{content:"";position:fixed;inset:0;z-index:-1;
  pointer-events:none;background:var(--ink)}
body::before{opacity:var(--ground-ink);
  -webkit-mask-image:url(tex/micro-halftone.png);mask-image:url(tex/micro-halftone.png);
  -webkit-mask-size:cover;mask-size:cover;
  -webkit-mask-position:center;mask-position:center;
  -webkit-mask-repeat:no-repeat;mask-repeat:no-repeat}
body::after{opacity:var(--grain-ink);
  -webkit-mask-image:url(tex/grain.png);mask-image:url(tex/grain.png);
  -webkit-mask-size:180px 180px;mask-size:180px 180px;
  -webkit-mask-repeat:repeat;mask-repeat:repeat}
@media (prefers-reduced-motion:no-preference){}
body{margin:0;background:transparent;color:var(--ink-soft);
  font:400 13.5px/1.7 var(--latin);
  -webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility}
a{color:inherit;text-decoration:none}
img{max-width:100%;display:block}
:focus-visible{outline:2px solid var(--ink);outline-offset:2px}
h1,h2,h3{margin:0}
/* Visible only on focus - keyboard users must be able to bypass the masthead,
   which repeats on all 90 pages. */
/* Parked ABOVE the viewport, not beside it: inset-inline-start:-9999px flips to the
   right under RTL and widens the document, which showed up as horizontal overflow on
   the Arabic pages at 375px. A vertical offset cannot do that. */
.skip{position:absolute;inset-block-start:-200%;inset-inline-start:0;z-index:99;
  background:var(--ink);color:var(--on-ink);padding:12px 18px;
  font:700 12.5px var(--latin);text-decoration:none}
.skip:focus{inset-block-start:0}
main:focus{outline:none}
/* Page identity as an H1, styled as the section headings were. */
h1.ph{font:700 24px/1.25 var(--latin);letter-spacing:.05em;text-transform:uppercase;color:var(--ink)}
[dir=rtl] h1.ph{font-family:var(--arabic);--ls:24px;text-transform:none;
  font-size:calc(var(--ls) * var(--ar-display));letter-spacing:0;line-height:1.5}
/* Any element given an explicit `display` outranks the UA's [hidden]{display:none}.
   .card is display:flex, so setting card.hidden did nothing and every filter looked
   dead. Declared once, defensively, so it cannot regress. */
[hidden]{display:none!important}

/* Arabic: family only. Every slot derives its own size from the Latin size
   beside it. Never a font-size here — it compounds on nesting. */
[dir=rtl],:lang(ar){font-family:var(--arabic)}
[lang=ar] body,body[dir=rtl]{font-family:var(--arabic)}
.ar-d{font-size:calc(var(--ls) * var(--ar-display))}
.ar-t{font-size:calc(var(--ls) * var(--ar-text))}

/* Spec numerals stay Latin lining in both locales (DESIGN.md §3) */
.num{font-family:var(--latin);font-variant-numeric:lining-nums tabular-nums}

.wrap{max-width:var(--maxw);margin-inline:auto;background:var(--paper);
  position:relative}
.wrap>*{position:relative;z-index:1}
/* The sheet gets its own register: a fine geometric dot screen inside the column,
   while the organic microbial field runs behind it in the margins. Two light-grey
   textures, deliberately different, so the content column still reads as a sheet
   laid on a ground rather than dissolving into it. */
.wrap::before{content:"";position:absolute;inset:0;pointer-events:none;z-index:0;
  background:var(--ink);opacity:var(--grid-ink);
  -webkit-mask-image:url(tex/dot-tile.png);mask-image:url(tex/dot-tile.png);
  -webkit-mask-size:24px 24px;mask-size:24px 24px;
  -webkit-mask-repeat:repeat;mask-repeat:repeat}
.cap{font:500 11px/1.4 var(--latin);letter-spacing:.16em;text-transform:uppercase;color:var(--ink-faint)}
.label{font:500 12px/1.4 var(--latin);letter-spacing:.22em;text-transform:uppercase;color:var(--ink-faint)}
.code{font:700 12px/1 var(--latin);color:var(--blue);letter-spacing:.02em}
.frame{block-size:4px;background:var(--ink);transform-origin:inline-start center}
.pad{padding-inline:var(--gutter)}

/* ---------------- masthead ---------------- */
.mast{display:flex;justify-content:space-between;align-items:center;gap:26px;
  padding:18px var(--gutter);border-block-end:1px solid var(--hairline);flex-wrap:wrap}
.mark{color:var(--ink);font-size:19px}
.nav{display:flex;gap:24px;align-items:center;font:500 12.5px var(--latin);color:var(--ink-soft)}
[dir=rtl] .nav{font-family:var(--arabic);--ls:12.5px;font-size:calc(var(--ls) * var(--ar-text))}
.nav a{transition:color .16s ease-out;white-space:nowrap;
  display:inline-flex;align-items:center;min-block-size:24px}
/* plain nav links only: .cta and .locale invert themselves on hover and must
   keep their own colour, or the text matches the fill it sits on. */
.nav a:not(.cta):not(.locale):hover,
.nav a[aria-current=page]{color:var(--blue)}
.locale{border:1px solid var(--ink);padding:5px 14px;transition:background .16s ease-out,color .16s ease-out;white-space:nowrap}
.locale:hover{background:var(--ink);color:var(--on-ink)}
.cta{background:var(--ink);color:var(--on-ink);padding:9px 18px;font:700 12.5px var(--latin);
  transition:background .16s ease-out;white-space:nowrap}
[dir=rtl] .cta{font-family:var(--arabic)}
/* colour must be restated: .nav a:hover turns this blue, and the hover
   background is also blue - together they rendered the CTA at 1.00:1. */
.cta:hover{background:var(--blue);color:var(--on-ink)}

/* ---------------- generic bands ---------------- */
.band-h{display:flex;justify-content:space-between;align-items:baseline;gap:20px;
  padding:26px var(--gutter) 10px;flex-wrap:wrap}
h2{font:700 24px/1.25 var(--latin);letter-spacing:.05em;text-transform:uppercase;color:var(--ink)}
[dir=rtl] h2{font-family:var(--arabic);--ls:24px;text-transform:none;font-size:calc(var(--ls) * var(--ar-display));
  letter-spacing:0;line-height:1.5}
h3{font:700 15px var(--latin);color:var(--ink)}
[dir=rtl] h3{font-family:var(--arabic);--ls:15px;font-size:calc(var(--ls) * var(--ar-text));line-height:1.6}
.rule-heavy{border-block-start:2px solid var(--ink)}

/* ---------------- breadcrumb ---------------- */
.crumb{display:flex;gap:9px;align-items:center;padding:14px var(--gutter);
  border-block-end:1px solid var(--hairline);font:500 11px var(--latin);
  letter-spacing:.14em;text-transform:uppercase;color:var(--ink-faint);flex-wrap:wrap}
[dir=rtl] .crumb{font-family:var(--arabic);letter-spacing:0;font-size:11.5px;text-transform:none}
.crumb a{display:inline-flex;align-items:center;min-block-size:24px}
.crumb a:hover{color:var(--blue)}
.crumb span[aria-current]{color:var(--ink-soft)}

/* ---------------- hero ---------------- */
.hero{display:grid;grid-template-columns:1.3fr 1fr;position:relative;
  border-block-end:1px solid var(--hairline)}
.hero-l{padding:56px var(--gutter) 44px;border-inline-end:1px solid var(--hairline)}
/* Caps display type needs its tracking opened up, not closed: the -0.028em that
   suited mixed case reads cramped in all-caps. */
/* Monument, not shout: scale carries the display, weight stays light (19-86).
   Tracking now matches DESIGN.md 3 (-.02 to -.028em); it shipped at +.005em. */
h1{font:400 76px/1.0 var(--latin);letter-spacing:-.022em;text-transform:uppercase;
  color:var(--ink);margin-block-start:22px;
  /* fluid so a long word ("CLEANLINESS,") can never outgrow its 52% column and
     spill glyphs onto the engraved ground - it did exactly that at 1024px */
  font-size:clamp(46px, 5.3vw, 76px)}
h1 .dot{color:var(--blue)}
[dir=rtl] h1{font-family:var(--arabic);--ls:76px;text-transform:none;font-weight:400;
  font-size:calc(var(--ls) * var(--ar-display));letter-spacing:0;line-height:1.3}
.btns{display:flex;gap:14px;margin-block-start:32px;flex-wrap:wrap}
.btn{font:700 12.5px var(--latin);padding:14px 26px;transition:background .16s ease-out,color .16s ease-out}
[dir=rtl] .btn{font-family:var(--arabic)}
.btn-p{background:var(--ink);color:var(--on-ink)}
.btn-p:hover{background:var(--blue);color:var(--on-ink)}
.btn-s{border:1.5px solid var(--ink);color:var(--ink)}
.btn-s:hover{background:var(--ink);color:var(--on-ink)}
.stats{display:flex;gap:38px;margin-block-start:44px;border-block-start:2px solid var(--ink);
  padding-block-start:16px;flex-wrap:wrap}
.stats b{display:block;font:700 30px/1 var(--latin);color:var(--ink);letter-spacing:-.01em}
.stats i{display:block;font:500 11px/1.4 var(--latin);letter-spacing:.14em;text-transform:uppercase;
  color:var(--ink-faint);font-style:normal;margin-block-start:5px}
[dir=rtl] .stats i{font-family:var(--arabic);letter-spacing:0;text-transform:none;font-size:11px}
.hero-r{background:var(--panel);position:relative;display:flex;align-items:center;
  justify-content:center;min-block-size:520px;padding:40px}
.hero-r img{block-size:400px;inline-size:auto;object-fit:contain;mix-blend-mode:multiply}
.fig-tl{position:absolute;inset-block-start:18px;inset-inline-start:22px}
.fig-br{position:absolute;inset-block-end:18px;inset-inline:22px;display:flex;flex-direction:column;gap:5px}

/* ---------------- range index ---------------- */
.rrow{display:grid;grid-template-columns:52px 1.1fr 2.4fr 74px 24px;gap:20px;
  align-items:center;padding:18px var(--gutter);
  border-block-start:1px solid var(--hairline);transition:background .16s ease-out}
.rrow:hover{background:var(--hover)}
/* A2c — family colour as a GROUND, type reversed out. Never colour on paper. */
.fam-block{inline-size:38px;block-size:38px;display:grid;place-items:center;
  font:700 19px/1 var(--latin);background:var(--fam);color:var(--fam-on)}
.fam-bar{block-size:6px;background:var(--fam)}
.rname{font:700 15px var(--latin);color:var(--ink);letter-spacing:.02em}
[dir=rtl] .rname{font-family:var(--arabic);--ls:15px;font-size:calc(var(--ls) * var(--ar-text));line-height:1.6}
[dir=rtl] .rdesc{color:var(--ink-muted);font-size:12.5px;line-height:1.6}
[dir=rtl] .rdesc{font-family:var(--arabic);--ls:12.5px;font-size:calc(var(--ls) * var(--ar-text));line-height:2}
[dir=rtl] .rcount{font:700 17px var(--latin);color:var(--ink);text-align:end}
.rcount i{display:block;font:500 11px var(--latin);letter-spacing:.14em;color:var(--ink-faint);
  font-style:normal;margin-block-start:2px}
.rarrow{color:var(--ink-faint);font-size:15px;text-align:end;transition:color .16s ease-out}
.rrow:hover .rarrow{color:var(--fam,var(--blue))}
.gov{padding:14px var(--gutter) 26px;border-block-start:1px solid var(--hairline)}
/* a full sentence, so it is set as one: caps + letterspacing destroys word shape
   over this length. It stays subordinate through colour, not through shouting. */
.gov .cap{text-transform:none;letter-spacing:0;font-size:12.5px;line-height:1.7;
  max-inline-size:78ch;display:block}

/* ---------------- product grid ---------------- */
.grid{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));border-block-start:2px solid var(--ink)}
.grid>*{min-inline-size:0}
.grid.g3{grid-template-columns:repeat(3,1fr)}
.card{border-inline-end:1px solid var(--hairline);border-block-end:1px solid var(--hairline);
  display:flex;flex-direction:column;transition:background .16s ease-out}
.card:hover{background:var(--hover)}
.card-in{padding:16px 20px 22px;display:flex;flex-direction:column;flex:1}
/* Specimen frame (stage 1). The render is the content, so it gets the frame and the
   annotations sit on it - DESIGN.md 5 - instead of a header row competing above it.
   Hairline border per 4: panels are flat --cn-panel rectangles with hairline borders. */
.card-fig{background:var(--panel);border:1px solid var(--hairline);position:relative;
  margin-block:14px 16px;block-size:260px;
  display:flex;align-items:center;justify-content:center;padding:26px 16px}
.card-fig img{block-size:100%;inline-size:auto;object-fit:contain;mix-blend-mode:multiply}
.fig-tl{position:absolute;inset-block-start:9px;inset-inline-start:11px;
  font-size:11px;letter-spacing:.14em;line-height:1.3;max-inline-size:calc(100% - 22px)}
.fig-brc{position:absolute;inset-block-end:9px;inset-inline-end:11px;line-height:1}
[dir=rtl] .fig-tl{font-family:var(--latin)}
.card-name{font:700 15px var(--latin);color:var(--ink)}
[dir=rtl] .card-name{font-family:var(--arabic);--ls:15px;font-size:calc(var(--ls) * var(--ar-text));line-height:1.6}
[dir=rtl] .card-desc{font-size:11.5px;line-height:1.55;color:var(--ink-muted);margin-block-start:8px;flex:1}
[dir=rtl] .card-desc{--ls:11.5px;font-size:calc(var(--ls) * var(--ar-text) * 1.08);line-height:1.9}
.spec{margin:14px 0 0;border-block-start:1px solid var(--hairline);padding-block-start:10px}
.spec>div{display:flex;align-items:baseline;gap:6px;margin-block-start:5px}
.spec dt{font:500 11px var(--latin);letter-spacing:.12em;text-transform:uppercase;
  color:var(--ink-faint);white-space:nowrap}
[dir=rtl] .spec dt{font-family:var(--arabic);letter-spacing:0;text-transform:none;font-size:11px}
.lead{flex:1;border-block-end:1px dotted var(--dots);transform:translateY(-3px)}
.spec dd{margin:0;font:700 11.5px var(--latin);color:var(--ink);white-space:nowrap}

/* ---------------- range page header ---------------- */
.rhead{display:grid;grid-template-columns:auto 1fr;gap:34px;align-items:start;
  padding:44px var(--gutter);border-block-end:1px solid var(--hairline)}
.rhead .letter{inline-size:230px;block-size:230px;display:grid;place-items:center;
  background:var(--fam);color:var(--fam-on);font:700 158px/1 var(--latin);
  letter-spacing:-.03em}
.rhead h1{font-size:52px;font-weight:500;margin-block-start:0}
[dir=rtl] .rhead h1{--ls:48px}
.rhead p{color:var(--ink-muted);max-inline-size:56ch;margin-block-start:14px}

/* ---------------- filters ---------------- */
.filters{display:flex;gap:8px;flex-wrap:wrap;padding:20px var(--gutter);
  border-block-end:1px solid var(--hairline)}
.chip{font:500 11.5px var(--latin);padding:8px 15px;min-block-size:32px;border:1px solid var(--hairline);
  color:var(--ink-soft);cursor:pointer;background:none;
  transition:border-color .16s ease-out,background .16s ease-out,color .16s ease-out}
[dir=rtl] .chip{font-family:var(--arabic)}
.chip:hover{border-color:var(--ink)}
.chip[aria-pressed=true]{background:var(--ink);color:var(--on-ink);border-color:var(--ink)}
.empty{padding:44px var(--gutter);color:var(--ink-muted)}

/* ---------------- product detail ---------------- */
.pdet{display:grid;grid-template-columns:1fr 1.05fr;border-block-end:1px solid var(--hairline)}
/* Product subtitle. Was a 35-character all-caps label; at that length caps costs
   more in word shape than it gains in hierarchy, so it is set as a subtitle and
   held back by colour and weight instead. */
.psub{margin-block-start:10px;font:400 15.5px/1.5 var(--latin);color:var(--ink-muted)}
[dir=rtl] .psub{font-family:var(--arabic);--ls:15.5px;
  font-size:calc(var(--ls) * var(--ar-text));line-height:1.85}
.pfig{background:var(--panel);position:relative;display:flex;align-items:center;
  justify-content:center;min-block-size:520px;padding:44px;border-inline-end:1px solid var(--hairline)}
.pfig img{block-size:400px;inline-size:auto;object-fit:contain;mix-blend-mode:multiply}
.pinfo{padding:44px var(--gutter)}
.pinfo h1{font-size:50px;font-weight:500;margin-block-start:10px;line-height:1.06}
[dir=rtl] .pinfo h1{--ls:42px}
.pinfo .desc{margin-block-start:18px;max-inline-size:52ch;color:var(--ink-soft)}
[dir=rtl] .pinfo .desc{font-family:var(--arabic);--ls:13.5px;
  font-size:calc(var(--ls) * var(--ar-text) * 1.05);line-height:2.1}
.stable{border-block-start:2px solid var(--ink);padding:26px var(--gutter) 30px}
.srow{display:flex;align-items:baseline;gap:10px;padding-block:9px;
  border-block-end:1px solid var(--hairline)}
.srow .k{font:500 11px var(--latin);letter-spacing:.14em;text-transform:uppercase;color:var(--ink-faint)}
.srow .v{font:700 13px var(--latin);color:var(--ink);white-space:nowrap}
.srow .v.absent{font-weight:500;color:var(--ink-faint);font-style:italic}
.packs{display:flex;gap:8px;flex-wrap:wrap;margin-block-start:18px}
.pack{border:1px solid var(--hairline);padding:9px 14px;font:500 11.5px var(--latin);color:var(--ink-soft)}
.pack b{font-weight:700;color:var(--ink)}
.dl-btns{display:flex;gap:12px;flex-wrap:wrap;margin-block-start:24px}
.btn-dis{opacity:.42;cursor:not-allowed}

.prog{padding:30px var(--gutter) 36px;border-block-start:2px solid var(--ink)}
.prog-steps{display:grid;grid-template-columns:repeat(3,1fr);gap:0;margin-block-start:18px}
.prog-step{border-block-start:2px solid var(--ink);padding:16px 26px 8px 0;padding-inline:0 26px}
.prog-step b{display:block;font:700 22px/1 var(--latin);color:var(--ink)}
.prog-step .t{display:block;font:500 11px var(--latin);letter-spacing:.16em;text-transform:uppercase;
  color:var(--ink-faint);margin-block-start:9px}
[dir=rtl] .prog-step .t{font-family:var(--arabic);letter-spacing:0;text-transform:none;font-size:11.5px}
.prog-step .v{display:block;margin-block-start:6px;color:var(--ink-soft);font-size:13px}
.prog-step .v.absent{color:var(--ink-faint);font-style:italic}

/* ---------------- content pages ---------------- */
.two{display:grid;grid-template-columns:1fr 1.15fr;border-block-start:2px solid var(--ink);
  border-block-end:1px solid var(--hairline)}
.two-l{padding:44px var(--gutter);border-inline-end:1px solid var(--hairline)}
.two-l p{color:var(--ink-muted);max-inline-size:46ch;margin-block-start:14px}
.q{background:var(--ink);color:var(--on-ink);padding:56px var(--gutter)}
.q h2{color:var(--on-ink)}
.q .label{color:var(--muted-on-ink)}
.q-body{display:grid;grid-template-columns:1fr 1fr;gap:44px;margin-block-start:26px}
.q-body p{color:var(--muted-on-ink);margin:0 0 16px;max-inline-size:52ch}
.q-body p.lead-p{color:var(--on-ink)}
[dir=rtl] .q-body p{font-family:var(--arabic);--ls:13.5px;font-size:calc(var(--ls) * var(--ar-text) * 1.05);line-height:2.1}
.q-stats{display:flex;gap:38px;margin-block-start:36px;border-block-start:1px solid var(--rule-on-ink);
  padding-block-start:18px;flex-wrap:wrap}
.q-stats b{display:block;font:700 26px/1 var(--latin);color:var(--on-ink)}
.q-stats i{display:block;font:500 11px var(--latin);letter-spacing:.14em;text-transform:uppercase;
  color:var(--muted-on-ink);font-style:normal;margin-block-start:5px}
[dir=rtl] .q-stats i{font-family:var(--arabic);letter-spacing:0;text-transform:none;font-size:11px}

.dlrow{display:flex;align-items:baseline;gap:14px;padding:18px var(--gutter);
  border-block-end:1px solid var(--hairline);transition:background .16s ease-out}
.dlrow:hover{background:var(--hover)}
/* status, not a link: no pointer, no arrow, no promise of a file */
.dlrow-pending{cursor:default}
.dlrow-pending:hover{background:transparent}
.dlrow-pending .meta{color:var(--ink-faint);font-style:italic}
.dlrow b{font:700 14px var(--latin);color:var(--ink);white-space:nowrap}
[dir=rtl] .dlrow b{font-family:var(--arabic)}
.dlrow .meta{font-size:11.5px;color:var(--ink-muted);white-space:nowrap}
.dlrow .arw{color:var(--ink-faint);transition:color .16s ease-out}
.dlrow:hover .arw{color:var(--blue)}

/* ---------------- form ---------------- */
.form{display:grid;grid-template-columns:1fr 1fr;gap:0 34px;max-inline-size:760px}
.field{display:flex;flex-direction:column;gap:7px;margin-block-end:20px}
.field.full{grid-column:1/-1}
.field label{font:500 11px var(--latin);letter-spacing:.16em;text-transform:uppercase;color:var(--ink-faint)}
[dir=rtl] .field label{font-family:var(--arabic);letter-spacing:0;text-transform:none;font-size:11.5px}
.field input,.field textarea,.field select{font:400 13.5px var(--latin);color:var(--ink);
  background:var(--paper);border:1px solid var(--hairline);padding:11px 13px;border-radius:0;
  transition:border-color .16s ease-out}
[dir=rtl] .field input,[dir=rtl] .field textarea,[dir=rtl] .field select{font-family:var(--arabic)}
.field input:hover,.field textarea:hover,.field select:hover{border-color:var(--ink-faint)}
.field input:focus,.field textarea:focus,.field select:focus{border-color:var(--ink);outline:none}
.field textarea{min-block-size:120px;resize:vertical}
.field .hint{font-size:11px;color:var(--ink-faint)}
.field[data-invalid] input,.field[data-invalid] textarea{border-color:var(--alert)}
.field[data-invalid] .hint{color:var(--alert)}

/* ---------------- footer ---------------- */
footer{background:var(--ink);color:var(--muted-on-ink);padding:40px var(--gutter) 34px}
.f-top{display:flex;justify-content:space-between;align-items:flex-start;gap:30px;flex-wrap:wrap}
.f-mark{color:var(--on-ink);font-size:17px}
.f-nav{display:flex;gap:22px;font:500 11px var(--latin);letter-spacing:.14em;text-transform:uppercase;flex-wrap:wrap}
[dir=rtl] .f-nav{font-family:var(--arabic);letter-spacing:0;text-transform:none;font-size:11.5px}
.f-nav a{transition:color .16s ease-out;display:inline-flex;align-items:center;min-block-size:24px}
.f-nav a:hover{color:var(--on-ink)}
.f-bot{margin-block-start:30px;border-block-start:1px solid var(--rule-on-ink);padding-block-start:16px;
  display:flex;justify-content:space-between;gap:20px;flex-wrap:wrap;
  font:500 12px var(--latin);letter-spacing:.01em}
[dir=rtl] .f-bot{font-family:var(--arabic);letter-spacing:0;text-transform:none;font-size:11px}

/* ---------------- notice (mock-state honesty) ---------------- */
.notice{padding:20px var(--gutter);border-block-start:1px solid var(--hairline);background:var(--panel)}
.notice p{margin:0;font-size:11.5px;color:var(--ink-muted);max-inline-size:80ch}
[dir=rtl] .notice p{font-family:var(--arabic);--ls:11.5px;font-size:calc(var(--ls) * var(--ar-text) * 1.08);line-height:1.9}

/* ---------------- motion ---------------- */
/* Scoped to .js-motion, which site.js adds. If the script fails to parse or run,
   content stays visible instead of the page appearing blank. */
.js-motion .reveal{opacity:0;transform:translateY(12px)}
.reveal.in{opacity:1;transform:none;transition:opacity .3s ease-out,transform .3s ease-out}
@keyframes rule-in{from{transform:scaleX(0)}to{transform:scaleX(1)}}
.frame{animation:rule-in .7s cubic-bezier(.2,.7,.2,1) both}
.frame.b{animation-delay:.1s}
@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{animation:none!important;transition:none!important}
  .reveal{opacity:1;transform:none}
}

/* ---------------- responsive ---------------- */
@media (max-width:1080px){
  .grid,.grid.g3{grid-template-columns:repeat(2,1fr)}
  .rrow{grid-template-columns:44px 1fr 64px 22px}
  .rdesc,  .prog-steps{grid-template-columns:1fr}
  .prog-step{padding-inline:0}
}
@media (max-width:680px){
  .mast{flex-direction:column;align-items:stretch;gap:14px}
  .nav{flex-wrap:wrap;gap:12px 18px;row-gap:12px}
  .nav .locale{margin-inline-start:auto}
  .nav .cta{inline-size:100%;text-align:center}
}
@media (max-width:820px){
  /* Arabic values like "حسب صحيفة البيانات" cannot fit one line in a 2-up card here. */
  .spec dd,.spec dt{white-space:normal}
  .srow .v{white-space:normal}
  :root{--gutter:22px}
  .hero,.pdet,.two,.q-body,.form{grid-template-columns:1fr}
  .hero-l,.two-l,.pfig{border-inline-end:0;border-block-end:1px solid var(--hairline)}
  h1{font-size:46px}
  .pinfo h1,.rhead h1{font-size:30px}
  .hero-r,.pfig{min-block-size:360px}
  .hero-r img,.pfig img{block-size:270px}
  .grid,.grid.g3{grid-template-columns:1fr}
  .rhead{grid-template-columns:1fr;gap:20px}
  .rhead .letter{inline-size:132px;block-size:132px;font-size:88px}
  .nav{gap:14px;font-size:11.5px}
  .stats,.q-stats{gap:24px}
}


/* ============================================================
   v2 — items 1, 3, 4, 5, 6, 8
   ============================================================ */

.lede{color:var(--ink-muted);max-inline-size:52ch;margin:14px 0 0;font-size:14px}
[dir=rtl] .lede{--ls:14px;font-size:calc(var(--ls) * var(--ar-text) * 1.08);line-height:2}

/* ---- item 1: the plate. The whole range at equal weight; no hero product ---- */
/* min-inline-size:0 everywhere a grid/flex child holds a grid — without it the
   plate cells' intrinsic width blows the hero track out to ~2700px. */
.hero>*{min-inline-size:0}
/* The one band where the microbial field is allowed to read: images only, no
   small text, so no contrast budget to spend. */
.plate{position:relative;overflow:hidden}
.plate>*{position:relative;z-index:1}
.plate::before{content:"";position:absolute;inset:0;pointer-events:none;
  background:var(--ink);opacity:.20;
  -webkit-mask-image:url(tex/micro-colony.png);mask-image:url(tex/micro-colony.png);
  -webkit-mask-size:cover;mask-size:cover;
  -webkit-mask-position:center;mask-position:center;
  -webkit-mask-repeat:no-repeat;mask-repeat:no-repeat}
.plate{background:var(--panel);padding:26px 30px;display:flex;flex-direction:column;
  min-block-size:520px;min-inline-size:0;transition:background .16s ease-out}
.plate:hover{background:#EEEAE0}
.plate-h{margin-block-end:16px}
.plate-f{margin-block-start:16px;text-align:end}
.plate-grid{flex:1;min-inline-size:0;display:grid;grid-template-columns:repeat(6,minmax(0,1fr));
  gap:6px;align-content:center}
.plate-cell{aspect-ratio:1;min-inline-size:0;overflow:hidden;display:grid;place-items:center;padding:3px;
  transition:background .16s ease-out}
.plate-cell:hover{background:var(--paper)}
.plate-cell img{max-block-size:100%;max-inline-size:100%;inline-size:auto;
  object-fit:contain;mix-blend-mode:multiply}

/* ---- items 3-6: control bar ---- */
.controls{display:flex;flex-wrap:wrap;gap:18px 30px;align-items:flex-start;
  padding:18px var(--gutter);border-block:1px solid var(--hairline);background:var(--paper)}
.cgroup{display:flex;align-items:baseline;gap:12px;flex-wrap:wrap}
.clab{font:500 11px var(--latin);letter-spacing:.16em;text-transform:uppercase;
  color:var(--ink-faint);white-space:nowrap}
[dir=rtl] .clab{font-family:var(--arabic);letter-spacing:0;text-transform:none;font-size:11px}
.chips{display:flex;gap:6px;flex-wrap:wrap}
.cgroup-view{margin-inline-start:auto}
.cgroup-count{display:flex;align-items:center;gap:12px}
.count{font:500 11px var(--latin);color:var(--ink-muted);white-space:nowrap}
.chip-reset{border-style:dashed}

/* ---- item 4: density ---- */
.grid[data-cols="3"]{grid-template-columns:repeat(3,minmax(0,1fr))}
.grid[data-cols="4"]{grid-template-columns:repeat(4,minmax(0,1fr))}
.grid[data-cols="5"]{grid-template-columns:repeat(5,minmax(0,1fr))}
.grid[data-cols="3"] .card-fig{block-size:360px}
.grid[data-cols="4"] .card-fig{block-size:290px}
.grid[data-cols="5"] .card-fig{block-size:225px}
.grid[data-cols="3"] .card-name{font-size:17px}

/* ---- item 3: list view ---- */
.grid[data-view="list"]{display:block;border-block-start:2px solid var(--ink)}
.grid[data-view="list"] .card{border-inline-end:0;flex-direction:row;align-items:stretch}
.grid[data-view="list"] .fam-bar{block-size:auto;inline-size:6px;flex:0 0 6px}
.grid[data-view="list"] .card-in{flex-direction:row;align-items:center;gap:24px;
  padding-block:14px;flex:1}
/* Explicit px, never a percentage: block-size:100% here resolved against the grid
   area instead of the 72px box and let the intrinsic aspect ratio push the thumbnail
   to 109px, overlapping the next row. */
.grid[data-view="list"] .card-fig{position:relative;display:flex;align-items:center;
  margin:0;block-size:72px;inline-size:178px;flex:0 0 178px;
  padding:6px;padding-inline-start:96px;border:0;background:none}
.grid[data-view="list"] .card-fig img{block-size:60px;inline-size:auto;
  max-inline-size:76px;object-fit:contain}
.grid[data-view="list"] .fig-tl,.grid[data-view="list"] .fig-brc{position:absolute;
  inset-inline-start:0;inset-inline-end:auto;text-align:start;max-inline-size:90px}
/* longest category ("FLOOR PROGRAMME - HEAVY TRAFFIC") wrapped to three lines and
   ran into the code anchored below it; two lines is all the 72px row affords. */
.grid[data-view="list"] .fig-tl{inset-block-start:5px;display:-webkit-box;
  -webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;
  line-height:1.25;max-block-size:2.5em}
.grid[data-view="list"] .fig-brc{inset-block-end:5px}
.grid[data-view="list"] .card-name{flex:0 0 26%;font-size:15px}
.grid[data-view="list"] .card-desc{flex:1;margin:0;font-size:12px}
.grid[data-view="list"] .spec{margin:0;border-block-start:0;padding-block-start:0;
  flex:0 0 210px;display:flex;flex-direction:column;gap:2px}
.grid[data-view="list"] .spec>div{margin-block-start:0}
.grid[data-view="list"] .lead{min-inline-size:14px}


.rhead{position:relative;display:block;padding:0;overflow:hidden}
.rhead-in{position:relative;display:grid;grid-template-columns:auto 1fr;gap:34px;
  align-items:start;padding:44px var(--gutter)}
.rhead .letter{inline-size:150px;block-size:150px;display:grid;place-items:center;
  background:var(--fam);color:var(--fam-on);font:700 96px/1 var(--latin)}
.pfig{position:relative;overflow:hidden}
.pfig img,.pfig .cap,.pfig .fig-br{position:relative;z-index:1}

/* ---- industries: four family tiles, replacing the single terrazzo ---- */
.ind-grid{display:grid;grid-template-columns:1fr 1fr}
.ind-tile{--tile:color-mix(in srgb, var(--fam) var(--wash-mix), var(--paper));position:relative;min-block-size:210px;display:grid;place-items:center;gap:10px;
  align-content:center;overflow:hidden;
  border-inline-start:1px solid var(--hairline);border-block-end:1px solid var(--hairline)}
.ind-tile>*{position:relative;z-index:1}
.ind-n{font:700 15px var(--latin);color:var(--ink);letter-spacing:.06em}
[dir=rtl] .ind-n{font-family:var(--arabic);--ls:15px;
  font-size:calc(var(--ls) * var(--ar-text));letter-spacing:0}

@media (max-width:1080px){
  .plate-grid{grid-template-columns:repeat(5,minmax(0,1fr))}
  .grid[data-cols="5"],.grid[data-cols="4"]{grid-template-columns:repeat(3,1fr)}
  .grid[data-cols="5"] .card-fig,.grid[data-cols="4"] .card-fig{block-size:265px}
  .cgroup-view{margin-inline-start:0}
  .grid[data-view="list"] .card-desc,.grid[data-view="list"] .spec{display:none}
}
@media (max-width:820px){
  .plate{min-block-size:340px;padding:18px 20px}
  .plate-grid{grid-template-columns:repeat(6,minmax(0,1fr));gap:4px}
  .grid[data-cols="3"],.grid[data-cols="4"],.grid[data-cols="5"]{grid-template-columns:repeat(2,1fr)}
  .grid[data-cols="3"] .card-fig,.grid[data-cols="4"] .card-fig,
  .grid[data-cols="5"] .card-fig{block-size:190px}
  .rhead-in{grid-template-columns:1fr;gap:20px}
  .rhead .letter{inline-size:96px;block-size:96px;font-size:60px}
  .grid[data-view="list"] .card-name{flex:1}
  .grid[data-view="list"] .card-fig{flex:0 0 156px;inline-size:156px;padding-inline-start:74px}
  .grid[data-view="list"] .fig-tl,.grid[data-view="list"] .fig-brc{max-inline-size:70px}
}


/* ============================================================
   v3 — Ahmed's review of 2026-08-22
   ============================================================ */

/* ---- item 1: textures retired. Flat family colour fields instead. ---- */
/* Family-derived ground. Solid. The product render sits on it under
   mix-blend-mode:multiply, so its white seamless picks up the same tint. */
.field{position:absolute;inset:0;
  background:color-mix(in srgb, var(--fam) var(--wash-mix), var(--paper))}
.field-fig{background:color-mix(in srgb, var(--fam) var(--wash-mix), var(--panel))}

/* ---- item 4: the wordmark. Cleanova blue; one measured draw, then rest. ----
   The dash animation is scoped to .wm-ready, which site.js adds only AFTER it has
   set pathLength="1" on every stroke. Without that gate the paths would flash at
   their real lengths before normalising. */
/* These two tokens ARE the mark's colour. Without a :root definition,
   var(--cn-mark) is invalid and the stroke silently inherits body ink
   instead of falling back to blue. */
:root{--cn-mark:#2C5FBF;--cn-mark-lit:#9CC0F5}
.mark{color:var(--cn-mark)}
.mark svg{overflow:visible}
/* The RESTING state is drawn (dashoffset defaults to 0). The animation only ever
   moves away from that and back. If it is throttled, blocked or never fires, the
   mark is simply there — a logo must never depend on an animation completing. */
.mark svg.wm-ready path{
  stroke-dasharray:1;
  animation:wm-draw .52s cubic-bezier(.25,.8,.3,1) forwards}
@keyframes wm-draw{from{stroke-dashoffset:1}to{stroke-dashoffset:0}}
.mark svg.wm-static path{stroke-dasharray:none;stroke-dashoffset:0}
.f-mark{--cn-mark:#F9F8F4;--cn-mark-lit:#FFFFFF}
a:hover>.mark{--cn-mark:var(--ink)}
footer a:hover>.f-mark{--cn-mark:#FFFFFF}
@media (prefers-reduced-motion:reduce){
  .mark svg path{stroke-dasharray:none!important;stroke-dashoffset:0!important;animation:none!important}
}

/* ---- item 7: landing page ---- */
/* Stage 3: the landing hero had no imagery above the fold at all - the right half
   was bare paper. It now carries a water-ripple engraving as a ground. inset-inline-end
   flips under dir=rtl, so the Arabic page mirrors it without a second rule. */
.lead-band{padding:64px var(--gutter) 0;border-block-end:1px solid var(--hairline);
  position:relative;overflow:hidden}
.lead-band::after{content:"";position:absolute;inset-block:0;inset-inline-end:0;
  inline-size:46%;pointer-events:none;background:var(--ink);opacity:var(--tex-ink);
  -webkit-mask-image:url(tex/water-ripples.png);mask-image:url(tex/water-ripples.png);
  -webkit-mask-size:cover;mask-size:cover;
  -webkit-mask-position:center;mask-position:center;
  -webkit-mask-repeat:no-repeat;mask-repeat:no-repeat}
.lead-in{max-inline-size:52%;position:relative;z-index:1}

/* Reusable engraved ground. Any band can take one by adding data-tex="<piece>". */
.tex-ground{position:relative;overflow:hidden}
.tex-ground>*{position:relative;z-index:1}
.tex-ground::before{content:"";position:absolute;inset:0;pointer-events:none;
  background:var(--ink);opacity:var(--tex-ink);
  -webkit-mask-size:cover;mask-size:cover;
  -webkit-mask-position:center;mask-position:center;
  -webkit-mask-repeat:no-repeat;mask-repeat:no-repeat}
[data-tex="glass-sheen"]::before{-webkit-mask-image:url(tex/glass-sheen.png);mask-image:url(tex/glass-sheen.png)}
[data-tex="drain-chevrons"]::before{-webkit-mask-image:url(tex/drain-chevrons.png);mask-image:url(tex/drain-chevrons.png)}
[data-tex="steel-brushed"]::before{-webkit-mask-image:url(tex/steel-brushed.png);mask-image:url(tex/steel-brushed.png)}
[data-tex="marble-veins"]::before{-webkit-mask-image:url(tex/marble-veins.png);mask-image:url(tex/marble-veins.png)}
[data-tex="micro-colony"]::before{-webkit-mask-image:url(tex/micro-colony.png);mask-image:url(tex/micro-colony.png)}
[data-tex="dot-grid"]::before{-webkit-mask-image:url(tex/dot-grid.png);mask-image:url(tex/dot-grid.png)}
.lede-lg{font-size:16px;max-inline-size:62ch;line-height:1.75;color:var(--ink-soft)}
[dir=rtl] .lede-lg{--ls:16px;font-size:calc(var(--ls) * var(--ar-text) * 1.06);line-height:2.05}
.stats-band{margin-block:44px 0;padding-block:18px 30px;border-block-start:2px solid var(--ink)}

/* the four systems as the image */
.board{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));
  border-block-start:2px solid var(--ink)}
.board-tile{--tile:color-mix(in srgb, var(--fam) var(--wash-mix), var(--paper));position:relative;display:flex;flex-direction:column;gap:10px;
  padding:26px 24px 24px;min-block-size:300px;
  border-inline-end:1px solid var(--hairline);
  background:var(--tile);transition:background .2s ease-out}
.board-tile:last-child{border-inline-end:0}
.board-tile:hover{background:color-mix(in srgb, var(--fam) var(--wash-hover), var(--paper))}
/* Stage 2: the index letter is the image. Bleeds to the tile edges so the family
   colour reads as a ground with the letter reversed out (§2), at the oversized
   index-letter scale §5 specifies. */
.board-l{margin:-26px -24px 6px;inline-size:auto;block-size:138px;
  display:grid;place-items:center;
  background:var(--fam);color:var(--fam-on);
  font:700 104px/1 var(--latin);letter-spacing:-.03em}
.board-n{font:700 17px var(--latin);color:var(--ink);letter-spacing:.06em}
[dir=rtl] .board-n{font-family:var(--arabic);--ls:17px;
  font-size:calc(var(--ls) * var(--ar-text));letter-spacing:0}
.board-d{font-size:12.5px;line-height:1.65;color:var(--ink-muted);flex:1}
[dir=rtl] .board-d{--ls:12.5px;font-size:calc(var(--ls) * var(--ar-text) * 1.06);line-height:1.95}
.board-c{font:500 11px var(--latin);color:var(--ink-faint);
  letter-spacing:.14em;text-transform:uppercase}
.board-c b{font:700 15px var(--latin);color:var(--ink);margin-inline-end:6px}
[dir=rtl] .board-c{font-family:var(--arabic);letter-spacing:0;text-transform:none;font-size:11.5px}

/* the complete range, one size for all */
.plate-band{padding:0 var(--gutter) 34px}
.plate-grid{display:grid;grid-template-columns:repeat(12,minmax(0,1fr));gap:2px}
.plate-cell{aspect-ratio:3/4;min-inline-size:0;overflow:hidden;display:block;
  background:var(--panel);transition:background .16s ease-out}
.plate-cell:hover{background:var(--hover)}
.plate-cell img{inline-size:100%;block-size:100%;object-fit:contain;
  mix-blend-mode:multiply;display:block}

/* industries tiles now carry text, not texture */
.ind-grid{display:grid;grid-template-columns:1fr 1fr}
.ind-tile{position:relative;display:flex;flex-direction:column;gap:9px;
  align-items:flex-start;justify-content:flex-end;padding:24px;min-block-size:190px;
  border-inline-start:1px solid var(--hairline);border-block-end:1px solid var(--hairline);
  background:var(--tile);transition:background .2s ease-out}
.ind-tile:hover{background:color-mix(in srgb, var(--fam) var(--wash-hover), var(--paper))}
/* 20px, not 17: at 17px bold this is "normal" text to WCAG and Foamex green
   (4.12:1 reversed) would fail AA. At >=18.66px bold it is large text, 3:1. */
.ind-l{inline-size:38px;block-size:38px;display:grid;place-items:center;
  background:var(--fam);color:var(--fam-on);font:700 20px/1 var(--latin)}
.ind-d{font-size:12px;line-height:1.6;color:var(--ink-muted)}
[dir=rtl] .ind-d{--ls:12px;font-size:calc(var(--ls) * var(--ar-text) * 1.06);line-height:1.9}
.ind-c{font:700 14px var(--latin);color:var(--ink)}

/* range header + product figure sit on the colour field */
.rhead-in,.rhead-in *{position:relative;z-index:1}

/* control bar: label sits with its chips */
.filters .clab{align-self:center;margin-inline-end:4px}

@media (max-width:1080px){
  .board{grid-template-columns:repeat(2,minmax(0,1fr))}
  .board-l{block-size:112px;font-size:82px}
  .board-tile:nth-child(2n){border-inline-end:0}
  .board-tile:nth-child(-n+2){border-block-end:1px solid var(--hairline)}
  .plate-grid{grid-template-columns:repeat(9,minmax(0,1fr))}
}
@media (max-width:820px){
  /* the ground gets its own reserved band under the copy - never behind it */
  .lead-band{padding-block-start:40px;padding-block-end:196px}
  .lead-in{max-inline-size:none}
  .lead-band::after{inline-size:100%;inset-block-start:auto;block-size:180px;
    -webkit-mask-position:center bottom;mask-position:center bottom}
  .board{grid-template-columns:1fr}
  .board-l{block-size:92px;font-size:64px}
  .board-tile{border-inline-end:0;border-block-end:1px solid var(--hairline);min-block-size:0}
  .plate-grid{grid-template-columns:repeat(6,minmax(0,1fr))}
  .ind-grid{grid-template-columns:1fr}
  .lede-lg{font-size:15px}
}


/* Faint is calibrated for paper. On any family-washed ground it drops below AA,
   so captions and labels there step to muted. This is the only reason the wash
   can be 10% instead of 5%. */
.field ~ * .cap, .rhead .cap, .rhead .label,
.board-tile .board-c, .ind-tile .cap, .pfig .cap{color:var(--ink-muted)}
.board-tile .board-d,.ind-tile .ind-d{color:var(--ink-soft)}
/* Fourth tonal step gives the plate its own ground, so the range index, the plate
   and the find-by band read as three planes rather than one flat sheet. */
.plate-band{background:var(--deep);padding-block:26px}
.plate-cell{background:var(--paper)}
.plate-cell:hover{background:#fff}
