/* ==========================================================================
   BISON — design system
   --------------------------------------------------------------------------
   Built from a measured teardown of the three reference sites the client
   picked (ProMotors, Cras, Ducatibox v-dark). The formula they share, and
   that this file implements:

     1. Three background layers, none of them pure black
        (#0f0e0e page -> #1a1818 surface -> #383434 line).
     2. Exactly one hot accent, used on roughly 5% of the surface.
     3. A soft radius scale. The first pass followed Ducatibox and kept
        structure at zero; the client rejected it as too severe ("too many
        corners", then "not those traditional sharp angles"), so the scale was
        reworked: surfaces round to 10/16/24px by size, and everything the
        visitor presses is a pill or a circle. The accent, the type ratio and
        the layered darks carry the industrial mood on their own -- the sharp
        corners were never the part doing that work.
     4. Two type roles only: a condensed uppercase display face and a
        humanist body face set in grey, never white.
     5. An extreme display-to-body size ratio (up to 4.4x) with a display
        line-height of exactly 1.

   Layout uses logical properties throughout (margin-inline, inset-inline,
   border-inline-start) so the Arabic RTL and English LTR renderings come from
   one set of rules rather than a mirrored override sheet.
   ========================================================================== */

:root {
  /* Brand — taken from the logo package, which ships these exact values. */
  --red:        #e00b00;
  --red-hover:  #b30900;
  --red-deep:   #7a0600;

  /* Surfaces */
  --bg:         #0f0e0e;
  --bg-alt:     #141313;
  --surface:    #1a1818;
  --surface-2:  #221f1f;
  --line:       #383434;   /* the brand grey, doing duty as the border layer */
  --line-soft:  rgba(255, 255, 255, 0.08);

  /* Text */
  --text:       #ffffff;
  --text-dim:   #9a9696;
  --text-faint: #6b6767;

  /* Type */
  --font-display: "Theridge", "Barlow Condensed", "Cairo", system-ui, sans-serif;
  --font-body:    "Barlow", "IBM Plex Sans Arabic", system-ui, sans-serif;
  --font-accent:  "Arthos", var(--font-display);

  /* Radius scale. The original build kept structure at 0 to match Ducatibox;
     the client asked for something less severe, so surfaces now sit on a soft
     scale and every pressable control is a pill or a circle. Nothing in the
     layout is fully square any more. */
  --radius-sm:    10px;   /* inputs, alerts, small chrome */
  --radius-md:    16px;   /* cards, media, panels */
  --radius-lg:    24px;   /* large panels */
  --radius-pill:  999px;  /* buttons, filters, chips */
  --radius-round: 50%;    /* icon affordances */

  /* Rhythm */
  --container: 1240px;
  --gutter:    24px;
  --section-y: clamp(64px, 9vw, 120px);

  --t-fast: 0.18s cubic-bezier(0.4, 0, 0.2, 1);
  --t-med:  0.35s cubic-bezier(0.4, 0, 0.2, 1);
  --t-slow: 0.9s  cubic-bezier(0.16, 1, 0.3, 1);

  /* Depth. On a near-black page a shadow only reads if it is large and soft,
     so these are wide and offset well below the element. */
  --shadow-card: 0 24px 56px -28px rgba(0, 0, 0, 0.95);
  --shadow-lift: 0 32px 70px -26px rgba(0, 0, 0, 1);
  --glow-red:    0 12px 34px -12px rgba(224, 11, 0, 0.7);

  --header-h: 76px;

  /* Gradient direction that follows the writing direction.

     linear-gradient() has no logical <side-or-corner>: `to inline-end` is not
     valid CSS anywhere, and because an invalid layer invalidates the entire
     background declaration, using it silently dropped every scrim in the hero
     rather than just mis-aiming one. Angles take a var() substitution cleanly,
     so this is the flippable form. 90deg points right, 270deg points left. */
  --dir-angle: 90deg;
}
[dir="rtl"] { --dir-angle: 270deg; }

/* Client-supplied faces. Both are Latin-only, so unicode-range confines them
   to Latin glyphs and Cairo/IBM Plex pick up the Arabic by normal per-character
   fallback. Note it does not stop the download on Arabic pages the way an
   earlier version of this comment claimed: those pages still set the BISON
   wordmark, the EN language switch, product codes like 9H and IR, and the
   numerals in Latin, so the file is legitimately fetched — just for a handful
   of glyphs rather than the body copy.
   Drop the files into assets/fonts/ and these activate automatically; until
   then the Google faces below carry the design, and the 404 on the missing
   woff2 is expected. */
@font-face {
  font-family: "Theridge";
  src: url("../fonts/Theridge.woff2") format("woff2");
  font-weight: 400 700;
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+2000-206F, U+2122, U+2212;
}
@font-face {
  font-family: "Arthos";
  src: url("../fonts/Arthos.woff2") format("woff2");
  font-weight: 400;
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+2000-206F;
}

/* ==========================================================================
   Reset
   ========================================================================== */

*, *::before, *::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--text-dim);
  font-family: var(--font-body);
  font-size: 17px;
  font-weight: 400;
  line-height: 1.75;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

/* Arabic sits lower on the line and needs more leading than the Latin body. */
[dir="rtl"] body { line-height: 1.95; }

img, svg, video { max-width: 100%; height: auto; display: block; }
a { color: inherit; text-decoration: none; }
button, input, select, textarea { font: inherit; color: inherit; }

h1, h2, h3, h4 {
  font-family: var(--font-display);
  color: var(--text);
  font-weight: 700;
  margin: 0;
  text-transform: uppercase;
  letter-spacing: -0.01em;
}
/* Arabic has no case, and the tight Latin tracking crowds its joined forms. */
[dir="rtl"] h1, [dir="rtl"] h2, [dir="rtl"] h3, [dir="rtl"] h4 {
  text-transform: none;
  letter-spacing: 0;
}

p { margin: 0 0 1em; }
p:last-child { margin-bottom: 0; }

::selection { background: var(--red); color: #fff; }

:focus-visible {
  outline: 2px solid var(--red);
  outline-offset: 3px;
}

.sr-only {
  position: absolute; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* Honeypot — off-screen rather than display:none, which some bots skip. */
.bs-hp {
  position: absolute;
  inset-inline-start: -9999px;
  width: 1px; height: 1px;
  overflow: hidden;
}

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

.bs-container {
  width: 100%;
  max-width: var(--container);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

.bs-section { padding-block: var(--section-y); }
.bs-section--alt { background: var(--bg-alt); }
.bs-section--tight { padding-block: clamp(48px, 6vw, 72px); }

/* Section heading block: kicker, rule, title, optional lead. */
.bs-head { margin-bottom: clamp(36px, 5vw, 56px); max-width: 720px; }
.bs-head--center { margin-inline: auto; text-align: center; }

.bs-kicker {
  display: inline-flex;
  align-items: center;
  gap: 12px;
  font-family: var(--font-display);
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--red);
  margin-bottom: 16px;
}
[dir="rtl"] .bs-kicker { letter-spacing: 0; font-size: 15px; }

/* The short red rule that opens every kicker. */
.bs-kicker::before {
  content: "";
  width: 28px;
  height: 2px;
  background: var(--red);
  flex: none;
}
.bs-head--center .bs-kicker::after {
  content: "";
  width: 28px;
  height: 2px;
  background: var(--red);
  flex: none;
}

.bs-title {
  font-size: clamp(1.9rem, 4vw, 2.75rem);
  line-height: 1.12;
  letter-spacing: -0.02em;
}
[dir="rtl"] .bs-title { line-height: 1.35; letter-spacing: 0; }

.bs-lead {
  margin-top: 18px;
  font-size: 1.0625rem;
  color: var(--text-dim);
  max-width: 62ch;
}
.bs-head--center .bs-lead { margin-inline: auto; }

/* ==========================================================================
   Buttons
   ========================================================================== */

.bs-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  padding: 0 34px;
  height: 54px;
  border: 1px solid transparent;
  border-radius: var(--radius-pill);
  font-family: var(--font-display);
  font-size: 15px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  cursor: pointer;
  position: relative;
  overflow: hidden;
  isolation: isolate;
  transition: color var(--t-fast), border-color var(--t-fast),
              background var(--t-fast), transform var(--t-fast),
              box-shadow var(--t-med);
}
[dir="rtl"] .bs-btn { letter-spacing: 0; text-transform: none; font-size: 16px; }

.bs-btn > * { position: relative; z-index: 1; }

/* A light sheen crosses the button once on hover. It replaces the old hard
   left-to-right colour wipe, which was built for the square geometry and read
   as a block sliding across a box once the corners went round.
   Deliberately in physical units: the sweep is decoration with no reading
   direction, so it should look identical in Arabic and English. */
.bs-btn::after {
  content: "";
  position: absolute;
  inset-block: -60%;
  left: -75%;
  width: 45%;
  background: linear-gradient(90deg,
    transparent 0%, rgba(255, 255, 255, 0.3) 50%, transparent 100%);
  transform: skewX(-20deg);
  opacity: 0;
  z-index: 0;
  pointer-events: none;
}
.bs-btn:hover::after { animation: bs-sheen 0.72s ease-out; }

@keyframes bs-sheen {
  from { opacity: 1; transform: skewX(-20deg) translateX(0); }
  to   { opacity: 1; transform: skewX(-20deg) translateX(390%); }
}

/* Depth rather than a flat fill: a slight gradient across the face, a red
   glow cast on the page beneath, and a lift on hover. */
.bs-btn--primary {
  background: linear-gradient(135deg, #f5180b 0%, var(--red) 52%, var(--red-hover) 100%);
  color: #fff;
  box-shadow: var(--glow-red);
}
.bs-btn--primary:hover {
  transform: translateY(-2px);
  box-shadow: 0 18px 44px -12px rgba(224, 11, 0, 0.85);
}

.bs-btn--ghost {
  background: rgba(255, 255, 255, 0.03);
  color: var(--text);
  border-color: var(--line);
  backdrop-filter: blur(6px);
}
.bs-btn--ghost:hover {
  color: #fff;
  border-color: var(--red);
  background: rgba(224, 11, 0, 0.12);
  transform: translateY(-2px);
}

.bs-btn:active { transform: translateY(0); }

.bs-btn--sm { height: 44px; padding: 0 24px; font-size: 13px; }
.bs-btn--block { display: flex; width: 100%; }

@media (prefers-reduced-motion: reduce) {
  .bs-btn:hover::after { animation: none; }
  .bs-btn--primary:hover, .bs-btn--ghost:hover { transform: none; }
}

/* --------------------------------------------------------------------------
   Round controls — the counterweight to the square structure. Everything here
   is an affordance you press, never a container that holds content.
   -------------------------------------------------------------------------- */

.bs-round {
  display: inline-grid;
  place-items: center;
  width: 54px;
  height: 54px;
  flex: none;
  border-radius: var(--radius-round);
  border: 1px solid var(--line);
  background: transparent;
  color: var(--text);
  cursor: pointer;
  transition: background var(--t-fast), border-color var(--t-fast), color var(--t-fast), transform var(--t-fast);
}
.bs-round:hover { background: var(--red); border-color: var(--red); color: #fff; }
.bs-round svg { width: 20px; height: 20px; }
.bs-round--sm { width: 42px; height: 42px; }
.bs-round--sm svg { width: 16px; height: 16px; }
.bs-round--solid { background: var(--red); border-color: var(--red); color: #fff; }
.bs-round--solid:hover { background: var(--red-hover); border-color: var(--red-hover); }

/* Back-to-top, fixed bottom corner, revealed by bison.js past the fold. */
.bs-totop {
  position: fixed;
  inset-block-end: 24px;
  inset-inline-end: 24px;
  z-index: 90;
  background: var(--surface);
  opacity: 0;
  visibility: hidden;
  transform: translateY(10px);
}
.bs-totop.is-shown { opacity: 1; visibility: visible; transform: none; }
/* In RTL the arrow glyph must still point up, so rotate the icon not the box. */
.bs-totop svg { transform: rotate(-90deg); }

/* Pill — reserved for toggles and small status chips. */
.bs-pill {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  height: 34px;
  padding-inline: 15px;
  border-radius: var(--radius-pill);
  border: 1px solid var(--line);
  font-family: var(--font-display);
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--text-dim);
  transition: color var(--t-fast), border-color var(--t-fast), background var(--t-fast);
}
[dir="rtl"] .bs-pill { letter-spacing: 0; text-transform: none; font-size: 14px; }
.bs-pill:hover { color: var(--text); border-color: var(--text-dim); }

/* Text link with a rule that grows on hover. */
.bs-link {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  font-family: var(--font-display);
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--text);
  transition: color var(--t-fast);
}
[dir="rtl"] .bs-link { letter-spacing: 0; text-transform: none; font-size: 15px; }
.bs-link::after {
  content: "";
  width: 18px;
  height: 1px;
  background: currentColor;
  transition: width var(--t-fast);
}
.bs-link:hover { color: var(--red); }
.bs-link:hover::after { width: 34px; }

/* The link's own line box is only ~29px tall, under the 44px touch guideline.
   Padding rather than a min-height, so the rule that grows on hover stays
   optically attached to the text. Coarse pointers only — it would loosen the
   desktop rhythm for no gain. */
@media (pointer: coarse) {
  .bs-link { padding-block: 8px; }
}

/* Same reason: the footer's phone/WhatsApp/email links, and the matching rows
   on the contact page, sit on a ~29px line box. inline-block because the
   contact-page ones are inline inside a flex row, where padding-block alone
   would overflow rather than grow the target. */
@media (pointer: coarse) {
  .bs-footer__contact a {
    display: inline-block;
    padding-block: 8px;
  }
}

/* ==========================================================================
   Header
   ========================================================================== */

.bs-header {
  position: fixed;
  inset-block-start: 0;
  inset-inline: 0;
  z-index: 100;
  height: var(--header-h);
  display: flex;
  align-items: center;
  background: transparent;
  border-bottom: 1px solid transparent;
  transition: background var(--t-med), border-color var(--t-med), height var(--t-med);
}
/* Solid once scrolled past the hero fold; toggled from bison.js. */
.bs-header.is-stuck {
  height: 64px;
  background: rgba(15, 14, 14, 0.94);
  backdrop-filter: blur(10px);
  border-bottom-color: var(--line);
}

.bs-header__inner {
  width: 100%;
  max-width: var(--container);
  margin-inline: auto;
  padding-inline: var(--gutter);
  display: flex;
  align-items: center;
  gap: 28px;
}

.bs-logo { flex: none; }
.bs-logo img {
  height: 44px;
  width: auto;
  transition: height var(--t-med);
}
.bs-header.is-stuck .bs-logo img { height: 36px; }

.bs-nav {
  display: flex;
  align-items: center;
  gap: 4px;
  margin-inline-start: auto;
}

.bs-nav__link {
  position: relative;
  padding: 10px 14px;
  font-family: var(--font-display);
  font-size: 14px;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--text-dim);
  transition: color var(--t-fast);
  white-space: nowrap;
}
[dir="rtl"] .bs-nav__link {
  letter-spacing: 0;
  text-transform: none;
  font-size: 16px;
}
.bs-nav__link:hover { color: var(--text); }

/* Red underline marking the current page. */
.bs-nav__link::after {
  content: "";
  position: absolute;
  inset-block-end: 2px;
  inset-inline-start: 14px;
  width: 0;
  height: 2px;
  background: var(--red);
  transition: width var(--t-fast);
}
.bs-nav__link.is-active { color: var(--text); }
.bs-nav__link.is-active::after { width: calc(100% - 28px); }

.bs-header__actions {
  display: flex;
  align-items: center;
  gap: 10px;
  flex: none;
}

/* The warranty entry point — the only link out to the separate project, so it
   is styled as a distinct outlined chip rather than a plain nav item. */
.bs-warranty-link {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  height: 40px;
  padding-inline: 18px;
  border-radius: var(--radius-pill);
  border: 1px solid var(--line);
  font-family: var(--font-display);
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--text);
  transition: border-color var(--t-fast), color var(--t-fast), background var(--t-fast);
}
[dir="rtl"] .bs-warranty-link { letter-spacing: 0; text-transform: none; font-size: 15px; }
.bs-warranty-link:hover { border-color: var(--red); background: var(--red); color: #fff; }
.bs-warranty-link svg { width: 15px; height: 15px; }

.bs-lang {
  display: inline-flex;
  align-items: center;
  height: 40px;
  padding-inline: 16px;
  border-radius: var(--radius-pill);
  font-family: var(--font-display);
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.08em;
  color: var(--text-dim);
  border: 1px solid transparent;
  transition: color var(--t-fast), border-color var(--t-fast);
}
.bs-lang:hover { color: var(--text); border-color: var(--line); }

.bs-burger {
  display: none;
  width: 44px; height: 44px;
  align-items: center; justify-content: center;
  background: transparent;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  cursor: pointer;
}
.bs-burger span {
  display: block;
  width: 20px; height: 2px;
  background: var(--text);
  position: relative;
  transition: background var(--t-fast);
}
.bs-burger span::before,
.bs-burger span::after {
  content: "";
  position: absolute;
  inset-inline-start: 0;
  width: 20px; height: 2px;
  background: var(--text);
  transition: transform var(--t-fast);
}
.bs-burger span::before { top: -6px; }
.bs-burger span::after  { top: 6px; }
.bs-burger.is-open span { background: transparent; }
.bs-burger.is-open span::before { transform: translateY(6px) rotate(45deg); }
.bs-burger.is-open span::after  { transform: translateY(-6px) rotate(-45deg); }

/* Mobile drawer */
.bs-drawer {
  position: fixed;
  inset-block-start: var(--header-h);
  inset-inline: 0;
  z-index: 99;
  background: var(--bg-alt);
  border-bottom: 1px solid var(--line);
  padding: 12px var(--gutter) 24px;
  display: none;
  flex-direction: column;
  gap: 2px;
  max-height: calc(100vh - var(--header-h));
  overflow-y: auto;
}
.bs-drawer.is-open { display: flex; }
.bs-drawer .bs-nav__link {
  padding: 14px 0;
  font-size: 16px;
  border-bottom: 1px solid var(--line-soft);
}
.bs-drawer .bs-nav__link::after { inset-inline-start: 0; }
.bs-drawer .bs-nav__link.is-active::after { width: 24px; }
.bs-drawer__actions { display: flex; gap: 10px; margin-top: 18px; }

@media (max-width: 1080px) {
  .bs-nav, .bs-header__actions .bs-warranty-link { display: none; }
  .bs-burger { display: flex; }
  .bs-header__actions { margin-inline-start: auto; }
}

/* ==========================================================================
   Hero
   ========================================================================== */

/* Full viewport height, the way Cras does it: measured there at min-height
   720px against a 720px client height, i.e. exactly 100vh, with the
   transparent header overlaying the top of the frame rather than sitting above
   it. The first build capped the hero at min(88vh, 780px), which on a short
   laptop window left a band of empty page between the photo and the stats
   strip — the gap the client flagged.
   svh is the small viewport height, so mobile browsers do not jump the layout
   when the URL bar collapses; the vh line is the fallback for older engines. */
.bs-hero {
  position: relative;
  min-height: 100vh;
  min-height: 100svh;
  display: flex;
  align-items: center;
  padding-block: calc(var(--header-h) + 60px) 80px;
  overflow: hidden;
  isolation: isolate;
}

.bs-hero__media {
  position: absolute;
  inset: 0;
  z-index: -2;
}
.bs-hero__media img {
  width: 100%; height: 100%;
  object-fit: cover;
  object-position: center;
}

/* Three stacked scrims, tuned to the actual hero photograph rather than to a
   generic image: it is already near-black in its upper third and carries its
   subject low and centred.
     1. directional, so the headline side stays readable over the workshop;
     2. top-down, so the fixed header has something to sit on;
     3. bottom-up, so the photo dissolves into the page instead of ending on a
        hard horizontal edge.
   Kept deliberately light on the directional pass — a heavy one fights a photo
   that is mostly shadow already and flattens the red rim light. */
.bs-hero__media::after {
  content: "";
  position: absolute;
  inset: 0;
  background:
    linear-gradient(var(--dir-angle), rgba(15, 14, 14, 0.88) 0%, rgba(15, 14, 14, 0.55) 42%, rgba(15, 14, 14, 0.15) 100%),
    linear-gradient(to bottom, rgba(15, 14, 14, 0.75) 0%, rgba(15, 14, 14, 0) 22%),
    linear-gradient(to top, var(--bg) 0%, rgba(15, 14, 14, 0) 38%);
}

/* --------------------------------------------------------------------------
   Photo hero adjustments.
   -------------------------------------------------------------------------- */
/* Top-aligned, and it has to stay that way at full height too. Measured at
   1440x860: flex-centring puts the headline at y 250-350, which is exactly
   where the technician's head and shoulders land — the brightest thing in the
   frame. Top-aligning lifts it above him into the near-black upper band.
   Bottom-weighting is not an option either: the car's nose is now the animated
   element (see the lamp rig below) and has to stay uncovered. The bottom
   padding reserves that space plus room for the scroll cue. */
.bs-hero--photo {
  align-items: flex-start;
  padding-block: calc(var(--header-h) + clamp(24px, 5vh, 56px)) clamp(96px, 16vh, 170px);
}
.bs-hero--photo .bs-hero__inner { max-width: 560px; }

/* Centred, not pushed to one side. At the old 88vh/760px cap only ~140px of
   the 2.5:1 frame was croppable, so spending it all away from the text column
   was free. At full viewport height the height binds instead and the crop is
   severe — around a third of the image width is lost — and an `object-position:
   100%` shove took the near-side headlight off screen entirely. Centre keeps
   both lamps in frame; the directional scrim below does the legibility work
   the offset used to help with. */
.bs-hero--photo .bs-hero__media img { object-position: center; }

/* Mirrored in Arabic.

   The replacement hero photograph moves the technician off the car's centre
   line — which was the point of replacing it — and parks him on the right, at
   68.6-74.3% of the frame. In LTR that is ideal: he stands opposite the copy.
   In RTL the copy is also on the right, and measuring at 1440x860 puts the
   headline straight across his head, with the directional scrim then burying
   him under ~0.9 alpha. Arabic is the default language, so that is the
   rendering most visitors would get.

   `object-position` cannot fix it: the frame is 2.5:1 and the hero is full
   height, so a shove either way takes one of the two headlights off screen.
   Flipping does, and costs nothing here — the car is dead-on front view and
   the shop behind it carries no legible text, so the mirror is undetectable.
   bison.js reads this transform back to mirror the lamp centres and the
   hover region with it. */
[dir="rtl"] .bs-hero--photo .bs-hero__media img { transform: scaleX(-1); }

/* The directional scrim holds solid across the text column (the first ~42% of
   the inline axis) and then falls away fast, so the technician, the film
   highlights and the red rim light on the far side stay at full strength. An
   evenly-spread ramp reads muddy: it dims the whole photograph to protect a
   strip that only needs the near edge covered.

   The bottom pass is now a short seam-softener rather than a fade-out. It used
   to run to 26%, which dissolved the lower quarter of the frame into the page
   background — half of why the hero looked like it stopped short of the fold.
   Cras runs its photo hard to the bottom edge; this keeps 8% of feathering so
   the join with the section below is not a hard rule. */
.bs-hero--photo .bs-hero__media::after {
  background:
    linear-gradient(var(--dir-angle),
      rgba(15, 14, 14, 0.95) 0%,
      rgba(15, 14, 14, 0.93) 40%,
      rgba(15, 14, 14, 0.85) 50%,
      rgba(15, 14, 14, 0.55) 62%,
      rgba(15, 14, 14, 0.12) 78%,
      rgba(15, 14, 14, 0) 100%),
    linear-gradient(to bottom, rgba(15, 14, 14, 0.7) 0%, rgba(15, 14, 14, 0) 24%),
    linear-gradient(to top, rgba(15, 14, 14, 0.9) 0%, rgba(15, 14, 14, 0) 8%);
}

/* --------------------------------------------------------------------------
   Headlight lamp rig — the motion the client picked out of ProMotors.

   Their hero lights the headlights of a front-facing car while the pointer is
   over the car, and drops them when it leaves. Sampled off the reference
   recording at 12fps: the bloom ramps in over ~0.25s to a peak with horizontal
   flare streaks and a lift on the surrounding bodywork, holds for as long as
   the pointer stays, and falls away over ~0.3s. The car itself never moves.

   (First read as a ~4s timed loop, which was wrong — the mouse cursor is
   visible in the recording, entering the car right as the lights come up and
   leaving as they go out. It is an interaction, not an animation.)

   It transfers directly because the BISON hero photograph is also a
   front-facing car with both headlight clusters clearly visible. The two lamp
   centres are measured on the source file (1983x793) and passed in from the
   markup as percentages, so replacing the photo means editing one attribute
   rather than this stylesheet; bison.js maps them through the object-fit crop
   into pixels.

   z-index -1 puts the rig above .bs-hero__media (-2) and therefore above the
   scrim inside it, which is right: the scrim darkens the photograph, but these
   are light sources and should punch through it. screen blending adds light to
   what is underneath instead of painting opaque white over it.
   -------------------------------------------------------------------------- */
.bs-hero__lamps {
  position: absolute;
  inset: 0;
  z-index: -1;
  overflow: hidden;
  pointer-events: none;
  mix-blend-mode: screen;
}

/* bison.js adds .is-ready once it has mapped the centres; without this the
   lamps would animate at 0,0 for a frame if the photo is still decoding. */
.bs-hero__lamps:not(.is-ready) .bs-hero__lamp { visibility: hidden; }

.bs-hero__lamp {
  position: absolute;
  width: var(--lamp-w, 150px);
  height: var(--lamp-w, 150px);
  /* bison.js sets left/top to the lamp centre, so pull the box back by half
     its size. A negative margin rather than a translate, because the keyframes
     below own the transform property for the pulse scale. */
  margin: calc(var(--lamp-w, 150px) / -2);
  border-radius: var(--radius-round);
  background: radial-gradient(circle,
    rgba(255, 255, 255, 0.95) 0%,
    rgba(255, 253, 248, 0.98) 11%,
    rgba(255, 246, 232, 0.62) 24%,
    rgba(255, 236, 214, 0.27) 42%,
    rgba(255, 228, 206, 0.08) 62%,
    rgba(255, 226, 204, 0)    78%);
  opacity: 0;
  transform: scale(0.72);
  /* Out is slower than in, the way a filament falls off. */
  transition: opacity 0.34s ease-in, transform 0.34s ease-in;
}

/* bison.js adds .is-lit while the pointer is inside the car. */
.bs-hero__lamps.is-lit .bs-hero__lamp {
  opacity: 1;
  transform: scale(1.04);
  transition: opacity 0.26s ease-out, transform 0.26s ease-out;
}

/* The far lamp strikes a hair later — real pairs never come up in perfect
   unison, and the offset keeps it from reading as one flat flash. */
.bs-hero__lamp:nth-child(2) { transition-delay: 0.06s; }

/* The wide, dim halo: this is what lifts the bodywork around each lamp at
   peak, which is the part that sells the light as belonging to the car. */
.bs-hero__lamp::before {
  content: "";
  position: absolute;
  inset: -155%;
  border-radius: var(--radius-round);
  background: radial-gradient(circle,
    rgba(255, 242, 228, 0.32) 0%,
    rgba(255, 242, 228, 0.1) 34%,
    rgba(255, 242, 228, 0)   66%);
}

/* The horizontal flare streak, the anamorphic-style bar in the reference. */
.bs-hero__lamp::after {
  content: "";
  position: absolute;
  top: 50%;
  left: -140%;
  width: 380%;
  height: 15%;
  transform: translateY(-50%);
  background: linear-gradient(90deg,
    transparent 0%,
    rgba(255, 250, 242, 0.28) 22%,
    rgba(255, 255, 255, 0.72) 40%,
    rgba(255, 255, 255, 0.98) 50%,
    rgba(255, 255, 255, 0.72) 60%,
    rgba(255, 250, 242, 0.28) 78%,
    transparent 100%);
  filter: blur(2.5px);
}

@media (prefers-reduced-motion: reduce) {
  .bs-hero__lamps { display: none; }
}

/* On a portrait screen the 2.5:1 frame crops to the car and the technician,
   which is a good mobile hero on its own — so the copy goes back to sitting
   over the middle of it rather than fighting for a clean band that no longer
   exists. */
@media (max-width: 760px) {
  .bs-hero--photo {
    align-items: center;
    padding-block: calc(var(--header-h) + 24px) clamp(80px, 16vh, 130px);
  }
  .bs-hero--photo .bs-hero__inner { max-width: none; }
  /* Portrait crops to roughly the middle fifth of the frame, so the scrim goes
     top-and-bottom instead of directional — there is no clean side left. */
  .bs-hero--photo .bs-hero__media::after {
    background:
      linear-gradient(to bottom, rgba(15, 14, 14, 0.84) 0%, rgba(15, 14, 14, 0.42) 40%, rgba(15, 14, 14, 0.72) 100%),
      linear-gradient(to top, rgba(15, 14, 14, 0.9) 0%, rgba(15, 14, 14, 0) 10%);
  }
  /* At that crop the lamps land near the frame edges and their streaks mostly
     clip, so the pulse reads as edge flicker rather than headlights. */
  .bs-hero__lamps { display: none; }
}

/* Oversized brand watermark behind the headline. */
.bs-hero__watermark {
  position: absolute;
  inset-block-start: 50%;
  inset-inline-end: -4%;
  transform: translateY(-50%);
  z-index: -1;
  width: min(46%, 520px);
  opacity: 0.05;
  pointer-events: none;
}

.bs-hero__inner { position: relative; max-width: 720px; }

.bs-hero__title {
  font-size: clamp(2.5rem, 6.4vw, 5rem);
  line-height: 1;
  letter-spacing: -0.03em;
  margin-bottom: 22px;
}
[dir="rtl"] .bs-hero__title {
  line-height: 1.22;
  letter-spacing: 0;
  font-size: clamp(2.1rem, 5.4vw, 4.25rem);
}

/* Lighter than the page body grey. --text-dim (#9a9696) is tuned for text on
   a flat surface; over a photograph it measured 3.04:1 at its worst point on a
   short, wide window — under the 4.5:1 AA floor, and exactly the line the
   client could not read. Still grey rather than white, so the two-tone type
   rule holds. */
.bs-hero__lead {
  font-size: 1.125rem;
  color: #c9c6c6;
  max-width: 54ch;
  margin-bottom: 36px;
}

.bs-hero__actions { display: flex; flex-wrap: wrap; align-items: center; gap: 14px; }

/* Circular "watch"/scroll affordance beside the hero CTAs, mirroring Cras's
   55px circle. Pure decoration on a page with no video, so it scrolls rather
   than opening anything. */
.bs-hero__scroll {
  position: absolute;
  inset-block-end: 42px;
  inset-inline-end: 6%;
  display: grid;
  place-items: center;
  gap: 10px;
  color: var(--text-dim);
  font-family: var(--font-display);
  font-size: 11px;
  letter-spacing: 0.2em;
  text-transform: uppercase;
}
[dir="rtl"] .bs-hero__scroll { letter-spacing: 0; text-transform: none; font-size: 13px; }
.bs-hero__scroll .bs-round { background: rgba(15, 14, 14, 0.5); backdrop-filter: blur(6px); }
.bs-hero__scroll svg { transform: rotate(90deg); }

@media (max-width: 860px) { .bs-hero__scroll { display: none; } }

/* Angled red rule echoing the diagonal cuts in the wordmark. */
.bs-hero__slash {
  position: absolute;
  inset-block-end: 0;
  inset-inline-start: 0;
  width: 100%;
  height: 3px;
  background: linear-gradient(var(--dir-angle), var(--red) 0%, var(--red-deep) 40%, transparent 75%);
}

/* ==========================================================================
   Stats strip
   ========================================================================== */

/* Stays one welded panel rather than four cards — the internal rules are the
   point of a stats strip — so only the outer corners round. */
.bs-stats {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  overflow: hidden;
  background: var(--surface);
}
.bs-stat {
  padding: 34px 28px;
  border-inline-end: 1px solid var(--line);
}
.bs-stat:last-child { border-inline-end: none; }

.bs-stat__value {
  display: flex;
  align-items: baseline;
  gap: 2px;
  font-family: var(--font-display);
  font-size: clamp(2.25rem, 4vw, 3.25rem);
  font-weight: 700;
  line-height: 1;
  color: var(--text);
}
.bs-stat__suffix { color: var(--red); }
.bs-stat__label {
  margin-top: 10px;
  font-size: 0.875rem;
  color: var(--text-dim);
  line-height: 1.5;
}

@media (max-width: 860px) {
  .bs-stats { grid-template-columns: repeat(2, 1fr); }
  .bs-stat:nth-child(2n) { border-inline-end: none; }
  .bs-stat:nth-child(-n + 2) { border-bottom: 1px solid var(--line); }
}

/* ==========================================================================
   Cards
   ========================================================================== */

/* Was a 1px gap over a border-coloured parent, which drew hairline rules
   between cards and made each grid read as one welded slab. Now the cards are
   separate objects that float on the page — the same change the product grid
   needed, applied consistently so a rounded product card does not sit two
   sections away from a square feature card. */
.bs-grid {
  display: grid;
  gap: clamp(14px, 1.6vw, 22px);
}
.bs-grid--3 { grid-template-columns: repeat(3, 1fr); }
.bs-grid--4 { grid-template-columns: repeat(4, 1fr); }

.bs-card {
  background: var(--surface);
  border: 1px solid var(--line-soft);
  border-radius: var(--radius-md);
  padding: 32px 28px;
  position: relative;
  transition: background var(--t-fast), border-color var(--t-fast),
              transform var(--t-med), box-shadow var(--t-med);
}
.bs-card:hover {
  background: var(--surface-2);
  border-color: rgba(224, 11, 0, 0.38);
  transform: translateY(-4px);
  box-shadow: var(--shadow-card);
}

/* Circular icon badge, the same move Cras makes with its 50px red circle. It
   is the one round element inside an otherwise square card, which is what
   stops a grid of four from reading as a wall of boxes. */
.bs-card__icon {
  width: 58px; height: 58px;
  display: grid; place-items: center;
  border-radius: var(--radius-round);
  border: 1px solid var(--line);
  background: var(--bg);
  color: var(--red);
  margin-bottom: 22px;
  transition: background var(--t-fast), border-color var(--t-fast), color var(--t-fast);
}
.bs-card:hover .bs-card__icon { background: var(--red); border-color: var(--red); color: #fff; }
.bs-card__icon svg { width: 24px; height: 24px; }

.bs-card__title {
  font-size: 1.1875rem;
  line-height: 1.3;
  margin-bottom: 10px;
}
.bs-card__text { font-size: 0.9375rem; color: var(--text-dim); }

/* Numbered variant for the process/benefit lists. */
.bs-card__num {
  font-family: var(--font-display);
  font-size: 2.75rem;
  font-weight: 700;
  line-height: 1;
  color: var(--line);
  margin-bottom: 16px;
}

/* Partner card — image over a caption block. Kept in this shape because a
   partner is a logo plus a line of text, with no page to click through to. */
.bs-media-card {
  background: var(--surface);
  border: 1px solid var(--line-soft);
  border-radius: var(--radius-md);
  overflow: hidden;
  display: flex;
  flex-direction: column;
  transition: background var(--t-fast), border-color var(--t-fast),
              transform var(--t-med), box-shadow var(--t-med);
}
.bs-media-card:hover {
  background: var(--surface-2);
  border-color: rgba(224, 11, 0, 0.38);
  transform: translateY(-4px);
  box-shadow: var(--shadow-card);
}

.bs-media-card__media {
  position: relative;
  aspect-ratio: 4 / 3;
  overflow: hidden;
  background: var(--bg-alt);
}
.bs-media-card__media img {
  width: 100%; height: 100%;
  object-fit: cover;
  transition: transform 0.6s cubic-bezier(0.4, 0, 0.2, 1);
}
.bs-media-card:hover .bs-media-card__media img { transform: scale(1.06); }

.bs-media-card__body {
  padding: 22px 22px 26px;
  display: flex;
  flex-direction: column;
  gap: 10px;
  flex: 1;
}
.bs-media-card__title { font-size: 1.125rem; line-height: 1.3; }
.bs-media-card__text { font-size: 0.9375rem; color: var(--text-dim); flex: 1; }

@media (max-width: 980px) {
  .bs-grid--3, .bs-grid--4 { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 620px) {
  .bs-grid--3, .bs-grid--4 { grid-template-columns: 1fr; }
}

/* ==========================================================================
   Product card
   --------------------------------------------------------------------------
   The first pass was a photo in a 4:3 box with a title, a paragraph and a
   "details" link stacked underneath — the default catalogue tile, which the
   client called too classic. This replaces it with an editorial cover: a tall
   portrait card the image fills edge to edge, the name set over the foot of
   the photograph, the blurb held back until the visitor is on the card, and a
   round arrow that arms on hover.

   Everything lives on one <a>, so the whole cover is the hit area and one
   :hover/:focus-visible state drives the image zoom, the scrim, the blurb and
   the arrow together.
   ========================================================================== */

.bs-pgrid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: clamp(16px, 2vw, 26px);
}

.bs-pcard {
  position: relative;
  display: block;
  aspect-ratio: 3 / 4;
  border-radius: var(--radius-md);
  overflow: hidden;
  background: var(--surface);
  isolation: isolate;
  transition: transform var(--t-med), box-shadow var(--t-med);
}
.bs-pcard:hover,
.bs-pcard:focus-visible {
  transform: translateY(-6px);
  box-shadow: var(--shadow-lift), 0 0 0 1px rgba(224, 11, 0, 0.5);
}

.bs-pcard__img {
  position: absolute;
  inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
  transition: transform 1s cubic-bezier(0.2, 0.8, 0.2, 1);
}
.bs-pcard:hover .bs-pcard__img,
.bs-pcard:focus-visible .bs-pcard__img { transform: scale(1.07); }

/* Reads down to near-opaque at the foot so the name holds over any photograph
   the client uploads, without needing to know what is in it. */
.bs-pcard::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
  background: linear-gradient(to top,
    rgba(8, 7, 7, 0.96) 0%,
    rgba(8, 7, 7, 0.74) 30%,
    rgba(8, 7, 7, 0.2)  58%,
    rgba(8, 7, 7, 0.04) 100%);
  pointer-events: none;
}

.bs-pcard__body {
  position: absolute;
  z-index: 2;
  inset-inline: 0;
  inset-block-end: 0;
  padding: 24px 22px 26px;
}

.bs-pcard__title {
  font-size: 1.1875rem;
  line-height: 1.25;
}
[dir="rtl"] .bs-pcard__title { line-height: 1.45; }

/* Collapsed by default: a grid of clean covers, with the blurb revealed only
   on the one being looked at. max-height animates where height:auto will not;
   7em clears the two-line short description the schema allows. */
.bs-pcard__text {
  font-size: 0.9rem;
  color: var(--text-dim);
  margin-top: 0;
  max-height: 0;
  opacity: 0;
  overflow: hidden;
  transition: max-height var(--t-med), opacity var(--t-med), margin-top var(--t-med);
}
.bs-pcard:hover .bs-pcard__text,
.bs-pcard:focus-visible .bs-pcard__text {
  max-height: 7em;
  opacity: 1;
  margin-top: 9px;
}

/* A hover reveal is a dead end on touch, where :hover never fires — so there
   the blurb is simply always out. */
@media (hover: none) {
  .bs-pcard__text { max-height: 7em; opacity: 1; margin-top: 9px; }
}

/* Glass chip until hover, then it fills red — the same round-affordance role
   as the hero scroll circle and the back-to-top button. */
.bs-pcard__go {
  position: absolute;
  z-index: 2;
  inset-block-start: 18px;
  inset-inline-end: 18px;
  width: 46px; height: 46px;
  display: grid;
  place-items: center;
  border-radius: var(--radius-round);
  border: 1px solid rgba(255, 255, 255, 0.2);
  background: rgba(255, 255, 255, 0.1);
  backdrop-filter: blur(8px);
  color: #fff;
  opacity: 0;
  transform: scale(0.82) translateY(-6px);
  transition: opacity var(--t-med), transform var(--t-med),
              background var(--t-fast), border-color var(--t-fast);
}
.bs-pcard__go svg { width: 18px; height: 18px; }
/* The glyph points inline-end; mirror it rather than the circle in RTL. */
[dir="rtl"] .bs-pcard__go svg { transform: scaleX(-1); }

.bs-pcard:hover .bs-pcard__go,
.bs-pcard:focus-visible .bs-pcard__go {
  opacity: 1;
  transform: none;
  background: var(--red);
  border-color: var(--red);
}
@media (hover: none) {
  .bs-pcard__go { opacity: 1; transform: none; }
}

.bs-pcard__tag {
  position: absolute;
  z-index: 2;
  inset-block-start: 18px;
  inset-inline-start: 18px;
  padding: 5px 14px;
  border-radius: var(--radius-pill);
  background: rgba(224, 11, 0, 0.92);
  color: #fff;
  font-family: var(--font-display);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}
[dir="rtl"] .bs-pcard__tag { letter-spacing: 0; text-transform: none; font-size: 13px; }

@media (max-width: 980px) { .bs-pgrid { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 560px) { .bs-pgrid { grid-template-columns: 1fr; } }

@media (prefers-reduced-motion: reduce) {
  .bs-pcard, .bs-pcard__img, .bs-pcard__go, .bs-pcard__text { transition: none; }
  .bs-pcard:hover, .bs-pcard:focus-visible { transform: none; }
  .bs-pcard:hover .bs-pcard__img { transform: none; }
}

/* ==========================================================================
   Split section (image beside text)
   ========================================================================== */

.bs-split {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: clamp(32px, 6vw, 72px);
  align-items: center;
}
.bs-split__media { position: relative; }
.bs-split__media img {
  width: 100%;
  aspect-ratio: 4 / 3;
  object-fit: cover;
  border-radius: var(--radius-md);
}
/* Offset red frame behind the image. */
.bs-split__media::before {
  content: "";
  position: absolute;
  inset-block-start: 18px;
  inset-inline-start: 18px;
  width: 100%; height: 100%;
  border: 1px solid var(--red);
  border-radius: var(--radius-md);
  z-index: -1;
}
.bs-split--reverse .bs-split__media { order: 2; }

.bs-checklist { list-style: none; margin: 26px 0 0; padding: 0; display: grid; gap: 12px; }
.bs-checklist li {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  font-size: 0.9375rem;
  color: var(--text-dim);
}
.bs-checklist li::before {
  content: "";
  flex: none;
  width: 8px; height: 8px;
  margin-top: 0.55em;
  background: var(--red);
}

@media (max-width: 860px) {
  .bs-split { grid-template-columns: 1fr; }
  .bs-split--reverse .bs-split__media { order: 0; }
  .bs-split__media::before { display: none; }
}

/* ==========================================================================
   Marquee
   ========================================================================== */

.bs-marquee {
  border-block: 1px solid var(--line);
  background: var(--surface);
  padding-block: 22px;
  overflow: hidden;
  display: flex;
}
.bs-marquee__track {
  display: flex;
  align-items: center;
  gap: 48px;
  flex: none;
  padding-inline-end: 48px;
  animation: bs-marquee 32s linear infinite;
}
.bs-marquee:hover .bs-marquee__track { animation-play-state: paused; }

.bs-marquee__item {
  display: flex;
  align-items: center;
  gap: 48px;
  font-family: var(--font-display);
  font-size: clamp(1.25rem, 2.4vw, 1.75rem);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--text);
  white-space: nowrap;
}
[dir="rtl"] .bs-marquee__item { text-transform: none; letter-spacing: 0; }
.bs-marquee__item::after {
  content: "";
  width: 9px; height: 9px;
  background: var(--red);
  flex: none;
}

@keyframes bs-marquee {
  from { transform: translateX(0); }
  to   { transform: translateX(-100%); }
}
/* The track scrolls left in both directions; in RTL the duplicated copy sits on
   the other side, so flip the travel to keep it seamless. */
[dir="rtl"] .bs-marquee__track { animation-name: bs-marquee-rtl; }
@keyframes bs-marquee-rtl {
  from { transform: translateX(0); }
  to   { transform: translateX(100%); }
}

@media (prefers-reduced-motion: reduce) {
  .bs-marquee__track { animation: none; }
}

/* ==========================================================================
   CTA band
   ========================================================================== */

.bs-cta {
  position: relative;
  background: linear-gradient(120deg, var(--red) 0%, var(--red-deep) 100%);
  overflow: hidden;
}
.bs-cta__inner {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 32px;
  padding-block: clamp(48px, 6vw, 72px);
  flex-wrap: wrap;
}
.bs-cta__title {
  font-size: clamp(1.75rem, 3.4vw, 2.5rem);
  line-height: 1.15;
  color: #fff;
  max-width: 20ch;
}
[dir="rtl"] .bs-cta__title { line-height: 1.4; }
.bs-cta__text { color: rgba(255, 255, 255, 0.85); margin-top: 12px; max-width: 48ch; }

/* Inverted against the red band. The sheen inherited from .bs-btn::after is
   white-on-white here, so it is dimmed to a grey pass instead. */
.bs-cta .bs-btn--primary {
  background: #fff;
  color: var(--red);
  box-shadow: 0 12px 34px -12px rgba(0, 0, 0, 0.55);
}
.bs-cta .bs-btn--primary::after {
  background: linear-gradient(90deg,
    transparent 0%, rgba(0, 0, 0, 0.12) 50%, transparent 100%);
}
.bs-cta .bs-btn--primary:hover {
  color: var(--red-hover);
  box-shadow: 0 18px 44px -12px rgba(0, 0, 0, 0.7);
}

/* Faint mark watermark, matching the hero treatment. */
.bs-cta__mark {
  position: absolute;
  inset-block-start: 50%;
  inset-inline-end: -30px;
  transform: translateY(-50%);
  width: 260px;
  opacity: 0.09;
  pointer-events: none;
}

/* ==========================================================================
   Forms
   ========================================================================== */

.bs-form { display: grid; gap: 20px; }
.bs-form__row { display: grid; grid-template-columns: 1fr 1fr; gap: 20px; }

.bs-field label {
  display: block;
  font-family: var(--font-display);
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--text);
  margin-bottom: 9px;
}
[dir="rtl"] .bs-field label { letter-spacing: 0; text-transform: none; font-size: 15px; }
.bs-field label span { color: var(--red); }
.bs-field .bs-optional { color: var(--text-faint); font-weight: 400; }

.bs-field input,
.bs-field textarea,
.bs-field select {
  width: 100%;
  padding: 14px 16px;
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  color: var(--text);
  font-size: 1rem;
  transition: border-color var(--t-fast), background var(--t-fast);
}
.bs-field textarea { min-height: 140px; resize: vertical; }
.bs-field input:focus,
.bs-field textarea:focus,
.bs-field select:focus {
  outline: none;
  border-color: var(--red);
  background: var(--surface);
}
.bs-field input::placeholder,
.bs-field textarea::placeholder { color: var(--text-faint); }
.bs-field.has-error input,
.bs-field.has-error textarea { border-color: var(--red); }
.bs-field__error {
  margin-top: 7px;
  font-size: 0.8125rem;
  color: var(--red);
}

.bs-alert {
  padding: 16px 20px;
  border-inline-start: 3px solid;
  border-radius: var(--radius-sm);
  font-size: 0.9375rem;
}
.bs-alert--ok {
  background: rgba(45, 160, 90, 0.1);
  border-color: #2da05a;
  color: #7fd6a2;
}
.bs-alert--err {
  background: rgba(224, 11, 0, 0.1);
  border-color: var(--red);
  color: #ff8b84;
}

@media (max-width: 620px) {
  .bs-form__row { grid-template-columns: 1fr; }
}

/* ==========================================================================
   Inner page header
   ========================================================================== */

.bs-pagehead {
  position: relative;
  padding-block: calc(var(--header-h) + 64px) 64px;
  background: var(--bg-alt);
  border-bottom: 1px solid var(--line);
  overflow: hidden;
}
.bs-pagehead__mark {
  position: absolute;
  inset-block-start: 50%;
  inset-inline-end: 2%;
  transform: translateY(-50%);
  width: 260px;
  opacity: 0.045;
  pointer-events: none;
}
.bs-pagehead__title {
  font-size: clamp(2.1rem, 4.6vw, 3.25rem);
  line-height: 1.1;
  letter-spacing: -0.02em;
}
[dir="rtl"] .bs-pagehead__title { line-height: 1.3; letter-spacing: 0; }

.bs-crumbs {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 0.8125rem;
  color: var(--text-faint);
  margin-top: 14px;
}
.bs-crumbs a:hover { color: var(--red); }
.bs-crumbs span { color: var(--line); }

/* ==========================================================================
   Filter bar (products)
   ========================================================================== */

/* Separate pills rather than a segmented bar: they are links you press, so
   they follow the same pill rule as the buttons. */
.bs-filters {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  margin-bottom: 34px;
}
.bs-filter {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius-pill);
  padding: 11px 22px;
  font-family: var(--font-display);
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--text-dim);
  transition: background var(--t-fast), color var(--t-fast),
              border-color var(--t-fast), box-shadow var(--t-med);
}
[dir="rtl"] .bs-filter { letter-spacing: 0; text-transform: none; font-size: 15px; }
.bs-filter:hover { color: var(--text); border-color: var(--text-faint); }
.bs-filter.is-active {
  background: var(--red);
  border-color: var(--red);
  color: #fff;
  box-shadow: var(--glow-red);
}

/* ==========================================================================
   Product detail
   ========================================================================== */

.bs-product { display: grid; grid-template-columns: 1.05fr 1fr; gap: clamp(32px, 5vw, 64px); }
.bs-product__main {
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  overflow: hidden;
  background: var(--surface);
}
.bs-product__main img { width: 100%; aspect-ratio: 4 / 3; object-fit: cover; }

.bs-thumbs { display: grid; grid-template-columns: repeat(4, 1fr); gap: 10px; margin-top: 10px; }
.bs-thumb {
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  overflow: hidden;
  background: var(--surface);
  padding: 0;
  cursor: pointer;
  transition: border-color var(--t-fast);
}
.bs-thumb img { aspect-ratio: 1; object-fit: cover; width: 100%; }
.bs-thumb:hover, .bs-thumb.is-active { border-color: var(--red); }

.bs-product__title {
  font-size: clamp(1.75rem, 3.4vw, 2.5rem);
  line-height: 1.15;
  margin-bottom: 8px;
}
[dir="rtl"] .bs-product__title { line-height: 1.35; }
.bs-product__body { margin-top: 22px; }
.bs-product__body p { color: var(--text-dim); }

@media (max-width: 860px) {
  .bs-product { grid-template-columns: 1fr; }
}

/* ==========================================================================
   Footer
   ========================================================================== */

.bs-footer {
  background: var(--bg-alt);
  border-top: 1px solid var(--line);
  padding-block: clamp(48px, 6vw, 72px) 0;
}
.bs-footer__grid {
  display: grid;
  grid-template-columns: 1.4fr 1fr 1.2fr;
  gap: clamp(28px, 5vw, 64px);
  padding-bottom: 48px;
}
.bs-footer__logo img { height: 96px; width: auto; margin-bottom: 20px; }
.bs-footer__blurb { font-size: 0.9375rem; color: var(--text-dim); max-width: 34ch; }

.bs-footer__title {
  font-size: 1rem;
  margin-bottom: 18px;
  letter-spacing: 0.08em;
}
[dir="rtl"] .bs-footer__title { letter-spacing: 0; }

.bs-footer__links { list-style: none; margin: 0; padding: 0; display: grid; gap: 11px; }
.bs-footer__links a { font-size: 0.9375rem; color: var(--text-dim); transition: color var(--t-fast); }
.bs-footer__links a:hover { color: var(--red); }

.bs-footer__contact { display: grid; gap: 12px; font-size: 0.9375rem; }
.bs-footer__contact a { color: var(--text-dim); transition: color var(--t-fast); }
.bs-footer__contact a:hover { color: var(--red); }

.bs-social { display: flex; gap: 10px; margin-top: 22px; }
.bs-social a {
  width: 42px; height: 42px;
  display: grid; place-items: center;
  border-radius: var(--radius-round);
  border: 1px solid var(--line);
  color: var(--text-dim);
  transition: border-color var(--t-fast), color var(--t-fast), background var(--t-fast);
}
.bs-social a:hover { border-color: var(--red); background: var(--red); color: #fff; }
.bs-social svg { width: 17px; height: 17px; }

.bs-footer__bottom {
  border-top: 1px solid var(--line);
  padding-block: 22px;
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 16px;
  flex-wrap: wrap;
  font-size: 0.8125rem;
  color: var(--text-faint);
}

@media (max-width: 860px) {
  .bs-footer__grid { grid-template-columns: 1fr; }
}

/* ==========================================================================
   Scroll reveal — opt-in, and a no-op when the visitor prefers less motion.
   bison.js adds .is-in as elements enter the viewport.
   ========================================================================== */

.bs-reveal {
  opacity: 0;
  transform: translateY(22px);
  transition: opacity 0.7s ease, transform 0.7s cubic-bezier(0.16, 1, 0.3, 1);
}
.bs-reveal.is-in { opacity: 1; transform: none; }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .bs-reveal { opacity: 1; transform: none; transition: none; }
  .bs-media-card__media img { transition: none; }
}

/* ==========================================================================
   Notices — shown while the site runs without a database
   ========================================================================== */

.bs-devnote {
  position: fixed;
  /* Clears the back-to-top button, which shares this corner. */
  inset-block-end: 92px;
  inset-inline-end: 16px;
  z-index: 200;
  max-width: 300px;
  background: var(--surface);
  border: 1px solid var(--red);
  border-inline-start-width: 3px;
  border-radius: var(--radius-sm);
  padding: 12px 16px;
  font-size: 0.8125rem;
  color: var(--text-dim);
  line-height: 1.55;
}
.bs-devnote strong { color: var(--text); display: block; margin-bottom: 3px; }
