/* Rotary Actuator India — industrial design system
   Dark charcoal + safety yellow. No gradients, no shadows, no frills. */

:root{
  --ink:#1a1a1a; --steel:#2b2b2b; --line:#d9d9d9; --paper:#ffffff;
  --yellow:#f5b700; --mut:#666; --faint:#999;
  --mono:"SFMono-Regular",Consolas,"Liberation Mono",Menlo,monospace;
}
*{box-sizing:border-box;margin:0;padding:0}
html{scroll-behavior:smooth}
body{font-family:Arial,Helvetica,"Segoe UI",sans-serif;color:var(--ink);background:var(--paper);line-height:1.55}
.mono{font-family:var(--mono);font-size:.95em}
.wrap{max-width:1080px;margin:0 auto;padding:0 20px}
a{color:inherit}

/* header */
header.site{background:var(--ink);border-bottom:4px solid var(--yellow)}
.nav{display:flex;align-items:center;gap:24px;max-width:1080px;margin:0 auto;padding:14px 20px}
.brand{color:#fff;font-weight:bold;letter-spacing:.5px;font-size:17px}
.brand small{display:block;font-weight:400;color:var(--faint);font-size:11px;letter-spacing:2px}
.nav nav{margin-left:auto;display:flex;gap:18px}
.nav nav a{color:#ccc;text-decoration:none;font-size:14px;padding:4px 2px;border-bottom:2px solid transparent}
.nav nav a:hover{color:#fff;border-color:var(--yellow)}

/* hero */
.hero{background:var(--ink);color:#fff;padding:56px 0 48px}
.hero h1{font-size:30px;line-height:1.25;max-width:760px}
.hero h1 em{color:var(--yellow);font-style:normal}
.hero p.sub{color:#bbb;max-width:640px;margin-top:12px;font-size:15px}

/* search */
.searchbox{margin-top:28px;max-width:640px;display:flex}
.searchbox input{flex:1;padding:14px 16px;font-size:16px;font-family:var(--mono);border:2px solid var(--yellow);background:#111;color:#fff}
.searchbox input:focus{outline:none;background:#000}
.searchbox button{padding:14px 22px;background:var(--yellow);border:none;font-weight:bold;font-size:15px;cursor:pointer;color:var(--ink)}
.searchbox button:hover{background:#ffd033}
.searchhint{color:var(--faint);font-size:12px;margin-top:8px}
.searchhint code{color:#ccc}
#searchOut{margin-top:20px;max-width:760px}

/* hit card */
.hit-card{background:#fff;color:var(--ink);border-left:6px solid var(--yellow);padding:18px 20px}
.hit-head{display:flex;justify-content:space-between;align-items:baseline;gap:12px;flex-wrap:wrap;margin-bottom:10px}
.hit-oem{font-size:15px}
.hit-oem b{font-size:17px}
.hit-status{font-size:11px;letter-spacing:1px;text-transform:uppercase;border:1px solid var(--ink);padding:2px 8px}
.hit-status.custom{border-color:var(--yellow);background:var(--yellow)}
table.spec{width:100%;border-collapse:collapse;font-size:14px}
table.spec td{padding:6px 8px;border-top:1px solid var(--line)}
table.spec td:first-child{color:var(--mut);width:46%}
table.spec.wide th{font-size:12px;text-transform:uppercase;letter-spacing:.5px;color:var(--mut);text-align:left;padding:6px 8px;border-top:1px solid var(--line)}
table.spec.wide td.mono a{color:var(--ink)}
.highlight{color:#8a6800;font-weight:bold}
.hit-actions{margin-top:14px;display:flex;gap:10px;flex-wrap:wrap}
.muted{color:var(--mut);font-size:14px}

/* buttons */
.btn{display:inline-block;background:var(--ink);color:#fff;text-decoration:none;padding:10px 18px;font-size:14px;border:1px solid var(--ink)}
.btn:hover{background:#000;border-color:#000}
.btn.ghost{background:transparent;color:var(--ink)}
.btn.ghost:hover{background:var(--ink);color:#fff}
.btn.yellow{background:var(--yellow);color:var(--ink);border-color:var(--yellow);font-weight:bold}
.btn.yellow:hover{background:#ffd033}

/* sections */
section.block{padding:56px 0}
section.block:nth-of-type(even){background:#f4f4f4}
.block h2{font-size:22px;margin-bottom:8px}
.block .lead{color:var(--mut);max-width:720px;margin-bottom:28px;font-size:15px}
.kicker{font-size:12px;letter-spacing:2px;text-transform:uppercase;color:var(--faint);margin-bottom:6px}

/* two panel */
.panels{display:grid;grid-template-columns:1fr 1fr;gap:20px}
@media(max-width:760px){.panels{grid-template-columns:1fr}}
.panel{border:1px solid var(--line);border-top:5px solid var(--ink);padding:24px;background:#fff}
.panel h3{font-size:18px;margin-bottom:8px}
.panel p{font-size:14px;color:var(--mut);margin-bottom:16px}
.panel ul{margin:0 0 18px 18px;font-size:14px}
.panel li{margin:4px 0}

/* stats strip */
.stats{display:grid;grid-template-columns:repeat(4,1fr);gap:1px;background:var(--line);border:1px solid var(--line)}
@media(max-width:760px){.stats{grid-template-columns:repeat(2,1fr)}}
.stat{background:#fff;padding:18px;text-align:center}
.stat b{display:block;font-size:26px}
.stat span{font-size:12px;color:var(--mut);text-transform:uppercase;letter-spacing:1px}

/* factory photo */
.photo{border:1px solid var(--line)}
.photo img{width:100%;display:block}
.photo figcaption{padding:10px 14px;font-size:12px;color:var(--mut);border-top:1px solid var(--line)}

/* process steps */
.steps{counter-reset:s;display:grid;grid-template-columns:repeat(4,1fr);gap:16px}
@media(max-width:760px){.steps{grid-template-columns:1fr 1fr}}
.step{border:1px solid var(--line);padding:18px;position:relative;background:#fff}
.step::before{counter-increment:s;content:counter(s,decimal-leading-zero);position:absolute;top:10px;right:14px;font-family:var(--mono);color:var(--faint);font-size:13px}
.step h4{font-size:15px;margin-bottom:6px}
.step p{font-size:13px;color:var(--mut)}

/* forms */
form.inq{max-width:640px}
form.inq label{display:block;font-size:13px;margin:14px 0 4px;color:var(--mut)}
form.inq input,form.inq select,form.inq textarea{width:100%;padding:10px 12px;border:1px solid var(--line);font-size:14px;font-family:inherit;background:#fff}
form.inq input:focus,form.inq textarea:focus,form.inq select:focus{outline:2px solid var(--yellow);outline-offset:-1px}
form.inq .row2{display:grid;grid-template-columns:1fr 1fr;gap:14px}
form.inq button{margin-top:20px}

/* tables page */
table.big{width:100%;border-collapse:collapse;font-size:14px;background:#fff}
table.big th{background:var(--ink);color:#fff;text-align:left;padding:9px 10px;font-size:12px;letter-spacing:.5px;text-transform:uppercase}
table.big td{padding:8px 10px;border:1px solid var(--line)}
table.big tr:hover td{background:#fbf6e3}
table.big td.mono{font-size:13px}

footer.site{background:var(--ink);color:#999;padding:32px 0;font-size:13px;margin-top:0}
footer.site .wrap{display:flex;justify-content:space-between;gap:20px;flex-wrap:wrap}
footer.site b{color:#fff}

/* whatsapp float */
.wa{position:fixed;right:16px;bottom:16px;background:#25d366;color:#fff;text-decoration:none;font-weight:bold;font-size:14px;padding:12px 18px;border:2px solid #1da851}
.wa:hover{background:#1ebe5b}

.note{font-size:12px;color:var(--faint);margin-top:18px;border-top:1px dashed var(--line);padding-top:12px}

/* photo gallery */
.gallery{display:grid;grid-template-columns:1fr 1fr;gap:16px}
@media(max-width:760px){.gallery{grid-template-columns:1fr}}
.gallery .photo{margin:0}

/* ===== ADDITIONS — not in the original site =====
   Everything ABOVE this banner is byte-identical to the original stylesheet, and
   tools/verify/run.mjs asserts it. New rules go below, never above. The pages
   that still mirror the original are pixel-diffed against it, so a rule here
   that leaks onto them fails the build. */

/* brand is a link home; it was a <div> */
.brand{text-decoration:none}

/* lazy photos carry width/height so their box is reserved before load; without
   this the height attribute would win over the image's aspect ratio */
.photo img{height:auto}

/* factory.html — sticky stage bar (it sticks under the sticky header: top is set in
   the design pass block, #26, which also keeps in-page targets clear of both) */
.stagebar{position:sticky;top:0;z-index:5;background:var(--ink);border-top:1px solid #333;border-bottom:4px solid var(--yellow)}
.stagebar .wrap{display:flex;gap:22px;overflow-x:auto;white-space:nowrap;scrollbar-width:none}
.stagebar .wrap::-webkit-scrollbar{display:none}
.stagebar a{flex:none;color:#ccc;text-decoration:none;font-size:14px;padding:12px 2px 10px;border-bottom:2px solid transparent}
.stagebar a b{font-family:var(--mono);font-weight:400;font-size:12px;color:var(--yellow);margin-right:7px}
.stagebar a:hover,.stagebar a[aria-current]{color:#fff;border-color:var(--yellow)}

/* factory.html — a sub-group inside a stage block (an original page section) */
.group{margin-top:40px;padding-top:28px;border-top:1px solid var(--line)}
.group h3{font-size:18px;margin-bottom:8px}

/* factory.html — machine-list rows link to their stage */
#machines table.big td a{text-decoration-color:var(--yellow);text-decoration-thickness:2px;text-underline-offset:3px}

/* ----- SEO pass (2026-10-04) ----- */

/* Phones: nothing may push the page wider than the screen. Before this, every page
   measured 591px wide on a 375px phone — the header nav ran off the right edge, the
   search button overflowed, and the fixed WhatsApp button sat off-screen. The nav
   now wraps under the brand, the search input may shrink, and wide tables scroll
   inside themselves instead of dragging the whole page sideways. Desktop is
   untouched: every rule is inside the site's one breakpoint. */
@media(max-width:760px){
  .nav{flex-wrap:wrap;row-gap:10px}
  .nav nav{margin-left:0;flex-wrap:wrap;gap:2px 18px}
  .brand small{letter-spacing:1px}
  .searchbox input{min-width:0}
  table.big{display:block;overflow-x:auto}
  #searchOut{overflow-x:auto}
}

/* footer — the phone and email are links now; at rest they look exactly like the
   <span>s they replaced, and underline on hover. Third column: site links. */
footer.site a{text-decoration:none}
footer.site a:hover{color:#fff;text-decoration:underline}
footer.site .sitelinks ul{list-style:none}

/* FAQ band (src/components/Faq.astro) */
.faq{display:grid;grid-template-columns:1fr 1fr;gap:24px 40px;margin-top:20px}
@media(max-width:760px){.faq{grid-template-columns:1fr}}
.faq .qa{border-top:1px solid var(--line);padding-top:14px}
.faq h3{font-size:16px;line-height:1.35;margin-bottom:6px}
.faq p{font-size:14px;color:var(--mut)}

/* rotary-actuator-guide.html — steps use <h3> (the right level under a section
   <h2>) and look exactly like .step h4; numbered list in a panel; the worked
   example borrows the search hit-card's yellow rule; glossary as two columns */
.step h3{font-size:15px;margin-bottom:6px}
.panel ol{margin:0 0 18px 18px;font-size:14px}
.panel ol li{margin:4px 0}
.example{background:#fff;border-left:6px solid var(--yellow);padding:16px 20px;margin-top:24px}
.example p{font-size:15px}
.cta{margin-top:20px;display:flex;gap:10px;flex-wrap:wrap}
.glossary{display:grid;grid-template-columns:1fr 1fr;gap:18px 40px}
@media(max-width:760px){.glossary{grid-template-columns:1fr}}
.glossary>div{scroll-margin-top:9px}
.glossary dt{font-weight:bold;font-size:15px}
.glossary dd{font-size:14px;color:var(--mut)}

/* 404.html — every page, one per line */
.pagelist{list-style:none;font-size:14px;color:var(--mut)}
.pagelist li{padding:8px 0;border-top:1px solid var(--line)}
.pagelist a{color:var(--ink);font-weight:bold}

/* Homepage hero background video (src/components/HeroVideo.astro). Everything is
   keyed on .hero-media, so no other hero changes, and the parity harness strips
   .hero-media to prove the rest of the homepage is unchanged.
   Shown only where :has() works: without it the hero would not be the layer's
   containing block, and the footage would cover the top of the viewport instead.
   Crossfade: the incoming clip fades in on top while the outgoing one is held,
   fully visible, underneath until the fade ends — so the picture never dips.
   Overlay: --scrim behind the text column (the .wrap's left 780px), easing to
   --clear on wide screens where the right of the hero holds no text. Do not lighten
   it: with the video's brightness(.85), --scrim .88 holds the 12px grey hint (#999)
   at 4.57:1 over the brightest pixel of any clip — WCAG AA needs 4.5. */
.hero-media{display:none}
@supports selector(:has(*)){
  .hero:has(>.hero-media){position:relative}
  .hero:has(>.hero-media)>.wrap{position:relative}
  .hero-media{--scrim:.88;--clear:.5;display:block;position:absolute;inset:0;z-index:0;overflow:hidden;background:var(--ink)}
  .hero-media video{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;filter:saturate(.6) brightness(.85);opacity:0;transition:opacity 0s .6s}
  .hero-media video.on{opacity:1;z-index:1;transition:opacity .6s}
  .hero-media::after{content:"";position:absolute;inset:0;z-index:2;background:linear-gradient(90deg,rgba(26,26,26,var(--scrim)) max(780px,50% + 240px),rgba(26,26,26,var(--clear)) max(1080px,50% + 540px))}
}

/* part-number pages (src/pages/[part].astro) — this page's own row in its family's
   size table, and the 210-bar rating in the pressure table: the interchange table's
   hover colour, held */
table.big tr.current td{background:#fbf6e3;font-weight:bold}

/* replacements.html #part-pages — every published part-number page, in up to three
   columns that drop to one on a phone */
.partlist{list-style:none;columns:3 220px;column-gap:28px;font-size:14px;margin-top:6px}
.partlist li{padding:3px 0;break-inside:avoid}

/* Homepage factory reel (src/components/VideoReel.astro) — four portrait clips side by
   side, two by two on phones; captions styled like .photo's. The <video>'s width and
   height attributes give it its 9:16 box before anything loads. */
.reel{display:grid;grid-template-columns:repeat(4,1fr);gap:16px}
@media(max-width:760px){.reel{grid-template-columns:1fr 1fr;gap:10px}}
.reel figure{border:1px solid var(--line)}
.reel video{display:block;width:100%;height:auto;background:var(--ink)}
.reel figcaption{padding:10px 14px;font-size:12px;color:var(--mut);border-top:1px solid var(--line)}

/* ----- Design pass (2026-10-05) -----
   The approved design-critique decisions, numbered as in the critique. Everything
   between this banner and the END marker below is mirrored into the reference
   stylesheet by tools/verify/run.mjs (approved change 7), so the parity pages are
   compared like with like and the pixel diff still proves nothing outside this
   block changed. Rules for later passes go after the END marker. */

/* 12 — section headings: 26px on desktop, the old 22px on phones */
.block h2{font-size:26px;line-height:1.25}
@media(max-width:760px){.block h2{font-size:22px}}

/* 18 — the light grey #999 is 2.85:1 on white and 2.59:1 on the grey band, under
   WCAG AA's 4.5:1. On light surfaces it becomes #6b6b6b (5.33:1 / 4.85:1); #999
   stays on the dark header, hero and footer, where it passes at 6.1:1. */
.block .kicker,.note,.step::before{color:#6b6b6b}

/* 20 — small text: notes and photo captions 12px -> 13px; the warranty and
   trademark notes -> 14px */
.note,.photo figcaption,.reel figcaption{font-size:13px}
.note.legal{font-size:14px}

/* 14 — a gallery card no longer stretches to its row-mate's height, so a landscape
   photo beside a portrait one stops sitting on a box of empty white */
.gallery{align-items:start}

/* 17 — replacements.html: every series table shares one column grid, so the stacked
   tables read as one; torque and holding torque are right-aligned. HN50 has no mount
   column, so its status column spans mount + status. On phones the tables scroll
   (display:block) and these widths do not apply. */
[id^="tbl-"] table.big{table-layout:fixed}
[id^="tbl-"] th:nth-child(1){width:13%}
[id^="tbl-"] th:nth-child(2){width:15%}
[id^="tbl-"] th:nth-child(3){width:12%}
[id^="tbl-"] th:nth-child(4){width:10%}
[id^="tbl-"] th:nth-child(5){width:15%}
[id^="tbl-"] th:nth-child(6){width:15%}
[id^="tbl-"] th:nth-child(7){width:12%}
[id^="tbl-"] th:nth-child(8){width:8%}
#tbl-HN50 th:nth-child(6){width:27%}
#tbl-HN50 th:nth-child(7){width:8%}
[id^="tbl-"] th:nth-child(3),[id^="tbl-"] td:nth-child(3),
[id^="tbl-"] th:nth-child(4),[id^="tbl-"] td:nth-child(4){text-align:right;font-variant-numeric:tabular-nums}
[id^="tbl-"] th:nth-child(4),[id^="tbl-"] td:nth-child(4){padding-right:22px}

/* 8 — phone tables: part numbers never break at a hyphen, and a soft shadow at the
   edge shows there is more table to the side. background-attachment:local lets the
   white covers scroll with the content and hide each shadow once its edge is
   reached, so a table that fits shows none. The "swipe" line above an overflowing
   table is added by src/scripts/table-hint.ts. */
@media(max-width:760px){
  table.big td.mono,[id^="tbl-"] td:nth-child(3),[id^="tbl-"] td:nth-child(4){white-space:nowrap}
  table.big{background:linear-gradient(90deg,#fff 30%,rgba(255,255,255,0)) 0 0/40px 100% no-repeat local,linear-gradient(270deg,#fff 30%,rgba(255,255,255,0)) 100% 0/40px 100% no-repeat local,radial-gradient(farthest-side at 0 50%,rgba(0,0,0,.2),rgba(0,0,0,0)) 0 0/14px 100% no-repeat scroll,radial-gradient(farthest-side at 100% 50%,rgba(0,0,0,.2),rgba(0,0,0,0)) 100% 0/14px 100% no-repeat scroll #fff}
}
.swipe{font-size:12px;color:#6b6b6b;margin:0 0 6px}

/* 6 — "Quote" link at the end of every interchange row (src/lib/table.ts). The cell is
   positioned so its .sr-only text (absolute) stays inside the phone table's scroll
   box; without it that text escaped and made replacements.html 713px wide at 390px. */
table.big .q{position:relative}
table.big td.q{white-space:nowrap}
table.big td.q a{font-weight:bold;text-decoration-color:var(--yellow);text-decoration-thickness:2px;text-underline-offset:3px}

/* 1 + 2 — floating WhatsApp button: ink text on the brand green (8.78:1; white was
   1.98:1). On phones it shrinks to a 52px round icon in the corner, so it stops
   covering the numbers at the right edge of tables and search results; its text
   stays in the accessibility tree, and the footer gets room so its last line clears
   the icon. */
.wa{color:var(--ink)}
.wa svg{display:none}
@media(max-width:760px){
  .wa{width:52px;height:52px;padding:0;border-radius:50%;display:flex;align-items:center;justify-content:center}
  .wa svg{display:block;width:28px;height:28px;fill:currentColor}
  .wa span{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap}
  footer.site{padding-bottom:84px}
}

/* 21 — footer links on phones: tap targets clear WCAG 2.5.8's 24px */
@media(max-width:760px){footer.site a{display:inline-block;padding:6px 0}}

/* 19 — inquiry form fields: an ink frame (17:1; #d9d9d9 was 1.41:1) and a thick
   yellow outline on focus */
form.inq input,form.inq select,form.inq textarea{border-color:var(--ink)}
form.inq input:focus,form.inq textarea:focus,form.inq select:focus{outline:3px solid var(--yellow);outline-offset:0}

/* 24 — the original rule takes the hero search box's outline away on focus; keyboard
   focus now shows a white ring outside the yellow border */
.searchbox input:focus-visible{outline:2px solid #fff;outline-offset:2px}

/* 5 — the "Try:" examples are buttons that run the search, styled like the <code>
   they replaced; the padding makes each a 24px tap target */
.searchhint .try{font-family:var(--mono);font-size:inherit;color:#ccc;background:none;border:0;border-bottom:1px dashed #777;padding:5px 0;cursor:pointer}
.searchhint .try:hover,.searchhint .try:focus-visible{color:#fff;border-bottom-color:var(--yellow)}

/* 22 — skip link, off-screen until a keyboard user tabs to it */
.skip{position:absolute;left:12px;top:-60px;z-index:20;background:var(--yellow);color:var(--ink);font-weight:bold;font-size:14px;padding:10px 16px;text-decoration:none}
.skip:focus{top:12px}
main:focus{outline:none}

/* 7 — replacements.html reuses the factory page's sticky .stagebar; a series kicker
   it jumps to stops 9px below it (on top of html's scroll-padding, #26) */
.kicker[id]{scroll-margin-top:9px}

/* 9 — custom.html hero button down to the inquiry form */
.hero-cta{margin-top:24px}

/* 10 — closing contact band above the footer on every page; the nav's "Contact"
   lands here (id="contact"). An <aside>, not a <section>: the zebra striping counts
   <section>s (I2). */
.cta-band{background:var(--ink);color:#fff;padding:40px 0;border-top:4px solid var(--yellow);border-bottom:1px solid #333}
.cta-band .wrap{display:flex;align-items:center;justify-content:space-between;gap:20px 40px;flex-wrap:wrap}
.cta-band h2{font-size:22px;margin-bottom:6px}
.cta-band p{color:#bbb;font-size:15px;max-width:560px}
.cta-band .cta{margin-top:0}
.btn.on-dark{background:transparent;color:#fff;border-color:#777}
.btn.on-dark:hover{border-color:#fff;background:transparent}

/* 25 — the favicon mark as the header logo, before the wordmark. Its tile is the
   header's own ink, so only the yellow arc and hub show. */
.brand{display:flex;align-items:center;gap:12px}
.brand img{width:44px;height:44px;flex:none}
@media(max-width:760px){.brand{gap:10px}.brand img{width:36px;height:36px}}

/* 26 — sticky header. Every layout has a FIXED height, held in --head, so a page's
   sticky bar (.stagebar, height --bar) can stick right under it and every in-page
   jump or keyboard-focus scroll can stop below both (html scroll-padding-top).
   tools/verify/run.mjs measures both at seven widths and fails if they drift.
     1024px and up  one row, as before: 14 + 44 (logo) + 14 + 4 (yellow rule) = 76
     761-1023px     two rows — brand, then the nav in one row that scrolls sideways:
                    10 + 44 + 6 + 32 + 6 + 4 = 102
     760px and down the same, with a 32px logo and no tagline: 10 + 32 + 6 + 32 + 6 + 4 = 90
   Nothing in the header may wrap, or the height would no longer be the variable's. */
:root{--head:76px;--bar:0px}
:root:has(.stagebar){--bar:51px}
html{scroll-padding-top:calc(var(--head) + var(--bar))}
header.site{position:sticky;top:0;z-index:10}
.stagebar{top:var(--head)}
.brand,.brand small,.nav nav a{white-space:nowrap}
@media(max-width:1023px){
  :root{--head:102px}
  .nav{flex-wrap:wrap;row-gap:6px;padding-top:10px;padding-bottom:6px}
  .nav nav{margin-left:0;width:100%;height:32px;flex-wrap:nowrap;gap:0 18px;overflow-x:auto;overflow-y:hidden;scrollbar-width:none}
  .nav nav::-webkit-scrollbar{display:none}
  .nav nav a{flex:none}
}
@media(max-width:760px){
  :root{--head:90px}
  .brand img{width:32px;height:32px}
  .brand small{display:none}
}

/* visually hidden, still read by screen readers */
.sr-only{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap}

/* ----- END design pass (2026-10-05) ----- */
