/* 2027 Custom - shared styles. Monochrome: black, white, gray only. */

/* ---------- type ramp ---------- */
/*
  Every font-size in this file uses one of these nine steps. Do not add a
  tenth, and do not set a size inside a rule that is not on the ramp.

  --t-mono      0.75rem                       12px      mono labels, captions, chips, fit codes, eyebrows
  --t-fine      0.875rem                      14px      spec rows, buy notes, meta, footer, mobile nav
  --t-action    0.95rem                       15.2px    buttons, nav links, contact links
  --t-body      1rem                          16px      all prose, line-height 1.6, measure capped 40-44em
  --t-lead      1.15rem                       18.4px    hero tagline, 404 lead
  --t-sub       1.25rem                       20px      card names, step headings, scan group titles, manual titles
  --t-title     1.75rem                       28px      section headings, product price
  --t-display-2 clamp(2.25rem, 4vw, 2.9rem)   36-46.4px product h1, service hero h1, manuals title
  --t-display   clamp(2.6rem, 7vw, 4.25rem)   41.6-68px home hero headline, 404 headline

  Smallest to largest: 12px -> 68px (5.7:1), and still 3:1 at a 360px viewport.
*/

:root {
  --black: #0a0a0a;       /* header, hero, footer, buttons, headings */
  --paper: #ffffff;       /* page + card background */
  --line: #e4e4e4;        /* hairlines inside a surface */
  --line-strong: #8f8f8f; /* structural edges: cards, gallery, figures, spec rules; 3.23:1 on white */
  --line-dark: #2a2a2a;   /* hairlines on black */
  --chip-stroke: #4a4a4a; /* chip border on the black field, one step above the grid */
  --text: #1a1a1a;
  --muted: #6b6b6b;
  --muted-on-black: #9a9a9a;

  --t-mono: 0.75rem;
  --t-fine: 0.875rem;
  --t-action: 0.95rem;
  --t-body: 1rem;
  --t-lead: 1.15rem;
  --t-sub: 1.25rem;
  --t-title: 1.75rem;
  --t-display-2: clamp(2.25rem, 4vw, 2.9rem);
  --t-display: clamp(2.6rem, 7vw, 4.25rem);
}

* { margin: 0; padding: 0; box-sizing: border-box; }

/* the chassis filter hides cards with the hidden attribute, and .card carries an
   explicit display, which would otherwise beat the UA rule */
[hidden] { display: none !important; }

html { scroll-behavior: smooth; }

body {
  /* column flex so the footer always sits at the bottom, even on short pages */
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  background: var(--paper);
  color: var(--text);
  font-family: "IBM Plex Sans", system-ui, -apple-system, "Segoe UI", sans-serif;
  font-size: var(--t-body);
  /* IBM Plex Sans sits on a smaller x-height than Inter and runs wider, so the
     same measure yields longer, sparser lines: 1.55 puts the block back. */
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
}

img { max-width: 100%; display: block; }

::selection { background: var(--black); color: #ffffff; }
.hero ::selection,
.notfound ::selection,
.site-header ::selection,
.site-footer ::selection { background: #ffffff; color: var(--black); }

a {
  color: inherit;
  text-decoration: none;
  text-underline-offset: 0.18em;
  text-decoration-thickness: 1px;
}
a:hover { text-decoration: underline; }

a:focus-visible, button:focus-visible, summary:focus-visible {
  outline: 2px solid var(--black);
  outline-offset: 3px;
}

/* the black bars and black fields need the inverse ring, or focus is invisible */
.site-header a:focus-visible,
.site-header button:focus-visible,
.site-footer a:focus-visible,
.site-footer button:focus-visible,
.hero a:focus-visible,
.hero button:focus-visible,
.notfound a:focus-visible,
.notfound button:focus-visible {
  outline-color: #ffffff;
}

h1, h2, h3 {
  font-family: "Chakra Petch", "IBM Plex Sans", sans-serif;
  font-weight: 600;
  line-height: 1.15;
  letter-spacing: 0.01em;
  color: var(--black);
}

.mono {
  font-family: "IBM Plex Mono", ui-monospace, Consolas, monospace;
  font-size: var(--t-mono);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--muted);
}

.wrap { max-width: 1100px; margin: 0 auto; padding: 0 24px; }

/* ---------- header ---------- */

.site-header {
  background: var(--black);
  position: sticky;
  top: 0;
  z-index: 10;
}

.site-header .wrap {
  display: flex;
  align-items: center;
  justify-content: space-between;
  height: 60px;
}

.site-header .logo img { height: 22px; width: auto; }

.site-header nav { display: flex; align-items: center; gap: 28px; }

.site-header nav a {
  color: #ffffff;
  font-family: "Chakra Petch", sans-serif;
  font-weight: 600;
  font-size: var(--t-action);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  transition: color 0.15s ease;
}
.site-header nav a:hover { color: var(--muted-on-black); text-decoration: none; }
.site-header nav a:active { color: var(--muted-on-black); }

/* current page inverts into a white plate: no color, no underline */
.site-header nav a[aria-current="page"] {
  background: #ffffff;
  color: var(--black);
  padding: 5px 11px;
  border-radius: 3px;
}
.site-header nav a[aria-current="page"]:hover {
  background: #ffffff;
  color: var(--black);
  text-decoration: none;
}

/* ---------- hero ---------- */

.hero {
  position: relative;
  background: var(--black);
  color: #ffffff;
  padding: 96px 0 84px;
  overflow: hidden;
}

/* blueprint grid, quiet */
.hero::before,
.notfound::before {
  content: "";
  position: absolute;
  inset: 0;
  background-image:
    linear-gradient(var(--line-dark) 1px, transparent 1px),
    linear-gradient(90deg, var(--line-dark) 1px, transparent 1px);
  background-size: 48px 48px;
  opacity: 0.5;
  mask-image: radial-gradient(ellipse 80% 90% at 50% 0%, black 30%, transparent 75%);
  -webkit-mask-image: radial-gradient(ellipse 80% 90% at 50% 0%, black 30%, transparent 75%);
}

.hero .wrap { position: relative; }

.hero h1 { color: #ffffff; font-size: var(--t-display-2); letter-spacing: -0.01em; }

.hero .mono { color: var(--muted-on-black); margin-bottom: 14px; }

.hero p.tag {
  font-size: var(--t-lead);
  color: var(--muted-on-black);
  max-width: 34em;
}

.hero .fitment {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  margin-top: 32px;
}

.hero .fitment span {
  font-family: "IBM Plex Mono", monospace;
  font-size: var(--t-mono);
  letter-spacing: 0.12em;
  color: #ffffff;
  border: 1px solid var(--chip-stroke);
  padding: 5px 12px;
  border-radius: 3px;
}

/* ---------- home hero (logo left, copy right) ---------- */

.hero-logo {
  width: min(100%, 380px);
  height: auto;
  margin-bottom: 32px;
}

h1.hero-title {
  font-size: var(--t-display-2);
  letter-spacing: -0.01em;
  color: #ffffff;
  margin-bottom: 18px;
}

/* the headline is the entry point, so hold it to a strong two-line block */
.hero--logo-top h1 { max-width: 24ch; }

/* manuals page carries the same black field as the service page */
.manuals-hero .tag a { text-decoration: underline; }

/* ---------- product grid ---------- */

.catalog { padding: 72px 0 96px; }

.catalog > .wrap > h2 {
  font-size: var(--t-title);
  margin-bottom: 8px;
}

.catalog .count { margin-bottom: 20px; }

/* ---------- chassis filter ---------- */

/* wraps onto as many rows as it needs; never a horizontal scroller */
.chassis-filter {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-bottom: 32px;
}

/* a real selectable control in the chip language: mono label, 3px radius */
.chip-filter {
  background: var(--paper);
  color: var(--black);
  border: 1px solid var(--line-strong);
  border-radius: 3px;
  padding: 10px 14px;
  font-family: "IBM Plex Mono", ui-monospace, Consolas, monospace;
  font-size: var(--t-mono);
  font-weight: 400;
  line-height: 1.2;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  cursor: pointer;
  transition: border-color 0.15s ease, background 0.15s ease, color 0.15s ease;
}
.chip-filter:hover { border-color: var(--black); }
.chip-filter:focus-visible { outline: 2px solid var(--black); outline-offset: 3px; }

/* selected inverts the plate: black ground, white label. Never a color. */
.chip-filter[aria-pressed="true"] {
  background: var(--black);
  border-color: var(--black);
  color: #ffffff;
}
.chip-filter[aria-pressed="true"]:hover {
  background: var(--black);
  color: #ffffff;
}
.chip-filter:active { border-color: var(--black); }

.grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
  gap: 20px;
}

/* zero matches for a chassis: the honest answer, plus the way out */
.grid-empty {
  border: 1px solid var(--line-strong);
  border-radius: 6px;
  padding: 26px 28px;
  margin-top: 20px;
  max-width: 44em;
  color: var(--muted);
}

.card {
  background: var(--paper);
  border: 1px solid var(--line-strong);
  border-radius: 6px;
  overflow: hidden;
  color: var(--text);
  display: flex;
  flex-direction: column;
  transition: border-color 0.15s ease, transform 0.15s ease;
}
.card:hover, .card:focus-visible {
  border-color: var(--black);
  transform: translateY(-2px);
  text-decoration: none;
}
.card:active { border-color: var(--black); transform: translateY(0); }

/* 4:3 matches the source photos, so landscape shots are not crop-zoomed */
.card .thumb {
  aspect-ratio: 4 / 3;
  background: #ffffff;
  border-bottom: 1px solid var(--line);
  overflow: hidden;
}
.card .thumb img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.card .body { padding: 16px 18px 18px; flex: 1; display: flex; flex-direction: column; gap: 4px; }

.card h3 { font-size: var(--t-sub); font-weight: 500; }

.card .price {
  margin-top: auto;
  padding-top: 10px;
  font-family: "Chakra Petch", sans-serif;
  font-weight: 600;
  color: var(--black);
  font-size: var(--t-sub);
}

/* ---------- product page ---------- */

.product { padding: 56px 0 96px; }

.breadcrumb { margin-bottom: 28px; display: inline-block; }

.product-layout {
  display: grid;
  grid-template-columns: minmax(0, 7fr) minmax(0, 5fr);
  gap: 48px;
  align-items: start;
}

.gallery .main {
  background: #ffffff;
  border: 1px solid var(--line-strong);
  border-radius: 6px;
  overflow: hidden;
  aspect-ratio: 1 / 1;
  transition: border-color 0.15s ease;
}
.gallery .main img { width: 100%; height: 100%; object-fit: contain; }

.gallery .thumbs {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(72px, 1fr));
  gap: 8px;
  margin-top: 8px;
}
.gallery .thumbs button {
  background: #ffffff;
  border: 1px solid var(--line-strong);
  border-radius: 4px;
  padding: 0;
  cursor: pointer;
  aspect-ratio: 1 / 1;
  overflow: hidden;
  transition: border-color 0.15s ease;
}
.gallery .thumbs button img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: 0.68;
  transition: opacity 0.15s ease;
}
.gallery .thumbs button:hover { border-color: var(--black); }
.gallery .thumbs button:hover img { opacity: 1; }

/* selected thumbnail: 2px stroke plus an offset ring, so it reads on a 72px tile */
.gallery .thumbs button.active,
.gallery .thumbs button[aria-pressed="true"] {
  border: 2px solid var(--black);
  outline: 1px solid var(--black);
  outline-offset: 2px;
}
.gallery .thumbs button.active img,
.gallery .thumbs button[aria-pressed="true"] img { opacity: 1; }

.details .fit-code {
  font-family: "IBM Plex Mono", monospace;
  font-size: var(--t-mono);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--black);
  border: 1px solid var(--black);
  display: inline-block;
  padding: 4px 10px;
  border-radius: 3px;
  margin-bottom: 14px;
}

.details h1 {
  font-size: var(--t-display-2);
  letter-spacing: -0.01em;
  margin-bottom: 10px;
}

.details .price {
  font-family: "Chakra Petch", sans-serif;
  font-weight: 600;
  font-size: var(--t-title);
  color: var(--black);
  margin-bottom: 22px;
}

.details .desc { color: var(--muted); max-width: 44em; margin-bottom: 22px; }
.details .desc p + p { margin-top: 10px; }

.details ul.specs {
  list-style: none;
  border-top: 1px solid var(--line-strong);
  margin-bottom: 40px;
}

/* buy block: generous separation above, tight group within */
.details .buy-fit {
  color: var(--black);
  margin-bottom: 14px;
}
.details ul.specs li {
  border-bottom: 1px solid var(--line-strong);
  padding: 9px 2px;
  font-size: var(--t-fine);
  display: flex;
  justify-content: space-between;
  gap: 16px;
}
.details ul.specs li span:first-child { color: var(--muted); }

/* ---------- fulfilment state ---------- */

/* Fulfilment state plus the lead-time band, on a catalog card and beside the Buy
   button. The state is machine data, so it takes the mono label treatment; the
   band is a phrase a person wrote and sits on the Fine step. No fill, no border,
   no badge shape and no status color: the palette is monochrome, and a green
   in-stock pill would be a break in the system rather than a feature. */
.fulfil {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 2px 10px;
}
.fulfil .fulfil-state { color: var(--black); }
.fulfil .fulfil-lead { font-size: var(--t-fine); color: var(--muted); }

/* the card body already carries a 4px column gap, so the line needs no margin */
.details .fulfil { margin-bottom: 14px; }

/* ---------- buy button ---------- */

.buy {
  display: inline-block;
  background: var(--black);
  color: #ffffff;
  font-family: "Chakra Petch", sans-serif;
  font-weight: 600;
  font-size: var(--t-action);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  padding: 14px 36px;
  border: 0;
  border-radius: 4px;
  cursor: pointer;
  transition: background 0.15s ease, transform 0.15s ease;
}
.buy:hover { background: #333333; text-decoration: none; color: #ffffff; }
.buy:active { transform: translateY(1px); }

/* the only other size */
.buy--compact { padding: 11px 26px; }

/* The buy form. The postcode decides the postage, so it sits with the button
   rather than being deferred to the checkout page, and the button stays the
   same control it has always been. */
.buy-form {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: 12px;
  margin: 20px 0 0;
}
.buy-field {
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.buy-field > span {
  font-family: "IBM Plex Mono", monospace;
  font-size: 0.72rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--muted);
}
.buy-field input,
.buy-field select {
  font-family: "IBM Plex Mono", monospace;
  font-size: 0.95rem;
  padding: 12px 14px;
  border: 1px solid var(--line-strong);
  border-radius: 4px;
  background: #ffffff;
  color: var(--black);
  min-width: 7.5rem;
}
.buy-field input:focus-visible,
.buy-field select:focus-visible {
  outline: 2px solid var(--black);
  outline-offset: 1px;
}
.buy-field--qty input { min-width: 4.5rem; }
.buy-form .buy:disabled { background: var(--muted); cursor: progress; }

/* The postage, under the fields, as soon as the destination is complete. It
   takes a whole row like the error line does, so adding it never reflows the
   fields or the button. Mono because it is a figure, not prose.

   Three states, all in gray or black like everything else here: the figure
   itself in black, and both waiting states in muted, so a number that is being
   recalculated visibly stops being the current answer without moving or
   flashing. A refusal borrows the error line's rule, because it reads the same
   way even though it is an answer rather than a fault. */
.buy-quote {
  flex-basis: 100%;
  margin: 0;
  font-family: "IBM Plex Mono", monospace;
  font-size: var(--t-fine);
  line-height: 1.5;
  color: var(--black);
}
.buy-quote--pending,
.buy-quote--stale { color: var(--muted); }
.buy-quote--refused {
  border-left: 2px solid var(--black);
  padding-left: 12px;
}

.buy-error {
  flex-basis: 100%;
  margin: 0;
  font-size: 0.9rem;
  line-height: 1.5;
  color: var(--black);
  border-left: 2px solid var(--black);
  padding-left: 12px;
}

@media (max-width: 700px) {
  .buy-form .buy { width: 100%; }
}

.details .buy-note {
  margin-top: 18px;
  font-size: var(--t-fine);
  color: var(--muted);
}
.details .buy-note + .buy-note { margin-top: 5px; }

/* ---------- order confirmation ----------

   Stands where the buy form stood, and only after Stripe has confirmed the
   session the buyer came back with was really paid. It borrows the checkout
   page's summary rows on purpose: this is the same order one step later, and a
   buyer checking what they were charged against what they agreed to should
   recognise the second as the first rather than having to re-read it.

   The border is the black one rather than the hairline every other panel on
   this page uses. That is the whole visual job here: somebody who is not sure
   whether their money went anywhere has to find this block before they find
   anything else, and the alternative to finding it is paying twice. */
.order-confirmed {
  border: 1px solid var(--black);
  border-radius: 4px;
  padding: 20px;
  margin-top: 24px;
}
.order-confirmed h2 {
  font-family: "Chakra Petch", sans-serif;
  font-size: var(--t-sub);
  font-weight: 600;
  margin: 0 0 6px;
}
.order-confirmed-lead {
  max-width: 40em;
  margin: 0 0 16px;
  font-size: var(--t-fine);
  color: var(--muted);
}
.order-confirmed dl { margin: 0; }
/* The address gets the same mono, uppercase, muted label the summary headings
   wear, so it reads as another field of the order rather than as new prose. */
.order-confirmed-label {
  margin: 18px 0 6px;
  font-family: "IBM Plex Mono", monospace;
  font-size: var(--t-mono);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--muted);
}
.order-confirmed-address {
  margin: 0;
  font-family: "IBM Plex Mono", monospace;
  font-size: var(--t-fine);
  line-height: 1.5;
  color: var(--black);
}

/* ---------- checkout page ----------

   Stripe's frame brings its own layout, type and spacing, and none of it can be
   restyled from here. So this page stays deliberately plain: a way back, a
   heading, one line of context, and then the frame. Anything more decorative
   around it would only draw attention to the seam. */

.checkout { padding: 48px 0 96px; }
.checkout h1 {
  font-size: var(--t-display-2);
  margin: 0 0 12px;
}
.checkout-back {
  display: inline-block;
  font-family: "IBM Plex Mono", monospace;
  font-size: var(--t-mono);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--muted);
  margin-bottom: 20px;
}
.checkout-back:hover { color: var(--black); }
.checkout-lead {
  max-width: 44em;
  font-size: var(--t-body);
  line-height: 1.6;
  color: var(--text);
  margin: 0 0 32px;
}
/* Form and order summary. The summary comes first in the markup so that on a
   phone the buyer reads what they are buying before the fields, and moves to
   the right hand column on a wide screen, where it sticks: the breakdown is
   worth having in view while the address is being typed, because typing the
   address is what changes it. */
.checkout-layout {
  display: grid;
  gap: 32px;
}
@media (min-width: 900px) {
  .checkout-layout {
    grid-template-columns: minmax(0, 34em) minmax(240px, 20em);
    gap: 56px;
    align-items: start;
  }
  .checkout-layout .checkout-form { grid-column: 1; grid-row: 1; }
  .checkout-layout .order-summary {
    grid-column: 2;
    grid-row: 1;
    position: sticky;
    top: 24px;
  }
}

.order-summary {
  border: 1px solid var(--line-strong);
  border-radius: 4px;
  padding: 20px 20px 16px;
}
.order-summary h2 {
  font-family: "IBM Plex Mono", monospace;
  font-size: var(--t-mono);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--muted);
  font-weight: 500;
  margin: 0 0 14px;
}
.order-summary dl { margin: 0; }
.summary-row {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 16px;
  padding: 10px 0;
  border-top: 1px solid var(--line);
}
.summary-row:first-child { border-top: 0; padding-top: 0; }
.summary-row dt {
  font-size: var(--t-fine);
  color: var(--text);
}
/* The unit price and quantity, or the postage service. This is the line that
   turns a total into something a buyer can check. */
.summary-unit {
  display: block;
  font-family: "IBM Plex Mono", monospace;
  font-size: var(--t-mono);
  color: var(--muted);
  margin-top: 3px;
}
.summary-row dd {
  margin: 0;
  font-family: "IBM Plex Mono", monospace;
  font-size: var(--t-fine);
  color: var(--black);
  white-space: nowrap;
}
.summary-row--total {
  border-top: 1px solid var(--line-strong);
  margin-top: 4px;
  padding-top: 14px;
}
.summary-row--total dt,
.summary-row--total dd {
  font-size: var(--t-sub);
  color: var(--black);
}
.summary-row--total dt { font-family: "Chakra Petch", sans-serif; font-weight: 600; }

/* The composed form. One column, capped at a comfortable measure: Stripe's
   fields set their own internal layout and fight a wide container. */
.checkout-form {
  max-width: 34em;
  display: flex;
  flex-direction: column;
  gap: 32px;
}
.checkout-step { display: block; }
.checkout-step h2 {
  font-family: "IBM Plex Mono", monospace;
  font-size: var(--t-mono);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--muted);
  font-weight: 500;
  margin: 0 0 12px;
  padding-bottom: 8px;
  border-bottom: 1px solid var(--line);
}
/* Each element reserves roughly the room it opens at, so the page does not jump
   as three separate frames land at three different moments. Deliberately the
   COLLAPSED height, not the filled one: the address element grows to four more
   fields once an address is chosen, and reserving for that would leave a void
   under the form for everyone who has not typed anything yet. */
#contact-details-element { min-height: 76px; }
#shipping-address-element { min-height: 150px; }
#payment-element { min-height: 220px; }

.checkout-form .buy { width: 100%; }
/* Disabled is the resting state here, not an edge case: the button stays off
   until the postage has actually been applied. It has to look deliberate
   rather than broken. */
.checkout-form .buy:disabled {
  background: var(--muted);
  cursor: not-allowed;
}

.checkout-postage {
  margin: 12px 0 0;
  font-family: "IBM Plex Mono", monospace;
  font-size: var(--t-fine);
  line-height: 1.5;
  color: var(--black);
}
.checkout-postage--refused {
  border-left: 2px solid var(--black);
  padding-left: 12px;
}
.checkout-error {
  max-width: 44em;
  margin: 0;
  font-size: var(--t-body);
  line-height: 1.6;
  color: var(--black);
  border-left: 2px solid var(--black);
  padding-left: 12px;
}

/* ---------- custom service page ---------- */

/* the secondary black bands are one height, so moving between the two pages
   does not shift the field under the nav */
.service-hero,
.manuals-hero {
  padding: 80px 0 64px;
  /* one band height for both pages; plain block flow, so content sits top-left
     exactly like the home hero */
  min-height: 380px;
}

.service { padding: 64px 0 40px; }

.service-block { margin-bottom: 64px; }
.service-block h2 { font-size: var(--t-title); margin-bottom: 20px; }

.service-copy { color: var(--muted); max-width: 44em; }

ol.steps { list-style: none; }
ol.steps li {
  display: flex;
  gap: 22px;
  border-top: 1px solid var(--line-strong);
  padding: 22px 0;
}
ol.steps li:last-child { border-bottom: 1px solid var(--line-strong); }
ol.steps .step-num {
  color: var(--black);
  font-size: var(--t-fine);
  padding-top: 4px;
  min-width: 2em;
}
ol.steps h3 { font-size: var(--t-sub); margin-bottom: 6px; }
ol.steps p { color: var(--muted); max-width: 40em; font-size: var(--t-body); }

.scan-group { margin-top: 44px; }
.scan-group h3 { font-size: var(--t-sub); margin-bottom: 14px; }

/* scan figures read as evidence, not as thumbnails */
.scan-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(340px, 1fr));
  gap: 20px;
}
.scan-grid figure {
  margin: 0;
  transition: transform 0.15s ease;
}
.scan-grid img {
  width: 100%;
  aspect-ratio: 4 / 3;
  object-fit: cover;
  border: 1px solid var(--line-strong);
  border-radius: 6px;
  background: #f2f2f2;
  transition: border-color 0.15s ease;
}
.scan-grid figure:hover { transform: translateY(-2px); }
.scan-grid figure:hover img { border-color: var(--black); }
.scan-grid figcaption {
  margin-top: 9px;
  font-size: var(--t-mono);
  /* sentence case: these are per-image descriptions, not machine-data labels */
  text-transform: none;
  letter-spacing: 0.02em;
  line-height: 1.45;
}

.scan-more { margin-top: 14px; }
.scan-more summary {
  cursor: pointer;
  list-style: none;
  display: inline-block;
  border: 1px solid var(--line-strong);
  border-radius: 4px;
  padding: 7px 16px;
  color: var(--black);
  user-select: none;
  transition: border-color 0.15s ease;
}
.scan-more summary::-webkit-details-marker { display: none; }
.scan-more summary:hover { border-color: var(--black); }
.scan-more[open] summary { margin-bottom: 14px; border-color: var(--black); }

.details .manual-note {
  margin-top: 20px;
  font-size: var(--t-fine);
  color: var(--muted);
}
.details .manual-note a { text-decoration: underline; }

/* ---------- image lightbox ---------- */

/* the trigger has to read as a control, not as a plain photo */
.zoom-trigger {
  display: block;
  width: 100%;
  height: 100%;
  padding: 0;
  border: 0;
  background: none;
  font: inherit;
  color: inherit;
  cursor: zoom-in;
}

.gallery .main:has(.zoom-trigger:hover),
.gallery .main:has(.zoom-trigger:focus-visible) { border-color: var(--black); }

.lightbox {
  /* the * reset zeroes the dialog's auto margins, so centre it back */
  margin: auto;
  max-width: 92vw;
  max-height: 88vh;
  padding: 0;
  border: 0;
  background: none;
  overflow: visible;
  color: #ffffff;
}
.lightbox::backdrop { background: rgba(10, 10, 10, 0.94); }

.lightbox[open] {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 12px;
}

/* portrait and landscape both fit: the height cap leaves room for the control */
.lightbox img {
  width: auto;
  height: auto;
  max-width: 92vw;
  max-height: calc(88vh - 58px);
  object-fit: contain;
  border-radius: 6px;
  background: var(--paper);
}

/* white plate on a near-black field, same button language as the 404 action */
.lightbox-close {
  background: #ffffff;
  color: var(--black);
  font-family: "Chakra Petch", sans-serif;
  font-weight: 600;
  font-size: var(--t-action);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  padding: 11px 26px;
  border: 0;
  border-radius: 4px;
  cursor: pointer;
  transition: background 0.15s ease;
}
.lightbox-close:hover { background: #e4e4e4; }
.lightbox-close:active { background: #e4e4e4; transform: translateY(1px); }
.lightbox-close:focus-visible { outline: 2px solid #ffffff; outline-offset: 3px; }

/* ---------- manuals page ---------- */

.manual-card {
  border: 1px solid var(--line-strong);
  border-radius: 6px;
  padding: 24px 26px 26px;
  max-width: 680px;
  margin-bottom: 20px;
}
.manual-card h2 { font-size: var(--t-sub); margin-bottom: 4px; }
.manual-card .manual-meta { margin-bottom: 12px; }
.manual-actions {
  margin-top: 20px;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 18px;
}
.manual-product-link { text-decoration: underline; font-size: var(--t-fine); }

/* ---------- 404 ---------- */

.notfound {
  position: relative;
  overflow: hidden;
  background: var(--black);
  color: #ffffff;
  padding: 120px 0 128px;
}
.notfound .wrap { position: relative; }
.notfound .mono { display: block; color: var(--muted-on-black); margin-bottom: 14px; }
.notfound h1 {
  font-size: var(--t-display);
  letter-spacing: -0.01em;
  color: #ffffff;
  margin-bottom: 18px;
}
.notfound p { color: var(--muted-on-black); font-size: var(--t-lead); max-width: 40em; }
.notfound .buy { background: #ffffff; color: var(--black); }
.notfound .buy:hover { background: #e4e4e4; color: var(--black); }

/* homepage strip linking to the service */
.service-strip {
  border: 1px solid var(--line-strong);
  border-radius: 6px;
  margin-bottom: 36px;
  padding: 26px 28px;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
}
.service-strip p { color: var(--muted); max-width: 34em; }
.service-strip h3 { font-size: var(--t-sub); margin-bottom: 4px; }

/* ---------- about / contact ---------- */

.about {
  border-top: 1px solid var(--line-strong);
  padding: 72px 0;
}
.about h2 { font-size: var(--t-title); margin-bottom: 14px; }
.about p { color: var(--muted); max-width: 44em; }
.about p + p { margin-top: 10px; }

.contact-links {
  display: flex;
  flex-wrap: wrap;
  gap: 14px;
  margin-top: 24px;
}
.contact-links a {
  border: 1px solid var(--black);
  color: var(--black);
  padding: 10px 22px;
  border-radius: 4px;
  font-family: "Chakra Petch", sans-serif;
  font-weight: 600;
  font-size: var(--t-action);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  transition: background 0.15s ease, color 0.15s ease;
}
.contact-links a:hover { background: var(--black); color: #ffffff; text-decoration: none; }
.contact-links a:active { background: #333333; color: #ffffff; }

/* ---------- footer ---------- */

.site-footer {
  margin-top: auto;
  background: var(--black);
  color: var(--muted-on-black);
  padding: 28px 0;
}
.site-footer .wrap {
  display: flex;
  flex-wrap: wrap;
  gap: 8px 24px;
  justify-content: space-between;
  font-size: var(--t-fine);
}
.site-footer a:hover { color: #ffffff; }

/* ---------- responsive ---------- */

/* Mobile: no top bar, nav becomes a persistent bottom bar */
@media (max-width: 700px) {
  .site-header {
    position: static;
    background: transparent;
  }
  .site-header .wrap {
    height: 0;
    padding: 0;
  }
  .site-header .logo { display: none; }

  .site-header nav {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 20;
    background: var(--black);
    border-top: 1px solid var(--line-dark);
    gap: 0;
    justify-content: space-around;
    padding: 13px 6px;
    padding-bottom: calc(13px + env(safe-area-inset-bottom));
  }
  .site-header nav a { font-size: var(--t-fine); letter-spacing: 0.06em; }

  /* same inverted plate on the bottom bar, tighter */
  .site-header nav a[aria-current="page"] { padding: 4px 9px; }

  /* keep the footer clear of the fixed bar */
  .site-footer { padding-bottom: 76px; }
}

@media (max-width: 800px) {
  .hero { padding: 64px 0 56px; }
  .service-hero,
  .manuals-hero { min-height: 0; padding: 56px 0 48px; }
  .hero-logo { width: min(72%, 280px); margin-bottom: 24px; }
  .hero p.tag { font-size: var(--t-body); }
  
  .product { padding: 36px 0 72px; }
  .product-layout { grid-template-columns: 1fr; gap: 28px; }
  .site-header nav { gap: 18px; }
  .catalog { padding: 52px 0 72px; }
  .scan-grid { grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); }
  .notfound { padding: 84px 0 96px; }
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .card,
  .buy,
  .site-header nav a,
  .contact-links a,
  .scan-more summary,
  .chip-filter,
  .lightbox-close,
  .gallery .main,
  .scan-grid figure,
  .scan-grid img,
  .gallery .thumbs button,
  .gallery .thumbs button img { transition: none; }
}
