/* Winkem Labs design system. Bond direction. Light only.
   Written mobile first: every base rule is the phone layout, and each
   min-width block adds to it. Nothing is authored for desktop then squeezed down.
   Breakpoints: 520 / 600 / 760 / 860 / 900 / 1040 / 1200. */


/* ---------- the typefaces ----------
   Three faces, self hosted. Inter for text, Archivo for headings and IBM Plex Mono
   for the small caps labels: the two the design samples are set in.
   Nothing here is decoration. The stylesheet has named Inter since the first commit
   and for most of this rebuild no face was actually loaded at all, so every heading
   rendered in whatever the operating system uses for its own interface and every
   small caps label in whatever it calls monospace. That is a different width, weight
   and colour on every machine, and it is why the new sections did not match the
   samples they were drawn from. */
@font-face{font-family:Inter;font-style:normal;font-weight:400 800;font-display:swap;
  src:url(../fonts/inter-latin.woff2) format('woff2');
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,
    U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}
@font-face{font-family:Inter;font-style:normal;font-weight:400 800;font-display:swap;
  src:url(../fonts/inter-latin-ext.woff2) format('woff2');
  unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,
    U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,
    U+2113,U+2C60-2C7F,U+A720-A7FF}
@font-face{font-family:Archivo;font-style:normal;font-weight:400 800;font-display:swap;
  src:url(../fonts/archivo-latin.woff2) format('woff2');
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,
    U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}
@font-face{font-family:Archivo;font-style:normal;font-weight:400 800;font-display:swap;
  src:url(../fonts/archivo-latin-ext.woff2) format('woff2');
  unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,
    U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,
    U+2113,U+2C60-2C7F,U+A720-A7FF}
@font-face{font-family:"IBM Plex Mono";font-style:normal;font-weight:400;font-display:swap;
  src:url(../fonts/plexmono-400.woff2) format('woff2')}
@font-face{font-family:"IBM Plex Mono";font-style:normal;font-weight:500;font-display:swap;
  src:url(../fonts/plexmono-500.woff2) format('woff2')}
@font-face{font-family:"IBM Plex Mono";font-style:normal;font-weight:600;font-display:swap;
  src:url(../fonts/plexmono-600.woff2) format('woff2')}

*,*::before,*::after{box-sizing:border-box}
:root{
  /* The original palette, including orange text. Client decision, taken twice.
     Note for whoever picks this up: #F17E01 measures 2.72 against white, so
     orange text and white-on-orange fills do not meet WCAG AA at any size.
     --orange-ink exists so that is one line to change, not a hunt through the
     file. Setting it to #AE5A01 restores AA everywhere and nothing else moves. */
  --indigo:#3C2A98; --indigo-d:#241963; --indigo-s:#6E5DD6; --indigo-w:#EFECFB;
  --orange:#F17E01; --orange-ink:#F17E01; --orange-w:#FFF4E6;
  --ink:#171533; --body:#585679; --faint:#6F6C8E;
  --paper:#FFFFFF; --tint:#F7F5FD; --tint2:#FFF6EC; --line:#E5E1F3;
  /* The display face, at the top rather than inside one section's block. It was
     declared only inside the rule for sections 8 and 9, so .sectors h2 asked for
     a variable that did not exist where it was used and quietly stayed on the
     body face, and every inner page kept its headings in Inter while the newest
     sections of the home page were set in Archivo. */
  --disp:Archivo,var(--sans);
  --ok:#1B7A4C;
  --sans:Inter,-apple-system,BlinkMacSystemFont,"Segoe UI",Helvetica,Arial,sans-serif;
  --mono:ui-monospace,"SF Mono",Menlo,Consolas,monospace;
  --r:14px; --rs:8px;            /* rounded rectangles, not pills */
  /* Named spacing scale, multiples of 4. Nothing should use a loose px value. */
  --space-3xs:4px;  --space-2xs:6px;  --space-xs:8px;   --space-s:12px;
  --space-m:16px;   --space-l:20px;   --space-xl:24px;  --space-2xl:32px;
  --space-3xl:40px; --space-4xl:56px; --space-5xl:80px;
  --tap:44px;                    /* minimum comfortable touch target */
  --pad:20px;
  --shadow:0 20px 46px -26px rgba(23,21,51,.4);
}
html{scroll-behavior:smooth;scroll-padding-top:calc(var(--barh) + 10px)}
/* clip rather than hidden: clip does not create a scroll container, so the
   sticky header keeps working. Both elements need it. */
html,body{overflow-x:clip}
body{margin:0;background:var(--paper);color:var(--ink);font-family:var(--sans);
  font-size:16px;line-height:1.6;-webkit-font-smoothing:antialiased}
img{max-width:100%;display:block}
a{color:inherit;text-decoration:none}
button,input,select,textarea{font-family:inherit}
:focus-visible{outline:2px solid var(--indigo);outline-offset:2px;border-radius:3px}
.chip:focus-visible,.fc:focus-visible,.viewtog button:focus-visible{outline-offset:1px}
/* The container runs nearly the full viewport. Structure, grids and imagery
   want the width; running prose does not, so text blocks carry their own
   character caps rather than stretching to 150 characters a line. */
.wrap{max-width:1760px;margin:0 auto;padding:0 var(--pad)}
.mono{font-family:var(--mono);font-variant-numeric:tabular-nums}
.sr{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}
@media(min-width:600px){:root{--pad:24px}}
@media(min-width:1040px){:root{--pad:26px} body{font-size:16.5px}}
/* ascending order matters: these have equal specificity, so a later rule wins */
@media(min-width:1400px){:root{--pad:40px}}
@media(min-width:1800px){:root{--pad:56px}}

/* ---------- scroll reveal ---------- */
.rv{opacity:0;transform:translateY(18px);
  transition:opacity .7s cubic-bezier(.2,.7,.3,1),transform .7s cubic-bezier(.2,.7,.3,1)}
.rv.in{opacity:1;transform:none}
.rv-d1{transition-delay:.07s}.rv-d2{transition-delay:.14s}.rv-d3{transition-delay:.21s}
.rv-d4{transition-delay:.28s}.rv-d5{transition-delay:.35s}.rv-d6{transition-delay:.42s}
@media(min-width:860px){.rv{transform:translateY(22px)}}
@media(prefers-reduced-motion:reduce){
  html{scroll-behavior:auto}
  .rv{opacity:1;transform:none;transition:none}
  *{animation-duration:.01ms!important;transition-duration:.01ms!important}
}

/* ---------- header ----------
   Links left, the mark in the middle, search and call to action on the right.
   The middle is its own grid track between two equal ones, so the mark sits at
   the true centre of the bar whatever the two sides weigh.

   Nothing in this bar is allowed to change the flow. The logo moves with a
   transform, which layout ignores; the search and the call to action sit
   absolutely inside fixed size slots, so they can hold hero size and fold back
   without the links beside them shifting a pixel. That is what lets the hero
   hand its controls over without the bar flinching. */
:root{--barh:62px}
@media(min-width:1040px){:root{--barh:84px}}
header.site{position:sticky;top:0;z-index:100}
/* The bar's surface is a pseudo element rather than the header. A backdrop
   filter on an ancestor is a trap for anything that has to travel outside it,
   and this gives the dock one number to fade up as the mark arrives. */
/* No backdrop filter. A blurred surface has to re-composite everything behind
   it on every frame of a scroll, and this one is stuck to the top of the window
   during the whole of the fold, which is the one stretch of the page where the
   frames matter. Measured at 1600 wide it cost two thirds of them. At 97 per
   cent white the blur was worth at most 16 levels out of 255 anywhere on the
   page, which is to say it was paying nothing for it. */
header.site::before{content:"";position:absolute;inset:0;z-index:-1;
  background:rgba(255,255,255,.97);
  border-bottom:1px solid var(--line);opacity:1;transition:opacity .32s var(--ease)}
/* on the home page it starts clear, so the hero runs the full height of the
   window, and takes its surface as the mark lands on it */
.docking header.site::before{opacity:0}
.docking.barred header.site::before{opacity:1}
/* Three tracks at every width, not only where the links fit. The mark docks
   into the middle one, and minmax(0,1fr) on both sides rather than a bare 1fr
   because a bare 1fr will not shrink below its own content, so the heavier side
   pushes the middle track off centre.

   Which of the three controls fly into the bar is decided here, one flag each,
   and the script obeys. A count was wrong: the widths that can hold a call to
   action cannot all hold a search field, so the rule had to be able to say mark
   and call to action but not search, and a count taken in order cannot skip its
   middle. The mark always flies.

   The search flies at every width. What it arrives as changes: at 1040 and up
   there is room for a field, and below that it closes onto its own button on
   the way and lands as the magnifier. It is the same control travelling the
   same path either way, which is the point. The magnifier that sits in the bar
   from the start belongs to pages that have no hero to fly from.

   760 for the call to action, and it is arithmetic rather than taste. The
   button is 214px, the mark 132, the search 44, the menu 64, and each side of
   the mark gets half of what is left: at 700 the right hand side wants 262 of
   the 256 it is given and puts 4px of itself over the mark. 712 is where it
   first fits and 760 is the next honest breakpoint above it. */
.bar{display:grid;grid-template-columns:minmax(0,1fr) auto minmax(0,1fr);
  gap:var(--space-2xs);align-items:center;height:var(--barh);
  --dock-find:1;--dock-cta:0}
@media(min-width:760px){.bar{--dock-cta:1}}

.logo{grid-column:2;grid-row:1;justify-self:center;z-index:1;display:flex;align-items:center;
  transform-origin:0 0;will-change:transform}
.logo img{height:40px;width:auto;max-width:none}
.bar-right{grid-column:3;grid-row:1;justify-self:end;display:flex;align-items:center;gap:var(--space-2xs)}

/* the burger is the only route to navigation on a phone, so it gets the full
   44px target even though the label alone would sit at 36 */
.burger{grid-column:1;grid-row:1;justify-self:start;background:none;border:1px solid var(--line);
  border-radius:var(--rs);padding:0 var(--space-s);min-height:var(--tap);cursor:pointer;
  font-size:14.5px;color:var(--ink);font-weight:600}
.burger:active{background:var(--tint)}
nav.main{display:none;position:absolute;top:var(--barh);left:0;right:0;background:#fff;
  border-bottom:1px solid var(--line);flex-direction:column;gap:0;padding:6px var(--pad) 14px;
  box-shadow:0 18px 30px -22px rgba(23,21,51,.35)}
/* Above the mark. The bar's logo comes after the menu in the markup and
   carries will-change:transform for the dock, so without this it paints over
   the open menu panel and the first two links are unreadable behind it. */
nav.main{z-index:6}
nav.main.open{display:flex}
nav.main a{padding:13px 0;border-bottom:1px solid var(--line);font-size:16px;font-weight:550;color:var(--ink)}
nav.main a:last-child{border-bottom:none}
/* the call to action inside the menu, for the widths whose bar cannot hold it */
nav.main .navcta{display:flex;align-items:center;justify-content:center;gap:var(--space-xs);
  margin:var(--space-xs) 0 var(--space-s);padding:0 var(--space-l);min-height:var(--tap);
  background:var(--orange-ink);color:#fff;border:none;border-radius:var(--rs);
  font-weight:650;font-size:15px}
nav.main .navcta i{font-style:normal}
nav.main .navcta:hover{background:var(--indigo)}
@media(min-width:700px){nav.main .navcta{display:none}}

/* The two controls that change shape rather than scale. The slot holds the
   space; the control floats inside it. */
/* A slot is an empty box until something folds into it, so it is only on the
   page where a rider is coming. The script says which by the class it puts on
   the root, so an inner page with no hero never shows an empty square. */
.slot{position:relative;flex:none;display:none}
.slot-cta{z-index:2}
.dock-find .slot-search,.dock-cta .slot-cta{display:block}
/* the magnifier is the search until the hero's own field takes the job over */
.dock-find .hsearch-ico{display:none}
.slot-search{width:var(--tap);height:var(--tap)}
.slot-cta{width:150px;height:var(--tap)}
/* the placeholder goes as the field closes, rather than at a breakpoint: during
   the fold this control is still hero sized and has to stay readable */
.hsearch-bar input{opacity:var(--io,1)}
.hsearch-bar{overflow:hidden}
/* The same button the home page's search folds into, so the bar reads the same
   on every page and the home page simply happens to animate into it. */
.hsearch-ico{display:grid;place-items:center;width:var(--tap);height:var(--tap);flex:none;
  background:var(--indigo);color:#fff;
  border-radius:10px;transition:background var(--t-res) var(--ease)}
.hsearch-ico .ico-mag{width:calc(var(--tap) * .5);height:calc(var(--tap) * .5)}
.hsearch-ico:hover{background:var(--indigo-d)}
.hsearch-ico:active{background:var(--indigo-d)}

@media(min-width:1040px){
  .bar{gap:var(--space-m)}
  nav.main{display:flex;position:static;grid-column:1;grid-row:1;justify-self:start;
    flex-direction:row;gap:16px;padding:0;border:none;background:none;box-shadow:none}
  nav.main a{padding:4px 0;border:none;font-size:14.5px;font-weight:500;color:var(--body);position:relative}
  nav.main a::after{content:"";position:absolute;left:0;right:100%;bottom:0;height:1.5px;
    background:var(--orange);transition:right .25s}
  nav.main a:hover,nav.main a[aria-current=page]{color:var(--ink)}
  nav.main a:hover::after,nav.main a[aria-current=page]::after{right:0}
  .logo img{height:44px}
  .burger,.hsearch-ico{display:none}
  /* from here the bar carries a working search and call to action of its own on
     every page, hero or not */
  .slot{display:block}
  /* the search slot gives first: the bar keeps its links, its mark and its call
     to action intact at every width */
  .slot-search{width:180px;height:38px}
  .slot-cta{width:178px;height:var(--tap)}   /* a floor; the real width is measured */
}
@media(min-width:1240px){
  .logo img{height:48px}
  nav.main{gap:21px}
  nav.main a{font-size:15.5px}
  .slot-search{width:210px}
  .bar-right{gap:var(--space-m)}
}
@media(min-width:1500px){
  nav.main{gap:25px}
  nav.main a{font-size:16px}
  .slot-search{width:250px}
}

/* ============================ the About group ============================
   About opens onto about us, leadership, careers and the gallery. In the phone
   menu it is an accordion inside the list; on a laptop it is a dropdown under
   the word. The entry itself is a button, so it behaves the same under a thumb
   as under a mouse. */
.navgroup{display:flex;flex-direction:column}
.navtop{display:flex;align-items:center;justify-content:space-between;width:100%;
  background:none;border:0;border-bottom:1px solid var(--line);padding:13px 0;margin:0;
  font:inherit;font-size:16px;font-weight:550;color:var(--ink);cursor:pointer;text-align:left}
.navcaret{display:inline-block;width:7px;height:7px;flex:none;margin:0 4px 3px 0;
  border-right:1.6px solid currentColor;border-bottom:1.6px solid currentColor;
  transform:rotate(45deg);transition:transform .2s var(--ease)}
.navgroup.open .navcaret{transform:rotate(225deg);margin-bottom:-3px}
.navsub{display:none;flex-direction:column;padding-left:var(--space-m);
  border-bottom:1px solid var(--line)}
.navgroup.open .navsub{display:flex}
nav.main .navsub a{font-size:15px;font-weight:500;color:var(--body);padding:11px 0}
nav.main .navsub a[aria-current=page]{color:var(--indigo);font-weight:600}

@media(min-width:1040px){
  /* above the mark: the logo carries a transform for the dock, which makes it
     its own layer, and on the home page at rest it is hero sized and close
     enough to the right of About to paint over the panel */
  .navgroup{position:relative;display:block;z-index:7}
  .navtop{display:inline-flex;gap:6px;width:auto;padding:4px 0;border:0;
    font-size:14.5px;font-weight:500;color:var(--body);position:relative}
  .navtop::after{content:"";position:absolute;left:0;right:100%;bottom:0;height:1.5px;
    background:var(--orange);transition:right .25s}
  .navtop:hover,.navtop.iscur,.navgroup.open .navtop{color:var(--ink)}
  .navtop:hover::after,.navtop.iscur::after{right:0}
  .navcaret{width:6px;height:6px;margin:0 0 3px;border-width:1.5px}
  .navgroup.open .navcaret{margin-bottom:-2px}

  .navsub{display:flex;position:absolute;top:calc(100% + 12px);left:-14px;min-width:196px;
    padding:7px;border:1px solid var(--line);border-radius:9px;background:#fff;
    box-shadow:0 20px 42px -20px rgba(23,21,51,.32);
    opacity:0;visibility:hidden;transform:translateY(-5px);
    transition:opacity .16s var(--ease),transform .16s var(--ease),visibility 0s .16s}
  /* a bridge over the gap, so the pointer can travel from the word to the panel
     without passing over nothing and closing it on the way */
  .navsub::before{content:"";position:absolute;left:0;right:0;top:-14px;height:14px}
  .navgroup.open .navsub{opacity:1;visibility:visible;transform:none;
    transition:opacity .16s var(--ease),transform .16s var(--ease)}
  nav.main .navsub a{display:block;padding:9px 12px;border-radius:6px;font-size:14.5px;
    color:var(--body);white-space:nowrap}
  nav.main .navsub a::after{display:none}
  nav.main .navsub a:hover{background:var(--tint);color:var(--ink)}
}
/* hover only where there is a pointer that can hover; on a touch screen a tap
   would otherwise leave it stuck open */
@media(min-width:1040px) and (hover:hover) and (pointer:fine){
  .navgroup:hover .navsub{opacity:1;visibility:visible;transform:none;
    transition:opacity .16s var(--ease),transform .16s var(--ease)}
  .navgroup:hover .navtop{color:var(--ink)}
}
/* Between 1040 and 1239 the bar is at its tightest: six entries on the left and
   the mark on the true centre. Contact was already running 14px into the mark
   at 1040 before About had a caret, and the caret took it to 26. The gaps and
   half a point of type come back in this band only, which clears the mark at
   every width in it without touching the mark itself: its size is the dock's
   to decide, not the menu's. */
@media(min-width:1040px) and (max-width:1239px){
  nav.main{gap:11px}
  nav.main > a,.navtop{font-size:14px}
  .navtop{gap:5px}
}

/* Home, on every page but the home page. In the phone menu it is a word like
   the others; in the bar it is a small house, because a seventh word would push
   the menu into the centred mark. Only pages that carry it tighten a little to
   make room, so the home page's own bar is exactly as it was. */
nav.main .navhome{display:flex;align-items:center;gap:8px}
nav.main .navhome svg{width:18px;height:18px;flex:none;fill:none;stroke:currentColor;stroke-width:2;stroke-linecap:round;stroke-linejoin:round}
@media(min-width:1040px){
  nav.main .navhome{padding:4px 2px}
  nav.main .navhome span{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}
}
@media(min-width:1040px) and (max-width:1239px){
  nav.main:has(.navhome){gap:9px}
  nav.main:has(.navhome) > a,nav.main:has(.navhome) .navtop{font-size:13.6px}
}
@media(min-width:1240px) and (max-width:1499px){
  nav.main:has(.navhome){gap:16px}
  nav.main:has(.navhome) > a,nav.main:has(.navhome) .navtop{font-size:15.2px}
}
@media(min-width:1240px){.navtop{font-size:15.5px}}
@media(min-width:1500px){.navtop{font-size:16px}}
@media(prefers-reduced-motion:reduce){.navsub,.navcaret{transition:none}}

/* The magnifier, drawn rather than typed. It was the character U+2315, whose
   ink measured 14.3 by 27.5px inside a 44px button: a tall thin shape, sized
   and placed by whatever monospace font the device happened to have, and never
   the same twice. This is symmetric about the centre of its own box by
   construction, so place-items:center puts it exactly in the middle of the
   square: the circle's outer edge and the handle's rounded end both stop at 4
   and 20 of a 24 box. */
.ico-mag{display:block;fill:none;stroke:currentColor;stroke-width:2;
  stroke-linecap:round;stroke-linejoin:round}
/* the magnifier that sits inside the big search rows, at reading size */
.rowmag{display:grid;place-items:center;color:var(--indigo);flex:none}
.rowmag .ico-mag{width:19px;height:19px;stroke-width:2.2}

/* ---------- buttons ---------- */
.btn{display:flex;align-items:center;justify-content:center;width:100%;
  padding:var(--space-s) var(--space-xl);min-height:var(--tap);
  border-radius:var(--rs);font-weight:650;font-size:15px;
  border:1.5px solid transparent;cursor:pointer;text-align:center}
.btn-p{background:var(--indigo);color:#fff;box-shadow:0 14px 30px -16px rgba(60,42,152,.7)}
.btn-p:hover{background:var(--indigo-d)}
.btn-p:active{background:var(--indigo-d);box-shadow:none}
.btn-o{background:var(--orange-ink);color:#fff}
.btn-o:hover{background:var(--indigo)}
.btn-o:active{background:var(--indigo-d)}
.btn-g{background:#fff;color:var(--indigo);border-color:var(--line)}
.btn-g:hover{border-color:var(--indigo)}
.btn-g:active{background:var(--tint)}
.btn-sm{min-height:38px;padding:var(--space-xs) var(--space-m);font-size:13.5px}
.btn:disabled,.btn[aria-disabled=true]{opacity:.55;cursor:not-allowed;box-shadow:none}
.btn:disabled:hover,.btn[aria-disabled=true]:hover{background:inherit}
.arrow{display:inline-flex;align-items:center;gap:var(--space-xs);font-weight:650;color:var(--indigo)}
.arrow i{font-style:normal;color:var(--orange-ink);transition:transform .2s}
.arrow:hover i{transform:translateX(5px)}
@media(min-width:600px){.btn{display:inline-flex;width:auto;padding:var(--space-s) var(--space-xl)}}

/* ---------- typography ---------- */
/* overflow-wrap on display type: a chemical name in an h1 can be one 70
   character token with no natural break opportunity */
h1{font-size:clamp(1.95rem,7vw,3.7rem);line-height:1.06;letter-spacing:-.034em;font-weight:800;
  margin:0 0 18px;text-wrap:balance;overflow-wrap:anywhere;min-width:0}
h2{font-size:clamp(1.45rem,5vw,2.5rem);line-height:1.14;letter-spacing:-.028em;font-weight:800;
  margin:0 0 12px;text-wrap:balance;overflow-wrap:anywhere;min-width:0}
h3{font-size:1.08rem;font-weight:700;letter-spacing:-.015em;margin:0 0 8px}
/* One face for headings, on every page. Archivo arrived for the last two
   sections of the home page and stopped there, which left six headings on that
   page in one face and three in another, and all nine inner pages in the first.
   The hero headline is deliberately not included: it is a piece of display type
   the client signed off as it stands, and it is the one heading on the site that
   is not part of this run. */
h1:not(.caps),h2,h3{font-family:var(--disp);font-variation-settings:'wdth' 92}
p{margin:0 0 15px;color:var(--body)}
.lede{font-size:clamp(1rem,2.6vw,1.2rem);color:var(--body);max-width:60ch}
/* There is no eyebrow on this site. A small coloured label above a heading
   says nothing the heading does not, and a page of them reads as a template
   rather than as writing. Where a label carried real information, that
   information moved into the heading, the caption or the record beside it.
   verify-home.py fails the build if the device comes back. */
section{padding:48px 0}
.tint{background:linear-gradient(180deg,var(--tint),#fff)}
.tint2{background:linear-gradient(180deg,var(--tint2),#fff)}
.shead{max-width:64ch;margin-bottom:28px}
@media(min-width:860px){section{padding:64px 0} .shead{margin-bottom:34px} h3{font-size:1.15rem}}
@media(min-width:1040px){section{padding:84px 0}}

/* ---------- page hero ---------- */
.phero{padding:34px 0 26px;
  background:radial-gradient(760px 420px at 88% 8%,var(--tint2),transparent 62%),
             radial-gradient(680px 420px at 4% 92%,var(--tint),transparent 64%)}
@media(min-width:860px){.phero{padding:56px 0 38px}}
@media(min-width:1040px){.phero{padding:70px 0 46px}}

/* ---------- section search, used on the catalogue band ---------- */
.hsearch{background:#fff;border:2px solid var(--indigo);border-radius:var(--r);overflow:hidden;min-width:0;
  box-shadow:0 24px 52px -30px rgba(60,42,152,.55);margin-bottom:var(--space-m)}
/* Phone first. The field gets the entire width and the action sits underneath
   it, which is how search behaves on a phone. Squeezing a label, a field and a
   button onto one 375px line left the input about 160px wide with a truncated
   placeholder. From 600px up all three share a line, as before. */
.hsearch .row{display:grid;grid-template-columns:auto minmax(0,1fr);align-items:center;
  gap:var(--space-2xs) var(--space-xs);padding:var(--space-s)}
/* no outline:none here. This is the primary control on the site and a keyboard
   user has to be able to see where they are. */
.hsearch input{width:100%;border:none;font-family:var(--mono);font-size:16px;min-width:0;color:var(--ink);
  background:transparent;padding:var(--space-xs) var(--space-3xs);border-radius:var(--rs)}
.hsearch .row button{grid-column:1/-1;width:100%;background:var(--indigo);color:#fff;border:none;
  border-radius:var(--rs);padding:0 var(--space-m);min-height:var(--tap);
  font-weight:700;font-size:14.5px;cursor:pointer}
.hsearch .row button:hover{background:var(--orange-ink)}
.hsearch .row button:active{background:var(--indigo-d)}
/* one scrolling line of examples rather than two rows of blocks */
.hsearch .chips{display:flex;gap:var(--space-2xs);padding:0 var(--space-s) var(--space-s);
  flex-wrap:nowrap;overflow-x:auto;scrollbar-width:none;-webkit-overflow-scrolling:touch}
.hsearch .chips::-webkit-scrollbar{display:none}
.chip{flex:none;font:inherit;font-size:12.5px;padding:var(--space-xs) var(--space-s);min-height:36px;
  display:inline-flex;align-items:center;border-radius:var(--rs);border:1px solid var(--line);
  color:var(--body);cursor:pointer;background:#fff;white-space:nowrap}
.chip:hover{border-color:var(--indigo);color:var(--indigo)}
.chip:active{background:var(--tint)}
@media(min-width:600px){
  .hsearch .row{grid-template-columns:auto minmax(0,1fr) auto;gap:var(--space-s);
    padding:var(--space-s) var(--space-m)}
  .hsearch .row button{grid-column:auto;width:auto;padding:0 var(--space-l);font-size:14px}
  .hsearch .chips{flex-wrap:wrap;overflow:visible;padding:0 var(--space-m) var(--space-s)}
  .chip{flex:0 0 auto}
}

/* ---------- product cards ---------- */
.pgrid{display:grid;grid-template-columns:1fr;gap:var(--space-s)}
.pcard{background:#fff;border:1px solid var(--line);border-radius:var(--r);overflow:hidden;
  display:flex;flex-direction:column;
  transition:border-color .18s ease,box-shadow .18s ease}
/* one hover effect, not three */
.pcard:hover{border-color:var(--indigo);box-shadow:0 14px 34px -22px rgba(60,42,152,.45)}
.pcard:active{border-color:var(--indigo-d)}
/* the well is sized to the drawing rather than the drawing floated in the well */
.pcard .sw{background:var(--tint);height:112px;display:grid;place-items:center;padding:var(--space-s);
  border-bottom:1px solid var(--line);position:relative;overflow:hidden}
/* explicit px cap: a percentage max-height is ignored inside a centred grid area */
.pcard .sw img{max-height:92px;max-width:100%;width:auto;object-fit:contain}
.pcard .sw .none{font-family:var(--mono);font-size:11.5px;color:var(--faint);text-align:center;line-height:1.6}
.pcard .pbody{padding:var(--space-s) var(--space-s) var(--space-s);display:flex;flex-direction:column;flex:1;
  align-items:flex-start}
.pcard .ptop{display:flex;align-items:center;flex-wrap:wrap;gap:var(--space-2xs) var(--space-xs);
  margin-bottom:var(--space-xs);width:100%}
.pcard .cas{font-family:var(--mono);font-size:12.5px;color:var(--orange-ink);font-weight:650;
  font-variant-numeric:tabular-nums}
.pcard h3{margin:0 0 var(--space-xs);font-size:14px;font-weight:650;line-height:1.42;color:var(--ink);
  overflow-wrap:anywhere}
.pcard .meta{margin-top:auto;padding-top:var(--space-s);border-top:1px solid var(--line);
  display:flex;justify-content:space-between;align-items:center;gap:var(--space-s);width:100%}
.pcard .api{font-size:12.4px;color:var(--body);min-width:0;overflow-wrap:anywhere}
.pcard .api b{color:var(--indigo)}
.pcard .go{font-size:12px;font-weight:700;color:var(--orange-ink);white-space:nowrap}
/* align-self:start, because .pbody is a flex column and flex items stretch by
   default, which is what turned this label into a full width banner */
.tag{align-self:flex-start;font-size:11.5px;font-weight:700;letter-spacing:.04em;
  padding:3px var(--space-xs);border-radius:5px;background:var(--indigo-w);color:var(--indigo)}
.tags{display:flex;flex-wrap:wrap;gap:var(--space-2xs);margin:-6px 0 var(--space-m)}
.tag.o{background:var(--orange-w);color:var(--orange-ink)}
/* the New marker sits with the text, not painted over the structure drawing */
.pcard .flag{align-self:flex-start;display:inline-flex;align-items:center;gap:var(--space-3xs);
  font-size:11px;font-weight:700;color:var(--orange-ink);margin-bottom:var(--space-2xs)}
.pcard .flag::before{content:"";width:6px;height:6px;border-radius:50%;background:var(--orange)}
@media(min-width:520px){.pgrid{grid-template-columns:1fr 1fr}}
@media(min-width:860px){
  .pgrid{grid-template-columns:repeat(3,1fr);gap:var(--space-m)}
  .pcard .pbody{padding:var(--space-m)}
  .pcard .sw{height:148px}
  .pcard .sw img{max-height:120px}
}
@media(min-width:1200px){.pgrid{grid-template-columns:repeat(4,1fr)}}
@media(min-width:1560px){.pgrid{grid-template-columns:repeat(5,1fr)}}
@media(min-width:1900px){.pgrid{grid-template-columns:repeat(6,1fr)}}

/* ---------- catalogue page ---------- */
.catbar{display:grid;grid-template-columns:1fr;gap:var(--space-s);align-items:center;margin-bottom:var(--space-m)}
.searchbox{display:flex;align-items:center;gap:var(--space-xs);background:#fff;border:2px solid var(--indigo);
  border-radius:var(--r);padding:var(--space-xs) var(--space-s)}
/* no outline:none, same reasoning as the hero search */
.searchbox input{flex:1;border:none;font-family:var(--mono);font-size:16px;min-width:0;
  background:transparent;padding:var(--space-xs) var(--space-3xs);border-radius:var(--rs)}
.filters{display:flex;gap:var(--space-2xs);flex-wrap:nowrap;overflow-x:auto;margin-bottom:var(--space-m);
  padding-bottom:var(--space-2xs);-webkit-overflow-scrolling:touch;scrollbar-width:thin}
.fc{flex:none;font:inherit;font-size:12.5px;padding:var(--space-xs) var(--space-s);min-height:38px;
  display:inline-flex;align-items:center;border-radius:var(--rs);border:1px solid var(--line);
  color:var(--body);cursor:pointer;background:#fff;font-weight:550;white-space:nowrap}
.fc:hover{border-color:var(--indigo);color:var(--indigo)}
.fc:active{background:var(--tint)}
.fc.on{background:var(--indigo);border-color:var(--indigo);color:#fff}
.count{font-family:var(--mono);font-size:12.5px;color:var(--body);margin-bottom:var(--space-m);
  font-variant-numeric:tabular-nums}
.empty{padding:44px 18px;text-align:center;color:var(--body);border:1px dashed var(--line);border-radius:var(--r)}
.more{display:block;margin:26px auto 0}
@media(min-width:600px){.more{display:inline-flex}}
@media(min-width:760px){
  .catbar{grid-template-columns:1fr auto;gap:12px}
  .filters{flex-wrap:wrap;overflow:visible;padding-bottom:0;margin-bottom:22px}
  .fc{font-size:13px;padding:8px 14px}
  .count{font-size:13px;margin-bottom:18px}
}

/* ---------- product detail ---------- */
.pdgrid{display:grid;grid-template-columns:1fr;gap:22px;align-items:start}
.pdimg{background:var(--tint);border:1px solid var(--line);border-radius:var(--r);
  min-height:220px;display:grid;place-items:center;padding:20px}
.pdimg img{max-width:100%;max-height:280px;height:auto;object-fit:contain}
.spec{border:1px solid var(--line);border-radius:var(--r);overflow:hidden;margin:20px 0}
.spec .sr2{display:grid;grid-template-columns:1fr;gap:2px;padding:12px 15px;
  border-bottom:1px solid var(--line);font-size:14.4px}
.spec .sr2:last-child{border-bottom:none}
.spec .sr2 dt{color:var(--faint)}
.spec .sr2 dd{margin:0;font-weight:600;color:var(--ink);overflow-wrap:anywhere}
.spec .sr2 dd.mono{font-family:var(--mono);color:var(--indigo)}
@media(min-width:560px){.spec .sr2{grid-template-columns:170px 1fr;gap:16px;padding:13px 18px}}
@media(min-width:900px){
  .pdgrid{grid-template-columns:.9fr 1.1fr;gap:44px}
  .pdimg{min-height:300px;padding:30px}
  .pdimg img{max-height:340px}
  .spec .sr2{grid-template-columns:180px 1fr;font-size:14.6px}
}

/* ---------- stage cards ---------- */
.stages{display:grid;grid-template-columns:1fr;gap:14px}
.stage{background:#fff;border:1px solid var(--line);border-radius:var(--r);padding:22px;
  position:relative;overflow:hidden;display:flex;flex-direction:column}
.stage::before{content:"";position:absolute;left:0;top:0;height:4px;width:100%}
.stage:nth-child(1)::before{background:var(--indigo)}
.stage:nth-child(2)::before{background:var(--indigo-s)}
.stage:nth-child(3)::before{background:#FFA63D}
.stage:nth-child(4)::before{background:var(--orange)}
.stage p{font-size:14.3px;margin:0 0 var(--space-s)}
.stage .sc{margin-top:auto;padding-top:var(--space-s);border-top:1px dashed var(--line);
  font-family:var(--mono);font-size:12.5px;font-weight:650;color:var(--indigo)}
.stage:nth-child(n+3) .sc{color:var(--orange-ink)}
@media(min-width:600px){.stages{grid-template-columns:1fr 1fr}}
@media(min-width:1040px){.stages{grid-template-columns:repeat(4,1fr);gap:16px}.stage{padding:24px}}

/* ---------- generic cards, lists, split ---------- */
.cards{display:grid;grid-template-columns:1fr;gap:14px}
.card{background:#fff;border:1px solid var(--line);border-radius:var(--r);padding:22px}
.card h3{margin-bottom:8px}
.card p{font-size:14.5px;margin:0}
.terms{list-style:none;margin:0;padding:0;display:flex;flex-wrap:wrap;gap:var(--space-s) var(--space-xl)}
.terms li{font-size:15px;font-weight:600;color:var(--indigo);padding-left:var(--space-s);
  border-left:2px solid var(--orange)}
.tickList{list-style:none;margin:14px 0 0;padding:0}
.tickList li{position:relative;padding-left:22px;margin-bottom:9px;font-size:14.6px;color:var(--body)}
.tickList li::before{content:"";position:absolute;left:0;top:9px;width:7px;height:7px;
  border-radius:50%;background:var(--orange)}
/* ruled list, the alternative to yet another symmetric card grid */
.vlist{display:grid;grid-template-columns:1fr;border-top:1px solid var(--line)}
.vrow{padding:var(--space-l) 0;border-bottom:1px solid var(--line)}
.vrow h3{margin-bottom:var(--space-2xs)}
.vrow p{font-size:14.8px;line-height:1.62;margin:0;max-width:58ch}
/* running text never inherits the container width */
.split p,.split li,.card p,.stage p,.media figcaption,.note{max-width:68ch}
.ccount{font-family:var(--mono);font-size:12px;font-weight:650;color:var(--indigo);
  margin-bottom:var(--space-xs);font-variant-numeric:tabular-nums}
@media(min-width:760px){
  .vlist{grid-template-columns:1fr 1fr;column-gap:var(--space-3xl)}
  .vrow:nth-last-child(-n+2){border-bottom:none}
}
.split{display:grid;grid-template-columns:1fr;gap:24px;align-items:start}
.media{border-radius:var(--r);overflow:hidden;border:1px solid var(--line);margin:0}
/* the photograph beside a column of text is a companion to it, not the subject
   of the page: it stops at a size the text can hold its own against */
/* The picture takes the width it is given rather than stopping short of it.
   A cap left a gap on one side and the section read as having two right edges;
   filling the column means one left edge and one right edge, whichever side
   the picture is on. */
.split>.media{width:100%;justify-self:stretch}

/* The introduction: every word in the left column, the picture in the right.
   The heading sits with the paragraphs it belongs to rather than across the
   top of both, which is what gives the section a single left edge and lets the
   picture have the right one. Even columns rather than the 1 to 1.2 the other
   splits use, because here the text is the longer half. */
.split.intro>div>h2{margin-top:0}
@media(min-width:1040px){
  .split.intro{grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:var(--space-4xl)}
}
/* The class the script narrows. It carries no number of its own: the number is
   the resolution of whatever photograph is in the slot, which only the loaded
   file knows, so WK.natural sets it. This rule is the floor it starts from, and
   it is what the class means in the stylesheet rather than only in the script.
   The section it sits in is built by script, so there is no case where the
   class is on the page and the script that measures it did not run. */
.no-upscale{max-width:100%}


.media img{width:100%;aspect-ratio:4/3;object-fit:cover}
.media figcaption{padding:12px 15px;font-size:13.4px;color:var(--body);background:#fff;border-top:1px solid var(--line)}
/* a tinted panel with a rule above it, rather than a coloured side stripe */
.note{background:var(--tint2);border-top:2px solid var(--orange);border-radius:0 0 var(--rs) var(--rs);
  padding:var(--space-s) var(--space-m);font-size:14.2px;color:var(--ink);margin:var(--space-m) 0 0}
@media(min-width:600px){.cards{grid-template-columns:repeat(auto-fit,minmax(258px,1fr));gap:16px}
  .card{padding:24px}}
@media(min-width:900px){
  .split{grid-template-columns:1fr 1.2fr;gap:48px}
  /* minmax(0,...) so a long address cannot set a minimum wider than its track */
  .split-form{grid-template-columns:minmax(0,1.25fr) minmax(0,.75fr)}
}

/* ---------- tables ---------- */
.tblwrap{border:1px solid var(--line);border-radius:var(--r);overflow:hidden}
.tblscroll{overflow-x:auto;-webkit-overflow-scrolling:touch}
table{width:100%;border-collapse:collapse;font-size:14.2px;min-width:520px}
th{text-align:left;background:var(--tint);font-size:11px;letter-spacing:.09em;text-transform:uppercase;
  color:var(--body);padding:12px 15px;font-weight:700;border-bottom:1px solid var(--line)}
td{padding:12px 15px;border-bottom:1px solid var(--line);color:var(--body)}
tr:last-child td{border-bottom:none}
td.i{font-family:var(--mono);font-weight:600;color:var(--indigo)}
.pillok{font-size:11px;font-weight:750;letter-spacing:.05em;text-transform:uppercase;
  background:var(--indigo-w);color:var(--indigo);padding:4px 10px;border-radius:5px;white-space:nowrap}
.pillok.ext{background:var(--orange-w);color:var(--orange-ink)}
@media(min-width:860px){table{font-size:14.6px}th,td{padding:13px 17px}}

/* ---------- forms ---------- */
.form{display:grid;gap:var(--space-s)}
.frow{display:grid;grid-template-columns:1fr;gap:var(--space-s)}
label{display:block;font-size:13.5px;font-weight:650;margin-bottom:var(--space-2xs);color:var(--ink)}
/* 16px keeps iOS from zooming the page when a field takes focus.
   Border width never changes between states, so nothing shifts on focus.
   Minimum height matches the button height on the same form. */
.field{width:100%;border:1px solid var(--line);border-radius:var(--rs);
  padding:var(--space-s) var(--space-s);min-height:var(--tap);
  font-size:16px;color:var(--ink);background:#fff;
  outline:2px solid transparent;outline-offset:1px}
.field:hover{border-color:var(--indigo-s)}
.field:focus,.field:focus-visible{border-color:var(--indigo);outline-color:var(--indigo)}
.field:disabled{opacity:.55;cursor:not-allowed;background:var(--tint)}
textarea.field{min-height:110px;resize:vertical;line-height:1.55}
/* reserve the helper line so an error appearing does not push the page down */
.fhelp{display:block;min-height:1lh;font-size:12.5px;color:var(--body);margin-top:var(--space-3xs)}
@media(min-width:640px){.frow{grid-template-columns:1fr 1fr;gap:var(--space-m)}.form{gap:var(--space-m)}}

/* ---------- CTA band ---------- */
/* solid colour underneath the gradient, so the white text still has a surface
   where background images do not paint: print, forced colours */
.ctaband{background-color:var(--indigo);
  background-image:linear-gradient(120deg,var(--indigo),var(--indigo-s) 62%,#7B62E8);
  border-radius:18px;padding:var(--space-xl) var(--space-l);color:#fff}
.ctaband h2{color:#fff}
.ctaband p{color:rgba(255,255,255,.9)}
@media(min-width:600px){.ctaband{border-radius:22px;padding:34px 30px}}
@media(min-width:1040px){.ctaband{padding:46px}}

/* ---------- footer ---------- */
footer.site{background:var(--indigo-d);color:#C3BEE8;padding:44px 0 36px;font-size:14.2px;margin-top:48px}
.fgrid{display:grid;grid-template-columns:1fr;gap:26px}
/* not a heading element: these are link group labels, and emitting h4 here was
   skipping heading levels for anyone navigating by heading */
.fcol-t{display:block;color:#fff;font-size:13.5px;font-weight:650;margin:0 0 12px}
footer.site a{display:block;margin-bottom:8px;color:#C3BEE8}
footer.site a:hover,footer.site a:focus-visible{color:#FFB870}
.flogo{background:#fff;border-radius:var(--rs);padding:10px 13px;display:inline-block;margin-bottom:14px}
.flogo img{height:46px}
.fnote{margin-top:28px;padding-top:17px;border-top:1px solid rgba(255,255,255,.16);
  font-size:12.2px;color:#948FC9;line-height:1.85}
@media(min-width:600px){.fgrid{grid-template-columns:1fr 1fr;gap:30px}}
@media(min-width:1040px){
  footer.site{padding:56px 0 44px;font-size:14.4px;margin-top:60px}
  .fgrid{grid-template-columns:1.7fr 1fr 1fr 1fr;gap:34px}
  .flogo img{height:52px}
  .fnote{margin-top:34px;font-size:12px}
}

/* ---------- catalogue: list view alongside grid ---------- */
.viewtog{display:flex;gap:var(--space-3xs);background:#fff;border:1px solid var(--line);
  border-radius:var(--rs);padding:3px;flex:none}
.viewtog button{border:none;background:transparent;border-radius:6px;
  padding:0 var(--space-s);min-height:38px;font:inherit;font-size:13px;
  font-weight:650;color:var(--body);cursor:pointer;display:flex;align-items:center;gap:var(--space-2xs)}
.viewtog button.on{background:var(--indigo);color:#fff}
.viewtog button:active{background:var(--tint)}
.viewtog button.on:active{background:var(--indigo-d)}
.viewtog i{font-style:normal;font-size:13px;line-height:1}

.plist{display:grid;gap:8px}
.prow{display:grid;grid-template-columns:56px 1fr auto;gap:12px;align-items:center;
  background:#fff;border:1px solid var(--line);border-radius:var(--rs);padding:var(--space-s);transition:border-color .15s ease,box-shadow .15s ease}
.prow:hover{border-color:var(--indigo);box-shadow:0 10px 24px -18px rgba(60,42,152,.5)}
.prow:active{border-color:var(--indigo-d)}
.prow .rsw{width:56px;height:56px;background:var(--tint);border-radius:6px;display:grid;
  place-items:center;overflow:hidden;padding:5px}
.prow .rsw img{max-width:100%;max-height:46px;width:auto;object-fit:contain}
.prow .rsw span{font-family:var(--mono);font-size:9px;color:var(--faint);text-align:center;line-height:1.3}
.prow .rmain{min-width:0;display:block;overflow-wrap:anywhere}
.prow .rname{display:block;font-size:14px;font-weight:650;color:var(--ink);
  line-height:1.35;margin-bottom:3px;overflow-wrap:anywhere}
.prow .rmeta{display:flex;flex-wrap:wrap;gap:4px 12px;font-size:12.3px;color:var(--body);
  align-items:center;overflow-wrap:anywhere}
.prow .rcas{font-family:var(--mono);color:var(--orange-ink);font-weight:650;font-variant-numeric:tabular-nums}
.prow .rcat{color:var(--indigo);font-weight:600}
.prow .rgo{font-size:12px;font-weight:700;color:var(--orange-ink);white-space:nowrap;align-self:center}
.prow .rnew{display:inline-block;font-size:10px;font-weight:700;letter-spacing:.04em;
  background:var(--orange-w);color:var(--orange-ink);padding:2px 6px;border-radius:4px}
@media(min-width:760px){
  .prow{grid-template-columns:64px 1.6fr 1fr auto;gap:16px;padding:11px 16px}
  .prow .rsw{width:64px;height:64px}
  .prow .rsw img{max-height:54px}
  .prow .rname{font-size:14.6px;margin-bottom:2px}
  .prow .rside{display:flex;flex-direction:column;gap:2px;font-size:12.8px;color:var(--body);
    min-width:0;overflow-wrap:anywhere}
  .prow .rside b{color:var(--indigo);font-weight:650}
}
.prow .rside{display:none}
@media(min-width:760px){.prow .rside{display:flex}}
/* at desktop the right column carries category and API, so drop the repeat */
@media(min-width:760px){
  .prow .rmeta .rcat,.prow .rmeta .rapi{display:none}
}

/* ============================================================ v2
   Home page rebuild. The motion scale, the hero, the header handoff,
   the route rail, compact catalogue rows and the per page footers.
   Everything below is transform and opacity only.
   ============================================================ */

:root{
  /* four durations and two curves. Nothing outside these gets built. */
  --t-res:120ms; --t-tr:260ms; --t-ent:420ms; --t-amb:9s;
  --ease:cubic-bezier(.2,.7,.3,1); --ease-out:cubic-bezier(.4,0,1,1);
  --bar:56px;
}
@media(min-width:900px){:root{--bar:64px}}

/* the reveal used to travel 18 to 22px over 700ms, which reads as a slide.
   8px over 420ms reads as the page settling. */
.rv{transform:translateY(8px);
  transition:opacity var(--t-ent) var(--ease),transform var(--t-ent) var(--ease)}
@media(min-width:860px){.rv{transform:translateY(8px)}}
.rv-d1{transition-delay:.05s}.rv-d2{transition-delay:.10s}.rv-d3{transition-delay:.15s}
.rv-d4{transition-delay:.20s}.rv-d5{transition-delay:.25s}.rv-d6{transition-delay:.30s}

/* ---------- the two header riders, at rest ---------- */
/* the shape variables are what let this one element be both the compact bar
   control and the full size hero field, without a second copy of either */
/* The field is a shell around its own button, and where the bar has no room
   for a field the shell is what goes: it thins to nothing as the width closes
   and leaves the button standing on its own, at full tap size. --shell is the
   whole of that, one number driven by the width, so there is no second state
   to keep in step. It defaults to 1, which is every case where the field
   survives the journey. */
.hsearch-bar{position:absolute;left:0;top:0;width:100%;height:100%;z-index:1;
  display:flex;align-items:center;
  /* The gap closes with the shell too. It is 6px of space between the field and
     its button, and 6px of space is 6px of push: with the box hiding its
     overflow, a gap that stays open shoves the button off the right hand edge
     and takes a slice of it with the padding it no longer has. */
  gap:calc(6px * var(--shell,1));
  /* The border thins as well as fades. Fading it alone leaves 1.5px of layout
     on every side, and the box is border-box with its overflow hidden, so the
     button that has grown to fill the slot is sliced by 2px top and bottom and
     loses its own corners. Invisible is not the same as gone. */
  border-style:solid;border-width:calc(1.5px * var(--shell,1));
  border-color:rgba(60,42,152,var(--shell,1));
  border-radius:var(--rad,8px);background:rgba(255,255,255,var(--shell,1));
  padding:0 var(--pr,5px) 0 var(--pl,13px);
  transform-origin:0 0;will-change:width,height,transform}
.hsearch-bar:focus-within{box-shadow:0 0 0 3px var(--indigo-w)}
/* max-width rather than width, because a search input has a minimum of its own
   that width will not argue with: at nought it still measured 4px, and 4px plus
   the gap is what moved the button off its own square. */
.hsearch-bar input{flex:1;min-width:0;max-width:calc(2000px * var(--shell,1));
  /* appearance:none, or the browser's own search decoration keeps a 4px box
     that max-width is not allowed to argue with, and those 4px are what push
     the button off its square once everything else has closed. */
  appearance:none;-webkit-appearance:none;padding:0;
  border:none;outline:none;background:none;
  color:var(--ink);text-overflow:ellipsis}
.hsearch-bar input::placeholder{color:var(--faint)}
.hsearch-bar input{font-size:var(--fs,13.5px)}
.hsearch-bar button{flex:none;border:none;cursor:pointer;background:var(--indigo);color:#fff;
  border-radius:var(--brad,6px);width:var(--sq,28px);height:var(--sq,28px);padding:0;
  display:grid;place-items:center;
  transition:background var(--t-res) var(--ease)}
.hsearch-bar button .ico-mag{width:calc(var(--sq,28px) * .5);height:calc(var(--sq,28px) * .5)}
.hsearch-bar button:hover{background:var(--indigo-d)}

/* the call to action arrives last, so it passes in front of the search on its
   way to the far right rather than being clipped by it */
.hcta{position:absolute;left:0;top:0;width:100%;height:100%;z-index:2;
  display:inline-flex;align-items:center;justify-content:center;gap:var(--gp,8px);
  padding:0 var(--space-l);font-size:var(--fs,14.5px);
  background:var(--orange-ink);color:#fff;border-radius:var(--rs);
  font-weight:650;white-space:nowrap;
  transform-origin:0 0;will-change:width,height,transform;
  transition:background var(--t-tr) var(--ease)}
.hcta:hover{background:var(--indigo)}
.hcta:active{background:var(--indigo-d)}
.hcta i{font-style:normal;transition:transform var(--t-tr) var(--ease)}
.hcta:hover i{transform:translateX(4px)}

/* the word that types itself. The ghost is a copy of the longest phrase, left
   in the flow at zero opacity: it is what holds the width, so the button cannot
   change size as the letters arrive. The typed line sits over it. */
.rot{position:relative;display:inline-block;text-align:left;vertical-align:baseline}
.rot .ghost{font-style:normal;display:block;opacity:0;pointer-events:none;white-space:nowrap}
.rot .typed{position:absolute;left:0;top:0;white-space:nowrap}
.rot .caret{display:inline-block;width:1.5px;height:1em;margin-left:2px;
  background:currentColor;vertical-align:-.13em;animation:caret-blink 1.05s steps(1) infinite}
.rot.nocaret .caret{display:none}
@keyframes caret-blink{0%,49%{opacity:1}50%,100%{opacity:0}}
@media(prefers-reduced-motion:reduce){.rot .caret{animation:none;opacity:0}}

/* ---------- home hero ----------
   No pin and no fading. The hero scrolls away exactly like any other block: the
   words hold their place on the page and leave with it. The only thing that
   ever moves independently is a control that has reached the bar, and it moves
   only from that moment on. See js/hero.js. */
.hpin{position:relative;margin-top:calc(-1 * var(--barh))}
.hstage{position:relative;overflow:hidden;isolation:isolate;background:var(--paper);
  padding:calc(var(--barh) + var(--space-2xl)) 0 var(--space-4xl)}
@media(min-width:1040px){
  .hstage{min-height:100svh;display:grid;align-content:center;
    padding:calc(var(--barh) + var(--space-l)) 0 var(--space-2xl)}
  .hbody{width:min(100%,1760px)}
}

.hstage .glow{position:absolute;inset:0;z-index:0;
  background:radial-gradient(1100px 620px at 82% 12%,var(--tint2),transparent 60%),
             radial-gradient(980px 640px at 8% 88%,var(--tint),transparent 62%),
             radial-gradient(760px 520px at 50% 46%,#FFFDF9,transparent 70%)}
/* wall.png is an alpha mask, not a picture: every pixel of the drawing is the
   same indigo, so only the transparency needs storing. 64 KB instead of 202,
   and the colour comes from the token rather than being baked in. */
.hstage .wall{position:absolute;inset:0;z-index:1;background:var(--indigo);opacity:.5;
  -webkit-mask-image:url(../img/site/wall.png);mask-image:url(../img/site/wall.png);
  -webkit-mask-size:400px auto;mask-size:400px auto;
  -webkit-mask-repeat:repeat;mask-repeat:repeat}
@media(min-width:900px){.hstage .wall{-webkit-mask-size:640px auto;mask-size:640px auto}}
@supports not ((-webkit-mask-image:url(x)) or (mask-image:url(x))){.hstage .wall{background:none}}
/* The veil lifts the middle clear of the drawings and lets them stay legible
   out at the edges. A soft ramp rather than an ellipse: an ellipse has an edge,
   and the edge showed as a pale shape behind the photographs. */
.hstage .wash{position:absolute;inset:0;z-index:2;
  background:linear-gradient(180deg,rgba(255,255,255,.24),rgba(255,255,255,.56) 30%,rgba(255,255,255,.56) 74%,rgba(255,255,255,.24))}
@media(min-width:1040px){
  .hstage .wash{background:linear-gradient(90deg,rgba(255,255,255,.1),rgba(255,255,255,.5) 32%,
    rgba(255,255,255,.5) 68%,rgba(255,255,255,.1))}
}

/* The bond field from v1: loose nodes joined by a line wherever two of them
   are close enough to be bonded, drifting.

   v1 drew this on a canvas, recomputing every pair every frame. That is fine
   on a laptop and costs whole frames on a wide screen, because a canvas the
   size of the hero repaints as the hero scrolls whether or not its contents
   changed. This is the same picture as six rigid clusters on six periods, in
   the same paint layer as everything else, animated by transform only. It
   costs nothing to scroll past. */
.hstage .mol{position:absolute;inset:0;width:100%;height:100%;z-index:2;
  opacity:.55;pointer-events:none;overflow:visible}
.hstage .mol circle{fill:var(--indigo);opacity:.5}
.hstage .mol circle.o{fill:var(--orange)}
.hstage .mol line{stroke:var(--indigo);stroke-width:1.1;stroke-linecap:round}
/* The field does not drift, and that is a measurement rather than a taste.
   Animating six groups the size of the hero promotes six large layers, and
   re-rastering them during a scroll cost a third of the frames on a 2560 wide
   window: zero dropped frames with the drift off, a third of them lost with it
   on. Pausing the animation was not enough, because a paused animation keeps
   its layer, so the field is drawn once and left alone. */

.hbody{position:relative;z-index:3;display:grid;grid-template-columns:minmax(0,1fr);
  align-items:center;gap:var(--space-2xl)}
.hmid{position:relative;text-align:center;display:flex;flex-direction:column;
  align-items:center;min-width:0}
/* The pattern behind the hero is the catalogue, and it should stay strong: it
   was made stronger on purpose two rounds ago. But it ran straight through the
   headline and the mark, and a bond line crossing a letter is the thing that
   makes type look cheap. So rather than turning the whole field down, a veil
   sits behind the middle column only, dense where the words are and gone by
   the time it reaches the edge of the column. The pattern is untouched
   everywhere else, which is most of the hero at a laptop width and above.
   It is drawn from the column, so it is the right size on a phone, where the
   column is the whole width, without a breakpoint saying so. */
.hmid::before{content:"";position:absolute;z-index:-1;pointer-events:none;
  left:50%;top:50%;transform:translate(-50%,-50%);
  width:min(132%,1180px);height:108%;
  background:radial-gradient(ellipse at center,
    rgba(255,255,255,.94) 0%,rgba(255,255,255,.9) 46%,
    rgba(255,255,255,.6) 72%,rgba(255,255,255,0) 100%)}

/* the photographs that flank the middle, once there is width to spare */
.hside{display:none;margin:0;position:relative}
/* a hairline ring rather than a border, and a shadow with enough weight to hold
   the frame where the photograph itself fades to a white floor */
.hside img{width:100%;height:clamp(340px,54vh,600px);object-fit:cover;object-position:center 38%;
  border-radius:var(--r);filter:saturate(1.16) contrast(1.09) brightness(.98);
  box-shadow:0 30px 62px -30px rgba(23,21,51,.5),0 0 0 1px rgba(60,42,152,.13)}
.hside figcaption{font-family:var(--mono);font-size:10px;letter-spacing:.12em;
  text-transform:uppercase;color:var(--faint);margin-top:var(--space-xs);text-align:center}
@media(min-width:1240px){
  .hbody{grid-template-columns:minmax(150px,244px) minmax(0,1fr) minmax(150px,244px);
    gap:var(--space-3xl)}
  /* placed explicitly: the photographs come first in the markup so they start
     loading early, but the middle belongs in the middle */
  .hside{display:block;grid-row:1}
  .hmid{grid-row:1;grid-column:2}
  .hside-l{grid-column:1;justify-self:start;transform:translateY(-26px)}
  .hside-r{grid-column:3;justify-self:end;transform:translateY(26px)}
}
@media(min-width:1600px){
  .hbody{grid-template-columns:minmax(0,300px) minmax(0,1fr) minmax(0,300px);gap:var(--space-5xl)}
}

/* the mark. It draws itself once on load and is then simply there: see
   js/intro.js. */
.hlock{position:relative;display:block;margin:0 0 var(--space-2xl)}
@media(min-width:1040px){.hlock{margin-bottom:56px}}
/* the mark is inline SVG here rather than an image, because the load animation
   moves its own nodes, bonds and letters */
.hlock .mark{position:relative;z-index:2;display:block;width:300px;max-width:80vw;height:auto}
@media(min-width:1040px){.hlock .mark{width:440px}}
@media(min-width:1600px){.hlock .mark{width:520px}}
/* the four things the load animation moves: nodes, bonds, wordmark letters,
   tagline. Each scales and wipes about its own middle, not the whole artboard. */
.hlock .mark .n,.hlock .mark .bd,.hlock .mark .w,.hlock .mark .tg{
  transform-box:fill-box;transform-origin:center}
/* while the mark is drawing itself, the bar's copy waits its turn */
.intro #hdr-logo{visibility:hidden}
.intro.dock-logo .hlock .mark{visibility:visible}

/* ---------- loading ----------
   The site fetches its catalogue before it can draw anything below the hero,
   and until now that time was a white screen with a header on it. It is now
   the mark assembling on an empty page.

   There is no overlay and no second copy of the mark. Everything except the
   mark is simply held at zero opacity, so when the page is ready nothing has
   to move: the mark is already exactly where the hero put it, and the rest
   fades up around it. The class is set in the document head before the first
   paint and removed by js/intro.js. */
/* the bar's parts rather than the bar itself: the mark in it is the one thing
   that must stay visible, because that is what the assembly hands off to */
.booting nav.main,.booting .bar-right,.booting header.site::before,
.booting .hstage .glow,.booting .hstage .wall,
.booting .hstage .wash,.booting .hstage .mol,
.booting .hside,
.booting .hmid>*:not(.hlock){opacity:0}
html:not(.booting) nav.main,html:not(.booting) .bar-right,
html:not(.booting) .hstage .glow,html:not(.booting) .hstage .wall,
html:not(.booting) .hstage .wash,html:not(.booting) .hstage .mol,
html:not(.booting) .hside,
html:not(.booting) .hmid>*:not(.hlock){transition:opacity .5s var(--ease)}
/* the rule that draws under the mark while it assembles. It is the assembly,
   not a measurement of the download, and it is only ever shown for as long as
   the assembly runs. */
.hboot{position:absolute;left:8%;right:8%;bottom:-18px;height:2px;border-radius:2px;
  background:linear-gradient(90deg,var(--indigo),var(--orange));
  transform:scaleX(0);transform-origin:0 50%;opacity:0}
.booting .hboot{opacity:.85;animation:boot-rule 1.5s cubic-bezier(.3,.8,.25,1) forwards}
@keyframes boot-rule{to{transform:scaleX(1)}}

.hstage .kicker{font-size:12px;font-weight:750;letter-spacing:.03em;color:var(--indigo);
  margin:0 0 var(--space-m)}
@media(min-width:1240px){.hstage .kicker{font-size:13px}}
/* the line changes. Every version stacked in the same box, so the block never
   changes height and nothing below it moves. */
.caps{position:relative;margin:0 0 var(--space-m);width:100%}
.caps span{display:block;font-size:clamp(1.95rem,5.4vw,3.7rem);font-weight:800;line-height:1.06;
  letter-spacing:-.034em;color:var(--ink);text-wrap:balance;max-width:17ch;margin:0 auto;
  transition:opacity .55s ease,transform .55s var(--ease)}
/* inset plus the auto margins centres them on exactly the line the first one
   sets, so nothing shifts on a swap */
.caps span+span{position:absolute;inset:0}
/* Bond signature: the phrase the line turns on runs indigo into orange. */
.caps span em{font-style:normal;color:var(--orange-ink);
  background:linear-gradient(96deg,var(--indigo) 28%,var(--orange));
  -webkit-background-clip:text;background-clip:text;
  color:transparent;-webkit-text-fill-color:transparent}
@supports not ((-webkit-background-clip:text) or (background-clip:text)){
  .caps span em{color:var(--orange-ink);-webkit-text-fill-color:currentColor}
}
.caps span b{font-weight:800;font-variant-numeric:tabular-nums}
.caps span[data-on="0"]{opacity:0;transform:translateY(10px);pointer-events:none}
.hstage .sub{font-size:clamp(1rem,1.6vw,1.2rem);color:var(--body);max-width:56ch;
  margin:0 0 var(--space-xl)}
/* the client's sub headline sits directly under the line and carries the whole
   offer, so it is set in the ink colour and close to the headline; the
   paragraph that explains it follows at reading weight */
.hstage .sub.lead{font-weight:650;color:var(--ink);margin-bottom:var(--space-s);max-width:48ch}

/* the hero versions of the three controls. These are real and working: with no
   JavaScript at all they are what the visitor uses. Once the dock takes over
   they are hidden and the header's own stand exactly on top of them, which is
   why the two have to be built to the same shape. */
.hfind{display:flex;align-items:center;gap:6px;width:min(100%,620px);height:56px;
  border:1.5px solid var(--indigo);border-radius:var(--r);background:#fff;padding:0 8px 0 18px;
  box-shadow:0 26px 54px -34px rgba(60,42,152,.65)}
.hfind:focus-within{box-shadow:0 0 0 3px var(--indigo-w)}
.hfind input{flex:1;min-width:0;border:none;outline:none;background:none;
  font-size:15.5px;color:var(--ink);text-overflow:ellipsis}
.hfind input::placeholder{color:var(--faint)}
.hfind button{flex:none;border:none;cursor:pointer;background:var(--indigo);color:#fff;
  border-radius:8px;width:40px;height:40px;padding:0;display:grid;place-items:center}
.hfind button .ico-mag{width:20px;height:20px}
.hfind button:hover{background:var(--indigo-d)}
.hnote{font-size:14px;color:var(--body);margin:var(--space-l) 0 var(--space-s)}
.hnote b{color:var(--ink);font-weight:650}
.hgo{display:inline-flex;align-items:center;justify-content:center;gap:10px;
  height:54px;padding:0 var(--space-2xl);background:var(--orange-ink);color:#fff;
  border-radius:var(--rs);font-weight:650;font-size:15px;white-space:nowrap;
  box-shadow:0 18px 34px -20px rgba(241,126,1,.75)}
.hgo:hover{background:var(--indigo)}
.hgo i{font-style:normal}
/* the second call to action is a link rather than a button. Two buttons of
   equal weight side by side make the visitor choose before they have read
   anything, and only one of the two is the thing we want them to do. */
.hacts{display:flex;flex-wrap:wrap;align-items:center;justify-content:center;
  gap:var(--space-m) var(--space-xl)}
.hsec{display:inline-flex;align-items:center;gap:var(--space-2xs);font-size:15px;
  font-weight:650;color:var(--indigo)}
.hsec i{font-style:normal;color:var(--orange-ink);transition:transform var(--t-res) var(--ease);
  display:inline-block}
.hsec:hover i{transform:translateX(5px)}

/* Handover. Only visibility, never display: visibility keeps the box, and the
   box is what the header control is measured against and rides on. One class
   per rider, because a width that has no room for the call to action leaves the
   hero's own in place and working rather than hiding it for nothing. */
.dock-logo .hlock .mark{visibility:hidden}
.dock-find .hfind,.dock-cta .hgo{visibility:hidden;pointer-events:none}
@media(prefers-reduced-motion:reduce){
  .caps span{transition:none}
}


/* ---------- how we work with you, as a numbered list ---------- */
.steps{list-style:none;margin:var(--space-l) 0 0;padding:0;
  border-top:1px solid var(--line)}
.step{display:grid;grid-template-columns:auto auto minmax(0,1fr);gap:var(--space-m);
  align-items:start;padding:var(--space-l) 0;border-bottom:1px solid var(--line)}
.step .n{font-family:var(--mono);font-size:12px;font-weight:700;color:var(--orange-ink);
  letter-spacing:.06em;padding-top:5px;width:22px}
.step .si{width:30px;height:30px;color:var(--indigo);flex:none}
.step .si svg{width:100%;height:100%;fill:none;stroke:currentColor;stroke-width:1.5;
  stroke-linecap:round;stroke-linejoin:round}
.step h3{margin:0 0 4px;font-size:16px}
.step p{margin:0;font-size:14.4px;line-height:1.62;max-width:74ch}
@media(max-width:559px){
  .step{grid-template-columns:auto minmax(0,1fr);gap:var(--space-s) var(--space-m)}
  .step .si{grid-row:1;grid-column:2;justify-self:end;width:24px;height:24px}
  .step div{grid-column:1/-1}
}
/* from here the row is wide enough to set the heading beside its paragraph
   rather than leaving half the page empty. display:contents lifts the two out
   of their wrapper and into the row's own grid. */
@media(min-width:900px){
  .step{grid-template-columns:auto auto minmax(0,25ch) minmax(0,1fr);
    gap:var(--space-l);align-items:baseline}
  .step div{display:contents}
  .step h3{margin:0}
  .step p{max-width:78ch}
}
/* The running text grows with the page. The headings and the lede were already
   right; it was the body underneath them that kept a size set for a phone and
   read small on a laptop. Placed here rather than with the section rules
   because these selectors have to come after the ones they raise. */
@media(min-width:1040px){
  .step p{font-size:15.2px}
  .vrow p{font-size:15.4px}
  .prow2 b{font-size:14.8px}
}

.after{margin-top:var(--space-xl)}
/* two ways on from one section, side by side rather than stacked */
.aftrow{display:flex;flex-wrap:wrap;gap:var(--space-s) var(--space-2xl)}

/* A heading beside its content rather than above it. Used where a section would
   otherwise be the sixth in a row to open with a heading over a list. */
.split.aside .vlist{grid-template-columns:1fr}
.split.aside .vrow:nth-last-child(-n+2){border-bottom:1px solid var(--line)}
.split.aside .vrow:last-child{border-bottom:none}
@media(min-width:1040px){
  .split.aside{grid-template-columns:minmax(0,.62fr) minmax(0,1.38fr);gap:var(--space-4xl)}
  .split.aside h2{position:sticky;top:calc(var(--barh) + var(--space-xl))}
}

/* ---------- the gallery ----------
   Not twenty identical tiles. A photograph of a room needs width to read and a
   close view of a tray does not, so every sixth picture takes the full row.
   The figure carries its own caption, which is the only place the pictures are
   described, and the alt text is written for someone who cannot see them. */
.gal{display:grid;gap:var(--space-m);grid-template-columns:1fr}
@media(min-width:700px){.gal{grid-template-columns:1fr 1fr}}
@media(min-width:1100px){.gal{grid-template-columns:repeat(3,1fr)}}
@media(min-width:700px){.gitem.wide2{grid-column:1/-1}}
.gitem{margin:0;border:1px solid var(--line);border-radius:var(--r);overflow:hidden;
  background:#fff}
.gitem img{display:block;width:100%;height:auto;aspect-ratio:16/9;object-fit:cover}
.gitem.wide2 img{aspect-ratio:auto}
@media(min-width:700px){.gitem.wide2 img{aspect-ratio:21/9}}
.gitem figcaption{padding:11px 14px;font-size:13.4px;color:var(--body);
  border-top:1px solid var(--line)}

/* a page that is built but deliberately not published says so at the top of
   itself, rather than in a commit message nobody reads */
.hold{margin:var(--space-l) 0 0;padding:var(--space-m) var(--space-l);
  border:1px solid var(--orange);border-left-width:4px;border-radius:var(--rs);
  background:var(--orange-w);color:var(--ink);font-size:14.5px;max-width:78ch}

/* ---------- the band ----------
   A heading and a row of terms on one line where there is room. Terms, not
   badges: setting them in small caps pills would make a plain statement look
   like a row of filters. It carries who the company serves, which is the one
   list on the page that is not a restatement of the six stages. */
.strip{padding:var(--space-l) 0;border-bottom:1px solid var(--line);background:var(--paper)}
.strip .wrap{display:grid;gap:var(--space-s)}
.strip h2{font-size:15px;font-weight:650;color:var(--ink);margin:0;white-space:nowrap}
/* A grid rather than a wrapping row. A row with rules between the items puts a
   rule at the start of the second line, which reads as a stray mark; a grid
   wraps into columns that line up and needs no rule to separate them. */
.strip ul{list-style:none;margin:0;padding:0;display:grid;
  grid-template-columns:repeat(auto-fit,minmax(190px,1fr));
  gap:var(--space-2xs) var(--space-xl)}
.strip li{font-size:14.5px;color:var(--body)}
@media(max-width:1099px){
  .strip ul{grid-template-columns:1fr 1fr;gap:var(--space-2xs) var(--space-l)}
}
@media(min-width:1100px){
  .strip .wrap{grid-template-columns:auto minmax(0,1fr);align-items:baseline;
    gap:var(--space-2xl)}
}

/* the invitation that follows the catalogue: a compound that is not listed is
   still a compound Winkem can quote for, and that is the whole point of it */
.ask{display:grid;gap:var(--space-m);align-items:center;margin-top:var(--space-2xl);
  padding:var(--space-l);border:1px solid var(--line);border-radius:var(--r);
  background:var(--paper)}
.ask h3{margin:0 0 var(--space-2xs)}
.ask p{margin:0;font-size:14.6px;max-width:62ch}
@media(min-width:760px){.ask{grid-template-columns:minmax(0,1fr) auto;gap:var(--space-2xl)}}

/* ---------- compact catalogue rows ---------- */
.prows{border-top:1px solid var(--line);margin-top:var(--space-l)}
.prow2{display:grid;grid-template-columns:52px minmax(0,1fr) auto;gap:var(--space-m);
  align-items:center;padding:var(--space-s) 0;border-bottom:1px solid var(--line);
  transition:background var(--t-res) var(--ease)}
.prow2:hover{background:var(--tint)}
.prow2 .sw2{width:52px;height:42px;display:grid;place-items:center}
.prow2 .sw2 img{max-width:100%;max-height:42px;width:auto;object-fit:contain}
.prow2 b{display:block;font-size:14px;color:var(--ink);line-height:1.3;font-weight:650}
.prow2 .m2{font-family:var(--mono);font-size:11.5px;color:var(--orange-ink);font-weight:650}
.prow2 .en2{font-size:12.5px;font-weight:700;color:var(--indigo);white-space:nowrap}
.prow2 .en2 i{font-style:normal;transition:transform var(--t-res) var(--ease);display:inline-block}
.prow2:hover .en2 i{transform:translateX(3px)}
@media(max-width:559px){
  .prow2{grid-template-columns:44px minmax(0,1fr);gap:var(--space-s)}
  .prow2 .en2{grid-column:2;justify-self:start;padding-top:2px}
}
.crows{border-top:1px solid var(--line);margin-top:var(--space-xl)}
.crow2{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:var(--space-m);align-items:center;
  padding:var(--space-m) 0;border-bottom:1px solid var(--line);
  transition:background var(--t-res) var(--ease)}
.crow2:hover{background:var(--tint)}
.crow2 b{display:block;font-size:15px;color:var(--ink);font-weight:650}
.crow2 span{font-size:13px;color:var(--body)}
.crow2 .ct2{font-family:var(--mono);font-size:14px;color:var(--indigo);font-weight:700;white-space:nowrap}

/* ---------- imagery: the frame follows the subject ---------- */
.media.portrait img{aspect-ratio:3/4}
.media.wide img{aspect-ratio:16/9}
.media.square img{aspect-ratio:1}
.media.free img{aspect-ratio:auto;height:auto}
/* A photograph does not get better by getting bigger. bench.jpg is 800px wide
   and was rendering at 871, which is an upscale of its own source; the pilot
   plant was 692 by 923, a photograph taller than a laptop's viewport sitting in
   the middle of a page that is meant to be a way through to the focus pages.
   The grid stops growing before the images pass their own size. */
.figgrid{display:grid;gap:var(--space-m)}
@media(min-width:760px){
  .figgrid{grid-template-columns:2fr 1fr}
  .figgrid > .media:first-child{grid-row:1 / 3;display:flex;flex-direction:column}
  .figgrid > .media:first-child img{flex:1;min-height:0;height:100%;aspect-ratio:auto;object-fit:cover}
}

/* ---------- footers, one treatment per page ---------- */
footer.site.v2{background:var(--paper);color:var(--body);border-top:1px solid var(--line)}
footer.site.v2 a{color:var(--body)}
footer.site.v2 a:hover{color:var(--indigo)}
footer.site.v2 .fgrid2{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));
  gap:var(--space-xl) var(--space-2xl);padding:var(--space-3xl) 0 var(--space-xl)}
@media(min-width:760px){footer.site.v2 .fgrid2{grid-template-columns:1.6fr repeat(3,1fr)}}
footer.site.v2 .fcol-t{display:block;font-family:var(--mono);font-size:10px;letter-spacing:.14em;
  text-transform:uppercase;color:var(--indigo);margin-bottom:var(--space-s)}
footer.site.v2 .fgrid2 a{display:block;font-size:13.5px;line-height:2;text-decoration:none}
footer.site.v2 .blurb2{font-size:13.5px;max-width:34ch;margin:0 0 var(--space-s)}
footer.site.v2 .flogo2{display:block;width:190px;max-width:60%;margin-bottom:var(--space-m)}
.fmeta{display:flex;flex-wrap:wrap;gap:6px var(--space-l);align-items:center;
  padding:var(--space-s) 0;border-top:1px solid var(--line);
  font-family:var(--mono);font-size:10.5px;letter-spacing:.07em;color:var(--faint)}
.fmeta .ok{width:6px;height:6px;border-radius:50%;background:var(--ok);display:inline-block;margin-right:6px}

/* G2 the plate */
.f-plate{height:150px;background:url(../img/site/plant-elevation.png) center bottom/cover no-repeat}
@media(min-width:900px){.f-plate{height:190px}}

/* G1 the bleed */
.f-bleed{height:120px;overflow:hidden;display:flex;align-items:flex-end;justify-content:center}
@media(min-width:900px){.f-bleed{height:180px}}
.f-bleed p{margin:0;font-size:clamp(64px,17vw,230px);line-height:.78;font-weight:800;
  letter-spacing:-.05em;transform:translateY(28%);
  background-image:url(../img/site/wall.png),linear-gradient(var(--indigo-w),var(--indigo-w));
  background-size:300px auto,100% 100%;background-position:center;background-blend-mode:multiply;
  -webkit-background-clip:text;background-clip:text;color:transparent;
  -webkit-text-stroke:.8px rgba(60,42,152,.42)}
@supports not ((-webkit-background-clip:text) or (background-clip:text)){
  .f-bleed p{color:var(--indigo-w);-webkit-text-stroke:0}
}

/* G5 the periodic strip */
.f-el{display:flex;gap:7px;padding:var(--space-l) 0 var(--space-xl);overflow-x:auto;
  scrollbar-width:none;-webkit-overflow-scrolling:touch}
.f-el::-webkit-scrollbar{display:none}
.pt2{flex:1 0 auto;min-width:74px;border:1px solid var(--line);border-radius:var(--rs);
  padding:var(--space-s);background:var(--paper)}
.pt2 .z2{font-family:var(--mono);font-size:9.5px;color:var(--faint)}
.pt2 .sy2{font-size:1.9rem;line-height:1;color:var(--ink);font-weight:700;margin:2px 0 4px;
  letter-spacing:-.02em}
.pt2 .nm2{font-size:10px;color:var(--body);display:block}
.pt2 .ct2b{font-family:var(--mono);font-size:8.5px;color:var(--faint);display:block;margin-top:3px}
.pt2.has{border-color:var(--orange);background:var(--tint2)}
.pt2.has .ct2b{color:var(--orange-ink)}
.pt2.term{border-color:var(--indigo);background:var(--indigo-w)}
.pt2.term .sy2,.pt2.term .z2{color:var(--indigo)}
.pt2.term .ct2b{color:var(--indigo)}
.f-el .gap2{flex:0 0 16px;min-width:16px;border:none;background:none;padding:0}

/* G3 the live figures */
.f-figs{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:var(--space-l) var(--space-2xl);
  padding:var(--space-l) 0 var(--space-xl);border-top:1px solid var(--line);font-family:var(--mono)}
@media(min-width:760px){.f-figs{grid-template-columns:repeat(4,minmax(0,1fr))}}
.f-figs b{display:block;font-size:1.15rem;color:var(--ink);font-weight:650;
  font-variant-numeric:tabular-nums}
.f-figs .lb2{font-size:11px;color:var(--body);font-family:var(--sans)}
.f-figs .sm2{font-size:9px;color:var(--faint);letter-spacing:.1em;text-transform:uppercase}


/* ================= v5: one shape per section =================
   The page below the hero used to be six variations on the same move: a
   heading, a lede, a row of cards, a link. The sameness was the thing that
   read as a template, and no amount of restyling the cards was going to fix
   a rhythm problem. So each section on the home page now has a shape of its
   own, chosen for what that section actually is: an index for the contents,
   a ladder for a sequence, a table for numbers, a diagnostic list for the
   problems work arrives as, a band for the close. None of them is a card. */

/* ---------- the index, section 2 of the client's document ----------
   Six terms under the hero. They are not a claim and they are not a fourth
   restatement of the six stages, which is what v4 deleted: they are the
   contents of this page, each one the name of a section and each one a link
   to it. That is what earns the numbering, and it is why they sit on a rule
   rather than in boxes. Quiet on purpose. It is the first thing after the
   hero and it should not compete with it. */
.idxband{padding:var(--space-xl) 0 var(--space-l);border-bottom:1px solid var(--line)}
.idxband h2{font-size:15px;font-weight:650;color:var(--ink);margin:0 0 var(--space-m)}
.idx{list-style:none;margin:0;padding:0;
  display:grid;grid-template-columns:repeat(2,minmax(0,1fr));
  column-gap:var(--space-l);row-gap:0}
.idx li{border-top:1px solid var(--line);min-width:0}
.idx a{display:flex;align-items:baseline;gap:var(--space-xs);
  padding:var(--space-s) 0;font-size:14.2px;font-weight:600;color:var(--ink);
  transition:color var(--t-res,.2s) var(--ease,ease)}
.idx a:hover{color:var(--indigo)}
.idx .k{font-family:var(--mono);font-variant-numeric:tabular-nums;
  font-size:11px;font-weight:700;color:var(--orange-ink);flex:none}
@media(min-width:600px){.idx{grid-template-columns:repeat(3,minmax(0,1fr))}}
@media(min-width:1100px){
  .idxband{padding:var(--space-l) 0}
  .idxband .wrap{display:grid;grid-template-columns:auto minmax(0,1fr);
    align-items:start;gap:var(--space-2xl)}
  .idxband h2{margin:var(--space-s) 0 0}
  .idx{grid-template-columns:repeat(6,minmax(0,1fr));column-gap:var(--space-m)}
  .idx a{font-size:13.6px;flex-direction:column;gap:var(--space-3xs);
    padding:var(--space-s) 0 var(--space-m)}
}

/* ---------- the ladder, sections 4 and 5 ----------
   The six stages, in order, as one long run of rows rather than a grid of
   equal tiles. A grid says these are six of a kind; a ladder says one leads
   to the next, which is the only thing this list has to say that none of the
   others do. The numeral is the graphic. It replaced six line drawings: the
   drawings were decoration that had to be invented, the number is already
   true. */
.ladder{list-style:none;margin:var(--space-xl) 0 0;padding:0;
  border-top:1px solid var(--line)}
.rung{display:grid;grid-template-columns:auto minmax(0,1fr);
  column-gap:var(--space-m);row-gap:var(--space-3xs);
  padding:var(--space-l) 0;border-bottom:1px solid var(--line)}
.rung .rn{grid-column:1;grid-row:1 / span 2;
  font-family:var(--mono);font-variant-numeric:tabular-nums;
  font-size:22px;font-weight:700;line-height:1.05;color:var(--indigo)}
.rung h3{grid-column:2;margin:0;font-size:17.5px;letter-spacing:-.01em}
.rung p{grid-column:2;margin:0;font-size:14.6px;line-height:1.62;
  color:var(--body);max-width:74ch}
@media(min-width:760px){
  .rung{grid-template-columns:auto minmax(0,20ch) minmax(0,1fr);
    column-gap:var(--space-xl);align-items:baseline;padding:var(--space-xl) 0}
  .rung .rn{grid-row:1;font-size:32px}
  .rung h3{font-size:20px}
  .rung p{grid-column:3;grid-row:1}
}
@media(min-width:1200px){
  .rung{grid-template-columns:auto minmax(0,26ch) minmax(0,1fr);
    column-gap:var(--space-3xl);padding:var(--space-2xl) 0}
  .rung .rn{font-size:44px}
  .rung h3{font-size:23px}
  .rung p{font-size:15.2px}
}

/* ---------- the specification table, section 7 ----------
   Their document asks, in its own words, for verified reactor capacities,
   scale ranges and equipment to be inserted here. So this section is the
   numbers rather than four more sentences about chemistry: the four
   development scales Winkem works at, with the ranges as written in the
   capability document. A table, because it is tabular. */
.spec{margin-top:var(--space-xl);overflow-x:auto}
.spec table{width:100%;border-collapse:collapse;min-width:600px}
.spec th{text-align:left;font-family:var(--mono);font-size:11.5px;font-weight:700;
  letter-spacing:.06em;text-transform:uppercase;color:var(--faint);
  padding:0 var(--space-l) var(--space-xs) 0;border-bottom:1.5px solid var(--ink)}
.spec td{padding:var(--space-m) var(--space-l) var(--space-m) 0;
  border-bottom:1px solid var(--line);vertical-align:baseline;
  font-size:14.6px;line-height:1.6;color:var(--body)}
.spec tr:last-child td{border-bottom:1.5px solid var(--ink)}
.spec td:last-child,.spec th:last-child{padding-right:0}
.spec .sn{font-family:var(--mono);font-variant-numeric:tabular-nums;font-size:12px;
  font-weight:700;color:var(--orange-ink);width:1%;white-space:nowrap}
.spec .st{color:var(--ink);font-weight:650;font-size:15.4px;width:22%}
.spec .sc{font-family:var(--mono);font-variant-numeric:tabular-nums;
  color:var(--indigo);font-weight:700;white-space:nowrap;width:1%}
.spec caption{caption-side:bottom;text-align:left;font-size:13.2px;
  color:var(--faint);padding-top:var(--space-m);max-width:74ch}
@media(min-width:1200px){.spec .st{font-size:16.5px}.spec td{font-size:15.2px}}

/* ---------- the diagnostic list, section 10 ----------
   Work does not arrive as a service name, it arrives as a problem, so the
   problem is the large half of each row and the service is the small half.
   That is the reverse of the ladder above, which is the point: the two
   sections are lists of the same length and they should not read alike. */
.diag{margin-top:var(--space-xl);border-top:1px solid var(--line)}
.dg{padding:var(--space-l) 0;border-bottom:1px solid var(--line);
  display:grid;gap:var(--space-2xs)}
.dg .q{margin:0;font-size:18.5px;line-height:1.3;font-weight:650;
  color:var(--ink);letter-spacing:-.012em;max-width:32ch;text-wrap:balance}
.dg .a{margin:0;font-size:14.6px;line-height:1.62;color:var(--body);max-width:60ch}
@media(min-width:900px){
  .dg{grid-template-columns:minmax(0,.95fr) minmax(0,1.05fr);
    column-gap:var(--space-3xl);align-items:baseline;padding:var(--space-xl) 0}
  .dg .q{font-size:22px}
}
@media(min-width:1400px){.dg{column-gap:var(--space-5xl)}.dg .q{font-size:26px}}

/* ---------- the closing band, section 12 ----------
   Full width and solid, not a rounded gradient panel floating on a tint. The
   page ends on the one flat surface it has, and it runs straight into the
   footer, which is the same family of colour: the footer's own top margin is
   there to hold it off a white page and would otherwise leave a white stripe
   between two dark blocks. */
.ctafull{background:var(--indigo);color:#fff;padding:var(--space-4xl) 0}
.ctafull h2{color:#fff;margin:0 0 var(--space-s);max-width:22ch}
.ctafull p{color:rgba(255,255,255,.88);margin:0;max-width:58ch;font-size:15.4px}
.ctafull .cta2{display:flex;gap:var(--space-s);flex-wrap:wrap;margin-top:var(--space-xl)}
.ctafull .cta2 .btn{width:auto}
.btn-w{background:transparent;color:#fff;border-color:rgba(255,255,255,.5)}
.btn-w:hover{border-color:#fff;background:rgba(255,255,255,.1)}
.btn-w:active{background:rgba(255,255,255,.18)}
body:has(.ctafull) footer.site{margin-top:0}
@media(min-width:1040px){
  .ctafull{padding:var(--space-5xl) 0}
  .ctafull .wrap{display:grid;grid-template-columns:minmax(0,1fr) auto;
    gap:var(--space-4xl);align-items:end}
  .ctafull .cta2{margin-top:0}
}

/* location column of the instrument table: which analysis is done on Winkem
   premises and which is sent out. It is small and quiet because it is a
   qualifier, not a claim. */
.spec .sl{font-family:var(--mono);font-size:12px;color:var(--faint);
  white-space:nowrap;width:1%}

/* ---------- the plant, section 8 ----------
   The only section on the page that leads with the photographs and puts its
   words underneath them. Everything else here opens with a heading, and a
   section about two rooms should show the rooms first. */
.plantwords{margin-top:var(--space-2xl);display:grid;gap:var(--space-s)}
.plantwords h2{margin:0}
.plantwords p{margin:0}
@media(min-width:1100px){
  .plantwords{grid-template-columns:minmax(0,.8fr) minmax(0,1.2fr);
    column-gap:var(--space-4xl);align-items:start}
  .plantwords h2{grid-column:1}
  .plantwords .lede{grid-column:2;grid-row:1}
  .plantwords .after{grid-column:2;margin-top:var(--space-m)}
}
/* the band of sectors reads as a band, not as another white section */
.strip{background:var(--tint);border-top:1px solid var(--line)}

/* One measure for the three rule bound lists and the figure grid, so the
   hairlines on the ladder, the table and the diagnostic list all stop in the
   same place down the page instead of each running to whatever its own
   content happened to need. At 1600 that leaves the same right margin under
   every one of them, which is the difference between a column and a leftover. */
.ladder,.diag,.spec table{}
/* six sectors in three columns is two even rows; the auto fit grid was making
   five and one, and the one looked like a mistake */
@media(min-width:1100px){
  .strip ul{grid-template-columns:repeat(3,minmax(0,1fr))}
}

.specnote{font-size:13.2px;color:var(--faint);margin:var(--space-m) 0 0;max-width:74ch}
/* Below the width the three columns need, the table stops being a table and
   becomes a run of blocks. The alternative was a sideways scroll on the one
   section of the page that exists to be read carefully. */
@media(max-width:599px){
  .spec{overflow-x:visible}
  .spec table{min-width:0;display:block}
  .spec thead{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0)}
  .spec tbody,.spec tr,.spec td{display:block}
  .spec tr{padding:var(--space-m) 0;border-bottom:1px solid var(--line)}
  .spec tr:first-child{border-top:1.5px solid var(--ink)}
  .spec tr:last-child{border-bottom:1.5px solid var(--ink)}
  .spec td,.spec tr:last-child td{border:none;padding:0;width:auto}
  /* the column widths are what makes it a table and they have to go with it,
     or the instrument name wraps every second word inside a 22 per cent block */
  .spec .st,.spec .sl,.spec .sc{width:auto;white-space:normal}
  .spec .st{font-size:15.4px;margin-bottom:var(--space-3xs)}
  .spec .sl{margin-top:var(--space-3xs)}
}

/* ---------- the catalogue, section 6 ----------
   The one section that had not been recomposed: a heading, a lede, a field,
   two lists, a button and a bordered box, stacked. The field now sits beside
   the words it belongs to, the second list gets a subordinate heading rather
   than a second h2 shrunk with an inline style, and the invitation at the end
   is a ruled row like every other row on the page instead of a card. */
.cathead{display:grid;gap:var(--space-l);}
@media(min-width:1100px){
  .cathead{grid-template-columns:minmax(0,1fr) minmax(0,1fr);
    column-gap:var(--space-4xl);align-items:end}
  .cathead .hsearch{margin-bottom:0}
}
.subhead{font-size:1.2rem;font-weight:800;letter-spacing:-.02em;
  margin:var(--space-3xl) 0 0;}
.crows,.prows{}
.askrow{display:grid;gap:var(--space-m);align-items:center;;
  margin-top:var(--space-2xl);padding-top:var(--space-l);
  border-top:1.5px solid var(--ink)}
.askrow h3{margin:0 0 var(--space-2xs)}
.askrow p{margin:0;font-size:14.6px;line-height:1.62;color:var(--body);max-width:62ch}
.askrow .btn{width:auto}
@media(min-width:760px){
  .askrow{grid-template-columns:minmax(0,1fr) auto;column-gap:var(--space-3xl)}
}

/* ---------- the load stage ----------
   A sheet over a page that is already complete underneath it. It is display
   none by default and only the inline script in the head turns it on, which is
   the whole safety argument: with scripts blocked, or with reduced motion, or
   on the second page of a session, it never exists and nothing is ever hidden
   waiting for it. The old animation worked the other way round, hiding the
   page and waiting for a script to reveal it. */
.loadstage{display:none}
html.loading .loadstage{position:fixed;inset:0;z-index:300;display:grid;
  place-items:center;background:var(--paper);padding:0 8vw;
  opacity:1;transition:opacity .42s var(--ease)}
html.loading .loadstage.out{opacity:0}
/* The opening size and position are the stylesheet's, not the script's, so
   they are settled before the first frame rather than applied during it. The
   script never moves the mark until the travel starts. */
html.loading .loadstage svg{width:min(560px,72vw);height:auto;overflow:visible;
  will-change:transform}
/* the page underneath must not scroll while the sheet is over it, or a visitor
   who flicks during the animation lands halfway down a page they never saw */
html.loading,html.loading body{overflow:hidden}
@media(prefers-reduced-motion:reduce){.loadstage{display:none!important}}

/* ================= the moving line, document section 2 =================
   The terms run across the page in one continuous loop. Two identical copies in a
   flex track, each translated by its own width plus the gap: transform percentages
   resolve against the element's own box, so the second copy lands exactly where the
   first began and there is no seam. The animation is entirely here; the script only
   decides how many times the terms have to repeat inside a copy to cover the track,
   and sets the duration from the measured width so the speed holds at any size.

   Spacing is one gap and nothing else. The sample used justify-content:space-between,
   which spreads the terms to fill the track and therefore spaces them differently at
   every width. Even spacing means the gap is the only thing between them. */
.rollband{background:#FFFDF9;padding:13px 0;
  border-top:1px solid var(--line);border-bottom:1px solid var(--line)}
.roll{position:relative;display:flex;overflow:hidden;user-select:none;
  --gap:clamp(24px,3.4vw,50px);
  --fade:clamp(30px,7vw,130px);
  --play:running;
  gap:var(--gap);
  -webkit-mask-image:linear-gradient(90deg,transparent 0,#000 var(--fade),
    #000 calc(100% - var(--fade)),transparent 100%);
  mask-image:linear-gradient(90deg,transparent 0,#000 var(--fade),
    #000 calc(100% - var(--fade)),transparent 100%)}
.rollset{list-style:none;margin:0;padding:0;flex-shrink:0;
  display:flex;align-items:center;gap:var(--gap);
  animation:rollrun var(--dur) linear infinite;
  animation-play-state:var(--play);will-change:transform}
@keyframes rollrun{to{transform:translateX(calc(-100% - var(--gap)))}}
.roll:hover .rollset,.roll:focus-within .rollset{animation-play-state:paused}
/* the dot sits in its own place in the rhythm, a gap either side of it, so the
   spacing between one term and the next is the same everywhere along the line */
.rollset li{display:flex;align-items:center;gap:var(--gap);white-space:nowrap;
  color:var(--ink);font-weight:700;letter-spacing:-.006em;
  font-size:clamp(0.95rem,1.6vw,1.22rem);line-height:1.35}
.rollset li::after{content:"";flex:none;width:.26em;height:.26em;
  border-radius:50%;background:var(--orange-ink)}
/* With no script the line still scrolls. The animation is CSS and the markup that
   build-static.py writes carries the second copy it needs, so nothing here waits
   to be told to start. What the script adds is exactness: it counts the repetitions
   the real width needs instead of the three that are written out, and it sets the
   duration from that width so the speed is the same at every size. These fallback
   durations are only ever seen when there is no script, so they are approximate on
   purpose rather than a second tuning to keep in step with the first. */
.roll{--dur:64s}
@media(min-width:760px){.roll{--dur:78s}}
@media(min-width:1280px){.roll{--dur:96s}}
@media(min-width:1800px){.roll{--dur:118s}}

/* Reduced motion is the one state that does not move: a wrapped, centred list of
   the terms, which is the same information standing still. flex-shrink:0 is what
   holds the copies at full width while the loop runs, and it is also what would
   stop this from ever wrapping, so it goes. */
.roll[data-ready="still"]{-webkit-mask-image:none;mask-image:none;
  flex-wrap:wrap;justify-content:center;overflow:visible;padding:0 var(--pad)}
.roll[data-ready="still"] .rollset{animation:none;flex-wrap:wrap;justify-content:center;
  flex-shrink:1;min-width:0;max-width:100%;row-gap:calc(var(--gap) * .34)}
.roll[data-ready="still"] .rollset[aria-hidden]{display:none}
.roll[data-ready="still"] .rollset li:last-child::after{display:none}
@media(prefers-reduced-motion:reduce){
  .roll{-webkit-mask-image:none;mask-image:none;flex-wrap:wrap;justify-content:center;
    overflow:visible;padding:0 var(--pad)}
  .rollset{animation:none;flex-wrap:wrap;justify-content:center;
    flex-shrink:1;min-width:0;max-width:100%;row-gap:calc(var(--gap) * .34)}
  .rollset li:last-child::after{display:none}
}

/* ---------- the hero resolves into it ----------
   Opt in, by class, so the page that is live is not touched. The hero's drawing and
   its bond network are taken to nothing over its last stretch, and the section below
   opens on the same warm ground, so there is no edge where one stops and the other
   starts. Fading the texture out before the boundary rather than continuing it past
   the boundary avoids having to match the tile phase across a height that moves with
   the viewport, which is where a seam would show. */
/* The fade belongs behind the words and the controls, not over them. Left above
   them it dimmed the call to action, which is the one thing in the hero that must
   not look disabled. The decorative layers sit at 0 to 2, so the ramp goes at 3 and
   the body is lifted clear of it. */
/* The hero and the line share the first screen.
   The stage is 100svh on its own from 1040 up, which put the line just off the
   bottom of it: on a laptop you had to scroll to find out the section existed.
   The wrapper takes the height instead and the stage takes what is left, so the
   two together are exactly one screen and the line is the last thing in it.
   Opt in by class, so the page that is live keeps the hero it has. */
@media(min-width:1040px){
  .hpin.hfit{min-height:100svh;display:flex;flex-direction:column}
  .hpin.hfit .hstage{min-height:0;flex:1 1 auto}
}
/* the rule above it stays: it is what separates the line from the hero */

/* On a screen that is wide but not tall, the hero's own content is taller than
   the window before the line is added at all, so no amount of arranging puts the
   line in the first screen: the hero has to give up some height. This is the only
   place it does, it is conditioned on the height rather than the width, and it
   changes spacing and the size of the mark, not the design. Above 920px tall the
   hero is exactly as it was. */
@media(min-width:1040px) and (max-height:920px){
  .hpin.hfit .hstage{padding-top:calc(var(--barh) + var(--space-xs));
    padding-bottom:var(--space-s)}
  .hpin.hfit .hlock{margin-bottom:var(--space-m)}
  .hpin.hfit .hlock .mark{width:250px}
  .hpin.hfit .caps{margin-bottom:var(--space-xs)}
  .hpin.hfit .sub{margin-top:var(--space-xs);line-height:1.5}
  .hpin.hfit .hfind{margin-top:var(--space-m)}
  .hpin.hfit .hnote{margin-top:var(--space-xs)}
  .hpin.hfit .hacts{margin-top:var(--space-m)}
}
/* Shorter still, which is where most laptops actually are: 1366 by 768 and 1280
   by 720 are both under 800 tall. Spacing alone does not find the last thirty
   pixels, so the mark and the headline come down a step. This is the only place
   on the site where they are not at full size, and it is the trade for the line
   being on screen when the page opens. */
@media(min-width:1040px) and (max-height:800px){
  .hpin.hfit .hlock .mark{width:208px}
  .hpin.hfit .caps{font-size:3.05rem}
  .hpin.hfit .sub{margin-top:var(--space-3xs)}
  /* the last few pixels come from the line's own padding rather than from the
     hero, because 1366 by 768 was missing it by five */
  .hpin.hfit .rollband{padding:9px 0}
}

.hstage.hfade .hbody{position:relative;z-index:5}
.hstage.hfade::after{content:"";position:absolute;left:0;right:0;bottom:0;z-index:3;
  height:min(230px,34%);pointer-events:none;
  background:linear-gradient(to bottom,rgba(255,253,249,0) 0%,
    rgba(255,253,249,.74) 52%,#FFFDF9 100%)}

/* ================= section 3, the introduction =================
   Words in one column with the photograph beside them, the photograph inside a
   drawing frame with a title block under it. The frame and the block are the
   point: a photograph dropped on a page is a picture, a photograph in a frame
   with two verifiable facts under it is a plate, which is the register the rest
   of this site is written in. */
.s3{padding:var(--space-4xl) 0}
.plate{display:grid;gap:var(--space-xl);align-items:start}
.platewords h2{margin:0 0 var(--space-m)}
.platewords .lede{margin:0 0 var(--space-m)}
.platewords p{margin:0 0 var(--space-s);color:var(--body);max-width:58ch}
/* .btn is full width by default, which is right for the buttons that sit alone
   at the end of a narrow column. Here it sits under a paragraph, so it takes
   the width of its own words. width:auto is not enough: a block level box with
   auto width fills the line, which is why this was fitted on a desktop and the
   full width of the column on a phone. */
.platego{width:fit-content;margin-top:var(--space-m)}

/* the frame, drawn rather than shadowed, with the corner marks the rest of the
   drawing language uses */
.pfig{position:relative;margin:0;border:1px solid var(--line);background:#fff;
  padding:14px}
.pfig::before,.pfig::after{content:"";position:absolute;width:10px;height:10px;
  pointer-events:none}
.pfig::before{top:-1px;right:-1px;border-top:1.5px solid var(--indigo);
  border-right:1.5px solid var(--indigo)}
.pfig::after{bottom:-1px;left:-1px;border-bottom:1.5px solid var(--indigo);
  border-left:1.5px solid var(--indigo)}
/* cover, not contain. Contain is right for a structure drawing on a white
   ground and wrong for a photograph, which sits letterboxed inside its own
   frame with white down both sides. */
.pfig img{width:100%;display:block;object-fit:cover;aspect-ratio:16/10;
  background:var(--tint)}
.pfig figcaption{margin-top:12px;padding-top:10px;border-top:1px solid var(--line)}
.pblock{display:grid;grid-template-columns:1fr;gap:10px}
.pblock b{display:block;font-size:13.6px;font-weight:650;color:var(--ink);margin-top:3px}
.pann{font-family:var(--mono);font-size:11px;letter-spacing:.13em;
  text-transform:uppercase;color:var(--faint)}

/* Below the split the picture is given a shorter frame rather than a narrower
   one: a centred figure under left aligned words reads as a mistake. */
@media(min-width:600px){
  .pblock{grid-template-columns:1fr 1fr;gap:var(--space-m)}
  .pfig img{aspect-ratio:16/9}
}
@media(max-width:599px){
  .pfig{padding:9px}
  .pfig img{aspect-ratio:4/3}
}
@media(min-width:900px){
  .plate{grid-template-columns:minmax(0,1.08fr) minmax(0,.92fr);
    gap:var(--space-4xl);align-items:center}
  .pfig img{aspect-ratio:4/3}
}
@media(min-width:1200px){
  .s3{padding:var(--space-5xl) 0}
  .plate{gap:var(--space-5xl);grid-template-columns:minmax(0,1fr) minmax(0,.86fr)}
}
/* The words stop growing at their measure and a 4/3 frame does not, so past a
   laptop the photograph was half again as tall as the column beside it: 477
   against 433 at 1600 and climbing. Shallower, and it stops climbing. */
@media(min-width:1400px){
  .pfig img{aspect-ratio:16/10;max-height:400px}
}
/* Centred, and on the same measure as the pathway below it. It was capped but not
   centred, so it sat against the left of a 1760px wrap and the space it did not use
   all collected on the right: 456 on the left against 704 on the right at 2560. */
.plate{margin-left:auto;margin-right:auto}

/* ================= section 4, the pathway =================
   Sections 4 and 5 of the document as one thing. One spine, six markers on it, the
   words to the right, and each marker turns over from its number into its icon as
   it passes. */
.s4{padding:var(--space-4xl) 0;background:var(--tint)}
.jrhead{margin-bottom:var(--space-2xl)}
.jrhead h2{margin:0 0 var(--space-s)}
.jrhead .lede{margin:0;max-width:76ch}

/* Centred and held to a measure. Left to the full 1760px wrap the description column
   ran to a 70ch cap and left the rest of a wide screen empty to the right, so the
   section read as pushed against the left edge rather than composed. */
.jrhead,.jrlist{margin-left:auto;margin-right:auto}
.jrlist{list-style:none;margin-top:0;margin-bottom:0;padding:0;display:grid;position:relative}
.jrrow{--mk:44px;--rp:14px;position:relative;display:grid;
  grid-template-columns:var(--mk) minmax(0,1fr);
  column-gap:var(--space-m);padding:var(--rp) 0;align-items:start}
/* The spine is drawn per row, marker to marker, so it starts and stops on them
   rather than running past the first and the last. Both ends come off the marker
   size rather than being typed: numbers written for a marker at the top of its row
   put the line inside one marker and short of the next once the rows centre theirs. */
.jrrow::after{content:"";position:absolute;left:calc(var(--mk) / 2 - 0.75px);
  top:calc(var(--rp) + var(--mk));bottom:calc(-1 * var(--rp));
  width:1.5px;background:var(--indigo);opacity:.2}
.jrrow:last-child::after{display:none}

.jrmark{position:relative;width:var(--mk);height:var(--mk);perspective:700px}
.jrflip{position:absolute;inset:0;transform-style:preserve-3d;
  transition:transform .52s cubic-bezier(.4,0,.2,1)}
.jrrow[data-on="1"] .jrflip{transform:rotateY(180deg)}
.jrface{position:absolute;inset:0;display:grid;place-items:center;border-radius:50%;
  background:var(--paper);border:1.5px solid rgba(60,42,152,.22);
  backface-visibility:hidden;-webkit-backface-visibility:hidden}
.jrnum{font-family:var(--mono);font-size:13px;font-weight:700;color:var(--indigo)}
.jricon{transform:rotateY(180deg);border-color:rgba(60,42,152,.34)}
.jricon svg{width:24px;height:24px;display:block;overflow:visible}
/* duo colour on one rule: the glassware and the structure indigo, what is inside it
   or what comes out of it orange */
.jricon svg path,.jricon svg circle{fill:none;stroke:var(--indigo);stroke-width:1.6;
  stroke-linecap:round;stroke-linejoin:round}
.jricon svg .o{stroke:var(--orange-ink)}
/* a bubble is a dot, not a ring: at this size a stroked circle of radius one
   is solid anyway, and reads as a smudge rather than as a shape */
.jricon svg .f{fill:var(--orange-ink);stroke:none}

.jrbody h3{margin:0 0 5px;font-size:16.5px;line-height:1.25}
.jrbody p{margin:0;font-size:14.4px;line-height:1.6;color:var(--body);max-width:70ch}
.jrafter{;margin:var(--space-xl) auto 0}

@media(min-width:700px){
  /* every row the height of the tallest, so a heading that wraps takes its space
     from its own row's slack rather than from the row above it */
  .jrlist{grid-auto-rows:1fr}
  .jrrow{--mk:52px;--rp:18px;column-gap:var(--space-xl)}
  .jricon svg{width:28px;height:28px}
  .jrbody h3{font-size:17.5px}
}
@media(min-width:1040px){
  .jrrow{--mk:60px;--rp:20px;
    grid-template-columns:var(--mk) minmax(0,24ch) minmax(0,1fr);
    column-gap:var(--space-3xl);align-items:center}
  .jrrow::after{top:calc(50% + var(--mk) / 2);bottom:calc(var(--mk) / 2 - 50%)}
  .jrnum{font-size:15px}
  .jricon svg{width:32px;height:32px}
  .jrbody{display:contents}
  .jrbody h3{font-size:18.5px;margin:0}
  .jrbody p{font-size:15px}
}
/* The photographs beside the pathway, on a wide screen only.
   The description column stops at its own measure, so on a wide screen the right
   third of the section was empty. Three photographs divide exactly the height the
   six stages take, so each one stands against two of them, and the block cannot
   run past the list or come up short of it however the sentences wrap. */
.jrshots{display:none}
@media(min-width:1280px){
  .jrwrap{display:grid;grid-template-columns:minmax(0,1fr) 320px;
    column-gap:var(--space-3xl);align-items:stretch}
  /* the auto margins that centred the list on its own are what a track is for
     now, and left in they shrink it to fit-content and indent it off the page
     margin the heading above it keeps */
  .jrwrap .jrlist{margin-left:0;margin-right:0}
  .jrshots{display:grid;grid-template-rows:repeat(3,minmax(0,1fr));gap:14px;
    min-height:0}
  /* the frame every photograph on this page sits in */
  .jrshot{position:relative;margin:0;min-height:0;display:grid;
    grid-template-rows:minmax(0,1fr) auto;
    background:var(--paper);border:1px solid var(--line);padding:8px}
  .jrshot::before,.jrshot::after{content:"";position:absolute;width:10px;height:10px;
    pointer-events:none}
  .jrshot::before{top:-1px;right:-1px;border-top:1.5px solid var(--indigo);
    border-right:1.5px solid var(--indigo)}
  .jrshot::after{bottom:-1px;left:-1px;border-bottom:1.5px solid var(--indigo);
    border-left:1.5px solid var(--indigo)}
  /* min-height zero on both, or the picture's own height would set the column's
     and the three would decide the section rather than the six stages */
  .jrshot img{width:100%;height:100%;min-height:0;object-fit:cover;display:block}
  .jrshot figcaption{margin-top:9px;padding-top:8px;border-top:1px solid var(--line);
    font-family:var(--mono);font-size:10.5px;letter-spacing:.11em;
    text-transform:uppercase;color:var(--faint);line-height:1.4}
}
@media(min-width:1560px){.jrwrap{grid-template-columns:minmax(0,1fr) 380px}}
@media(min-width:1200px){.s4{padding:var(--space-5xl) 0}}
/* the turn still happens, at the same scroll position, without the rotation */
@media(prefers-reduced-motion:reduce){.jrflip{transition:none}}

/* ================= section 6, the catalogue =================
   The wall behind the whole section, the question and the field centred on the left,
   and the latest molecules beside them under their own heading. Every compound sits
   on white, because a drawing on a wall of drawings is not a compound, it is more
   wall. */
.cat{position:relative;overflow:hidden;isolation:isolate;background:var(--paper);
  padding:var(--space-4xl) 0}
/* The wall fills the section rather than sitting at the top of it: align-content
   start left the lower half empty, so the drawings looked like a header rather than
   a ground. It fades out at the top and the bottom so it has no edge where the
   section meets what is above and below it. */
/* Fixed rows and more tiles than fit, so every row that shows is a full row. With
   the rows stretched to the section and a count that happened to be short, the last
   row came up two tiles shy at a wide width and the corner was empty. The extra
   tiles are the same handful of files repeated, so they cost nothing to fetch. */
.cattiles{position:absolute;inset:0;z-index:0;pointer-events:none;display:grid;
  grid-template-columns:repeat(auto-fill,minmax(148px,1fr));
  grid-auto-rows:168px;align-content:start;overflow:hidden;
  -webkit-mask-image:linear-gradient(to bottom,transparent 0,#000 12%,#000 88%,transparent 100%);
  mask-image:linear-gradient(to bottom,transparent 0,#000 12%,#000 88%,transparent 100%)}
/* multiply is what makes the white ground of a drawing disappear into the page, so
   the wall is line work on the section's own surface rather than a grid of cards */
.cattiles img{width:100%;height:100%;object-fit:contain;padding:12px;
  mix-blend-mode:multiply;opacity:.4}
.cat .wrap{position:relative;z-index:1}
.catgrid{display:grid;gap:var(--space-3xl);align-items:center;
  margin:0 auto}
@media(min-width:960px){
  .catgrid{grid-template-columns:minmax(0,.95fr) minmax(0,1.05fr);gap:var(--space-4xl)}
}

/* the words, centred, with the veil the hero uses so no bond line crosses a letter */
.catwords{position:relative;text-align:center;max-width:60ch;margin:0 auto}
.catwords::before{content:"";position:absolute;z-index:-1;pointer-events:none;
  left:50%;top:50%;transform:translate(-50%,-50%);width:min(148%,860px);height:132%;
  background:radial-gradient(ellipse at center,rgba(255,255,255,.97) 0%,
    rgba(255,255,255,.92) 48%,rgba(255,255,255,.55) 74%,rgba(255,255,255,0) 100%)}
/* a step down from the page's h2, so the question sits on one line in its column
   rather than breaking after two words */
.catwords h2{margin:0 0 var(--space-s);font-size:clamp(1.5rem,2.7vw,2.15rem)}
.catwords .lede{margin:0 auto;max-width:46ch}

/* the field, in the drawing frame the rest of the page uses */
.catfield{position:relative;display:flex;gap:var(--space-xs);align-items:center;
  margin:var(--space-xl) auto 0;padding:9px;background:var(--paper);
  border:1px solid var(--line)}
.catfield .tr,.catfield .bl{position:absolute;width:10px;height:10px;font-style:normal}
.catfield .tr{top:-1px;right:-1px;border-top:1.5px solid var(--indigo);
  border-right:1.5px solid var(--indigo)}
.catfield .bl{bottom:-1px;left:-1px;border-bottom:1.5px solid var(--indigo);
  border-left:1.5px solid var(--indigo)}
.catfield input{flex:1;min-width:0;border:none;outline:none;background:none;
  font-family:var(--mono);font-size:14.5px;padding:var(--space-xs);color:var(--ink)}
.catfield .btn{flex:none;width:auto}
@media(max-width:520px){.catfield{flex-wrap:wrap}.catfield .btn{width:100%}}

.catstats{list-style:none;margin:var(--space-l) 0 0;padding:0;display:flex;
  flex-wrap:wrap;justify-content:center;gap:var(--space-xs) var(--space-xl)}
.catstats li{font-size:13.4px;color:var(--body);white-space:nowrap}
.catstats b{color:var(--indigo);font-family:var(--mono);font-size:15.5px;
  font-weight:700;margin-right:5px}
/* the width of the field above it, not a narrower measure of its own: it is the
   answer to the field, and it reads as an aside when it is set narrower */
.catnote{margin:var(--space-l) 0 0;padding-top:var(--space-m);
  border-top:1px solid var(--line);font-size:13.6px;color:var(--body)}
.catask{display:flex;justify-content:center;margin-top:var(--space-s)}
.catask .btn{width:auto}

/* the molecule panel */
.catpanel{background:rgba(255,255,255,.74);border:1px solid var(--line);
  border-radius:12px;padding:14px}
.cathead{display:flex;align-items:center;justify-content:space-between;gap:var(--space-s);
  flex-wrap:wrap;margin:0 0 var(--space-s);padding:0 2px}
.cathead h3{margin:0;font-size:15.5px}
.cattog{display:flex;gap:3px;background:var(--paper);border:1px solid var(--line);
  border-radius:var(--rs);padding:3px;flex:none}
.cattog button{border:none;background:transparent;border-radius:6px;padding:0 11px;
  min-height:32px;font:inherit;font-size:12.5px;font-weight:650;color:var(--body);
  cursor:pointer;display:flex;align-items:center;gap:6px}
.cattog button.on{background:var(--indigo);color:#fff}
.cattog i{font-style:normal;font-size:12px;line-height:1}

.catscroll{max-height:404px;overflow-y:auto;overscroll-behavior:contain;padding:2px}
.catscroll:focus-visible{outline:2px solid var(--indigo);outline-offset:2px}
.catscroll a{background:var(--paper);border:1px solid var(--line);border-radius:9px;
  display:block}
/* A hundred and one of the drawings came off PubChem on a flat 245 grey and showed
   as a grey square inside a white card. Multiply does not fix that, whatever it looks
   like it should do: multiplying 245 by white returns 245. The drawings themselves
   were lifted to a white ground instead, once, so every place on the site that shows
   a structure gets it. Multiply stays because it is still what keeps a white ground
   from painting over the wall behind the section. */
.catscroll img{mix-blend-mode:multiply}
.catscroll a:hover{border-color:var(--indigo)}
/* two lines, then it stops, and the whole name is on the link's title: a twelve word
   systematic name will take a tile to four lines and break the grid's rhythm */
.catscroll b{font-size:12.8px;font-weight:650;color:var(--ink);line-height:1.3;
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
.catscroll .cas{font-family:var(--mono);font-size:11px;color:var(--orange-ink);
  display:block;margin-top:2px}
.catscroll[data-view="tile"]{display:grid;gap:10px;
  grid-template-columns:repeat(auto-fill,minmax(196px,1fr))}
.catscroll[data-view="tile"] a{padding:10px}
.catscroll[data-view="tile"] img{width:100%;aspect-ratio:4/3;object-fit:contain}
.catscroll[data-view="tile"] .txt{display:block;margin-top:8px;padding-top:8px;
  border-top:1px solid var(--line)}
.catscroll[data-view="list"]{display:grid;gap:8px}
.catscroll[data-view="list"] a{display:grid;grid-template-columns:52px minmax(0,1fr);
  gap:var(--space-s);align-items:center;padding:9px 11px}
.catscroll[data-view="list"] img{width:52px;height:40px;object-fit:contain}
.catall{display:inline-flex;align-items:center;gap:var(--space-2xs);
  margin-top:var(--space-s);padding:0 2px;font-weight:650;font-size:14px;
  color:var(--indigo)}
.catall i{font-style:normal;color:var(--orange-ink)}
@media(max-width:560px){
  .catscroll[data-view="tile"]{grid-template-columns:1fr}
  .catscroll{max-height:340px}
}

/* ================= section 7, the instruments =================
   Plates, three across, two on a phone. The frame and the title block are the ones
   section 3 uses, so a photograph on this page always means the same thing. */
.s7{padding:var(--space-4xl) 0;background:var(--tint2);
  border-top:1px solid #F4E4CF;border-bottom:1px solid #F4E4CF}
.s7head{margin:0 auto var(--space-2xl)}
.s7head h2{margin:0 0 var(--space-s)}
.s7head .lede{margin:0;max-width:76ch}
/* More columns as the screen grows, so a plate stays about the size it is on a
   phone rather than swelling into a poster of a beige box. Seven instruments never
   fill a row exactly, and that is fine: a short last row reads as a list ending,
   where a stretched plate reads as a mistake. */
.insgrid{display:grid;gap:var(--space-s);margin:0 auto;
  grid-template-columns:repeat(2,minmax(0,1fr))}
@media(min-width:600px){.insgrid{grid-template-columns:repeat(3,minmax(0,1fr))}}
@media(min-width:900px){.insgrid{grid-template-columns:repeat(4,minmax(0,1fr));
  gap:var(--space-m)}}
/* one row from a laptop up: as many tracks as there are instruments, so the set reads
   as one rack rather than a row of five and a stray two underneath */
@media(min-width:1180px){
  .insgrid{grid-template-columns:repeat(var(--n,7),minmax(0,1fr));gap:var(--space-s)}
  .ins{padding:6px}
  .ins b{font-size:11.6px}
  .inspurpose{font-size:11px;line-height:1.4}
  .insloc{font-size:9.5px}
  .insoff{font-size:9.5px;letter-spacing:.08em;padding:0 6px}
}
.ins{position:relative;margin:0;background:var(--paper);border:1px solid var(--line);
  padding:8px;display:flex;flex-direction:column}
.ins::before,.ins::after{content:"";position:absolute;width:9px;height:9px;
  pointer-events:none}
.ins::before{top:-1px;right:-1px;border-top:1.5px solid var(--indigo);
  border-right:1.5px solid var(--indigo)}
.ins::after{bottom:-1px;left:-1px;border-bottom:1.5px solid var(--indigo);
  border-left:1.5px solid var(--indigo)}
.inspic{position:relative;background:var(--tint);display:grid;place-items:center;
  aspect-ratio:4/3;overflow:hidden}
.inspic img{width:100%;height:100%;object-fit:cover;display:block}
/* the one technique done elsewhere has no photograph here, and says so */
.insoff{font-family:var(--mono);font-size:11.5px;letter-spacing:.12em;
  text-transform:uppercase;color:var(--faint);text-align:center;padding:0 12px}
.ins figcaption{margin-top:10px;padding-top:9px;border-top:1px solid var(--line);
  display:flex;flex-direction:column;gap:2px}
.ins b{font-size:12.8px;font-weight:650;color:var(--ink);line-height:1.3}
.inspurpose{font-size:12px;color:var(--body);line-height:1.45}
.insloc{font-family:var(--mono);font-size:10.5px;letter-spacing:.1em;
  text-transform:uppercase;color:var(--faint);margin-top:3px}
.insnote{margin:var(--space-l) auto 0;font-size:13.2px;
  color:var(--faint);line-height:1.6}
.insafter{margin:var(--space-m) auto 0}
.s7 .inspic{background:var(--orange-w)}
@media(min-width:1200px){.s7{padding:var(--space-5xl) 0}}

/* ================= the sectors band and the close =================
   The option's own measurements, including its tokens: its rule is E3E0EF and its
   ground F7F5FD. */
.sectors{--kit-rule:#E3E0EF;--kit-faint:#7C7890;font-size:16px;line-height:1.6;
  padding:34px 0;background:#F7F5FD;
  border-top:1px solid var(--kit-rule);border-bottom:1px solid var(--kit-rule)}

/* the ledger's own grid, so the band lines up with the six commitments directly
   above it rather than being a fourth arrangement invented for one strip */
.sectin{display:grid;gap:20px}
@media(min-width:900px){
  .sectin{grid-template-columns:minmax(0,.85fr) minmax(0,1.15fr);gap:44px;
    align-items:start}
}
/* band size, not section size: the display face at a little over body size, so
   it reads as the band saying what it is for rather than as a third heading
   between the ledger above it and the close below it */
.sectors h2{font-family:var(--disp);font-variation-settings:'wdth' 92;font-weight:800;
  letter-spacing:-.02em;line-height:1.3;margin:0;color:var(--ink);
  font-size:clamp(1.02rem,1.5vw,1.22rem);max-width:26ch}
/* Two columns, not three, and ruled. Three tracks across the page left six short
   names floating a long way from each other and from anything else on it. */
.sct{display:grid;grid-template-columns:1fr;margin:0}
.sct span{font-size:14.2px;color:var(--body);padding:8px 0;
  border-top:1px solid var(--kit-rule)}
@media(min-width:560px){.sct{grid-template-columns:1fr 1fr;column-gap:44px}}

.closeband{position:relative;background:var(--indigo);padding:56px 0;overflow:hidden;
  font-size:16px;line-height:1.6}
/* the drawing turned to white line work: grayscale and invert make the black lines
   white, and screen drops the ground it was drawn on */
.cbwash{position:absolute;right:-4%;top:-42%;width:46%;opacity:.2;pointer-events:none;
  filter:grayscale(1) invert(1);mix-blend-mode:screen}
.cbin{position:relative;display:grid;gap:26px}
@media(min-width:1000px){
  .cbin{grid-template-columns:minmax(0,1fr) auto;gap:56px;align-items:end}
}
.cbin h2{font-family:Archivo,var(--sans);font-variation-settings:'wdth' 92;
  font-weight:800;letter-spacing:-.026em;line-height:1.05;margin:0;
  font-size:clamp(1.7rem,3.6vw,2.7rem);color:#fff;max-width:18ch}
.cbin .lede{font-size:clamp(1rem,2vw,1.16rem);line-height:1.55;max-width:56ch;
  margin:16px 0 0;color:rgba(255,255,255,.82)}
.cbacts{display:flex;gap:10px;flex-wrap:wrap}
.cbtn{display:inline-flex;align-items:center;gap:8px;font-weight:700;font-size:14.5px;
  padding:12px 20px;border-radius:6px;color:#fff}
.cbtn-o{background:var(--orange-ink)}
.cbtn-o:hover{background:#fff;color:var(--indigo)}
.cbtn-g{background:transparent;border:1.5px solid rgba(255,255,255,.45)}
.cbtn-g:hover{border-color:#fff}

/* ================= section 8, the scale ladder =================
   The four development stages against the quantities they run at. The head is the
   plates' head: the heading and the sentence side by side rather than stacked. */
.s8{padding:var(--space-4xl) 0;background:var(--tint)}
/* stacked, as the option has it: the heading then the sentence under it */
.s8head{margin:0 auto var(--space-2xl)}
.s8head h2{margin:0 0 var(--space-s)}
.s8head .lede{margin:0;max-width:64ch}
.ladder{margin:0 auto;border-top:1px solid var(--line)}
.lrow{display:grid;gap:var(--space-2xs);padding:var(--space-m) 0;
  border-bottom:1px solid var(--line);align-items:center}
.lscale{font-family:var(--mono);font-variant-numeric:tabular-nums;font-size:13px;
  font-weight:600;color:var(--indigo);white-space:nowrap}
/* a full width track with the fill drawn on it, not a bare fill: the track is what
   makes each bar readable as a position on one axis rather than four loose lines of
   different lengths */
.lbar{display:block;position:relative;height:10px;border-radius:2px;
  background:rgba(60,42,152,.1)}
.lbar::after{content:"";position:absolute;left:0;top:0;bottom:0;width:var(--w);
  background:var(--indigo);border-radius:2px}
.lbar.o::after{background:var(--orange-ink)}
.linfo h3{margin:0 0 3px;font-size:16.5px}
.linfo p{margin:0;font-size:14.2px;line-height:1.55;color:var(--body);max-width:64ch}
@media(min-width:820px){
  .lrow{grid-template-columns:11ch minmax(0,1.05fr) minmax(0,1.35fr);
    column-gap:var(--space-l);padding:var(--space-l) 0;align-items:center}
}
/* the three rooms, at the points on the ladder they belong to, in the drawing frame
   the rest of the page uses for a photograph */
.lrooms{display:grid;gap:var(--space-m);;margin:var(--space-2xl) auto 0;
  grid-template-columns:1fr}
@media(min-width:640px){.lrooms{grid-template-columns:repeat(3,minmax(0,1fr))}}
.lroom{position:relative;margin:0;background:var(--paper);border:1px solid var(--line);
  padding:10px}
.lroom::before,.lroom::after{content:"";position:absolute;width:10px;height:10px;
  pointer-events:none}
.lroom::before{top:-1px;right:-1px;border-top:1.5px solid var(--indigo);
  border-right:1.5px solid var(--indigo)}
.lroom::after{bottom:-1px;left:-1px;border-bottom:1.5px solid var(--indigo);
  border-left:1.5px solid var(--indigo)}
.lroom img{width:100%;display:block;aspect-ratio:4/3;object-fit:cover}
.lroom figcaption{margin-top:10px;padding-top:9px;border-top:1px solid var(--line)}
.lann{font-family:var(--mono);font-size:11px;letter-spacing:.13em;text-transform:uppercase;
  color:var(--faint);display:block}
.lroom b{display:block;font-size:13.6px;font-weight:650;color:var(--ink);margin-top:3px}
.s8after{margin:var(--space-l) auto 0}

/* ================= section 9, the six commitments =================
   Statements, not boxes. Everyone claims the same six things, so the only thing that
   can carry them is how plainly they are said. */
.s9{padding:var(--space-4xl) 0}
.s9head{display:flex;align-items:baseline;justify-content:space-between;gap:var(--space-l);
  flex-wrap:wrap;margin:0 auto var(--space-2xl)}
.s9head h2{margin:0;max-width:18ch}
.s9count{font-family:var(--mono);font-size:11.5px;letter-spacing:.14em;
  text-transform:uppercase;color:var(--faint)}
/* the list itself is drawn in the kit block below, which carries the option's own
   numbers; this only holds it to the page's measure */
.stmts{margin:0 auto}
@media(min-width:1200px){.s9{padding:var(--space-5xl) 0}}

/* ================= the drawing sheet footer =================
   On paper with a title block, rather than a dark slab. The plant elevation stays:
   it is a transparent near black silhouette, so it reads as a grey drawing on paper
   exactly as it read as a darker one on indigo. */
footer.site.sheet{background:var(--paper);color:var(--body);
  border-top:1px solid var(--line);padding:var(--space-3xl) 0 0;margin-top:0}

.shgrid{display:grid;gap:var(--space-2xl)}
@media(min-width:960px){
  .shgrid{grid-template-columns:minmax(0,.8fr) minmax(0,1.9fr);gap:var(--space-4xl)}
}
.shlogo img{width:172px;max-width:60%;display:block}
.shblurb{margin:var(--space-m) 0 0;font-size:14px;color:var(--body);max-width:38ch}
.shcols{display:grid;grid-template-columns:1fr 1fr;gap:var(--space-l)}
@media(min-width:640px){.shcols{grid-template-columns:repeat(4,1fr)}}
.fann{font-family:var(--mono);font-size:11px;letter-spacing:.13em;text-transform:uppercase;
  color:var(--faint);display:block}
.shcols ul{margin:var(--space-s) 0 0;padding:0;list-style:none}
.shcols li{margin-bottom:7px}
.shcols a{font-size:14px;color:var(--body)}
.shcols a:hover{color:var(--indigo)}
/* the title block */
.shblock{display:grid;gap:var(--space-m);margin-top:var(--space-2xl);
  padding-top:var(--space-m);border-top:1.5px solid var(--ink)}
@media(min-width:900px){
  .shblock{grid-template-columns:minmax(0,2fr) repeat(3,minmax(0,1fr));gap:var(--space-2xl)}
}
.shblock b{display:block;font-size:12.8px;font-weight:650;color:var(--ink);
  margin-top:3px;line-height:1.45}
.shmeta{display:flex;flex-wrap:wrap;gap:var(--space-2xs) var(--space-l);
  margin-top:var(--space-l);padding-top:var(--space-s);border-top:1px solid var(--line);
  font-family:var(--mono);font-size:11px;letter-spacing:.1em;text-transform:uppercase;
  color:var(--faint)}
.sheet .f-plate{margin-top:var(--space-l);opacity:.5}

/* section 8 takes the drafting grid from the sample rather than a flat tint */
.s8{background:var(--paper);
  background-image:linear-gradient(rgba(60,42,152,.055) 1px,transparent 1px),
    linear-gradient(90deg,rgba(60,42,152,.055) 1px,transparent 1px);
  background-size:28px 28px}

/* ================= the sample kit, exactly =================
   These sections are meant to be the design samples, not versions of them, so the
   numbers here are the samples' own rather than the site's nearest equivalents. That
   is why the tokens are written out: the samples' rule colour is E3E0EF against the
   site's E5E1F3, their faint is 7C7890 against 6F6C8E, and their body sets at 16px
   where the site sets at 16.5 from 1040 up. Small differences, but they are the
   difference between the same design and a close one. */
.s8,.s9,footer.site.sheet{
  --kit-rule:#E3E0EF; --kit-faint:#7C7890;
  --disp:Archivo,var(--sans);
  font-size:16px;line-height:1.6}
.s8 h2,.s9 h2{font-family:var(--disp);font-variation-settings:'wdth' 92;font-weight:800;
  letter-spacing:-.026em;line-height:1.05;margin:0;font-size:clamp(1.7rem,3.6vw,2.7rem)}
.s8 h3,.s9 h3{font-family:var(--disp);
  font-variation-settings:'wdth' 96;font-weight:700;letter-spacing:-.018em;margin:0;
  font-size:18px;line-height:1.2}
.s8 .lede,.s9 .lede{font-size:clamp(1rem,2vw,1.16rem);line-height:1.55;max-width:56ch;
  margin:16px 0 0}
.s8 .lann,.sheet .fann,.s9 .s9count{
  font-family:"IBM Plex Mono",ui-monospace,Menlo,Consolas,monospace;
  font-size:11px;letter-spacing:.13em;text-transform:uppercase;color:var(--kit-faint);
  font-weight:500}
.s8 .lscale{font-family:"IBM Plex Mono",ui-monospace,Menlo,Consolas,monospace;font-size:13px;font-weight:600;
  color:var(--indigo);white-space:nowrap;letter-spacing:normal}

/* section 8, the sample's own measurements */
.s8head{margin:0 auto 0}
.s8 .ladder{margin:0;max-width:none;border-top:1px solid var(--kit-rule)}
.s8 .lrow{gap:6px 20px;padding:18px 0;border-bottom:1px solid var(--kit-rule);
  grid-template-columns:minmax(0,1fr)}
@media(min-width:820px){
  /* a shorter bar. At 1.05fr against 1.35fr it was longer than the sentence beside
     it, which made the axis the loudest thing in the section rather than the scale
     it is labelling. */
  .s8 .lrow{grid-template-columns:11ch minmax(0,.55fr) minmax(0,1.85fr);
    align-items:center;column-gap:20px}
}
.s8 .linfo h3{font-size:16px;margin:0 0 2px;line-height:1.2}
.s8 .linfo p{font-size:13.8px;line-height:1.6;max-width:none;margin:0}
/* The rooms sit beside the ladder from 1080 up, stacked in a column on the right:
   they are the reference, the ladder is the argument. Below that they go back under
   it as a strip. Either way they are small, because three photographs given a third
   of the page each turn a reference into the subject. */
.s8body{display:grid;gap:var(--space-2xl);margin-top:36px}
/* the strip, for the widths where the rooms sit under the ladder */
.s8 .lrooms{margin:26px 0 0;gap:14px;max-width:640px;
  grid-template-columns:repeat(3,minmax(0,1fr))}
@media(max-width:479px){.s8 .lrooms{grid-template-columns:1fr;max-width:280px}}
/* and the column, for the widths where they sit beside it. This has to come after
   the strip rule, not before it: written above, the three track rule won on equal
   specificity and the rooms stayed three across inside a 220px column. */
/* Beside the ladder from a laptop up, two rooms over one: a single column of three
   ran to twice the ladder's height and left the section half empty below the last
   rung, with a corridor of nothing between the sentences and the photographs. Two
   over one is about as deep as the ladder is and about as wide as the gap was. */
@media(min-width:1080px){
  .s8body{grid-template-columns:minmax(0,1fr) clamp(320px,26vw,420px);
    grid-template-rows:auto minmax(0,1fr);
    gap:0 var(--space-3xl);align-content:start}
  .s8 .ladder{grid-column:1;grid-row:1}
  .s8 .lrooms{grid-column:2;grid-row:1 / span 2}
  /* into the space under the last rung, which the rooms column is taller than */
  .s8 .s8after{grid-column:1;grid-row:2;align-self:start;margin:var(--space-xl) 0 0}
  .s8 .lrooms{grid-template-columns:repeat(2,minmax(0,1fr));gap:14px;margin:0;
    max-width:none}
  /* the point of the triangle: half width, centred under the two above it */
  .s8 .lrooms .lroom:last-child{grid-column:1 / -1;width:calc(50% - 7px);
    justify-self:center}
  /* shallower than the strip's 4/3, so two rows of rooms cost about what four
     rungs of ladder cost */
  .s8 .lroom img{aspect-ratio:16/10}
}
.s8 .lroom{padding:8px;border:1px solid var(--kit-rule)}
.s8 .lroom img{aspect-ratio:4/3}
.s8 .lroom figcaption{margin-top:8px;padding-top:7px}
.s8 .lann{font-size:9.5px;letter-spacing:.1em}
.s8 .lroom b{font-size:11.5px;line-height:1.35;margin:2px 0 0}
.s8 .lroom figcaption{margin-top:12px;padding-top:10px;border-top:1px solid var(--kit-rule)}
.s8 .lroom b{font-size:13.4px;line-height:1.6;font-weight:650;margin:3px 0 0}
.s8 .s8after{max-width:none;margin:26px 0 0}

/* Section 9 is a ruled list that becomes two columns, not a grid of three. I had
   built the grid, which is a different design that happens to hold the same words. */
.s9 .s9head{max-width:none;margin:0 auto 0}
.s9 .stmts{display:block;max-width:none;margin:34px 0 0;gap:0;
  border-top:1px solid var(--kit-rule)}
.s9 .st{padding:22px 0;border-bottom:1px solid var(--kit-rule)}
.s9 .st h3{font-size:clamp(1.15rem,2.6vw,1.65rem);margin:0 0 6px;line-height:1.2;
  letter-spacing:-.018em}
.s9 .st p{font-size:14.8px;line-height:1.6;color:var(--body);max-width:66ch;margin:0}
@media(min-width:900px){
  .s9 .st{display:grid;grid-template-columns:minmax(0,.85fr) minmax(0,1.15fr);
    gap:44px;align-items:center;padding:26px 0}
  /* centred, so a row whose sentence runs to two lines has the same air above
     its heading as below it. On the first baseline the heading sat hard against
     the rule above and floated over the space below. The heading's own bottom
     margin is for the stacked layout and would skew the centring by three
     pixels here, so it goes. */
  .s9 .st h3{margin:0}
  /* the head takes the rows' grid: the count then sits directly over the column
     that holds all six sentences, rather than alone in the corner aligned to
     nothing */
  .s9 .s9head{display:grid;grid-template-columns:minmax(0,.85fr) minmax(0,1.15fr);
    gap:44px;align-items:baseline}
}

/* the footer sheet, on the sample's measurements */
footer.site.sheet{padding:44px 0 34px;border-top:1px solid var(--kit-rule);
  color:var(--ink)}
.sheet .shgrid{gap:32px}
@media(min-width:960px){
  .sheet .shgrid{grid-template-columns:minmax(0,.8fr) minmax(0,1.6fr);gap:56px}
}
.sheet .shcols{grid-template-columns:1fr 1fr;gap:24px}
/* three tracks for three columns. It was still set to four after the contact
   list came out, so each column had a quarter of the width and Research and
   Development, Chemical Development and Manufacturing and Supply all broke
   across two lines. */
@media(min-width:640px){.sheet .shcols{grid-template-columns:repeat(3,1fr)}}
.sheet .shcols ul{margin:10px 0 0}
.sheet .shcols li{margin-bottom:7px;font-size:14px;color:var(--body);
  line-height:1.6}
.sheet .shcols a{font-size:14px;color:var(--body)}
.sheet .shblurb{margin-top:16px;font-size:14px;max-width:38ch}
.sheet .shblock{margin-top:34px;padding-top:18px;border-top:1.5px solid var(--ink);gap:16px}
@media(min-width:900px){
  .sheet .shblock{grid-template-columns:minmax(0,2fr) repeat(3,minmax(0,1fr));gap:30px}
}
.sheet .shblock b{font-size:12.8px;margin-top:3px;line-height:1.45}
.sheet .shmeta{border-top:1px solid var(--kit-rule);color:var(--kit-faint);
  font-family:"IBM Plex Mono",ui-monospace,Menlo,Consolas,monospace;font-weight:500}

/* The way out of the catalogue. A visitor who does not find their compound is
   the most valuable visitor on the page and had nowhere to go. */
.pnotfound{margin:var(--space-3xl) 0 0;padding:var(--space-xl);border:1px solid var(--line);
  border-radius:10px;background:var(--tint2)}
.pnotfound h2{font-size:clamp(1.2rem,2.4vw,1.6rem);margin:0 0 8px}
.pnotfound p{margin:0;max-width:62ch;color:var(--body)}
.pnfacts{display:flex;gap:var(--space-m);align-items:center;flex-wrap:wrap;
  margin-top:var(--space-l)}
.pnfacts .btn{width:auto}

/* ===================== the people, on the about page =====================
   This sat white between two white sections and disappeared, which is the wrong
   fate for the only part of the page that names anybody. It takes the drafting
   grid the scale ladder uses on the home page, so it reads as a chapter rather
   than as more of the same, and the portraits take the drawing frame every
   other photograph on the site sits in. */
.leadband{position:relative;padding:var(--space-4xl) 0;
  background:var(--paper);
  background-image:linear-gradient(rgba(60,42,152,.055) 1px,transparent 1px),
    linear-gradient(90deg,rgba(60,42,152,.055) 1px,transparent 1px);
  background-size:28px 28px;
  border-top:1px solid var(--line);border-bottom:1px solid var(--line)}
.leadband .shead{margin-bottom:var(--space-xl)}
/* no marker above the heading: this site does not use eyebrows, the gate
   enforces it, and the ground and the rules already say this is a chapter */
.leadband .lede{max-width:66ch}

.people{display:grid;gap:var(--space-l);margin-top:var(--space-xl)}
@media(min-width:1000px){.people{grid-template-columns:1fr 1fr;gap:var(--space-2xl)}}
.person{margin:0;padding:var(--space-l);background:var(--paper);
  border:1px solid var(--line);border-radius:10px;
  display:grid;gap:var(--space-m);align-content:start}
@media(min-width:560px){
  .person.haspic{grid-template-columns:132px minmax(0,1fr);
    column-gap:var(--space-l);row-gap:var(--space-m);align-items:center}
  .person.haspic .pportrait{grid-column:1;grid-row:1}
  .person.haspic .pwho{grid-column:2;grid-row:1}
  /* under both, at the card's full measure */
  .person.haspic .pbody,.person.haspic .pquals{grid-column:1 / -1}
}
@media(min-width:1000px) and (max-width:1199px){
  .person.haspic{grid-template-columns:112px minmax(0,1fr)}
}

/* the frame a photograph always means on this site: hairline, two corner marks */
.pportrait{position:relative;margin:0;padding:7px;background:var(--paper);
  border:1px solid var(--line);align-self:start;width:132px;max-width:100%}
@media(min-width:1000px) and (max-width:1199px){.pportrait{width:112px}}
.pportrait::before,.pportrait::after{content:"";position:absolute;width:10px;height:10px;
  pointer-events:none}
.pportrait::before{top:-1px;right:-1px;border-top:1.5px solid var(--indigo);
  border-right:1.5px solid var(--indigo)}
.pportrait::after{bottom:-1px;left:-1px;border-bottom:1.5px solid var(--indigo);
  border-left:1.5px solid var(--indigo)}
.pportrait img{display:block;width:100%;aspect-ratio:1;object-fit:cover;
  object-position:center top;background:var(--tint)}

.pwho{min-width:0}
.person h3{font-size:1.28rem;margin:0 0 3px}
.prole{margin:0;font-size:14.6px;font-weight:650;color:var(--indigo)}
.pfield{margin:2px 0 0;font-size:13.4px;color:var(--faint)}
.pbody p{margin:0 0 var(--space-s);font-size:14.8px;line-height:1.62}
.pbody p:last-child{margin-bottom:0}
.pann{display:block;font-family:var(--mono);font-size:10.5px;letter-spacing:.12em;
  text-transform:uppercase;color:var(--faint);margin-bottom:4px}
.pquals{margin:var(--space-m) 0 0;padding-top:var(--space-s);border-top:1px solid var(--line);
  font-size:13.6px;line-height:1.55;color:var(--body)}
.pskills{margin-top:var(--space-2xl);padding-top:var(--space-l);border-top:1px solid var(--line)}
.pskills ul{list-style:none;margin:0;padding:0;display:flex;flex-wrap:wrap;gap:8px}
.pskills li{font-size:13.6px;color:var(--ink);background:var(--paper);
  border:1px solid var(--line);border-radius:20px;padding:6px 13px}
@media(max-width:559px){.person{padding:var(--space-m)}.pportrait{width:108px}}

/* ================================ contact ================================
   Three direct routes, then a drafter that turns six optional boxes into one
   message the visitor sends from their own WhatsApp or mail. */
.creach-s{padding:var(--space-l) 0 var(--space-3xl)}
.creach{display:grid;gap:var(--space-m)}
@media(min-width:760px){.creach{grid-template-columns:repeat(3,1fr)}}
.croute{display:flex;flex-direction:column;gap:5px;padding:var(--space-l);background:var(--paper);
  border:1px solid var(--line);border-radius:10px;color:var(--ink);text-decoration:none;
  transition:border-color .16s var(--ease),transform .16s var(--ease)}
.croute:hover{border-color:var(--indigo);transform:translateY(-2px)}
.crk{font-family:var(--mono);font-size:10.5px;letter-spacing:.12em;text-transform:uppercase;
  color:var(--faint)}
.croute b{font-family:var(--disp);font-variation-settings:'wdth' 92;font-weight:800;
  font-size:1.3rem;letter-spacing:-.02em;color:var(--ink);overflow-wrap:anywhere}
.crs{font-size:14px;line-height:1.5;color:var(--body)}
.crline{font-family:var(--disp);font-variation-settings:'wdth' 92;font-weight:800;
  font-size:1.18rem;letter-spacing:-.02em;color:var(--indigo);text-decoration:none;
  overflow-wrap:anywhere;line-height:1.3}
.crline:hover{text-decoration:underline;text-underline-offset:3px}
div.croute:hover{transform:none;border-color:var(--line)}
.crgo{margin-top:auto;padding-top:var(--space-s);font-weight:650;font-size:14.5px;color:var(--indigo)}
.crgo i{font-style:normal;color:var(--orange-ink)}
/* WhatsApp in its own green, darkened until white text reads on it: a green
   button is how people recognise that route before they read the word */
.cr-wa{border-color:#BFE3D5;background:#F2FAF6}
.cr-wa:hover{border-color:#0B6E55}
.cr-wa .crgo{color:#0B6E55}

.cdraft{display:grid;gap:var(--space-2xl)}
@media(min-width:960px){.cdraft{grid-template-columns:minmax(0,1.15fr) minmax(0,.85fr);
  gap:var(--space-3xl);align-items:start}}
.cdraft h2{margin:0 0 var(--space-s)}
.cquick{max-width:60ch;color:var(--body);margin:0 0 var(--space-l)}
.cneeds{border:0;margin:0 0 var(--space-l);padding:0;display:flex;flex-wrap:wrap;gap:8px}
.cneeds legend{font-weight:650;font-size:14.5px;color:var(--ink);margin-bottom:10px;padding:0}
.cneed input{position:absolute;opacity:0;pointer-events:none}
.cneed span{display:inline-block;padding:8px 14px;border:1px solid var(--line);border-radius:20px;
  background:var(--paper);font-size:14px;color:var(--body);cursor:pointer;
  transition:background .14s,border-color .14s,color .14s}
.cneed span:hover{border-color:#C9C0EC;color:var(--ink)}
.cneed input:checked + span{background:var(--indigo);border-color:var(--indigo);color:#fff}
.cneed input:focus-visible + span{outline:2px solid var(--indigo);outline-offset:2px}
.cgrid{display:grid;gap:var(--space-m) var(--space-l);margin-bottom:var(--space-m)}
@media(min-width:600px){.cgrid{grid-template-columns:1fr 1fr}}
@media(min-width:600px){.cwide{grid-column:1 / -1}}
.cfirst{margin-bottom:var(--space-l)}
@media(min-width:600px){.cfirst{grid-template-columns:minmax(0,1fr) minmax(0,1fr)}}
.cfield label{display:block;font-weight:600;font-size:14px;color:var(--ink);margin-bottom:6px}
.cfield .field{width:100%}

.cprev{background:var(--paper);border:1px solid var(--line);border-radius:10px;padding:var(--space-l)}
@media(min-width:960px){.cprev{position:sticky;top:calc(var(--barh) + 20px)}}
.cprevk{display:block;font-family:var(--mono);font-size:10.5px;letter-spacing:.12em;
  text-transform:uppercase;color:var(--faint);margin-bottom:8px}
.cmsg{margin:0 0 var(--space-m);padding:var(--space-m);background:var(--tint);border-radius:8px;
  border:1px solid var(--line);font-family:var(--sans);font-size:14.2px;line-height:1.6;
  color:var(--ink);white-space:pre-wrap;overflow-wrap:anywhere;min-height:120px}
.csend{display:flex;flex-wrap:wrap;gap:10px}
.csend .btn{width:auto;flex:1 1 180px;justify-content:center}
.cbtn-wa{background:#0B6E55;color:#fff;border:1px solid #0B6E55}
.cbtn-wa:hover{background:#085441;border-color:#085441;color:#fff}
.cfall{margin:var(--space-m) 0 0;font-size:13px;line-height:1.55;color:var(--faint)}
.cfall a{color:var(--indigo)}
.linkish{background:none;border:0;padding:0;font:inherit;color:var(--indigo);font-weight:600;
  cursor:pointer;text-decoration:underline;text-underline-offset:3px}

.cwhere{display:grid;gap:var(--space-m)}
@media(min-width:760px){.cwhere{grid-template-columns:repeat(3,1fr)}}
.cwhere a{color:var(--indigo);font-weight:600}
.cmuted{font-size:12.5px;color:var(--faint)}
@media(prefers-reduced-motion:reduce){.croute{transition:none}.croute:hover{transform:none}}

/* ======================== approvals: the Udyam lead ========================
   The registration and its certificate side by side on a laptop, stacked on a
   phone with the facts first. The document sits in the drawing frame every
   other picture on the site uses. */
.applead{padding:var(--space-xl) 0 var(--space-4xl)}
.appgrid{display:grid;gap:var(--space-2xl);align-items:start}
@media(min-width:960px){.appgrid{grid-template-columns:minmax(0,.95fr) minmax(0,1.05fr);
  gap:var(--space-3xl)}}
.applead h2{margin:0 0 4px}
.appissuer{margin:0 0 var(--space-l);color:var(--indigo);font-weight:600;font-size:15px}
.appno{margin:0 0 var(--space-l);padding:var(--space-m) var(--space-l);background:var(--tint);
  border:1px solid var(--line);border-left:3px solid var(--indigo);border-radius:0 8px 8px 0}
.appk{display:block;font-family:var(--mono);font-size:10.5px;letter-spacing:.12em;
  text-transform:uppercase;color:var(--faint);margin-bottom:4px}
.appno b{font-family:var(--mono);font-size:clamp(1.15rem,2.4vw,1.5rem);font-weight:600;
  letter-spacing:.02em;color:var(--ink);overflow-wrap:anywhere}
.appfacts{margin:0 0 var(--space-l);border-top:1px solid var(--line)}
.appfacts div{display:grid;gap:2px 16px;padding:10px 0;border-bottom:1px solid var(--line)}
@media(min-width:600px){.appfacts div{grid-template-columns:170px minmax(0,1fr)}}
.appfacts dt{font-size:13.4px;color:var(--faint)}
.appfacts dd{margin:0;font-size:14.6px;line-height:1.55;color:var(--ink)}
.appnote{font-size:13.6px;line-height:1.6;color:var(--body);margin:0 0 var(--space-l);
  max-width:60ch}
.appacts{display:flex;gap:18px;flex-wrap:wrap;align-items:center}
.appacts .btn{width:auto}

.appview{position:relative;margin:0;padding:9px;background:var(--paper);
  border:1px solid var(--line)}
.appview::before,.appview::after{content:"";position:absolute;width:12px;height:12px;
  pointer-events:none;z-index:1}
.appview::before{top:-1px;right:-1px;border-top:1.5px solid var(--indigo);
  border-right:1.5px solid var(--indigo)}
.appview::after{bottom:-1px;left:-1px;border-bottom:1.5px solid var(--indigo);
  border-left:1.5px solid var(--indigo)}
/* the proportion of an A4 page exactly, so the page drawn as an image fills it */
.appobj{display:block;width:100%;aspect-ratio:595/842;border:0;background:var(--tint)}
.appobj img{display:block;width:100%;height:auto}
.appview figcaption{margin-top:9px;font-family:var(--mono);font-size:10.5px;
  letter-spacing:.08em;text-transform:uppercase;color:var(--faint)}

/* ================================= about =================================
   After Toggl's about page, in structure and not in colour: each section a
   shape of its own. A statement and a drawn molecule, a bento, a photo
   collage of the laboratory, one dark band, a wall of words, a plain two by two,
   the people, and a table of facts. */

/* 1. the statement */
.abhero{padding:var(--space-2xl) 0 var(--space-3xl)}
.abtop{display:grid;gap:var(--space-2xl);align-items:center}
@media(min-width:900px){.abtop{grid-template-columns:minmax(0,1.25fr) minmax(0,.75fr);gap:var(--space-4xl)}}
.abstate h1{margin:0 0 var(--space-l);font-size:clamp(2.1rem,4.6vw,3.7rem);line-height:1.04;
  letter-spacing:-.038em;text-wrap:balance}
.abstate h1 span{display:block}
.abstate h1 span:last-child{color:var(--indigo)}
.abstate .lede{margin:0;max-width:58ch}
.abcta{display:flex;flex-wrap:wrap;gap:var(--space-s);margin-top:var(--space-xl)}
.abcta .btn{width:auto;display:inline-flex}
.abart{max-width:520px;width:100%;justify-self:center}
.ablogo{display:block;width:100%;height:auto}
@media(max-width:899px){.abart{max-width:320px;justify-self:start}}
.abcust{margin-top:var(--space-3xl);padding-top:var(--space-l);border-top:1px solid var(--line);
  display:grid;gap:var(--space-m);align-items:center}
.abcust p{margin:0;font-size:14.4px;font-weight:600;color:var(--body)}
.abcust ul{list-style:none;margin:0;padding:0;display:grid;grid-template-columns:repeat(2,1fr);
  gap:var(--space-m) var(--space-s)}
.abcust li{display:flex;align-items:center;min-height:36px}
.abcust img{display:block;max-height:34px;max-width:140px;object-fit:contain;filter:grayscale(1);opacity:.7}
@media(min-width:900px){
  .abcust{grid-template-columns:auto 1fr;gap:var(--space-2xl)}
  .abcust ul{display:flex;justify-content:space-between;gap:var(--space-xl)}
  .abcust .custword{white-space:nowrap}
}

/* 2. the bento */
.abbento{display:grid;gap:var(--space-m)}
.abb{margin:0;padding:var(--space-xl);border-radius:var(--r);background:var(--paper);
  border:1px solid var(--line)}
.abb p{margin:0;color:var(--body)}
.abb-lead{background:var(--indigo);border-color:var(--indigo)}
.abb-lead p{color:#fff;font-size:clamp(1.15rem,2vw,1.5rem);line-height:1.45;text-wrap:pretty}
.abb-pic{padding:0;overflow:hidden;min-height:240px}
.abb-pic img{display:block;width:100%;height:100%;object-fit:cover}
.abb-exp{display:grid;gap:var(--space-l);background:var(--tint2);border-color:#F3DFC2}
.abb-exp h3{font-size:clamp(1.25rem,2.2vw,1.6rem);margin-bottom:var(--space-xs)}
.abskills{list-style:none;margin:0;padding:0;display:flex;flex-wrap:wrap;gap:8px;align-content:start}
.abskills li{font-size:14px;color:var(--ink);background:var(--paper);border:1px solid #F3DFC2;
  border-radius:20px;padding:7px 14px}
.abb .abmotto{margin-top:var(--space-m);font-weight:650;color:var(--ink)}
@media(min-width:900px){
  .abbento{grid-template-columns:repeat(6,1fr);gap:var(--space-l)}
  .abb{grid-column:span 2}
  .abb-lead{grid-column:span 4;display:flex;align-items:center;padding:var(--space-3xl)}
  .abb-pic{grid-column:5 / 7;grid-row:1 / 3}
  .abb-exp{grid-column:1 / -1;grid-template-columns:minmax(0,1fr) minmax(0,1fr);
    gap:var(--space-3xl);padding:var(--space-2xl)}
}

/* 3. the laboratory in photographs */
.abcollage{display:grid;gap:var(--space-m)}
.abcollage figure{margin:0;position:relative;border-radius:var(--r);overflow:hidden;background:var(--tint)}
.abcollage img{display:block;width:100%;height:100%;object-fit:cover;aspect-ratio:16/9}
.abcollage figcaption{position:absolute;left:12px;bottom:12px;padding:5px 10px;border-radius:6px;
  background:rgba(23,21,51,.72);color:#fff;font-size:13px}
@media(min-width:760px){
  .abcollage{grid-template-columns:1.6fr 1fr;grid-template-rows:1fr 1fr}
  .abcollage figure:first-child{grid-row:1 / 3}
  .abcollage figure:first-child img{aspect-ratio:auto}
}

/* 4. the one dark band */
.abband{background:var(--indigo-d);color:#fff}
.abband h2,.abband h3{color:#fff;margin:0}
.abbrow{display:grid;gap:var(--space-m)}
.abbig{margin:0;font-family:var(--disp);font-variation-settings:'wdth' 92;font-weight:700;
  font-size:clamp(1.12rem,2.7vw,2.05rem);line-height:1.3;letter-spacing:-.02em;color:#fff;text-wrap:pretty}
.abbsub{margin-top:var(--space-3xl);padding-top:var(--space-xl);border-top:1px solid rgba(255,255,255,.18)}
.abbsub h3{color:#FFC98F}
.abbsub p{margin:0;color:rgba(255,255,255,.82);max-width:62ch}
@media(min-width:900px){.abbrow{grid-template-columns:minmax(0,.33fr) minmax(0,1fr);gap:var(--space-3xl)}}

/* 5. the wall of values */
.abvals{display:grid;gap:var(--space-2xl);align-items:center}
.abvals p{color:var(--body);max-width:56ch}
.abwall{list-style:none;margin:0;padding:0;display:grid;grid-template-columns:repeat(2,1fr);gap:var(--space-s)}
.abwall li{padding:var(--space-l) var(--space-m);border-radius:var(--r);text-align:center;
  font-family:var(--disp);font-variation-settings:'wdth' 92;font-weight:800;
  font-size:clamp(1.05rem,1.8vw,1.35rem);letter-spacing:-.02em;color:var(--indigo);
  background:var(--indigo-w)}
.abwall li:nth-child(3n+2){background:var(--orange-w);color:#A14F00}
.abwall li:nth-child(3n){background:var(--paper);border:1px solid var(--line);color:var(--ink)}
@media(min-width:900px){
  .abvals{grid-template-columns:minmax(0,.9fr) minmax(0,1.1fr);gap:var(--space-4xl)}
  .abwall{grid-template-columns:repeat(3,1fr);gap:var(--space-m)}
  /* the middle column hangs lower, so the words read as a wall and not a table */
  .abwall li:nth-child(3n+2){transform:translateY(28px)}
  .abwall li:nth-child(4){rotate:-1.5deg}
  .abwall li:last-child{rotate:1.5deg}
}

/* 6. the commitments, a plain two by two with hairlines, not four cards */
.abfour{display:grid;border-top:1px solid var(--line)}
.abfour > div{padding:var(--space-xl) 0;border-bottom:1px solid var(--line)}
.abfour h3{font-size:clamp(1.15rem,1.8vw,1.35rem)}
.abfour p{margin:0;color:var(--body);max-width:52ch}
@media(min-width:760px){
  .abfour{grid-template-columns:1fr 1fr}
  .abfour > div{padding:var(--space-2xl) var(--space-2xl) var(--space-2xl) 0}
  .abfour > div:nth-child(2n){padding-left:var(--space-2xl);border-left:1px solid var(--line)}
}

/* 7. the people, and the way in */
.abteam{display:grid;gap:var(--space-2xl);text-align:center}
.abteam h2{margin:0 0 var(--space-xl)}
.abfolk{list-style:none;margin:0 0 var(--space-xl);padding:0;display:flex;flex-wrap:wrap;
  justify-content:center;gap:var(--space-2xl)}
.abfolk li{display:flex;flex-direction:column;align-items:center;gap:4px;width:200px}
.abfolk img{width:132px;height:132px;border-radius:50%;object-fit:cover;object-position:center top;
  margin-bottom:var(--space-s);border:4px solid var(--paper);box-shadow:0 0 0 1px var(--line),var(--shadow)}
.abfolk b{font-size:15.5px;color:var(--ink);font-weight:700}
.abfolk span{font-size:13.8px;color:var(--faint)}
.abjoinc{padding:var(--space-3xl) var(--space-xl);border-radius:24px;background:var(--tint2);
  display:flex;flex-direction:column;align-items:center;justify-content:center}
.abjoinc h2{margin-bottom:var(--space-s)}
.abjoinc p{margin:0 0 var(--space-xl);color:var(--body);max-width:56ch}
.abjoinc .btn{width:auto;display:inline-flex}
@media(min-width:900px){.abteam{grid-template-columns:1fr 1fr;align-items:stretch}
  .abteam > div:first-child{padding:var(--space-3xl) var(--space-xl)}}

/* 8. at a glance */
.abglance{display:grid;gap:var(--space-2xl);align-items:start}
@media(min-width:900px){.abglance{grid-template-columns:minmax(0,1.3fr) minmax(0,.7fr);gap:var(--space-4xl)}}
.abfacts{margin:var(--space-l) 0 0;border-top:1px solid var(--line)}
.abfacts div{display:grid;gap:2px var(--space-l);padding:var(--space-s) 0;border-bottom:1px solid var(--line)}
@media(min-width:620px){.abfacts div{grid-template-columns:190px 1fr}}
.abfacts dt{font-size:14px;font-weight:600;color:var(--faint)}
.abfacts dd{margin:0;font-size:15px;color:var(--ink);overflow-wrap:anywhere}
.abgo{display:flex;gap:var(--space-s) var(--space-xl);flex-wrap:wrap;margin-top:var(--space-xl)}
.abpic{margin:0;border:1px solid var(--line);border-radius:var(--r);overflow:hidden;background:#fff}
.abpic img{display:block;width:100%;aspect-ratio:4/5;object-fit:cover}
.abpic figcaption{padding:10px 14px;font-size:13px;color:var(--body);border-top:1px solid var(--line)}
@media(max-width:899px){.abpic img{aspect-ratio:3/2}}

/* the leadership page closes on these two panels */
.abpeople{display:grid;gap:var(--space-l)}
@media(min-width:900px){.abpeople{grid-template-columns:1fr 1fr;gap:var(--space-2xl)}}
.abpanel{padding:var(--space-xl);border:1px solid var(--line);border-radius:10px;background:var(--paper);
  display:flex;flex-direction:column;gap:var(--space-m)}
.abpanel h2{margin:0;font-size:clamp(1.35rem,2.6vw,1.8rem)}
.abpanel p{margin:0;color:var(--body);max-width:56ch}
.abpanel .arrow{margin-top:auto}
.abjoin{background:var(--tint2);border-color:#F3DFC2}

/* ============================ what customers say ============================
   Quote cards when there are real quotes, the named customers always. The cards
   carry the speaker and their company along the bottom, the way a reference
   carries its signature: the name is the part a reader checks. */
.proof{padding:var(--space-3xl) 0 var(--space-4xl)}
.proof:not(.hasq){padding:var(--space-2xl) 0 var(--space-3xl)}
.pfhead{text-align:center;max-width:720px;margin:0 auto var(--space-2xl)}
.pfhead h2{margin:0}
.pfhead .lede{margin:var(--space-s) auto 0}
.pfgrid{display:grid;gap:var(--space-l);align-items:start}
@media(min-width:760px){.pfgrid{grid-template-columns:1fr 1fr}}
@media(min-width:1240px){.pfgrid{grid-template-columns:repeat(3,1fr)}}
.pfcard{margin:0;padding:var(--space-l);background:var(--paper);border:1px solid var(--line);
  border-radius:12px;box-shadow:0 22px 44px -30px rgba(23,21,51,.28);
  display:flex;flex-direction:column;gap:var(--space-l);transition:transform .2s var(--ease)}

.pfcard blockquote{margin:0;font-size:15.4px;line-height:1.62;color:var(--ink)}
.pfcard figcaption{display:flex;align-items:center;gap:12px;margin-top:auto;
  padding-top:var(--space-m);border-top:1px solid var(--line)}
.pfav{width:40px;height:40px;border-radius:50%;object-fit:cover;flex:none;background:var(--tint)}
.pfwho{display:flex;flex-direction:column;font-size:13.2px;line-height:1.4;color:var(--faint);
  min-width:0;flex:1}
.pfwho b{font-size:14.4px;color:var(--ink);font-weight:650}
.pfco{max-height:24px;max-width:96px;object-fit:contain;flex:none;filter:grayscale(1);opacity:.8}

@media(prefers-reduced-motion:reduce){.pfcard{transition:none}}

/* ========================== supply capabilities ==========================
   Two by two, each card a drawing, a name, Winkem's own paragraph, and its
   note at the foot, level across the row whatever the paragraph's length. */
.supply{display:grid;gap:var(--space-l)}
@media(min-width:760px){.supply{grid-template-columns:1fr 1fr}}
.sup{display:flex;flex-direction:column;gap:var(--space-s);padding:var(--space-2xl) var(--space-xl) var(--space-xl);
  background:var(--paper);border:1px solid var(--line);border-radius:var(--r);
  box-shadow:0 18px 40px -30px rgba(23,21,51,.35);transition:border-color .2s,transform .2s}
.sup:hover{border-color:#D6D1EC;transform:translateY(-2px)}
.suphead{display:flex;align-items:center;gap:var(--space-m)}
.suphead h3{margin:0;font-size:clamp(1.12rem,1.6vw,1.3rem);line-height:1.25}
.supico{display:grid;place-items:center;width:48px;height:48px;flex:none;border-radius:12px;background:var(--indigo-w);color:var(--indigo)}
.supico svg{width:26px;height:26px;fill:none;stroke:currentColor;stroke-width:1.7;stroke-linecap:round;stroke-linejoin:round}
.sup > p:not(.supnote){margin:0;color:var(--body);max-width:62ch}
.supnote{margin:auto 0 0;display:flex;align-items:flex-start;gap:10px;padding-top:var(--space-m);
  border-top:1px solid var(--line);font-size:14px;font-weight:550;color:var(--ink)}
.supchk{width:18px;height:18px;flex:none;margin-top:1px;fill:none;stroke:var(--ok);stroke-width:2.4;stroke-linecap:round;stroke-linejoin:round}
a.supnote{color:var(--indigo);text-decoration:none}
a.supnote i{font-style:normal;color:var(--orange-ink);transition:transform .2s}
a.supnote:hover i{transform:translateX(4px)}
@media(prefers-reduced-motion:reduce){.sup,a.supnote i{transition:none}.sup:hover{transform:none}}

/* ======================== the catalogue as a PDF ========================
   The page's lead action, under the page's introduction: the brand indigo,
   larger than any other button on the page, with the format and the count
   said on it. Beside it on a wide screen, a QR code for the same PDF. */
.pherorow{display:grid;gap:var(--space-xl);align-items:center}
@media(min-width:860px){.pherorow{grid-template-columns:minmax(0,1fr) auto}}
.heroacts{display:flex;flex-wrap:wrap;gap:12px;align-items:stretch;margin-top:var(--space-xl)}
.dlbig{display:inline-flex;align-items:center;gap:14px;padding:14px 24px 14px 14px;border:0;border-radius:12px;cursor:pointer;
  font:inherit;background:var(--indigo);color:#fff;box-shadow:0 18px 36px -18px rgba(60,42,152,.75);
  transition:background .2s,transform .2s,box-shadow .2s}
.dlbig:hover{background:var(--indigo-d);box-shadow:0 20px 38px -18px rgba(36,25,99,.8);transform:translateY(-1px)}
.dlbig:focus-visible{outline:3px solid var(--indigo-s);outline-offset:3px}
.dlico{display:grid;place-items:center;width:44px;height:44px;flex:none;border-radius:10px;background:rgba(255,255,255,.18)}
.dlico svg{width:24px;height:24px;fill:none;stroke:#fff;stroke-width:2.2;stroke-linecap:round;stroke-linejoin:round}
.dltxt{display:grid;gap:2px;text-align:left}
.dltxt b{font-family:var(--disp);font-weight:800;font-size:1.12rem;letter-spacing:-.01em;line-height:1.15}
.dltxt small{font-size:13px;font-weight:500;opacity:.92}
@media(max-width:859px){.dlbig{width:100%}}
@media(prefers-reduced-motion:reduce){.dlbig{transition:none}.dlbig:hover{transform:none}}
.heroqr{justify-self:start;background:var(--paper);border:1px solid var(--line);border-radius:14px;
  box-shadow:0 18px 40px -26px rgba(23,21,51,.35)}
.heroqr summary{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:12px 16px;
  list-style:none;cursor:pointer;font-weight:650;color:var(--indigo)}
.heroqr summary::-webkit-details-marker{display:none}
.heroqr summary span{display:flex;align-items:center;gap:8px;font-weight:500;font-size:13px;color:var(--faint)}
.heroqr summary span::after{content:"";width:8px;height:8px;border-right:2px solid var(--indigo);border-bottom:2px solid var(--indigo);
  transform:translateY(-2px) rotate(45deg);transition:transform .2s}
.heroqr[open] summary span::after{transform:translateY(2px) rotate(-135deg)}
.heroqrbody{display:flex;align-items:center;gap:16px;padding:4px 16px 16px}
.heroqrbody img{display:block;width:160px;height:160px;border:1px solid var(--line);border-radius:10px;background:#fff}
@media(min-width:860px){.heroqrbody img{width:180px;height:180px}}
.heroqrbody p{margin:0;display:grid;gap:4px;max-width:18ch;font-size:13.5px;color:var(--body)}
.heroqrbody b{font-family:var(--disp);font-weight:800;font-size:1.02rem;color:var(--ink)}
@media(max-width:859px){.heroqr{justify-self:stretch}}
/* a wide screen shows the code itself, never the fold */
@media(min-width:860px){.heroqr summary{display:none}
  .heroqrbody{flex-direction:column;text-align:center;padding:18px 20px}
  .heroqrbody p{max-width:16ch;justify-items:center}}
@media(prefers-reduced-motion:reduce){.heroqr summary span::after{transition:none}}
/* Share: the quieter partner to the download button, the same height */
.shr{position:relative;display:flex}
.shr summary{display:flex;align-items:center;gap:10px;padding:0 22px;border:1.5px solid var(--line);border-radius:12px;
  background:var(--paper);color:var(--indigo);font-weight:650;list-style:none;cursor:pointer;transition:border-color .2s}
.shr summary::-webkit-details-marker{display:none}
.shr summary:hover,.shr[open] summary{border-color:var(--indigo)}
.shr summary:focus-visible{outline:3px solid var(--indigo-s);outline-offset:3px}
.shr summary svg{width:20px;height:20px;fill:none;stroke:currentColor;stroke-width:2;stroke-linecap:round}
.shrmenu{position:absolute;left:0;top:calc(100% + 8px);z-index:30;width:min(290px,86vw);display:grid;gap:2px;padding:8px;
  background:var(--paper);border:1px solid var(--line);border-radius:var(--r);box-shadow:var(--shadow)}
.dlpi{display:grid;gap:1px;width:100%;padding:8px 10px;border:0;border-radius:var(--rs);background:none;text-align:left;
  font:inherit;color:var(--ink);text-decoration:none;cursor:pointer}
.dlpi:hover,.dlpi:focus-visible{background:var(--tint)}
.dlpi b{font-weight:650;font-size:14px}
.dlpi small{font-size:12.5px;color:var(--faint)}
@media(max-width:859px){.heroacts{display:grid;grid-template-columns:1fr}.shr summary{flex:1;justify-content:center;min-height:52px}
  .shrmenu{right:0;width:auto}}
.dlsel{margin-left:6px;padding:0;border:0;background:none;font:inherit;font-weight:650;color:var(--indigo);
  text-decoration:underline;text-underline-offset:3px;cursor:pointer}
.dlsel:hover{color:var(--orange-ink)}
.pdfv{position:fixed;inset:0;z-index:120;background:#1B1840;display:grid;place-items:center;padding:16px}
.pdfvbox{width:min(1000px,100%);height:min(94vh,100%);display:flex;flex-direction:column;background:var(--paper);border-radius:var(--r);overflow:hidden}
.pdfvbar{display:flex;align-items:center;justify-content:space-between;gap:12px;flex-wrap:wrap;padding:10px 14px;border-bottom:1px solid var(--line)}
.pdfvacts{display:flex;gap:8px}
.pdfvacts .btn{width:auto;display:inline-flex}
.pdfvdoc{flex:1;width:100%;border:0;background:var(--tint)}
.pdfvcard{flex:1;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:14px;padding:28px;text-align:center}
.pdfvcard img{width:170px}
.pdfvcard p{margin:0;max-width:40ch;color:var(--body)}
.pdfvcard .pdfvt{font-family:var(--disp);font-weight:800;font-size:1.6rem;color:var(--ink)}
.pdfvcard .btn{width:auto;display:inline-flex}

/* ======================= a compound no longer listed =======================
   An old link to a hidden compound: what it was, and the two ways on. */
.gone{display:grid;gap:var(--space-xl);align-items:center}
@media(min-width:760px){.gone{grid-template-columns:220px 1fr}}
.gonepic{display:block;width:100%;max-width:220px;aspect-ratio:1;object-fit:contain;background:#fff;
  border:1px solid var(--line);border-radius:var(--r);padding:12px}
.gone h1{margin:0 0 6px;font-size:clamp(1.5rem,3.4vw,2.3rem)}
.gonecas{margin:0 0 var(--space-s);color:var(--orange-ink);font-weight:650}
.goneacts{display:flex;gap:12px;flex-wrap:wrap;margin-top:22px}
.goneacts .btn{width:auto;display:inline-flex}

/* =========================== who it is done for ============================
   The customers continue the numbers band rather than starting a section of
   their own: one block, the figures and then the names behind them, split by a
   hairline inside the column. A name in the display face until there is a logo
   file; a logo, when there is one, sits in grey and takes its colour on hover. */
.nums:has(+ .cust:not([hidden])){border-bottom:0}
.cust{padding:0 0 var(--space-l);background:var(--paper);border-bottom:1px solid var(--line)}
.custin{display:grid;gap:var(--space-m);align-items:center;
  border-top:1px solid var(--line);padding-top:var(--space-l)}
.custk{margin:0;text-align:center;font-family:inherit;font-variation-settings:normal;
  font-size:14.4px;font-weight:600;line-height:1.3;color:var(--body);letter-spacing:0}
.custrow{list-style:none;margin:0;padding:0;display:grid;grid-template-columns:repeat(2,1fr);
  gap:var(--space-m) var(--space-s)}
.custrow li{display:flex;align-items:center;justify-content:center;min-height:40px;text-align:center}
.custrow img{display:block;max-height:36px;max-width:148px;object-fit:contain;
  filter:grayscale(1);opacity:.7;transition:filter .2s,opacity .2s}
.custrow li:hover img{filter:none;opacity:1}
.custword{font-family:var(--disp);font-variation-settings:'wdth' 92;font-weight:800;
  font-size:clamp(1.12rem,1.9vw,1.5rem);line-height:1.1;letter-spacing:-.02em;
  color:#76738F;transition:color .2s;text-wrap:balance}
.custrow li:hover .custword{color:var(--ink)}
@media(min-width:900px){
  .custin{grid-template-columns:minmax(150px,auto) 1fr;gap:var(--space-xl)}
  .custk{text-align:left;padding-right:var(--space-xl);border-right:1px solid var(--line)}
  .custrow{display:flex;justify-content:space-around;gap:var(--space-xl)}
  .custword{white-space:nowrap}
}
@media(prefers-reduced-motion:reduce){.custrow img,.custword{transition:none}}

/* =============================== breadcrumbs ===============================
   Small, muted, and out of the way: a way back up, not a heading. */
.crumbs{padding:14px 0 0}
.crumbs ol{list-style:none;margin:0;padding:0;display:flex;flex-wrap:wrap;align-items:center;
  gap:6px 8px;font-size:14px;line-height:1.4;color:var(--faint)}
.crumbs li{display:inline-flex;align-items:center;min-width:0}
.crumbs a{color:var(--faint);text-decoration:none;transition:color .15s}
.crumbs a:hover{color:var(--ink)}
.crumbs [aria-current=page]{color:var(--ink);font-weight:500;overflow-wrap:anywhere}
.crsep{color:#B3B0C9}
.crsep svg{display:block}
@media(max-width:599px){.crumbs{padding-top:10px}.crumbs ol{font-size:13.4px}}

/* contact: the map */
.cmapsec{padding:var(--space-3xl) 0 0}
.cmapgrid{display:grid;gap:var(--space-xl);align-items:center}
@media(min-width:900px){.cmapgrid{grid-template-columns:minmax(0,1.5fr) minmax(0,1fr);gap:var(--space-3xl)}}
.cmap{border:1px solid var(--line);border-radius:10px;overflow:hidden;background:var(--tint)}
.cmap iframe{display:block;width:100%;aspect-ratio:16/10;border:0}
.cmapside h2{margin:0 0 var(--space-s)}
.cmapside p{color:var(--body);max-width:42ch}

/* the carousel: one card and a peek of the next on a phone, two on a tablet,
   three on a laptop, snapping to a card at every width */
.pfcar{position:relative}
.pftrack{display:flex;gap:var(--space-l);overflow-x:auto;scroll-snap-type:x mandatory;
  scroll-padding:0;padding:4px 2px 26px;scrollbar-width:none;overscroll-behavior-x:contain}
.pftrack::-webkit-scrollbar{display:none}
.pftrack:focus-visible{outline:2px solid var(--indigo);outline-offset:4px;border-radius:12px}
.pftrack .pfcard{flex:0 0 86%;scroll-snap-align:start}
/* one or two quotes sit centred under the heading; auto margins, not
   justify-content, so a track that overflows still scrolls from its start */
.pftrack .pfcard:first-child{margin-left:auto}
.pftrack .pfcard:last-child{margin-right:auto}
@media(min-width:760px){.pftrack .pfcard{flex-basis:calc((100% - var(--space-l)) / 2)}}
@media(min-width:1240px){.pftrack .pfcard{flex-basis:calc((100% - 2 * var(--space-l)) / 3)}}
.pfnav{display:flex;justify-content:center;gap:10px;margin-top:var(--space-s)}
.pfnav button{width:40px;height:40px;display:grid;place-items:center;border-radius:50%;
  border:1px solid var(--line);background:var(--paper);color:var(--ink);cursor:pointer;
  transition:border-color .15s,background .15s}
.pfnav button:hover:not(:disabled){border-color:var(--indigo);color:var(--indigo)}
.pfnav button:disabled{opacity:.35;cursor:default}
.pfnav svg{width:18px;height:18px;fill:none;stroke:currentColor;stroke-width:2;
  stroke-linecap:round;stroke-linejoin:round}
/* every card already in view: the buttons would move nothing */
.pfall .pfnav{display:none}

/* ============================ the numbers band ============================
   Thin: four figures on one row with hairlines between them, no heading, no
   cards. The figures carry it. */
.nums{padding:var(--space-l) 0;border-top:1px solid var(--line);border-bottom:1px solid var(--line);
  background:var(--paper)}
.numrow{margin:0;display:grid;grid-template-columns:repeat(2,1fr)}
/* as many columns as there are figures: one withheld leaves three, not a gap */
.numrow{grid-template-columns:none;grid-auto-flow:column;grid-auto-columns:1fr}
.numrow div{display:flex;flex-direction:column-reverse;justify-content:flex-end;align-items:center;text-align:center;
  padding:var(--space-s) var(--space-m)}
.numrow div + div{border-left:1px solid var(--line)}
@media(max-width:759px){.numrow div{padding:var(--space-xs) 6px}
  .numrow dt{font-size:12.4px;line-height:1.35}}
.numrow dd{margin:0;font-family:var(--disp);font-variation-settings:'wdth' 92;font-weight:800;
  font-size:clamp(1.8rem,3.6vw,2.6rem);letter-spacing:-.03em;line-height:1.05;color:var(--indigo);
  font-variant-numeric:tabular-nums}
.numrow dt{margin-top:4px;font-size:13.8px;color:var(--body)}

/* =================== a photograph beside a block of text ===================
   The shared split gives the second column the extra width, which is right
   where the second column is the argument and wrong where it is a photograph:
   on capabilities and facilities the picture was wider than the words and three
   times their height. Here the text takes the wider column and the photograph
   a 3:2 frame in the narrower one, on whichever side it sits. */
@media(min-width:900px){
  .split.msplit{grid-template-columns:minmax(0,1.35fr) minmax(0,.65fr);align-items:center;
    gap:var(--space-3xl)}
  .split.msplit.flip{grid-template-columns:minmax(0,.65fr) minmax(0,1.35fr)}
}
.split.msplit .media img{aspect-ratio:3/2}
.split.msplit .media.fit img{object-fit:contain;background:#fff}

/* ============================== the shortlist ==============================
   Collected while browsing, asked about in one message. The button sits beside
   a card or a row, never inside it: both are links. Rounded rectangles, as
   everywhere on the site. */
.pcell{position:relative;display:flex;flex-direction:column;min-width:0}
.pcell > .pcard{flex:1}
.sladd{display:inline-flex;align-items:center;justify-content:center;gap:5px;font:inherit;cursor:pointer;
  border:1px solid var(--line);background:#fff;color:var(--indigo);border-radius:var(--rs);font-weight:650;
  white-space:nowrap;transition:background .15s,border-color .15s,color .15s}
.sladd svg{width:15px;height:15px;flex:none;fill:none;stroke:currentColor;stroke-width:2.2;
  stroke-linecap:round;stroke-linejoin:round}
.sladd .sltick,.sladd .slon{display:none}
.sladd[aria-pressed=true] .sltick,.sladd[aria-pressed=true] .slon{display:inline}
.sladd[aria-pressed=true] .slplus,.sladd[aria-pressed=true] .sloff{display:none}
.sladd:hover{border-color:var(--indigo)}
.sladd:focus-visible{outline:2px solid var(--indigo);outline-offset:2px}
/* on a card: the corner of the drawing */
.sl-card{position:absolute;top:8px;right:8px;z-index:1;min-height:32px;padding:0 10px 0 8px;font-size:12px;
  box-shadow:0 6px 14px -10px rgba(23,21,51,.5)}
.sl-card[aria-pressed=true],.sl-row[aria-pressed=true]{background:var(--indigo);border-color:var(--indigo);color:#fff}
@media(pointer:coarse){.sl-card{min-height:38px}}
/* on a row: its own column, the height of the row */
.prcell{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:8px;align-items:stretch}
.sl-row{padding:0 14px;font-size:12.5px;min-width:46px}
@media(max-width:759px){
  .sl-row{padding:0;width:46px}
  .sl-row span{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}
}
/* on a compound page: beside the two requests, the same size */
.sl-big{gap:8px}
.sl-big svg{width:17px;height:17px}
.sl-big[aria-pressed=true]{background:var(--indigo-w);border-color:var(--indigo)}

/* the tray */
.sltab{position:fixed;right:16px;bottom:16px;z-index:95;display:inline-flex;align-items:center;gap:8px;
  min-height:48px;padding:0 12px 0 13px;border:0;border-radius:var(--rs);background:var(--indigo);color:#fff;
  font:inherit;font-size:14px;font-weight:650;cursor:pointer;box-shadow:0 16px 34px -14px rgba(36,25,99,.65);
  transition:background .15s}
.sltab[hidden]{display:none}
.sltab:hover{background:var(--indigo-d)}
.sltab:focus-visible{outline:2px solid var(--orange);outline-offset:3px}
.sltab svg{width:20px;height:20px;fill:none;stroke:currentColor;stroke-width:1.9;stroke-linecap:round;stroke-linejoin:round}
.sln{min-width:24px;height:24px;padding:0 7px;border-radius:6px;background:var(--orange);color:#fff;
  font-size:12.5px;display:grid;place-items:center;font-variant-numeric:tabular-nums}
.sltab.bump{animation:slbump .45s var(--ease)}
@keyframes slbump{35%{transform:translateY(-4px) scale(1.06)}}
@media(prefers-reduced-motion:reduce){.sltab.bump{animation:none}}
.slpanel{position:fixed;right:16px;bottom:74px;z-index:96;width:min(400px,calc(100vw - 32px));
  max-height:min(640px,calc(100vh - 150px));display:flex;flex-direction:column;background:#fff;
  border:1px solid var(--line);border-radius:var(--r);box-shadow:0 30px 60px -24px rgba(23,21,51,.45);overflow:hidden}
.slpanel[hidden]{display:none}
@media(max-width:599px){.slpanel{left:12px;right:12px;width:auto;bottom:72px;max-height:calc(100vh - 140px)}}
.slhead{display:flex;align-items:center;gap:10px;padding:12px 10px 12px 16px;border-bottom:1px solid var(--line)}
.slhead h2{margin:0;font-size:1.05rem}
.slcount{font-family:var(--mono);font-size:12px;color:var(--faint);font-variant-numeric:tabular-nums}
.slx,.slrm{flex:none;width:38px;height:38px;display:grid;place-items:center;border:0;background:none;
  border-radius:var(--rs);color:var(--faint);cursor:pointer}
.slx{margin-left:auto}
.slx:hover{background:var(--tint);color:var(--ink)}
.slrm:hover{background:#FDECEA;color:#B42318}
.slx svg,.slrm svg{width:18px;height:18px;fill:none;stroke:currentColor;stroke-width:2;stroke-linecap:round}
.sllist{list-style:none;margin:0;padding:6px 6px 6px 8px;overflow-y:auto;flex:1;min-height:0;overscroll-behavior:contain}
.sllist li{display:flex;align-items:center;gap:2px}
.sllist li + li{border-top:1px solid var(--line)}
.sllist a{flex:1;min-width:0;display:flex;align-items:center;gap:10px;padding:8px 6px;color:inherit;
  text-decoration:none;border-radius:var(--rs)}
.sllist a:hover{background:var(--tint)}
.sllist img,.slnopic{width:44px;height:44px;flex:none;object-fit:contain;background:var(--tint);border-radius:6px;padding:3px}
.slname{min-width:0;display:flex;flex-direction:column;gap:1px}
.slname b{font-size:13.4px;font-weight:650;color:var(--ink);line-height:1.35;overflow-wrap:anywhere;
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
.slname small{font-family:var(--mono);font-size:11.5px;color:var(--orange-ink);font-weight:650}
.slfoot{padding:12px 16px 2px;border-top:1px solid var(--line);display:grid;gap:8px}
.slgo{width:100%}
.slwhy{margin:0;font-size:12.4px;line-height:1.45;color:var(--faint);text-align:center}
.slacts{display:flex;gap:8px}
.slact{flex:1;display:inline-flex;align-items:center;justify-content:center;gap:6px;min-height:40px;
  border:1px solid var(--line);background:#fff;border-radius:var(--rs);font:inherit;font-size:13.5px;
  font-weight:650;color:var(--indigo);cursor:pointer}
.slact svg{width:16px;height:16px;fill:none;stroke:currentColor;stroke-width:2;stroke-linecap:round;stroke-linejoin:round}
.slact:hover,.slact[aria-expanded=true]{border-color:var(--indigo)}
.slact:focus-visible{outline:2px solid var(--indigo);outline-offset:2px}
.slclear{flex:0 0 auto;padding:0 14px;color:var(--body)}
.slshare{display:grid;gap:2px;padding:4px;border:1px solid var(--line);border-radius:var(--rs)}
.slshare a,.slshare button{display:grid;gap:1px;text-align:left;padding:8px 10px;border:0;background:none;
  font:inherit;border-radius:6px;color:var(--ink);cursor:pointer;text-decoration:none}
.slshare a:hover,.slshare button:hover{background:var(--tint)}
.slshare b{font-size:13.5px;font-weight:650}
.slshare small{font-size:12px;color:var(--faint)}
.slsure{display:flex;flex-wrap:wrap;align-items:center;gap:8px;padding:10px;background:var(--tint);border-radius:var(--rs)}
.slsure span{flex:1 1 100%;font-size:13.5px;font-weight:600;color:var(--ink)}
.slsure .btn{width:auto;flex:1}
.slempty{padding:18px 16px 6px;display:grid;gap:12px;justify-items:start}
.slempty p{margin:0;font-size:14px;line-height:1.55;color:var(--body)}
.slempty .btn{width:auto}
.slfine{margin:0;padding:8px 16px 12px;font-size:11.8px;color:var(--faint);text-align:center}
.slsay{position:fixed;right:16px;bottom:74px;z-index:97;max-width:min(340px,calc(100vw - 32px));margin:0;
  padding:10px 14px;background:var(--ink);color:#fff;border-radius:var(--rs);font-size:13.5px;line-height:1.45;
  box-shadow:0 18px 36px -18px rgba(23,21,51,.6);opacity:0;transform:translateY(6px);pointer-events:none;
  transition:opacity .2s,transform .2s}
.slsay.on{opacity:1;transform:none}
.sl:has(.slpanel:not([hidden])) .slsay{display:none}
@media(prefers-reduced-motion:reduce){.slsay{transition:none}}

/* a list opened from a link, on the catalogue */
.slnote{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:10px 16px;
  padding:12px 16px;margin-bottom:var(--space-m);background:var(--indigo-w);border:1px solid #D9D3F5;border-radius:var(--rs)}
.slnote p{margin:0;font-size:14px;line-height:1.5;color:var(--ink)}
.slnote .btn{width:auto}

/* the contact page's draft, for a whole shortlist */
.clist{display:grid;gap:10px}
.clisthead{display:flex;align-items:baseline;justify-content:space-between;gap:6px 14px;flex-wrap:wrap}
.clk{font-weight:600;font-size:14px;color:var(--ink)}
.clk b{display:inline-grid;place-items:center;min-width:24px;height:22px;margin-left:6px;padding:0 6px;
  border-radius:6px;background:var(--indigo);color:#fff;font-size:12.5px;font-variant-numeric:tabular-nums}
.clmore{font-size:13.5px}
.clrows{list-style:none;margin:0;padding:0;display:grid;gap:8px}
.clrow{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr) 40px;gap:8px;align-items:center;
  padding:10px 8px 10px 12px;background:#fff;border:1px solid var(--line);border-radius:var(--rs)}
.clname{grid-column:1 / 3;grid-row:1;display:flex;flex-direction:column;min-width:0}
.clname b{font-size:14px;font-weight:650;line-height:1.4;color:var(--ink);overflow-wrap:anywhere}
.clname span{font-family:var(--mono);font-size:12px;color:var(--orange-ink);font-weight:650}
.clrow .field{min-height:42px;padding:6px 10px}
.clrow [data-f=qty]{grid-column:1;grid-row:2}
.clrow [data-f=purity]{grid-column:2;grid-row:2}
.clrm{grid-column:3;grid-row:1;width:38px;height:38px;display:grid;place-items:center;border:0;background:none;
  border-radius:var(--rs);color:var(--faint);cursor:pointer}
.clrm:hover{background:#FDECEA;color:#B42318}
.clrm svg{width:18px;height:18px;fill:none;stroke:currentColor;stroke-width:2;stroke-linecap:round}
@media(min-width:1100px){
  .clrow{grid-template-columns:minmax(0,1fr) 128px 128px 40px}
  .clname{grid-column:1}
  .clrow [data-f=qty]{grid-column:2;grid-row:1}
  .clrow [data-f=purity]{grid-column:3;grid-row:1}
  .clrm{grid-column:4}
}
#draft,#slnote{scroll-margin-top:88px}

/* Winkem's own PDFs, under the catalogue's download button */
.mydocs{margin-top:var(--space-l);max-width:560px}
.mydocs[hidden]{display:none}
.mydocsk{margin:0 0 var(--space-xs);font-family:inherit;font-size:14px;font-weight:650;letter-spacing:0;color:var(--ink)}
.mydocs ul{list-style:none;margin:0;padding:0;display:grid;gap:6px}
.mydoc{width:100%;display:flex;align-items:center;gap:12px;padding:10px 12px;text-align:left;cursor:pointer;
  font:inherit;color:inherit;background:#fff;border:1px solid var(--line);border-radius:var(--rs);
  transition:border-color .15s}
.mydoc:hover{border-color:var(--indigo)}
.mydoc:focus-visible{outline:2px solid var(--indigo);outline-offset:2px}
.mydoc svg{width:22px;height:22px;flex:none;fill:none;stroke:var(--indigo);stroke-width:1.7;stroke-linejoin:round}
.mydoc span{display:flex;flex-direction:column;min-width:0}
.mydoc b{font-size:14.4px;font-weight:650;color:var(--indigo);overflow-wrap:anywhere}
.mydoc small{font-size:12.6px;color:var(--body)}

/* A page shown inside the dashboard's page editor: at rest, everything
   visible, nothing waiting on a scroll or an opening animation. */
html.wk-preview .rv{opacity:1!important;transform:none!important;transition:none!important}
html.wk-preview .loadstage{display:none!important}

/* ---------- pages Winkem adds (page.html?p=) ----------
   Prose in the site's own measure: a column of reading width, headings the
   template sets, pictures in the design's crops. */
.npbody{max-width:760px}
.npbody > h2{margin:var(--space-xl) 0 var(--space-s)}
.npbody > h2:first-child{margin-top:0}
.npbody > p{margin:0 0 var(--space-s);font-size:16px;line-height:1.7;color:var(--body)}
.npbody > p a{color:var(--indigo);text-decoration:underline;text-underline-offset:3px}
.npbody > p b{color:var(--ink)}
.npbody > .tickList{margin:0 0 var(--space-m)}
.npbody > .npfig{margin:var(--space-l) 0}
.npbody > .npfig img{width:100%;aspect-ratio:16/9;object-fit:cover}
.npsplit{margin:var(--space-l) 0;max-width:none}
.npsplit p{font-size:16px;line-height:1.7;color:var(--body);margin:0}
.npsplit .media img{width:100%;aspect-ratio:3/2;object-fit:cover}
.npgrid{margin-top:var(--space-s)}
.npacts{margin:var(--space-m) 0}
.nppdf{display:flex;align-items:center;gap:var(--space-s);flex-wrap:wrap;margin:var(--space-m) 0;padding:var(--space-s) var(--space-m);
  border:1px solid var(--line);border-radius:var(--r);background:var(--paper)}
.nppdf b{flex:1 1 220px;color:var(--ink)}
.nppdfi{font:700 11px/1 var(--mono);letter-spacing:.08em;color:var(--orange-ink);border:1.5px solid currentColor;border-radius:4px;padding:5px 6px}
.npdate{display:block;font:500 13px/1.4 var(--mono);color:var(--faint);margin-bottom:6px}
.npkind{font-weight:650;color:var(--orange-ink);margin:0 0 6px}
.nplist{list-style:none;margin:0;padding:0;display:grid;gap:var(--space-s);max-width:820px}
.nprow{display:grid;gap:6px;padding:var(--space-m);border:1px solid var(--line);border-radius:var(--r);background:var(--paper);color:inherit;text-decoration:none}
.nprow:hover{border-color:var(--indigo-s)}
.nprow h2{margin:0;font-size:1.25rem}
.nprow p{margin:0;color:var(--body)}
.npnf{max-width:640px}
.npsearch{display:grid;gap:8px}
.npsearch label{font-weight:650;color:var(--ink)}
.npsearchrow{display:flex;gap:8px;flex-wrap:wrap}
.npsearchrow input{flex:1 1 240px;min-width:0;padding:12px 14px;border:1px solid var(--line);border-radius:var(--rs);font:inherit}
.npnf .after{display:flex;gap:var(--space-l);flex-wrap:wrap}

/* the way in for Winkem's staff, quiet among the footer's small print */
footer.site a.fmanage,footer.site .shmeta a.fmanage,footer.site .fmeta a.fmanage{color:inherit;opacity:1;text-decoration:underline;text-underline-offset:3px;text-decoration-color:currentColor}
footer.site a.fmanage:hover{color:var(--indigo)}

/* a picture that did not arrive: its place kept, in a quiet tint */
img.imgfail{visibility:hidden}
.nojs{padding-top:56px;padding-bottom:72px}
.nojs a{color:inherit;text-decoration:underline}
.imgfailbox{background:var(--tint)}
