
/* ==========================================================================
   Sourcing globe — canvas dot-matrix earth with trade lanes
   ========================================================================== */
.globe-stage{
  position:relative; width:100%; aspect-ratio:1/.86; min-height:320px;
  cursor:grab; touch-action:pan-y;
  opacity:0; transition:opacity .8s cubic-bezier(.22,.61,.36,1);
}
.globe-stage.ready{opacity:1}
.globe-stage:active{cursor:grabbing}
.globe-stage canvas{display:block; width:100%; height:100%}

/* extra.css (written for the previous globe) fades the canvas in from
   opacity:0 and hides it entirely under prefers-reduced-motion. The dot
   matrix is a static-friendly visual, so keep it visible either way. */
.globe-stage canvas{position:absolute; inset:0; opacity:0; transition:opacity 1s var(--ease)}
.globe-stage.ready canvas,.globe-stage canvas.ready{opacity:1}
@media (prefers-reduced-motion:reduce){
  .globe-stage canvas{display:block}
}

.globe-legend{
  list-style:none; padding:0; margin:0; display:flex; flex-wrap:wrap; gap:.5rem 1.4rem;
  font-family:var(--f-mono); font-size:.62rem; letter-spacing:.16em; text-transform:uppercase;
  color:var(--muted);
}
.globe-legend li{display:flex; align-items:center; gap:.45rem}
.globe-legend i{width:7px; height:7px; border-radius:50%; background:var(--lime-2); flex-shrink:0}
.globe-legend li:nth-child(2) i{background:var(--sky-2)}
.globe-legend li:nth-child(3) i{background:#EBB256}

/* hero layout with the globe alongside the copy */
.hero-grid{align-items:center}
.hero-globe{position:relative; min-width:0}
.hero-legend{justify-content:center; margin-top:.2rem}

/* ==========================================================================
   Language picker
   ========================================================================== */
.lang{position:relative; flex-shrink:0}
.lang-btn{
  display:inline-flex; align-items:center; gap:.4rem; cursor:pointer;
  padding:.5rem .7rem; border-radius:100px; border:1px solid var(--line);
  background:rgba(7,16,25,.6); color:var(--muted);
  font-family:var(--f-mono); font-size:.66rem; letter-spacing:.12em; text-transform:uppercase;
  transition:.28s var(--ease);
}
.lang-btn:hover,.lang.open .lang-btn{color:#fff; border-color:var(--line-lime); background:rgba(140,198,63,.1)}
.lang-btn svg{opacity:.85}

.lang-menu{
  position:absolute; top:calc(100% + 8px); right:0; z-index:80; min-width:210px; padding:.4rem;
  border-radius:var(--r); border:1px solid var(--line-lime); background:rgba(7,16,25,.98);
  box-shadow:0 28px 56px -26px rgba(0,0,0,.95);
  opacity:0; visibility:hidden; transform:translateY(8px); transition:.26s var(--ease);
}
.lang.open .lang-menu{opacity:1; visibility:visible; transform:none}
.lang-menu button{
  display:flex; align-items:center; gap:.7rem; width:100%; cursor:pointer;
  padding:.5rem .65rem; border:0; border-radius:var(--r-sm); background:transparent;
  color:var(--paper-2); font-family:var(--f-display); font-size:.9rem; text-align:left;
  transition:.2s var(--ease);
}
.lang-menu button:hover{background:rgba(140,198,63,.12); color:#fff}
.lang-menu button.on{color:var(--lime-2)}
.lang-menu button i{
  font-style:normal; font-family:var(--f-mono); font-size:.56rem; letter-spacing:.1em;
  color:var(--faint); border:1px solid var(--line); border-radius:4px; padding:.1rem .3rem; min-width:26px;
  text-align:center; flex-shrink:0;
}
.lang-menu button.on i{color:var(--lime-2); border-color:var(--line-lime)}
.lang-note{
  margin:.4rem .35rem .15rem; padding-top:.45rem; border-top:1px solid var(--line);
  font-family:var(--f-mono); font-size:.54rem; line-height:1.6; letter-spacing:.04em; color:var(--faint);
}

/* right-to-left */
html.is-rtl .nav,html.is-rtl .head-in,html.is-rtl .foot-grid,html.is-rtl .foot-bar{direction:rtl}
html.is-rtl .lang-menu{right:auto; left:0}
html.is-rtl .eyebrow::after{transform:scaleX(-1)}
html.is-rtl .site-foot h5,html.is-rtl .site-foot li{text-align:right}
html.is-rtl .quote-dock{right:auto; left:1.2rem}
html.is-rtl .to-top{left:auto; right:1.2rem}

@media (max-width:1260px){
  .lang{width:100%}
  .lang-btn{width:100%; justify-content:center}
  .lang-menu{right:auto; left:0; width:100%}
}

/* ==========================================================================
   Mill drawings on the About page
   ========================================================================== */
.mill-svg{display:block; width:100%; height:auto; min-width:0}
.mill-scroll{overflow-x:auto; scrollbar-width:none}
.mill-scroll::-webkit-scrollbar{display:none}
.mill-scroll > .mill-svg{min-width:900px}
.mill-cycle > .mill-svg{min-width:560px}

.machine-hem{fill:none; stroke:var(--lime-2); stroke-width:2; stroke-linecap:round}

/* chemical spray from the bars */
.spray{
  fill:none; stroke:var(--sky-2); stroke-width:1; stroke-linecap:round;
  opacity:0; animation:spray 1.5s ease-in infinite;
  transform-box:fill-box; transform-origin:top center;
}
@keyframes spray{
  0%{opacity:0; transform:translateY(-6px) scaleY(.4)}
  35%{opacity:.85}
  100%{opacity:0; transform:translateY(10px) scaleY(1.15)}
}

/* infra-red emitter bars */
.ir{
  stroke:var(--lime-2); stroke-width:2.4; stroke-linecap:round;
  animation:irglow 2.4s ease-in-out infinite;
}
@keyframes irglow{
  0%,100%{opacity:.25; filter:none}
  50%{opacity:1; filter:drop-shadow(0 0 5px rgba(168,220,90,.9))}
}

/* hot-air puffs inside the stenter */
.puff{
  fill:none; stroke:var(--sky-2); stroke-width:1.4; stroke-linecap:round;
  opacity:0; animation:puff 2s ease-out infinite;
  transform-box:fill-box; transform-origin:top center;
}
@keyframes puff{
  0%{opacity:0; transform:translateY(-4px)}
  30%{opacity:.8}
  100%{opacity:0; transform:translateY(8px)}
}

/* console readout sweep */
.scan{
  fill:none; stroke:var(--lime-2); stroke-width:1.6; opacity:.75;
  animation:scan 3s ease-in-out infinite;
  transform-box:fill-box; transform-origin:center;
}
@keyframes scan{
  0%,100%{transform:translateY(-13px); opacity:.2}
  50%{transform:translateY(13px); opacity:.9}
}

@media (prefers-reduced-motion:reduce){
  .spray,.puff{display:none}
  .ir,.scan{animation:none; opacity:.7}
}



/* hero layout with the globe alongside the copy */
.hero-grid{align-items:center}
.hero-globe{position:relative; min-width:0}
.hero-legend{
  display:flex; flex-wrap:wrap; justify-content:center; gap:.5rem 1.4rem;
  list-style:none; padding:0; margin:.4rem 0 0;
}

/* scrolling rail of destination markets */
.flag-rail{
  overflow:hidden; margin-top:1.8rem; padding:.4rem 0;
  mask-image:linear-gradient(90deg,transparent,#000 8%,#000 92%,transparent);
  -webkit-mask-image:linear-gradient(90deg,transparent,#000 8%,#000 92%,transparent);
}
.flag-track{display:flex; gap:.7rem; width:max-content; animation:flagrun 52s linear infinite}
.flag-rail:hover .flag-track{animation-play-state:paused}
@keyframes flagrun{to{transform:translateX(-50%)}}
.flag-chip{
  display:inline-flex; align-items:center; gap:.5rem; white-space:nowrap;
  padding:.4rem .85rem; border-radius:100px; border:1px solid var(--line);
  background:rgba(6,16,25,.6); color:var(--paper-2);
  font-family:var(--f-mono); font-size:.66rem; letter-spacing:.1em;
  transition:.3s var(--ease);
}
.flag-chip:hover{border-color:var(--line-lime); color:#fff; background:rgba(140,198,63,.12)}
.flag-chip i{
  font-style:normal; font-size:.95rem; line-height:1;
  font-family:"Apple Color Emoji","Segoe UI Emoji","Noto Color Emoji",var(--f-mono),sans-serif;
}

@media (max-width:1080px){
  .hero-globe{max-width:620px; margin-inline:auto}
}
@media (prefers-reduced-motion:reduce){ .flag-track{animation:none} }

/* At phone widths the 760-unit globe scales to ~350px, which squeezes the flag
   badges into illegible specks. Drop them there — the scrolling flag rail
   further down the page carries the same information at a readable size. */

/* ==========================================================================
   Layout fixes
   ========================================================================== */

/* "Products ▾" and "Resources ▾" wrapped their caret onto a second line, which
   made those two items 64px tall against 40px for the rest and threw the whole
   header bar out of alignment. Keep every nav label on one line, and give them
   all the same box so the baselines agree. */
.nav > a,
.nav .has-sub > a{white-space:nowrap; display:inline-flex; align-items:center}
.nav .has-sub{display:inline-flex; align-items:center}

/* claw back the width that nowrap costs so the bar still fits at 1280 */
@media (max-width:1400px) and (min-width:1261px){
  .head-in{gap:clamp(.7rem,1.4vw,1.4rem)}
  .nav a{padding-inline:.55rem; letter-spacing:.1em}
  .head-cta{padding:.62rem .9rem; letter-spacing:.12em}
}

/* The header quote button sits outside <nav>, so the mobile rule that shows it
   left a 154px button competing with the logo and burger at 390px — the whole
   document scrolled sideways by 124px. Below 820px the nav menu and the
   floating quote dock both cover this action, so the header button stands down. */
@media (max-width:820px){
  .head-cta{display:none !important}
}

/* belt and braces: nothing should ever push the document sideways */
html,body{max-width:100%; overflow-x:hidden}

/* ==========================================================================
   Globe sits on the page, not in a box
   ========================================================================== */
/* extra.css framed the globe in a bordered, rounded panel with its own
   background. On a page whose whole character is the gradient behind it, that
   read as a widget dropped onto the design. Let the sphere sit directly on the
   background and carry its own atmosphere instead. */
.globe-stage{
  background:none !important;
  border:0 !important;
  border-radius:0 !important;
  overflow:visible !important;
  aspect-ratio:1/.9 !important;
}

/* ==========================================================================
   Card rails — one row, auto-advancing
   ========================================================================== */
/* These used to be wrapping grids. Seven cards over three columns left an
   orphan row with a hole in it; the rail keeps everything on one line and
   moves through them instead. */
.card-rail .slide-rail{
  gap:clamp(1.1rem,1.8vw,1.6rem);
  padding:.4rem .2rem 1.2rem;
  scroll-snap-type:x proximity;
}
.card-rail .slide-rail > .cat-card{
  width:clamp(250px,25vw,320px);
  flex-shrink:0;
  scroll-snap-align:start;
}
.card-rail .cat-card{display:flex; flex-direction:column}
.card-rail .cat-body{display:flex; flex-direction:column; flex:1}
.card-rail .cat-body .cat-count{margin-top:auto}

/* text-only variant (the "Other ranges" rail) needs a floor so the cards
   don't collapse to different heights */
.card-rail .cat-card:not(:has(.cat-media)) .cat-body{min-height:150px}

@media (max-width:640px){
  .card-rail .slide-rail > .cat-card{width:78vw}
}

/* ==========================================================================
   App toasts (install prompt, update notice, offline notice)
   ========================================================================== */
.app-toast{
  position:fixed; left:50%; bottom:1.2rem; z-index:95;
  transform:translate(-50%,180%); opacity:0;
  display:flex; align-items:center; gap:.9rem;
  max-width:min(560px,92vw); padding:.8rem .9rem .8rem 1.2rem;
  border-radius:100px; border:1px solid var(--line-lime);
  background:rgba(7,17,26,.97); backdrop-filter:blur(14px);
  box-shadow:0 24px 50px -24px rgba(0,0,0,.95);
  transition:transform .5s var(--ease), opacity .5s var(--ease);
}
.app-toast.show{transform:translate(-50%,0); opacity:1}
.app-toast > span{
  font-family:var(--f-display); font-size:.92rem; color:var(--paper-2); line-height:1.4;
}
.app-toast button{
  flex-shrink:0; cursor:pointer; border:0; border-radius:100px;
  padding:.5rem 1rem; font-family:var(--f-mono); font-size:.66rem;
  letter-spacing:.14em; text-transform:uppercase; font-weight:500;
  background:linear-gradient(120deg,var(--lime-2),var(--lime)); color:#08160a;
  transition:.28s var(--ease);
}
.app-toast button:hover{transform:translateY(-2px)}
.app-toast .app-toast-x{
  background:none; color:var(--faint); padding:.3rem .4rem; font-size:.8rem; letter-spacing:0;
}
.app-toast .app-toast-x:hover{color:var(--paper); transform:none}

/* optional install button — hidden until the browser offers the prompt */
[data-install][hidden]{display:none !important}

@media (max-width:560px){
  .app-toast{left:.7rem; right:.7rem; transform:translateY(180%); max-width:none; border-radius:var(--r)}
  .app-toast.show{transform:none}
}
