/* Tianneng Partner Portal — one stylesheet, one font request.
   Everything else is served with the page. */

:root{
  --red:#dc2626; --red-dark:#b91c1c; --ink:#111827; --body:#374151;
  --muted:#6b7280; --faint:#9ca3af; --line:#e5e7eb; --bg:#f9fafb;
  --card:#ffffff; --ok:#059669; --warn:#d97706; --info:#2563eb;
  --radius:10px; --shadow:0 1px 2px rgba(16,24,40,.06),0 1px 3px rgba(16,24,40,.1);

  --font-ui:'Inter',-apple-system,BlinkMacSystemFont,'Segoe UI Variable Text',
            'Segoe UI',Roboto,'Helvetica Neue',Arial,sans-serif;
  --font-mono:'IBM Plex Mono',ui-monospace,SFMono-Regular,'Cascadia Mono',
              Menlo,Consolas,'Liberation Mono',monospace;
}

*{box-sizing:border-box}
body{
  margin:0;background:var(--bg);color:var(--ink);
  font:14px/1.5 var(--font-ui);
  -webkit-font-smoothing:antialiased;
  -moz-osx-font-smoothing:grayscale;
  font-feature-settings:'liga' 1,'calt' 1;
}
a{color:var(--info);text-decoration:none}
a:hover{text-decoration:underline}

/* Inter is drawn on a large x-height, so headings want to be pulled
   in slightly or they read as shouting at these sizes. */
h1,h2,h3{margin:0;font-weight:600;letter-spacing:-.014em}
h1{font-size:20px;letter-spacing:-.02em}
h2{font-size:15.5px}
h3{font-size:14px}
p{margin:0 0 10px}
small{font-size:12px}

/* Figures line up in a column whatever the digits are. This single
   rule is most of what separates a finance screen that looks
   trustworthy from one that does not. */
table,.big,.price,.mono,input[type=number],.cap{font-variant-numeric:tabular-nums}

/* ---------- layout ---------- */
.wrap{max-width:1180px;margin:0 auto;padding:0 16px}
.wrap-narrow{max-width:720px;margin:0 auto;padding:0 16px}
.topbar{
  background:var(--card);border-bottom:1px solid var(--line);
  position:sticky;top:0;z-index:40;
}
.topbar-in{display:flex;align-items:center;gap:12px;min-height:56px;padding:7px 0}
/* The official mark, with the page name set beside it behind a hairline
   rule — the logo is the brand, the span says which room you are in. */
.logo{display:flex;align-items:center;gap:11px;white-space:nowrap;flex:none}
/* The logo is a link home on every shell, so strip the anchor styling
   and give it a focus ring it would otherwise not show. */
a.logo{text-decoration:none;color:inherit;border-radius:7px}
a.logo:hover{opacity:.78}
a.logo:focus-visible{outline:2px solid var(--red);outline-offset:3px}
.logo-mark{height:26px;width:auto;display:block;flex:none}
.logo span{
  color:var(--muted);font-weight:600;font-size:13px;letter-spacing:.01em;
  padding-left:11px;border-left:1px solid var(--line);
}
@media (max-width:700px){
  .logo-mark{height:22px}
  .logo span{display:none}   /* on a phone the nav needs the room */
}
.spacer{flex:1}
.nav{display:flex;gap:2px;flex:0 1 auto;min-width:0;overflow-x:auto;scrollbar-width:none}
#whoami{flex:none}
.nav::-webkit-scrollbar{display:none}
.nav button{
  background:none;border:0;padding:8px 12px;border-radius:8px;cursor:pointer;
  color:var(--muted);font:inherit;font-weight:500;white-space:nowrap;
}
.nav button:hover{background:var(--bg);color:var(--ink)}
.nav button.on{background:#fef2f2;color:var(--red)}
.nav button .pip{
  display:inline-block;min-width:18px;padding:0 5px;margin-left:5px;
  background:var(--red);color:#fff;border-radius:9px;font-size:11px;font-weight:700;
}
/* Grouped sections. Eleven top-level links did not fit beside the logo
   and the account block, so the ones staff reach for less often sit one
   click down. The panels are position:fixed and placed from script,
   because .nav scrolls and an overflow container would clip an
   absolutely positioned child. */
.nav-group{display:flex;flex:none}
.nav-group>button::after{
  content:"";display:inline-block;margin-left:7px;vertical-align:2px;
  border:4px solid transparent;border-top-color:currentColor;
}
.nav-group.active>button{background:#fef2f2;color:var(--red)}
.menu{
  position:fixed;z-index:60;min-width:190px;padding:6px;
  background:var(--card);border:1px solid var(--line);border-radius:11px;
  box-shadow:0 12px 30px rgba(15,23,42,.14);
}
.menu button{
  display:block;width:100%;text-align:left;background:none;border:0;
  padding:9px 11px;border-radius:8px;cursor:pointer;
  color:var(--ink);font:inherit;font-weight:500;white-space:nowrap;
}
.menu button:hover{background:var(--bg)}
.menu button.on{background:#fef2f2;color:var(--red)}
.menu-head{padding:6px 11px 9px;margin-bottom:6px;border-bottom:1px solid var(--line)}
.menu-sep{height:1px;background:var(--line);margin:6px 0}
/* The account control is one compact button, so a name set over a role
   can no longer push the header past its own height. */
.who{
  display:flex;align-items:center;gap:8px;max-width:190px;
  background:none;border:1px solid var(--line);border-radius:9px;
  padding:6px 10px;cursor:pointer;font:inherit;font-size:13px;color:var(--ink);
}
.who:hover{background:var(--bg)}
.who b{font-weight:600;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.who::after{
  content:"";flex:none;margin-top:2px;
  border:4px solid transparent;border-top-color:var(--muted);
}
main{padding:20px 0 60px}

/* ---------- cards ---------- */
.card{background:var(--card);border:1px solid var(--line);border-radius:var(--radius);box-shadow:var(--shadow)}
.card-pad{padding:16px}
.card-head{padding:14px 16px;border-bottom:1px solid var(--line);display:flex;align-items:center;gap:10px}
.grid{display:grid;gap:14px}
.g2{grid-template-columns:repeat(2,1fr)}
.g3{grid-template-columns:repeat(3,1fr)}
.g4{grid-template-columns:repeat(4,1fr)}
.row{display:flex;gap:10px;align-items:center;flex-wrap:wrap}
.between{display:flex;justify-content:space-between;align-items:center;gap:10px}
.stack{display:flex;flex-direction:column;gap:12px}

/* ---------- text ---------- */
.muted{color:var(--muted)}
.faint{color:var(--faint)}
.tiny{font-size:12px}
.mono{font-family:var(--font-mono);letter-spacing:-.01em}
.big{font-size:26px;font-weight:700;letter-spacing:-.02em}
.right{text-align:right}
.center{text-align:center}
.nowrap{white-space:nowrap}
.cap{text-transform:uppercase;letter-spacing:.06em;font-size:11px;font-weight:700;color:var(--faint)}

/* ---------- controls ---------- */
button,.btn{
  font:inherit;font-weight:600;border-radius:8px;border:1px solid var(--line);
  background:var(--card);color:var(--ink);padding:9px 14px;cursor:pointer;
}
button:hover,.btn:hover{background:var(--bg)}
button:disabled{opacity:.5;cursor:not-allowed}
.btn-primary{background:var(--red);border-color:var(--red);color:#fff}
.btn-primary:hover{background:var(--red-dark)}
.btn-ok{background:var(--ok);border-color:var(--ok);color:#fff}
.btn-ok:hover{filter:brightness(.94)}
.btn-sm{padding:6px 10px;font-size:13px}
.btn-link{border:0;background:none;color:var(--info);padding:4px 2px}
.btn-block{width:100%;justify-content:center}

input,select,textarea{
  font:inherit;width:100%;padding:9px 11px;border:1px solid var(--line);
  border-radius:8px;background:var(--card);color:var(--ink);
}
input:focus,select:focus,textarea:focus{outline:2px solid #fecaca;outline-offset:-1px;border-color:var(--red)}
textarea{min-height:78px;resize:vertical}
label{display:block;font-weight:600;font-size:13px;margin:0 0 5px}
.field{margin-bottom:14px}
.field .hint{font-size:12px;color:var(--muted);margin-top:4px}
.inline{display:flex;gap:10px;align-items:center}
.check{display:flex;gap:8px;align-items:flex-start;font-weight:500}
.check input{width:auto;margin-top:2px}

/* ---------- badges ---------- */
.badge{
  display:inline-block;padding:3px 8px;border-radius:999px;font-size:11.5px;
  font-weight:700;letter-spacing:.02em;background:var(--bg);color:var(--muted);
  border:1px solid var(--line);white-space:nowrap;
}
.badge.ok{background:#ecfdf5;color:#047857;border-color:#a7f3d0}
.badge.warn{background:#fffbeb;color:#b45309;border-color:#fde68a}
.badge.bad{background:#fef2f2;color:#b91c1c;border-color:#fecaca}
.badge.info{background:#eff6ff;color:#1d4ed8;border-color:#bfdbfe}
.badge.hot{background:#fff1f2;color:#be123c;border-color:#fecdd3}

/* ---------- tables ---------- */
.table-wrap{overflow-x:auto}
table{width:100%;border-collapse:collapse;font-size:13.5px}
th{
  text-align:left;font-size:11.5px;text-transform:uppercase;letter-spacing:.05em;
  color:var(--faint);font-weight:700;padding:9px 12px;border-bottom:1px solid var(--line);
  white-space:nowrap;background:var(--card);
}
th.sortable{cursor:pointer;user-select:none}
th.sortable:hover{color:var(--ink)}
td{padding:11px 12px;border-bottom:1px solid var(--line);vertical-align:top}
tbody tr:hover{background:#fcfcfd}
tbody tr.clickable{cursor:pointer}
.table-empty{padding:36px 16px;text-align:center;color:var(--muted)}

/* ---------- tabs ---------- */
.tabs{display:flex;gap:2px;border-bottom:1px solid var(--line);overflow-x:auto;scrollbar-width:none}
.tabs::-webkit-scrollbar{display:none}
.tabs button{
  border:0;background:none;padding:10px 14px;border-bottom:2px solid transparent;
  border-radius:0;color:var(--muted);white-space:nowrap;
}
.tabs button.on{color:var(--red);border-bottom-color:var(--red)}
.tabs .pip{
  display:inline-block;margin-left:6px;padding:0 6px;border-radius:9px;
  background:var(--bg);color:var(--muted);font-size:11px;font-weight:700;
}
.tabs button.on .pip{background:#fee2e2;color:var(--red)}

/* ---------- catalog ---------- */
.products{display:grid;gap:14px;grid-template-columns:repeat(auto-fill,minmax(216px,1fr))}
.product{background:var(--card);border:1px solid var(--line);border-radius:var(--radius);overflow:hidden;display:flex;flex-direction:column}
.product .thumb{
  height:150px;background:#fff;display:flex;align-items:center;justify-content:center;
  color:var(--faint);font-size:12px;font-weight:600;border-bottom:1px solid var(--line);
}
/* contain, not cover: these are product shots squared on white, and
   cover cropped the top and bottom off every battery. */
.product .thumb img{width:100%;height:100%;object-fit:contain;padding:10px}
.product .body{padding:12px;display:flex;flex-direction:column;gap:6px;flex:1}
.product .name{font-weight:600;line-height:1.35}
.price{font-size:17px;font-weight:700;color:var(--ink)}

/* ---------- pipeline ---------- */
.timeline{display:flex;flex-direction:column;gap:0}
.tl-step{display:flex;gap:12px;padding:0 0 16px;position:relative}
.tl-step:last-child{padding-bottom:0}
.tl-dot{
  width:11px;height:11px;border-radius:50%;background:var(--line);margin-top:4px;flex:none;
  box-shadow:0 0 0 3px var(--card);z-index:1;
}
.tl-step.done .tl-dot{background:var(--ok)}
.tl-step:not(:last-child):before{
  content:"";position:absolute;left:5px;top:12px;bottom:0;width:1px;background:var(--line);
}
.tl-step.done:not(:last-child):before{background:#a7f3d0}

/* ---------- wizard ---------- */
.steps{display:flex;gap:6px;flex-wrap:wrap;margin-bottom:20px}
.step{
  display:flex;align-items:center;gap:7px;padding:7px 12px;border-radius:999px;
  background:var(--card);border:1px solid var(--line);font-size:12.5px;font-weight:600;color:var(--muted);
}
.step .n{
  width:19px;height:19px;border-radius:50%;background:var(--line);color:var(--card);
  display:flex;align-items:center;justify-content:center;font-size:11px;font-weight:700;
}
.step.on{border-color:var(--red);color:var(--red);background:#fef2f2}
.step.on .n{background:var(--red)}
.step.done{color:var(--ok);border-color:#a7f3d0;background:#ecfdf5}
.step.done .n{background:var(--ok)}
.progress{height:5px;background:var(--line);border-radius:999px;overflow:hidden;margin-bottom:16px}
.progress i{display:block;height:100%;background:var(--red);transition:width .25s}

/* ---------- doc rows ---------- */
.doc{
  display:flex;align-items:center;gap:12px;padding:12px;border:1px solid var(--line);
  border-radius:8px;margin-bottom:8px;background:var(--card);
}
.doc.have{border-color:#a7f3d0;background:#f0fdf4}
.doc .doc-main{flex:1;min-width:0}
.doc .doc-name{font-weight:600;font-size:13.5px}
.doc .doc-file{font-size:12px;color:var(--muted);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}

/* ---------- banners ---------- */
.banner{padding:12px 14px;border-radius:8px;font-size:13.5px;margin-bottom:14px;border:1px solid}
.banner.info{background:#eff6ff;border-color:#bfdbfe;color:#1e40af}
.banner.warn{background:#fffbeb;border-color:#fde68a;color:#92400e}
.banner.bad{background:#fef2f2;border-color:#fecaca;color:#991b1b}
.banner.ok{background:#ecfdf5;border-color:#a7f3d0;color:#065f46}

/* ---------- modal ---------- */
.modal-bg{
  position:fixed;inset:0;background:rgba(17,24,39,.5);display:flex;align-items:flex-start;
  justify-content:center;padding:5vh 16px;z-index:60;overflow-y:auto;
}
.modal{background:var(--card);border-radius:12px;width:100%;max-width:640px;box-shadow:0 20px 40px rgba(0,0,0,.2)}
.modal-wide{max-width:900px}
.modal-head{padding:16px;border-bottom:1px solid var(--line);display:flex;align-items:center;gap:10px}
.modal-body{padding:16px;max-height:70vh;overflow-y:auto}
.modal-foot{padding:14px 16px;border-top:1px solid var(--line);display:flex;gap:8px;justify-content:flex-end}

/* ---------- terms and consent ---------- */
/* The hint sits on the left of the footer and the buttons stay right,
   so "scroll to the bottom to continue" is read as an instruction
   rather than mistaken for a third button. */
.terms-hint{margin-right:auto;align-self:center;text-align:left}
.terms{line-height:1.6}
.terms h3{font-size:14px;margin:20px 0 6px}
.terms h3:first-of-type{margin-top:6px}
.terms p{margin:0 0 10px}
.terms ul{margin:0 0 12px 18px;padding:0}
.terms li{margin-bottom:6px}
/* An explicit end marker. Without one, a reader who has reached the
   bottom cannot tell whether the document stopped or the scrolling
   did. */
.terms-end{
  margin-top:18px;padding:10px 12px;border-top:1px solid var(--line);
  color:var(--muted);font-size:12px;text-align:center;
}
.consent{
  display:flex;gap:10px;align-items:flex-start;margin:18px 0 12px;
  padding:12px 14px;border:1px solid var(--line);border-radius:8px;
  background:var(--bg);cursor:pointer;line-height:1.5;
}
.consent input{flex:none;width:17px;height:17px;margin-top:1px;cursor:pointer}
/* An anchor, because a <button> is coerced to inline-block by every
   browser and would be one unbreakable box — the sentence would break
   around the link rather than through it, stranding the comma. */
.consent .tlink{color:var(--info);text-decoration:underline;cursor:pointer}
.x{border:0;background:none;font-size:20px;line-height:1;color:var(--muted);padding:2px 6px}

/* ---------- product dialog ---------- */
/* Picture beside the numbers on a desktop, stacked on a phone. */
.pdet{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:22px;align-items:start}
.pdet-shot{
  background:#fff;border:1px solid var(--line);border-radius:10px;
  display:flex;align-items:center;justify-content:center;padding:14px;min-height:260px;
}
.pdet-shot img{max-width:100%;max-height:340px;object-fit:contain;display:block}
.pdet-blurb{color:var(--muted);font-size:13.5px;line-height:1.6;margin:0 0 16px}
.spec-table{width:100%;border-collapse:collapse;font-size:13px}
.spec-table th,.spec-table td{padding:7px 0;border-bottom:1px solid var(--line);vertical-align:top}
.spec-table th{text-align:left;font-weight:500;color:var(--muted);width:46%}
.spec-table td{text-align:right;font-weight:600}
.spec-table tr:last-child th,.spec-table tr:last-child td{border-bottom:0}
@media (max-width:640px){
  .pdet{grid-template-columns:1fr;gap:16px}
  .pdet-shot{min-height:0}
  .pdet-shot img{max-height:240px}
}

/* ---------- toast ---------- */
#toasts{position:fixed;right:16px;bottom:16px;z-index:80;display:flex;flex-direction:column;gap:8px}
.toast{
  background:var(--ink);color:#fff;padding:11px 15px;border-radius:8px;font-size:13.5px;
  box-shadow:0 8px 20px rgba(0,0,0,.25);max-width:340px;animation:pop .16s ease-out;
}
.toast.bad{background:var(--red)}
.toast.ok{background:var(--ok)}
@keyframes pop{from{opacity:0;transform:translateY(6px)}to{opacity:1;transform:none}}

/* ---------- loading ---------- */
.skel{background:linear-gradient(90deg,#eee,#f5f5f5,#eee);background-size:200% 100%;
  animation:sk 1.1s infinite;border-radius:6px;height:14px}
@keyframes sk{0%{background-position:200% 0}100%{background-position:-200% 0}}
.loading{padding:30px;text-align:center;color:var(--muted);font-size:13px}

/* ---------- map ---------- */
.map{position:relative;width:100%;height:520px;background:#eef2f7;border-radius:var(--radius);overflow:hidden}
.pin{position:absolute;transform:translate(-50%,-50%);border-radius:50%;border:2px solid #fff;
  box-shadow:0 1px 4px rgba(0,0,0,.35);cursor:pointer;z-index:2}
.pin.pending{background:#fff !important;border-style:dashed}
.grid-line{position:absolute;background:#dbe3ee}
.grid-line.horizontal{left:0;right:0;height:1px}
.grid-line.vertical{top:0;bottom:0;width:1px}
.grid-label{position:absolute;font-size:9px;color:#94a3b8;font-weight:600;
  transform:translate(0,-50%);pointer-events:none}

/* The applicant a reviewer sent over from their application. It has to
   be unmistakable against the network it is being judged against, so it
   is red, larger, ringed and named, where a real partner is a quiet dot. */
.pin.spotlight{
  z-index:5;background:var(--red);border:3px solid #fff;
  animation:pin-pulse 1.8s ease-out infinite;
}
@keyframes pin-pulse{
  0%  {box-shadow:0 0 0 3px rgba(220,38,38,.45),0 2px 8px rgba(0,0,0,.4)}
  70% {box-shadow:0 0 0 16px rgba(220,38,38,0),0 2px 8px rgba(0,0,0,.4)}
  100%{box-shadow:0 0 0 3px rgba(220,38,38,0),0 2px 8px rgba(0,0,0,.4)}
}
.pin-label{
  position:absolute;z-index:6;pointer-events:none;
  transform:translate(-50%,14px);max-width:190px;overflow:hidden;text-overflow:ellipsis;
  padding:3px 8px;border-radius:7px;white-space:nowrap;
  background:var(--red);color:#fff;font-size:11px;font-weight:600;
  box-shadow:0 2px 6px rgba(0,0,0,.25);
}
/* A pulsing dot is motion nobody asked for if they have asked not to. */
@media (prefers-reduced-motion:reduce){
  .pin.spotlight{animation:none;box-shadow:0 0 0 3px rgba(220,38,38,.45),0 2px 8px rgba(0,0,0,.4)}
}

/* ================= customer-facing site =================
   The portal is a dense tool for people who use it daily. This is
   the opposite job: a stranger on a phone who wants one answer. More
   air, bigger type, fewer things on screen. */

.site-bar{background:var(--card);border-bottom:1px solid var(--line);position:sticky;top:0;z-index:40}
.site-bar-in{display:flex;align-items:center;gap:22px;height:66px}
.site-bar .logo{text-decoration:none}
.site-nav{display:flex;gap:4px;align-items:center}
.site-nav a{
  padding:9px 13px;border-radius:8px;color:var(--body);font-weight:550;
  font-size:14px;text-decoration:none;white-space:nowrap;
}
.site-nav a:hover{background:var(--bg);text-decoration:none}
.site-nav a.on{color:var(--red);background:#fef2f2}
.site-login{text-decoration:none;white-space:nowrap}
/* Sign-in sits in the header on desktop and in the burger on a phone,
   never in both at once. */
.site-nav .nav-signin{display:none}
.site-burger{display:none;border:0;background:none;font-size:22px;padding:4px 8px;line-height:1}

.hero{
  background:linear-gradient(180deg,#fff 0%,var(--bg) 100%);
  border-bottom:1px solid var(--line);padding:68px 0 60px;
}
.site-foot .operator{
  color:#fff;font-weight:600;font-size:12.5px;letter-spacing:.02em;
  text-transform:uppercase;
}
.hero h1{font-size:40px;line-height:1.12;letter-spacing:-.03em;max-width:17ch}
.hero p{font-size:17px;color:var(--muted);max-width:56ch;margin-top:16px;line-height:1.6}
.hero .row{margin-top:28px}
.hero .btn{padding:12px 20px;font-size:15px;text-decoration:none}

/* ---------- home hero slider ----------
   The first thing a stranger sees has to say "batteries for electric
   two- and three-wheelers" before they read a word, because the one
   thing we are routinely mistaken for is solar. So: the vehicle in the
   photograph, and the actual packs that drive it standing on the floor
   in front of it.

   The copy sits beside the picture rather than on top of it. Text over
   a photograph is a contrast problem on every slide and an unreadable
   one on at least some of them, and no scrim dark enough to fix it
   leaves the vehicle visible. */
.hero-grid{display:grid;grid-template-columns:minmax(0,.92fr) minmax(0,1.08fr);gap:44px;align-items:center}
.hero-copy h1{font-size:40px;line-height:1.12;letter-spacing:-.03em;max-width:18ch}
.hero-copy p{font-size:17px;color:var(--muted);max-width:52ch;margin-top:16px;line-height:1.6}
.hero-copy .row{margin-top:28px}

.hero-stage{
  position:relative;border-radius:16px;overflow:hidden;background:#0f172a;
  aspect-ratio:16/10;box-shadow:0 18px 44px rgba(15,23,42,.18);
}
.hero-slide{position:absolute;inset:0;margin:0;opacity:0;transition:opacity .8s ease}
.hero-slide.on{opacity:1}
.hero-shot{width:100%;height:100%;object-fit:cover;display:block}

/* The floor the packs stand on. Dark enough to seat them and to carry
   the caption, light enough that the vehicle above is still the shot. */
.hero-floor{
  position:absolute;left:0;right:0;bottom:0;height:58%;pointer-events:none;
  background:linear-gradient(180deg,rgba(9,14,27,0) 0%,rgba(9,14,27,.42) 45%,rgba(9,14,27,.86) 100%);
}
.hero-packs{
  position:absolute;left:0;right:0;bottom:0;display:flex;gap:18px;
  align-items:flex-end;justify-content:center;padding:0 20px 16px;
}
.hero-packs img{
  height:clamp(54px,13.5cqw,104px);width:auto;display:block;
  filter:drop-shadow(0 12px 12px rgba(0,0,0,.55));
}
.hero-stage{container-type:inline-size}

.hero-cap{position:absolute;left:16px;top:16px;right:16px;display:flex;align-items:center;gap:10px}
.hero-chip{
  background:var(--red);color:#fff;font-size:11px;font-weight:700;letter-spacing:.08em;
  text-transform:uppercase;padding:5px 11px;border-radius:999px;white-space:nowrap;
}
.hero-cap span.what{
  color:#fff;font-size:12.5px;font-weight:600;
  text-shadow:0 1px 6px rgba(0,0,0,.8);
}

.hero-dots{display:flex;gap:8px;margin-top:16px;justify-content:center}
.hero-dots button{
  width:30px;height:5px;border:0;padding:0;border-radius:999px;cursor:pointer;
  background:var(--line);transition:background .2s;
}
.hero-dots button[aria-current="true"]{background:var(--red)}
.hero-dots button:focus-visible{outline:2px solid var(--red);outline-offset:3px}

@media (max-width:880px){
  .hero-grid{grid-template-columns:1fr;gap:26px}
  /* Picture first on a phone: it is the whole point of the section. */
  .hero-rail{order:-1}
  .hero-copy h1{font-size:30px;max-width:none}
  .hero-copy p{font-size:15.5px;max-width:none}
}
/* A carousel that moves on its own is the textbook case for honouring
   this. The dots still work, so nothing is lost. */
@media (prefers-reduced-motion:reduce){
  .hero-slide{transition:none}
}

.section{padding:56px 0}
.section + .section{border-top:1px solid var(--line)}
.section h2{font-size:25px;letter-spacing:-.02em}
.section .lede{color:var(--muted);margin-top:8px;max-width:62ch;font-size:15px}
.section-head{margin-bottom:28px}

.pcard{background:var(--card);border:1px solid var(--line);border-radius:var(--radius);overflow:hidden}
.pcard{position:relative}
.pcard .thumb{
  height:184px;background:#fff;display:flex;align-items:center;justify-content:center;
  color:var(--faint);font-weight:700;font-size:19px;letter-spacing:.04em;
  border-bottom:1px solid var(--line);
}
/* See .product .thumb img - same reason, same fix. */
.pcard .thumb img{width:100%;height:100%;object-fit:contain;padding:14px;transition:transform .18s}

/* The whole card opens the product, so it is one button. A div with a
   click handler is not reachable by keyboard and reads as nothing to a
   screen reader; a real <button> gets focus, Enter and Space for free. */
button.pcard{
  display:block;width:100%;padding:0;text-align:left;font:inherit;color:inherit;
  cursor:pointer;transition:border-color .18s,box-shadow .18s;
}
button.pcard:hover{border-color:var(--red);box-shadow:0 8px 22px rgba(15,23,42,.10)}
button.pcard:hover .thumb img{transform:scale(1.045)}
button.pcard:focus-visible{outline:2px solid var(--red);outline-offset:2px}
/* A quiet affordance, so it is not a guess that the card does something. */
.pcard .zoom{
  position:absolute;top:10px;right:10px;width:26px;height:26px;border-radius:50%;
  display:flex;align-items:center;justify-content:center;
  background:rgba(255,255,255,.92);border:1px solid var(--line);
  color:var(--muted);font-size:13px;line-height:1;opacity:0;transition:opacity .18s;
}
button.pcard:hover .zoom,button.pcard:focus-visible .zoom{opacity:1}
.pcard .body{padding:15px}
.pcard .body h3{font-size:15px;margin-bottom:5px}
.pcard dl{display:grid;grid-template-columns:auto 1fr;gap:3px 12px;margin:11px 0 0;font-size:12.5px}
.pcard dt{color:var(--muted)}
.pcard dd{margin:0;font-weight:600;text-align:right}

.tool{max-width:560px;margin:0 auto}
.tool .card-pad{padding:26px}
.steps-3{display:grid;grid-template-columns:repeat(3,1fr);gap:22px;counter-reset:s}
.steps-3 li{list-style:none;counter-increment:s}
.steps-3 li:before{
  content:counter(s);display:flex;align-items:center;justify-content:center;
  width:30px;height:30px;border-radius:50%;background:var(--red);color:#fff;
  font-weight:700;font-size:14px;margin-bottom:11px;
}
.steps-3 h3{font-size:15px;margin-bottom:5px}
.steps-3 p{color:var(--muted);font-size:13.5px;margin:0}

.site-foot{background:var(--ink);color:#d1d5db;margin-top:68px;padding:40px 0 32px;font-size:13.5px}
.site-foot a{color:#f3f4f6}
.site-foot h4{color:#fff;font-size:13px;text-transform:uppercase;letter-spacing:.07em;margin-bottom:11px}
.site-foot .cols{display:grid;grid-template-columns:2fr 1fr 1fr;gap:34px}
.site-foot .fine{
  margin-top:30px;padding-top:18px;border-top:1px solid #374151;
  color:#9ca3af;font-size:12px;display:flex;justify-content:space-between;gap:14px;flex-wrap:wrap;
}

@media (max-width:820px){
  .hero{padding:46px 0 42px}
  .hero h1{font-size:29px}
  .steps-3{grid-template-columns:1fr;gap:24px}
  .site-foot .cols{grid-template-columns:1fr;gap:26px}
  .site-nav{
    display:none;position:absolute;top:66px;left:0;right:0;flex-direction:column;
    align-items:stretch;gap:0;background:var(--card);
    border-bottom:1px solid var(--line);padding:8px;
    box-shadow:0 10px 24px rgba(16,24,40,.09);
  }
  .site-nav.open{display:flex}
  .site-nav a{padding:13px}
  .site-burger{display:block}
  .site-login{display:none}
  .site-nav .nav-signin{display:block;font-weight:700;color:var(--red);border-top:1px solid var(--line);margin-top:6px}
}

/* ---------- printable QR labels ----------
   The sheet takes over the whole page while it is open, so what is
   on screen is exactly what comes out of the printer. */
#label-sheet{display:none;padding:18px}
body.labels-open > *:not(#label-sheet){display:none !important}
body.labels-open #label-sheet{display:block}
/* Three across, not four. A live /exec URL plus serial and key is
   around 155 bytes, which is a version 9 code — 53 modules. At four
   per row those modules print below the ~0.5 mm that a phone camera
   can resolve, and a label that will not scan is worse than no label. */
.label-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:6px}
.label{
  border:1px dashed #cbd5e1;border-radius:4px;padding:10px;display:flex;gap:10px;
  align-items:center;background:#fff;break-inside:avoid;page-break-inside:avoid;
}
.label .qr{flex:none;width:104px;height:104px}
.label .qr svg{display:block;width:100%;height:100%}
.label .meta{min-width:0;font-size:9px;line-height:1.35;overflow:hidden}
.label .meta .sn{
  font-family:var(--font-mono);
  font-size:10px;font-weight:500;letter-spacing:-.02em;
}
.label .meta .nm{font-weight:600;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.label .meta .cta{color:#6b7280}

/* ---------- certificate ---------- */
.cert{
  background:#fff;border:3px double var(--red);border-radius:8px;padding:40px;text-align:center;
  max-width:720px;margin:0 auto;
}
.cert .cert-kicker{letter-spacing:.28em;font-size:11px;font-weight:700;color:var(--red)}
.cert .cert-logo{height:40px;width:auto;margin:0 auto 4px;display:block}
@media print{ .cert .cert-logo{height:44px} }
.cert .cert-name{font-size:27px;font-weight:700;margin:16px 0 6px}
.cert .cert-type{letter-spacing:.16em;font-weight:700;color:var(--red);font-size:14px}

@media (max-width:820px){
  .g4{grid-template-columns:repeat(2,1fr)}
  .g3{grid-template-columns:1fr}
}
@media (max-width:560px){
  .g2,.g4{grid-template-columns:1fr}
  .topbar-in{height:52px}
  .cert{padding:24px}
}
@media print{
  .topbar,.nav,.no-print{display:none !important}
  body{background:#fff}
  .cert{border-color:#000}
  body.labels-open #label-sheet{padding:0}
  .label{border-color:#e5e7eb}
  .label-grid{gap:4px}
  @page{margin:8mm}
}