/* ==========================================================================
   CANORA
   Design system. Built on the company's own brand tokens.
   Signature element: the Canora cut, the 45 degree geometry of the logo.
   ========================================================================== */

/* ------------------------------------------------------------ the Arabic face */
/* IBM Plex Sans Arabic, served from the site itself rather than Google: the
   owner's own files, all seven weights, cut down to the Arabic block - the
   Latin letters are IBM Plex Sans's job - and converted to WOFF2, about 40KB a
   weight. unicode-range means a page with no Arabic on it downloads none of
   them, and a browser only ever fetches the weights a page actually uses; the
   700 is what every RTL topic is set in (see 3), which Google was never asked
   for and browsers were thickening by hand. The ?v= is the font's own version
   (1.101): /assets/ is cached for a year, so bump it if the files change. */

@font-face{ font-family:"Canora Arabic"; font-weight:100; font-display:swap;
  src:url("../fonts/IBMPlexSansArabic-Thin.woff2?v=1101") format("woff2");
  unicode-range:U+0600-06FF,U+0750-077F,U+0870-088E,U+0890-0891,U+0897-08E1,U+08E3-08FF,U+200C-200E,U+2010-2011,U+204F,U+2E41,U+FB50-FDFF,U+FE70-FE74,U+FE76-FEFC,U+102E0-102FB,U+10E60-10E7E,U+10EC2-10EC4,U+10EFC-10EFF,U+1EE00-1EEFF }
@font-face{ font-family:"Canora Arabic"; font-weight:200; font-display:swap;
  src:url("../fonts/IBMPlexSansArabic-ExtraLight.woff2?v=1101") format("woff2");
  unicode-range:U+0600-06FF,U+0750-077F,U+0870-088E,U+0890-0891,U+0897-08E1,U+08E3-08FF,U+200C-200E,U+2010-2011,U+204F,U+2E41,U+FB50-FDFF,U+FE70-FE74,U+FE76-FEFC,U+102E0-102FB,U+10E60-10E7E,U+10EC2-10EC4,U+10EFC-10EFF,U+1EE00-1EEFF }
@font-face{ font-family:"Canora Arabic"; font-weight:300; font-display:swap;
  src:url("../fonts/IBMPlexSansArabic-Light.woff2?v=1101") format("woff2");
  unicode-range:U+0600-06FF,U+0750-077F,U+0870-088E,U+0890-0891,U+0897-08E1,U+08E3-08FF,U+200C-200E,U+2010-2011,U+204F,U+2E41,U+FB50-FDFF,U+FE70-FE74,U+FE76-FEFC,U+102E0-102FB,U+10E60-10E7E,U+10EC2-10EC4,U+10EFC-10EFF,U+1EE00-1EEFF }
@font-face{ font-family:"Canora Arabic"; font-weight:400; font-display:swap;
  src:url("../fonts/IBMPlexSansArabic-Regular.woff2?v=1101") format("woff2");
  unicode-range:U+0600-06FF,U+0750-077F,U+0870-088E,U+0890-0891,U+0897-08E1,U+08E3-08FF,U+200C-200E,U+2010-2011,U+204F,U+2E41,U+FB50-FDFF,U+FE70-FE74,U+FE76-FEFC,U+102E0-102FB,U+10E60-10E7E,U+10EC2-10EC4,U+10EFC-10EFF,U+1EE00-1EEFF }
@font-face{ font-family:"Canora Arabic"; font-weight:500; font-display:swap;
  src:url("../fonts/IBMPlexSansArabic-Medium.woff2?v=1101") format("woff2");
  unicode-range:U+0600-06FF,U+0750-077F,U+0870-088E,U+0890-0891,U+0897-08E1,U+08E3-08FF,U+200C-200E,U+2010-2011,U+204F,U+2E41,U+FB50-FDFF,U+FE70-FE74,U+FE76-FEFC,U+102E0-102FB,U+10E60-10E7E,U+10EC2-10EC4,U+10EFC-10EFF,U+1EE00-1EEFF }
@font-face{ font-family:"Canora Arabic"; font-weight:600; font-display:swap;
  src:url("../fonts/IBMPlexSansArabic-SemiBold.woff2?v=1101") format("woff2");
  unicode-range:U+0600-06FF,U+0750-077F,U+0870-088E,U+0890-0891,U+0897-08E1,U+08E3-08FF,U+200C-200E,U+2010-2011,U+204F,U+2E41,U+FB50-FDFF,U+FE70-FE74,U+FE76-FEFC,U+102E0-102FB,U+10E60-10E7E,U+10EC2-10EC4,U+10EFC-10EFF,U+1EE00-1EEFF }
@font-face{ font-family:"Canora Arabic"; font-weight:700; font-display:swap;
  src:url("../fonts/IBMPlexSansArabic-Bold.woff2?v=1101") format("woff2");
  unicode-range:U+0600-06FF,U+0750-077F,U+0870-088E,U+0890-0891,U+0897-08E1,U+08E3-08FF,U+200C-200E,U+2010-2011,U+204F,U+2E41,U+FB50-FDFF,U+FE70-FE74,U+FE76-FEFC,U+102E0-102FB,U+10E60-10E7E,U+10EC2-10EC4,U+10EFC-10EFF,U+1EE00-1EEFF }

/* --------------------------------------------------------------- 1. tokens */

/* ---------------------------------------------------------------------------
   DARK is the default, because it is the brand. LIGHT is a designed palette of
   its own further down, not an inversion: the contrast band flips with it, so
   the page keeps its light-dark-light rhythm in both themes.
   --------------------------------------------------------------------------- */

:root{
  color-scheme: dark;

  /* canvas, tinted toward the footage's cool grade, never pure black */
  --canvas:        #141619;
  --canvas-2:      #1a1d20;
  --panel:         #21252a;
  --panel-2:       #2a2f35;
  --line:          #333a41;
  --line-strong:   #4a535c;

  /* The blue exists in two tones: the bright one reads on a dark ground, the
     deep one on a light ground. The page uses whichever suits its own theme,
     --accent-page always names it, and the contrast band - which is the
     opposite tone to the page - reaches for --light-accent instead. */
  --accent-bright: #4d99ce;   /* Canora blue, preserved exactly */
  --accent-deep:   #2b7ab0;   /* the same blue, deepened for a light ground */

  --accent:        var(--accent-bright);
  --accent-page:   var(--accent-bright);
  --light-accent:  var(--accent-deep);
  --accent-hover:  #6fb0dd;
  --accent-muted:  rgba(77,153,206,.16);
  --accent-glow:   rgba(77,153,206,.40);
  /* The ink that sits ON the accent. It has to flip with the accent itself:
     dark type reads on the bright blue, and only white clears the floor on
     the deepened one. */
  --on-accent:     #0d1013;

  /* The Canora green, #51C480, is the one primary action and nothing else.
     It is the single source: every other state is mixed FROM it rather than
     being a second green picked by hand, so the brand colour can never drift.
     The ink on top is dark, because #51C480 is a light green and white type on
     it lands at 2.2:1 - well under the floor. Dark ink reads at 9.4:1. */
  --hot:           #51C480;
  --hot-ink:       #0d1013;
  --hot-hover:     #70cf97;                                  /* fallback */
  --hot-hover:     color-mix(in srgb, var(--hot) 82%, #ffffff);
  --hot-glow:      rgba(81,196,128,.45);

  /* ------------------------------------------------- the one hover rule
     Everything that answers the pointer moves AWAY from the ground it is
     standing on: lighter on a dark page, darker on a light one. Most of the
     site gets that for free by reaching for a pair that already flips with
     the theme - --text-primary over --text-secondary, --panel-2 over
     --panel, --line-strong over --line. These two are the cases that had no
     such pair, so they are stated once here and mixed the other way in the
     light palette. */

  /* the film a control with no fill of its own takes under the pointer */
  --hover-veil:    rgba(255,255,255,.055);
  /* a brand mark on the logo wall, shown in its own colours and then lifted */
  --logo-filter-hi:brightness(1.14);

  --text-primary:  #f1f4f6;
  --text-secondary:#b6bfc7;
  --text-tertiary: #8a939c;

  /* the one contrast band. It flips with the theme so the rhythm survives. */
  --light:         #efefef;
  --light-text:    #1a1d20;
  --light-muted:   #4e555c;
  --light-line:    #d9d9d9;

  /* surfaces that used to carry hardcoded colours */
  --nav-bg:        rgba(20,22,25,.82);
  --nav-solid:     rgba(18,20,23,.98);
  --veil:          rgba(8,10,13,.70);
  --lightbox-bg:   rgba(8,10,13,.95);
  --card-stage:    linear-gradient(180deg,#1b1f24 0%,#15181c 100%);
  --card-floor:    rgba(0,0,0,.55);
  --card-shadow:   0 26px 60px -22px rgba(0,0,0,.75);
  --logo-filter:   grayscale(1) brightness(1.7);
  --wall:          linear-gradient(90deg,#1e2227,#14171a);
  --badge-bg:      rgba(8,10,13,.72);
  --select-arrow:  url("data:image/svg+xml;charset=utf8,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 width=%2712%27 height=%278%27%3E%3Cpath d=%27M1 1l5 5 5-5%27 stroke=%27%238a939c%27 stroke-width=%271.6%27 fill=%27none%27/%3E%3C/svg%3E");

  /* the premium neon. Soft, wide, and low alpha: a glow, never a tube light. */
  --neon:          0 0 1px rgba(148,203,240,.34),
                   0 0 14px rgba(77,153,206,.30),
                   0 0 38px rgba(77,153,206,.13);
  --neon-strong:   0 0 1px rgba(168,214,246,.42),
                   0 0 18px rgba(77,153,206,.38),
                   0 0 52px rgba(77,153,206,.17);

  /* the star field */
  --env-a:         rgba(77,153,206,.075);
  --env-b:         rgba(77,153,206,.045);
  --grain:         .16;

  --star-a:        rgba(219,234,247,.62);
  --star-b:        rgba(77,153,206,.42);
  --star-opacity:  .60;

  /* type. Arabic and Kurdish are set in one face, --arabic, and it stands
     second in every stack: none of the Latin faces has a single Arabic letter,
     so every Arabic letter anywhere on the site falls through to it, and every
     Latin letter keeps exactly the face it always had. */
  --arabic:  "Canora Arabic";
  --display: "Archivo", var(--arabic), "Arial Black", system-ui, sans-serif;
  --body:    "IBM Plex Sans", var(--arabic), system-ui, sans-serif;
  --mono:    "IBM Plex Mono", var(--arabic), ui-monospace, "SFMono-Regular", monospace;

  /* motion: two curves, used everywhere, nothing snaps */
  --ease:      cubic-bezier(.22,.61,.36,1);
  --ease-out:  cubic-bezier(.16,1,.3,1);
  --dur:       .5s;
  --dur-slow:  .9s;

  /* the four-layer legibility system, layer 3 */
  --tshadow: 0 1px 2px rgba(5,5,10,.95),
             0 3px 12px rgba(5,5,10,.78),
             0 10px 44px rgba(5,5,10,.80);

  /* the Canora cut, one 45 degree corner */
  --cut: 22px;

  --shell: 1280px;
  --gutter: clamp(20px, 5vw, 64px);
  --nav-h: 72px;
}

/* ------------------------------------------------------------ light theme */
/* Its own palette, chosen for paper rather than for screens: a cool off-white
   canvas (never pure white), a deeper blue that actually passes contrast on a
   light ground, and the contrast band flipped to dark so the page still
   alternates the way it does in dark mode. */

:root[data-theme="light"]{
  color-scheme: light;

  --canvas:        #f1f4f6;
  --canvas-2:      #ffffff;
  --panel:         #ffffff;
  --panel-2:       #eaeef2;
  --line:          #dce2e8;
  --line-strong:   #9aa5ae;

  --accent:        var(--accent-deep);    /* deepened so it reads on white */
  --accent-page:   var(--accent-deep);
  --light-accent:  var(--accent-bright);  /* the band is dark here, so bright */
  --accent-hover:  #1f6395;
  --accent-muted:  rgba(43,122,176,.12);
  --accent-glow:   rgba(43,122,176,.28);
  --on-accent:     #ffffff;   /* 4.7:1 on the deepened blue; dark ink is 4.1 */

  /* The same #51C480, unchanged: it is the brand colour, not a per-theme
     choice. Only the hover mixes the other way, deepening on a light ground
     instead of lifting on a dark one. */
  --hot:           #51C480;
  --hot-ink:       #0d1013;
  --hot-hover:     #46a76e;                                  /* fallback */
  --hot-hover:     color-mix(in srgb, var(--hot) 84%, #0d1013);
  --hot-glow:      rgba(81,196,128,.42);

  /* the same two, mixed the other way: on paper a hover presses INTO the page
     rather than lifting off it */
  --hover-veil:    rgba(18,23,27,.055);
  --logo-filter-hi:brightness(.9) contrast(1.06);

  --text-primary:  #12171b;
  --text-secondary:#4b555e;
  --text-tertiary: #5c666f;   /* was #6d7780: 4.1:1 on the canvas, under the line */

  /* the band flips: dark on a light page */
  --light:         #171a1e;
  --light-text:    #f1f4f6;
  --light-muted:   #aab3bb;
  --light-line:    #2a2f35;

  --nav-bg:        rgba(255,255,255,.84);
  --nav-solid:     rgba(250,252,253,.98);
  --veil:          rgba(28,34,40,.55);
  --lightbox-bg:   rgba(232,236,240,.96);
  --card-stage:    linear-gradient(180deg,#ffffff 0%,#e9edf1 100%);
  --card-floor:    rgba(60,74,88,.20);
  --card-shadow:   0 20px 44px -20px rgba(31,45,58,.28);
  --logo-filter:   grayscale(1) brightness(.55) contrast(1.15);
  --wall:          linear-gradient(90deg,#e6eaee,#d5dbe1);
  --badge-bg:      rgba(255,255,255,.86);
  --select-arrow:  url("data:image/svg+xml;charset=utf8,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 width=%2712%27 height=%278%27%3E%3Cpath d=%27M1 1l5 5 5-5%27 stroke=%27%236d7780%27 stroke-width=%271.6%27 fill=%27none%27/%3E%3C/svg%3E");

  /* neon on paper is a whisper, not a tube: a tight halo and nothing wide */
  --neon:          0 0 10px rgba(43,122,176,.16),
                   0 0 22px rgba(43,122,176,.07);
  --neon-strong:   0 0 12px rgba(43,122,176,.22),
                   0 0 28px rgba(43,122,176,.10);

  --env-a:         rgba(43,122,176,.055);
  --env-b:         rgba(43,122,176,.035);
  --grain:         .05;

  --star-a:        rgba(58,94,128,.30);
  --star-b:        rgba(43,122,176,.24);
  --star-opacity:  .34;
}

/* The one transition that carries the whole theme change. Colour only, so it
   never fights the scroll or the hero, and it is skipped for reduced motion. */
:root.theme-anim,
:root.theme-anim body,
:root.theme-anim .section,
:root.theme-anim .nav,
:root.theme-anim .footer,
:root.theme-anim .vcard,
:root.theme-anim .vstage,
:root.theme-anim .ad-card,
:root.theme-anim .btn,
:root.theme-anim .stat,
:root.theme-anim .spec,
:root.theme-anim .logowall__i,
:root.theme-anim .input,
:root.theme-anim .select,
:root.theme-anim .textarea,
:root.theme-anim .chipbtn,
:root.theme-anim .widen,
:root.theme-anim .widen__answer,
:root.theme-anim .filterbar,
:root.theme-anim .specnav,
:root.theme-anim .marquee,
:root.theme-anim .marquee::before,
:root.theme-anim .marquee::after,
:root.theme-anim .marquee__i,
:root.theme-anim .bword,
:root.theme-anim .bmeta__n,
:root.theme-anim .bmeta__m,
:root.theme-anim .stars{
  transition: background-color .45s var(--ease),
              border-color .45s var(--ease),
              color .45s var(--ease),
              opacity .45s var(--ease) !important;
}
@media (prefers-reduced-motion: reduce){
  :root.theme-anim, :root.theme-anim *{ transition-duration:.001ms !important }
}

/* ---------------------------------------------------------------- 2. reset */

*,*::before,*::after{box-sizing:border-box}

html{
  overflow-x:hidden;          /* fallback first */
  overflow-x:clip;
  scroll-behavior:smooth;
  -webkit-text-size-adjust:100%;
}
body{
  overflow-x:hidden;
  overflow-x:clip;
  margin:0;
  background:var(--canvas);
  color:var(--text-primary);
  font-family:var(--body);
  font-size:17px;              /* readability pass: was 16 */
  line-height:1.62;
  -webkit-font-smoothing:antialiased;
  text-rendering:optimizeLegibility;
}

/* Arabic and Kurdish need a little more room than Latin at the same nominal
   size: the letterforms are taller and the marks sit above and below. */
html[dir="rtl"] body{
  font-size:17.8px;
  line-height:1.85;
}
html[dir="rtl"] .lede,
html[dir="rtl"] .step__d,
html[dir="rtl"] .widen__a,
html[dir="rtl"] .feat{ line-height:1.9 }
/* The About page's headings in Arabic and Kurdish. The display face is set at
   a Latin capital's leading - 1.02 - and Arabic letters climb above and drop
   below a Latin capital, so once a heading wrapped, the dots and tails of one
   line met the next. A comfortable step more, for the headings only: the
   paragraphs already have their room, and nothing changes size or weight. */
html[dir="rtl"] .page--about .h-section{ line-height:1.32 }
html[dir="rtl"] .page--about .step__t{ line-height:1.5 }
@media (prefers-reduced-motion: reduce){ html{scroll-behavior:auto} }

img,video,svg{display:block;max-width:100%}
img{height:auto}
a{color:inherit;text-decoration:none}
button{font:inherit;color:inherit;background:none;border:0;cursor:pointer}
input,textarea,select{font:inherit;color:inherit}
h1,h2,h3,h4{margin:0;font-weight:700;line-height:1.05}
p{margin:0}
ul{margin:0;padding:0;list-style:none}

:focus-visible{
  outline:2px solid var(--accent);
  outline-offset:3px;
  border-radius:2px;
}

::selection{background:var(--accent);color:#0d1013}

.sr-only{
  position:absolute;width:1px;height:1px;padding:0;margin:-1px;
  overflow:hidden;clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap;border:0;
}

.skip{
  position:absolute;inset-inline-start:12px;top:-60px;z-index:200;
  background:var(--accent);color:#0d1013;padding:10px 16px;font-weight:600;
  transition:top .2s var(--ease);
}
.skip:focus{top:12px}

/* ------------------------------------------------------------ 3. typography */

.display{
  font-family:var(--display);
  font-variation-settings:"wdth" 118,"wght" 700;
  text-transform:uppercase;
  letter-spacing:-.005em;
  line-height:.98;
}
.display--tight{ font-variation-settings:"wdth" 112,"wght" 800 }

.kicker{
  font-family:var(--mono);
  font-size:.76rem;
  font-weight:500;
  letter-spacing:.17em;
  text-transform:uppercase;
  color:var(--accent);
}
.kicker--muted{color:var(--text-tertiary)}

/* The readability pass. Supporting text is the text people actually read, so
   it is a step larger, a step heavier and a step clearer than it was. The bold
   display headings are untouched. */
/* Supporting text is the text people actually read, and at 500 it was reading
   as a whisper - especially in Arabic and Kurdish, where the strokes are finer
   at the same weight. 600 is a real cut of both families, already loaded, so
   this is a heavier face rather than the browser smearing the 500. */
.lede{
  font-size:clamp(1.06rem,1rem + .4vw,1.26rem);
  font-weight:600;
  line-height:1.7;
  color:var(--text-secondary);
  max-width:62ch;               /* ch on the text element itself */
}

.h-section{
  font-family:var(--display);
  font-variation-settings:"wdth" 116,"wght" 700;
  text-transform:uppercase;
  font-size:clamp(1.9rem,1.2rem + 3.1vw,3.9rem);
  line-height:1.02;
  letter-spacing:-.01em;
  max-width:20ch;
}

.mono-label{
  font-family:var(--mono);
  font-size:.74rem;
  letter-spacing:.14em;
  text-transform:uppercase;
  color:var(--text-tertiary);
}

/* Topics in Arabic and Kurdish, all on one weight.

   The headings take their weight from Archivo's "wght" axis, and Archivo has
   no Arabic - so in Arabic and Kurdish every one of their letters is drawn by
   --arabic, to which that axis means nothing. What actually decided each
   heading's weight was the element it happened to be: an h2 was bold by
   default, a div or a span was regular, which is why some topics read heavier
   than others. Stating one weight on every topic set in the display face puts
   them all on the same cut, whatever the element, at every screen size. Size,
   spacing and everything else about them is untouched. */
html[dir="rtl"] :is(.display, .h-section, .brand__word, .band__line, .static-hero__line,
  .vcard__model, .step__t, .stat__v, .logowall__t, .vhero__model, .spec__v,
  .colours__n, .bword, .intro__word, .catintro__h, h1, h2, h3){
  font-weight:700;
}

/* ------------------------------------------- 4. the Canora cut (signature) */

.cut{ clip-path:polygon(0 0, calc(100% - var(--cut)) 0, 100% var(--cut), 100% 100%, 0 100%) }
.cut-bl{ clip-path:polygon(0 0, 100% 0, 100% 100%, var(--cut) 100%, 0 calc(100% - var(--cut))) }
.cut-tl{ clip-path:polygon(var(--cut) 0, 100% 0, 100% 100%, 0 100%, 0 var(--cut)) }

/* the cut mirrors with writing direction so the geometry stays consistent */
[dir="rtl"] .cut{ clip-path:polygon(var(--cut) 0, 100% 0, 100% 100%, 0 100%, 0 var(--cut)) }
[dir="rtl"] .cut-tl{ clip-path:polygon(0 0, calc(100% - var(--cut)) 0, 100% var(--cut), 100% 100%, 0 100%) }

/* the blue sliver that lights the cut on hover */
.cut-spark{
  position:absolute;top:0;inset-inline-end:0;
  width:var(--cut);height:var(--cut);
  background:linear-gradient(225deg,var(--accent) 0%,transparent 70%);
  opacity:0;transition:opacity var(--dur) var(--ease);
  pointer-events:none;
}
[dir="rtl"] .cut-spark{ background:linear-gradient(135deg,var(--accent) 0%,transparent 70%) }

/* ------------------------------------------------------------- 5. the shell */

.shell{
  width:100%;
  max-width:var(--shell);
  margin-inline:auto;
  padding-inline:var(--gutter);
}

.section{ position:relative; padding-block:clamp(72px,10vw,140px) }
/* The band is the opposite tone to the page around it, so anything inside it
   that reached for the page's own colours landed the wrong way up. The band
   states its own palette once, and everything nested in it inherits correctly
   rather than needing a rule of its own. */
.section--light{
  background:var(--light); color:var(--light-text);
  --accent:var(--light-accent);
}
.section--light .lede{ color:var(--light-muted) }
.section--light .mono-label{ color:var(--light-muted) }
.section--light .kicker--muted{ color:var(--light-muted) }

/* 45 degree section edge, not a horizontal rule */
.section--wedge::before{
  content:"";position:absolute;inset-inline:0;top:0;height:clamp(40px,6vw,90px);
  background:inherit;
  clip-path:polygon(0 0,100% 100%,0 100%);
  transform:translateY(-99%);
  pointer-events:none;
}
[dir="rtl"] .section--wedge::before{ clip-path:polygon(100% 0,100% 100%,0 100%) }

/* --------------------------------------------- 6. the environment layer */
/* one fixed background behind everything, so scrolling feels like a place */

.env{
  position:fixed;inset:0;z-index:0;pointer-events:none;
  background:
    radial-gradient(120% 80% at 18% 12%, var(--env-a), transparent 62%),
    radial-gradient(90% 70% at 86% 88%, var(--env-b), transparent 60%);
  animation:envDrift 96s var(--ease) -22s infinite alternate;
}
.env::after{
  content:"";position:absolute;inset:-50%;opacity:var(--grain,.16);
  background-image:url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)' opacity='.5'/%3E%3C/svg%3E");
}
@keyframes envDrift{
  from{ transform:translate3d(-1.5%,-1%,0) scale(1.04) }
  to  { transform:translate3d(1.5%,1.2%,0) scale(1.09) }
}

.page{position:relative;z-index:1}

/* ------------------------------------------------------------ the stars */
/* Two stacked layers of tiny radial gradients. No DOM nodes, no JavaScript,
   nothing to repaint: the whole field is a background image, so it costs a
   single composited layer and the drift runs on transform alone.
   Slow on purpose. The brief is atmosphere, not sparkle. */

.stars{
  position:fixed;inset:0;z-index:0;pointer-events:none;
  opacity:var(--star-opacity);
}
.stars span{
  position:absolute;inset:-25%;display:block;
  background-repeat:repeat;
  will-change:transform,opacity;
}
/* the far field: many small, faint stars, drifting almost imperceptibly */
.stars .far{
  background-image:
    radial-gradient(1px 1px at 12% 18%,  var(--star-a), transparent),
    radial-gradient(1px 1px at 34% 62%,  var(--star-a), transparent),
    radial-gradient(1px 1px at 57% 27%,  var(--star-b), transparent),
    radial-gradient(1px 1px at 71% 74%,  var(--star-a), transparent),
    radial-gradient(1px 1px at 88% 41%,  var(--star-a), transparent),
    radial-gradient(1px 1px at 22% 85%,  var(--star-b), transparent),
    radial-gradient(1px 1px at 46% 9%,   var(--star-a), transparent),
    radial-gradient(1px 1px at 93% 92%,  var(--star-a), transparent),
    radial-gradient(1px 1px at 5% 48%,   var(--star-b), transparent),
    radial-gradient(1px 1px at 64% 55%,  var(--star-a), transparent);
  background-size:520px 520px;
  animation:starDriftA 240s linear infinite, starBreath 22s ease-in-out -6s infinite alternate;
}
/* the near field: fewer, very slightly larger, drifting the other way */
.stars .near{
  background-image:
    radial-gradient(1.6px 1.6px at 27% 33%, var(--star-a), transparent),
    radial-gradient(1.6px 1.6px at 68% 12%, var(--star-b), transparent),
    radial-gradient(1.6px 1.6px at 83% 68%, var(--star-a), transparent),
    radial-gradient(1.6px 1.6px at 15% 77%, var(--star-a), transparent),
    radial-gradient(1.6px 1.6px at 52% 91%, var(--star-b), transparent);
  background-size:760px 760px;
  opacity:.75;
  animation:starDriftB 340s linear infinite, starBreath 31s ease-in-out -13s infinite alternate;
}
@keyframes starDriftA{
  from{ transform:translate3d(0,0,0) }
  to  { transform:translate3d(-520px,-260px,0) }
}
@keyframes starDriftB{
  from{ transform:translate3d(0,0,0) }
  to  { transform:translate3d(380px,-760px,0) }
}
/* a breath, not a twinkle: the whole field brightens and dims very slowly */
@keyframes starBreath{
  from{ opacity:.55 } to{ opacity:1 }
}
/* the stars sit behind the page, never over the hero footage or a light band */
.stars{ mask-image:linear-gradient(to bottom, transparent 0, #000 55vh) }

/* --------------------------------------------------------------- 7. header */

.nav{
  position:fixed;inset-inline:0;top:0;z-index:100;
  height:var(--nav-h);
  display:flex;align-items:center;
  transition:background var(--dur) var(--ease),
             border-color var(--dur) var(--ease),
             backdrop-filter var(--dur) var(--ease);
  border-bottom:1px solid transparent;
}
.nav.is-stuck{
  background:var(--nav-bg);
  backdrop-filter:blur(14px) saturate(140%);
  border-bottom-color:var(--line);
}
.nav__inner{
  display:flex;align-items:center;gap:clamp(16px,3vw,40px);
  width:100%;max-width:var(--shell);margin-inline:auto;padding-inline:var(--gutter);
}
.brand{display:flex;align-items:center;gap:12px;flex:0 0 auto}
/* Arabic and Kurdish are the only right-to-left languages the site speaks, so
   this rule is theirs alone. The flow would otherwise put the mark on the
   leading edge - the right - and the word to its left; the company reads its
   own lockup the other way round, mark first and then the name, exactly as it
   sits in English. row-reverse restores that without touching the markup, the
   gap or the English layout, and it reaches the footer lockup too, because
   both are the same .brand. */
[dir="rtl"] .brand{flex-direction:row-reverse}
.brand__mark{width:34px;height:auto}
.brand__word{
  font-family:var(--display);
  font-variation-settings:"wdth" 120,"wght" 700;
  font-size:1.06rem;letter-spacing:.13em;text-transform:uppercase;
}
.nav__links{display:flex;align-items:center;gap:clamp(14px,2.2vw,30px);margin-inline-start:auto}
.nav__link{
  position:relative;font-size:.86rem;font-weight:500;
  color:var(--text-secondary);padding-block:6px;
  transition:color var(--dur) var(--ease);
}
.nav__link::after{
  content:"";position:absolute;inset-inline-start:0;bottom:0;
  width:100%;height:1px;background:var(--accent);
  transform:scaleX(0);transform-origin:inline-start;
  transition:transform var(--dur) var(--ease-out);
}
.nav__link:hover,.nav__link[aria-current="page"]{color:var(--text-primary)}
.nav__link:hover::after,.nav__link[aria-current="page"]::after{transform:scaleX(1)}

.langs{display:flex;gap:2px;margin-inline-start:8px}
.lang{
  font-family:var(--mono);font-size:.68rem;letter-spacing:.1em;text-transform:uppercase;
  padding:6px 9px;color:var(--text-tertiary);
  border:1px solid transparent;
  transition:color var(--dur) var(--ease),border-color var(--dur) var(--ease);
}
.lang:hover{color:var(--text-primary);border-color:var(--line-strong)}
.lang.is-on{color:var(--accent);border-color:var(--accent)}

.burger{display:none;width:44px;height:44px;align-items:center;justify-content:center;margin-inline-start:auto}
.burger span{display:block;width:22px;height:2px;background:currentColor;position:relative;transition:transform var(--dur) var(--ease),opacity .2s}
.burger span::before,.burger span::after{
  content:"";position:absolute;inset-inline-start:0;width:22px;height:2px;background:currentColor;
  transition:transform var(--dur) var(--ease);
}
.burger span::before{top:-7px}
.burger span::after{top:7px}
.burger[aria-expanded="true"] span{background:transparent}
.burger[aria-expanded="true"] span::before{transform:translateY(7px) rotate(45deg)}
.burger[aria-expanded="true"] span::after{transform:translateY(-7px) rotate(-45deg)}

/* ---------------------------------------------------------------- 8. buttons */

.btn{
  --btn-bg:var(--panel);
  position:relative;display:inline-flex;align-items:center;justify-content:center;gap:10px;
  padding:15px 26px;
  font-size:.88rem;font-weight:600;letter-spacing:.02em;
  background:var(--btn-bg);
  border:1px solid var(--line-strong);
  color:var(--text-primary);
  clip-path:polygon(0 0, calc(100% - 12px) 0, 100% 12px, 100% 100%, 0 100%);
  transition:background var(--dur) var(--ease),
             border-color var(--dur) var(--ease),
             transform .18s var(--ease-out),
             box-shadow var(--dur) var(--ease);
  will-change:transform;
}
[dir="rtl"] .btn{ clip-path:polygon(12px 0, 100% 0, 100% 100%, 0 100%, 0 12px) }

/* A disabled button is not a control, so it answers the pointer with nothing
   at all and simply holds whatever its variant already looks like. The two
   hover rules below are gated rather than a third rule being added to undo
   them, because undoing would have had to name each variant's own border
   colour back. The enquiry form's submit is the live case: it disables itself
   while the request posts. */
.btn:not([disabled]):not([aria-disabled="true"]):hover{
  border-color:var(--accent); background:var(--panel-2);
}

/* the green is the one primary action and nothing else */
/* This variant restates the transition rather than inheriting the base one.
   It has to: it moves its label colour and it carries a glow, neither of
   which the base .btn has any reason to list. Only the transition is
   restated - the fill, the border and the ink are the same three lines they
   always were, so the resting button is untouched. */
.btn--primary{
  --btn-bg:var(--hot);
  border-color:var(--hot);
  color:var(--hot-ink);
  /* Its own timing, and shorter than var(--dur). Half a second is the right
     length for a section settling into place and far too long for a button
     answering a pointer: the fill was still on its way when the pointer had
     already moved on, which is a large part of why the hover read as nothing
     happening at all. `filter` is in the list because that is what carries
     the glow - see the block below. */
  transition:background .2s var(--ease-out),
             border-color .2s var(--ease-out),
             color .2s var(--ease-out),
             filter .2s var(--ease-out),
             transform .18s var(--ease-out);
}

/* ---------------------------------------------------------------------------
   The green button under the pointer.

   It goes the way everything else on the site goes: away from the ground it
   is standing on. --hot-hover is the one brand green mixed towards white on a
   dark page and towards the ink on a light one, so a single rule reads as a
   lift in one theme and as a deepening in the other. The label stays the dark
   ink it was written in either way - 11:1 on the lifted green, 7:1 on the
   deepened one - and the border follows the fill, so the shape, the cut, the
   weight and the position are pixel for pixel what they were.

   It was an inversion before this: the fill took the ink and the label took
   the green. That is a handsome button and the wrong way round, because on
   the dark theme it made the one primary action DARKER under the pointer,
   which is the opposite of what every other hover on the site does.

   Two guards. A disabled primary - the enquiry form disables its own submit
   while it posts - is not a live control and must not answer the pointer. And
   the whole thing sits behind (hover:hover), because on a touch screen :hover
   latches after a tap and would leave the button stranded until something
   else was tapped.
   --------------------------------------------------------------------------- */
@media (hover:hover){
  .btn--primary:not([disabled]):not([aria-disabled="true"]):hover{
    /* `background` is restated, not just --btn-bg. The base .btn:hover sets
       background to var(--panel-2) DIRECTLY, so a variant that only moved the
       token never reached the property and the green button hovered to panel
       grey - which is what it had been quietly doing. This selector outweighs
       .btn:hover, so naming the property is what makes the fill actually
       land; the token is kept in step for anything that reads it. */
    --btn-bg:var(--hot-hover);
    background:var(--btn-bg);
    border-color:var(--hot-hover);
    color:var(--hot-ink);
    /* The glow is a drop-shadow filter and not a box-shadow. A box-shadow is
       painted outside the border box, and this button's cut corner is a
       clip-path, which throws away everything outside the polygon - so the
       glow was drawn and then clipped off again on every single hover, and
       the only thing left to see was the fill moving one step lighter. That
       is why the hover read as nothing happening. A filter is applied to what
       the element has already painted, clip and all, so the light follows the
       cut shape instead of being cut away by it.

       Two of them: the wide one throws the green onto the page underneath,
       the tight one puts a halo right against the cut edge so the shape reads
       even where the button sits on its own dark ground.

       No transform here. Every one of these buttons is [data-magnet] and the
       script writes an inline translate3d on pointermove, which outranks any
       transform a stylesheet could set - a lift written here would apply for
       one frame and then be overwritten. The magnet is the movement; this
       rule is the colour and the light. */
    filter:drop-shadow(0 8px 20px var(--hot-glow))
           drop-shadow(0 0 2px var(--hot-glow));
  }
}

.btn--ghost{ --btn-bg:transparent; border-color:var(--line-strong) }
/* A ghost button has no fill of its own, so the pointer gives it one: the
   veil, which is white on a dark page and ink on a light one. It was a fixed
   white before, which lifted the button on the dark theme and then lifted it
   again on the light one, where a hover has to press in rather than glow. */
.btn--ghost:not([disabled]):not([aria-disabled="true"]):hover{
  background:var(--hover-veil); border-color:var(--accent);
}

.btn--light{ --btn-bg:var(--light-text); color:var(--light); border-color:var(--light-text) }

/* A shadowed label over footage reads as grime, so buttons opt out - every
   button, not only the ones in a caption band. The rule named .band before,
   which left the phone's static hero and the vehicle hero out: both set
   text-shadow on their body, the buttons inside inherited it, and the green
   button's dark ink came out smeared. A button carries its own fill and its
   own contrast, so it never needs the shadow anywhere. */
.btn{text-shadow:none}

@media (pointer:coarse){
  .btn{ min-height:44px; display:inline-flex; align-items:center; justify-content:center }
}

/* =========================================================================
   9. THE HERO
   A tall pinned region containing a sticky full-viewport stage.
   ========================================================================= */

.hero{ position:relative; height:600vh }          /* scroll range = 500vh */

/* The hero stage stays dark in BOTH themes on purpose: the footage is a night
   shot and the captions are white over measured scrims. Lightening it would
   break the legibility audit and the film at the same time. */
.stage{
  position:sticky;top:0;height:100vh;overflow:hidden;
  background:#141619;
}

.stage__media{position:absolute;inset:0}

/* ---- the footage, mirrored for the languages that read right to left ---- */
/* The film has a direction in it: a dark wall down one side and a lit corridor
   running away down the other. In English the wall is on the left, which is
   where the reading starts and where the captions sit. In Arabic and Kurdish
   the reading starts on the right, so the frame is flipped to put the wall
   there and the captions follow it across.

   The flip is on the media layer, not on the section, so exactly one thing
   mirrors: the picture. The scrims go with it and are symmetrical anyway; the
   loading ring, the captions, the buttons, the navigation and every mark on
   the page are outside it and keep their own orientation - a mirrored logo or
   a backwards word would be a bug, not a translation.

   A horizontal flip is a flip. It does not stretch the frame, so the aspect
   ratio, the object-fit crop and the video's own decode are all untouched, and
   switching language switches nothing but the sign on one axis. */
[dir="rtl"] .stage__media{ transform:scaleX(-1) }
[dir="rtl"] .static-hero__img{ transform:scaleX(-1) }

.poster{
  position:absolute;inset:0;
  background-position:center;background-size:cover;background-repeat:no-repeat;
  transition:opacity .7s var(--ease);
}

#hero-video{
  position:absolute;inset:0;width:100%;height:100%;
  object-fit:cover;
  opacity:0;
  transition:opacity .7s var(--ease);
  transform:translateZ(0);          /* own compositor layer */
  will-change:transform;
}
.stage.video-ready #hero-video{opacity:1}
.stage.video-ready .poster{opacity:0}
.stage.video-failed #hero-video{display:none}

/* legibility layer 1: the global base scrim, always on */
.scrim{
  position:absolute;inset:0;pointer-events:none;
  background:radial-gradient(ellipse 120% 90% at 50% 45%,
    rgba(10,10,18,0) 35%, rgba(10,10,18,.62) 100%);
}
/* a touch of extra floor darkening so the lower content edge never fights */
.scrim--base{
  position:absolute;inset:0;pointer-events:none;
  background:linear-gradient(to bottom, rgba(10,11,14,.45) 0%, rgba(10,11,14,0) 26%,
             rgba(10,11,14,0) 62%, rgba(10,11,14,.55) 100%);
}

/* the loading ring */
.ring{
  position:absolute;inset-block-end:38px;inset-inline-end:38px;
  width:48px;height:48px;color:var(--accent);opacity:.85;
  transform:rotate(-90deg);
  pointer-events:none;
}
.ring circle{transition:stroke-dashoffset .18s linear}
.stage.video-ready .ring{opacity:0;transition:opacity .5s var(--ease)}

.cue{
  position:absolute;inset-block-end:34px;inset-inline-end:34px;
  display:flex;flex-direction:column;align-items:center;gap:6px;
  color:var(--text-tertiary);
}
.cue svg{animation:cueBob 2.6s var(--ease) -0.6s infinite}
@keyframes cueBob{0%,100%{transform:translateY(0)}50%{transform:translateY(5px)}}

/* ---- caption bands -------------------------------------------------- */

.bands{position:absolute;inset:0;pointer-events:none}

.band{
  position:absolute;
  opacity:0;
  text-shadow:var(--tshadow);
  will-change:opacity;
}
.band > *{position:relative;z-index:1}

/* legibility layer 2: the per-band scrim, riding the band's own --k.
   Sized to actually cover its own text box: the audit measures the worst pixel
   inside that box, and a scrim that dies out before the box edge fails there. */
.band::before{
  content:"";position:absolute;inset:-60% -55%;pointer-events:none;z-index:0;
  opacity:calc(.25 + .75 * var(--k,1));
  background:radial-gradient(ellipse 70% 62% at 50% 50%,
    rgba(5,5,10,var(--peak,.66)) 0%,
    rgba(5,5,10,calc(var(--peak,.66) * .86)) 40%,
    rgba(5,5,10,calc(var(--peak,.66) * .42)) 60%,
    rgba(5,5,10,0) 72%);
}

/* Bands live in the footage's calm space, and that space MOVES as the camera
   descends: the wall fills the left early, then shrinks up and left as the lit
   rows sweep in. So each band carries its own top and width, set from the
   frames it actually sits on. Band 4 centres for the settle. */
/* PHYSICAL left in English, because the calm dark wall the captions need is on
   the left of the frame, and inset-inline-start would have moved them onto the
   lit corridor the moment the page went right to left. */
.band--left{
  left:var(--gutter);
  inset-block-start:var(--top, 26vh);
  max-width:min(var(--w, 640px), 52vw);
}
/* Arabic and Kurdish read from the right, so the captions belong on the right
   of the frame - and they can be there, because the frame goes with them: the
   footage is mirrored for these two languages, which puts the calm dark wall
   on the right where the reading now starts. The captions are on the wall in
   every language, which is what the legibility audit measures, and neither the
   footage nor the type is distorted by it: a horizontal flip is a flip, not a
   stretch.

   The box is given a real width rather than being left to shrink-wrap. Without
   one, an absolutely positioned band is only as wide as its own longest line,
   and "start" then lands wherever that line happened to end - three captions
   beginning at three different places as the reader scrolls. Given a real box
   they all begin on the same edge. The width is the narrowest of the three
   safe widths, so every caption is inside every band's safe area rather than
   only its own. */
[dir="rtl"] .band--left{
  left:auto;
  right:var(--gutter);
  width:min(520px, 52vw);
  max-width:min(520px, 52vw);
  text-align:right;
}
/* The row of buttons under the settle caption is centred, and stays centred.
   These are the two captions that are not. */
[dir="rtl"] .band--left .band__cta{ justify-content:flex-start }
[dir="rtl"] .band--left .band__sub{ margin-inline-start:0 }

.band--settle{
  inset-inline:0;
  inset-block-start:20vh;
  display:flex;flex-direction:column;align-items:center;text-align:center;
  padding-inline:var(--gutter);
}
.band--settle::before{ inset:-10% 8% }

.band__line{
  font-family:var(--display);
  font-variation-settings:"wdth" 116,"wght" 700;
  text-transform:uppercase;
  font-size:clamp(2rem,1.1rem + 4.1vw,5rem);
  line-height:.98;
  letter-spacing:-.012em;
  margin:0;
}
.band--settle .band__line{ font-size:clamp(2.6rem,1.2rem + 6vw,7rem); font-variation-settings:"wdth" 122,"wght" 700 }

.band__sub{
  margin-top:22px;
  font-size:clamp(1rem,.95rem + .4vw,1.22rem);
  color:#dfe5ea;
  max-width:44ch;
}
.band--settle .band__sub{margin-inline:auto}

.band__cta{
  display:flex;flex-wrap:wrap;gap:14px;justify-content:center;
  margin-top:34px;
  pointer-events:auto;
}

/* small text over footage gets a chip, never the big radial */
.chip{
  display:inline-flex;align-items:center;gap:9px;
  background:rgba(8,8,15,.55);
  border:1px solid rgba(96,96,126,.34);
  padding:7px 13px;
  backdrop-filter:blur(10px);
  text-shadow:0 1px 3px rgba(5,5,10,.85);
  font-family:var(--mono);font-size:.68rem;letter-spacing:.14em;text-transform:uppercase;
  color:#cdd6dd;
}
.chip__dot{width:6px;height:6px;background:var(--hot);border-radius:50%}

/* ---- text choreography --------------------------------------------- */
/* transform and opacity only, scrubbed off the band's --k, reversible */

.band .w{display:inline-block;white-space:nowrap}
.band .c{display:inline-block;will-change:transform,opacity}

/* (a) scatter */
.e-scatter .c{
  --kc:clamp(0,(var(--k,0) - var(--th,0)) * 2.6,1);
  opacity:var(--kc);
  transform:translate(calc((1 - var(--kc)) * var(--jx,0px)),
                      calc((1 - var(--kc)) * var(--jy,0px)))
            rotate(calc((1 - var(--kc)) * var(--jr,0deg)));
}
/* (b) grid snap-align: ordered threshold, horizontal only */
.e-grid .c{
  --kc:clamp(0,(var(--k,0) - var(--th,0)) * 3,1);
  opacity:var(--kc);
  transform:translateX(calc((1 - var(--kc)) * var(--jx,0px)));
}
/* (h) halves parting */
.e-halves .half{
  display:inline-block;
  --kc:clamp(0,(var(--k,0) - var(--th,0)) * 2.4,1);
  opacity:var(--kc);
  transform:translateX(calc((1 - var(--kc)) * var(--jx,0px)));
}
/* (c) blur-to-sharp: two stacked copies, static blur, crossfade by opacity */
.e-blur{position:relative}
/* ...but never on a band. A band is absolutely positioned into the calm space
   of the frame, and position:relative dropped it back into normal flow, where
   `left` stops placing it and starts nudging it. In English that landed close
   enough to look right; in Arabic and Kurdish normal flow starts at the RIGHT
   edge, so the nudge pushed the caption a whole gutter off the screen and the
   line was cut in half. The band is already a containing block for .soft. */
.band.e-blur{position:absolute}
.e-blur .soft{
  position:absolute;inset:0;
  filter:blur(10px);
  opacity:calc(1 - var(--k,0));
  pointer-events:none;
}
.e-blur .sharp{opacity:var(--k,0)}
/* (e) word-by-word rise into a staged settle */
.e-rise .w{
  --kc:clamp(0,(var(--k,0) - var(--th,0)) * 2.6,1);
  opacity:var(--kc);
  transform:translateY(calc((1 - var(--kc)) * 26px));
}
.e-rise .band__sub{
  --ks:clamp(0,(var(--k,0) - .66) * 4,1);
  opacity:var(--ks);
  transform:translateY(calc((1 - var(--ks)) * 16px));
}
.e-rise .band__cta{
  --kb:clamp(0,(var(--k,0) - .78) * 5,1);
  opacity:var(--kb);
  transform:translateY(calc((1 - var(--kb)) * 14px));
}

/* ================================================= 10. the static hero */
/* Five gates. These five queries must match the JS strings exactly. */

.static-hero{display:none;position:relative;min-height:100svh;overflow:hidden}
.static-hero__img{
  position:absolute;inset:0;width:100%;height:100%;object-fit:cover;
}
.static-hero__body{
  position:relative;z-index:2;
  min-height:100svh;display:flex;flex-direction:column;justify-content:flex-end;
  padding:calc(var(--nav-h) + 32px) var(--gutter) clamp(48px,10vw,90px);
  text-shadow:var(--tshadow);
}
.static-hero__scrim{
  position:absolute;inset:0;z-index:1;pointer-events:none;
  background:linear-gradient(to bottom,
    rgba(10,11,14,.55) 0%, rgba(10,11,14,.18) 34%,
    rgba(10,11,14,.72) 78%, rgba(10,11,14,.93) 100%);
}
.static-hero__line{
  font-family:var(--display);
  font-variation-settings:"wdth" 114,"wght" 700;
  text-transform:uppercase;
  font-size:clamp(2.1rem,1.1rem + 6.4vw,4rem);
  line-height:.99;margin:18px 0 0;
}
.static-hero__sub{margin-top:18px;font-size:1.1rem;font-weight:500;color:#e6ebef;max-width:34ch}
.static-hero__cta{display:flex;flex-wrap:wrap;gap:12px;margin-top:28px}

@media (max-width: 720px),
       (orientation: portrait) and (max-width: 1024px),
       (orientation: portrait) and (pointer: coarse),
       (orientation: landscape) and (pointer: coarse) and (max-height: 560px),
       (prefers-reduced-motion: reduce){
  .hero{display:none}
  .static-hero{display:block}
}

/* ---- light theme: the hero keeps its dark-mode type ------------------ */
/* The stage and the static hero are dark in BOTH themes (see .stage above),
   so the captions over them must stay light in both themes too. Light mode
   would otherwise inherit the page's near-black --text-primary and drop dark
   type onto night footage. Colour only, scoped to the two hero containers:
   the footage, the scrims, the type, the motion and the layout are untouched,
   and dark mode never sees this rule. */
/* The vehicle hero belongs in this list for exactly the same reason. It is a
   scrimmed photograph or the dark placeholder stage, never the page canvas, so
   in light mode it was landing near-black type - the model name, the back
   link, the ghost button - onto a dark picture. The whole dark palette is
   restated rather than two tokens of it, so every borrowed colour inside these
   regions (borders, the accent, the panel behind a chip) lands the right way
   up instead of needing a rule of its own later. */
:root[data-theme="light"] .stage,
:root[data-theme="light"] .static-hero,
:root[data-theme="light"] .vhero{
  --text-primary:  #f1f4f6;
  --text-secondary:#b6bfc7;
  --text-tertiary: #8a939c;
  --accent:        var(--accent-bright);
  --accent-page:   var(--accent-bright);
  --accent-muted:  rgba(77,153,206,.16);
  --accent-glow:   rgba(77,153,206,.40);
  --line:          #333a41;
  --line-strong:   #4a535c;
  --panel:         #21252a;
  --panel-2:       #2a2f35;
  --badge-bg:      rgba(8,10,13,.72);
  color:var(--text-primary);
}

/* The navigation has the same problem for the same reason. Before it sticks it
   has no background of its own and floats directly on the footage, so in light
   mode it was putting near-black type and a near-black wordmark onto a night
   shot. It reads as dark-on-dark, which is exactly what it is.

   So while it is still transparent over a dark hero it keeps the dark theme's
   type, and the moment it sticks - and gains its light background - the normal
   light palette takes over again. Colour only. The scroll behaviour, the
   layout and the stick threshold are untouched, and only pages that actually
   have a hero carry .has-dark-hero. */
:root[data-theme="light"] .has-dark-hero .nav:not(.is-stuck){
  --text-primary:  #f1f4f6;
  --text-secondary:#b6bfc7;
  --text-tertiary: #8a939c;
  --accent:        #4d99ce;
  --line-strong:   #4a535c;
  color:var(--text-primary);
}

/* scrub-capable but short: keep the scrub, drop overlays with no room */
@media (max-height:560px){ .cue,.ring{display:none} }

/* ==================================================== 11. entrances */

.reveal{opacity:0;transform:translateY(26px);
  transition:opacity var(--dur-slow) var(--ease-out),transform var(--dur-slow) var(--ease-out)}
.reveal.in{opacity:1;transform:none}

.stagger .s-item{opacity:0;transform:translateY(22px);
  transition:opacity var(--dur-slow) var(--ease-out),transform var(--dur-slow) var(--ease-out)}
.stagger.in .s-item{opacity:1;transform:none}
.stagger.in .s-item:nth-child(1){transition-delay:0ms}
.stagger.in .s-item:nth-child(2){transition-delay:80ms}
.stagger.in .s-item:nth-child(3){transition-delay:160ms}
.stagger.in .s-item:nth-child(4){transition-delay:240ms}
.stagger.in .s-item:nth-child(5){transition-delay:320ms}
.stagger.in .s-item:nth-child(6){transition-delay:400ms}
/* retire the delays once the entrance is done, at matching specificity,
   or every later hover lags by the stagger forever */
.stagger.in.done .s-item:nth-child(1),
.stagger.in.done .s-item:nth-child(2),
.stagger.in.done .s-item:nth-child(3),
.stagger.in.done .s-item:nth-child(4),
.stagger.in.done .s-item:nth-child(5),
.stagger.in.done .s-item:nth-child(6){transition-delay:0s}

/* ============================================ 12. the vehicle card (3D) */

.grid-cards{
  display:grid;gap:clamp(16px,2vw,26px);
  grid-template-columns:repeat(auto-fill,minmax(min(100%,300px),1fr));
}

.vcard{
  position:relative;
  background:var(--panel);
  border:1px solid var(--line);
  transform-style:preserve-3d;
  transition:border-color var(--dur) var(--ease),
             box-shadow var(--dur) var(--ease),
             transform .35s var(--ease-out);
  will-change:transform;
}
.vcard::after{                         /* the cut */
  content:"";position:absolute;inset:0;pointer-events:none;
}
.vcard:hover{
  border-color:var(--line-strong);
  box-shadow:var(--card-shadow), 0 0 0 1px var(--accent-muted);
}
.vcard:hover .cut-spark{opacity:.9}

/* the layered stage: floor shadow, rim light, subject, grain */
.vstage{
  position:relative;
  aspect-ratio:16/10;
  overflow:hidden;
  background:
    radial-gradient(90% 70% at 50% 118%, var(--card-floor), transparent 62%),
    radial-gradient(70% 55% at 50% 24%, rgba(77,153,206,.13), transparent 68%),
    var(--card-stage);
}
.vstage__img{
  position:absolute;inset:0;width:100%;height:100%;object-fit:cover;
  transition:transform .55s var(--ease-out);
  will-change:transform;
}
.vstage__rim{
  position:absolute;inset:0;pointer-events:none;
  background:radial-gradient(58% 44% at var(--rx,50%) var(--ry,26%),
    rgba(77,153,206,.20), transparent 70%);
  transition:opacity var(--dur) var(--ease);
  opacity:.75;
}
.vstage__floor{
  position:absolute;inset-inline:8%;bottom:5%;height:16%;
  background:radial-gradient(ellipse at center, var(--card-floor), transparent 72%);
  filter:blur(7px);pointer-events:none;
  transition:transform .55s var(--ease-out);
}
.vcard:hover .vstage__img{transform:scale(1.055)}
.vcard:hover .vstage__rim{opacity:1}

/* the designed placeholder, for vehicles with no photo yet */
.vplaceholder{
  position:absolute;inset:0;display:grid;place-items:center;
  background:
    radial-gradient(70% 55% at 50% 28%, rgba(77,153,206,.10), transparent 70%),
    var(--card-stage);
}
.vplaceholder svg{width:58%;height:auto;color:var(--line-strong);opacity:.85}
.vplaceholder__tag{
  position:absolute;inset-block-end:14px;inset-inline-start:16px;
  font-family:var(--mono);font-size:.62rem;letter-spacing:.16em;text-transform:uppercase;
  color:var(--text-tertiary);
}

.vcard__body{padding:20px}
.vcard__brand{
  font-family:var(--mono);font-size:.66rem;letter-spacing:.16em;text-transform:uppercase;
  color:var(--accent);
}
.vcard__model{
  font-family:var(--display);
  font-variation-settings:"wdth" 112,"wght" 700;
  text-transform:uppercase;
  font-size:1.16rem;line-height:1.08;margin-top:8px;
}
.vcard__meta{
  display:flex;flex-wrap:wrap;gap:6px 14px;margin-top:14px;
  font-family:var(--mono);font-size:.74rem;font-weight:500;letter-spacing:.05em;color:var(--text-tertiary);
}
.vcard__meta span{display:inline-flex;align-items:center;gap:6px}
.vcard__meta span::before{content:"";width:3px;height:3px;background:var(--line-strong);border-radius:50%}

.vcard__link{position:absolute;inset:0;z-index:3}
.vcard__link:focus-visible{outline-offset:-3px}

.badge{
  position:absolute;top:14px;inset-inline-start:14px;z-index:2;
  font-family:var(--mono);font-size:.6rem;letter-spacing:.16em;text-transform:uppercase;
  padding:5px 9px;background:var(--badge-bg);border:1px solid var(--accent);
  color:var(--accent);backdrop-filter:blur(6px);
}

/* no tilt where a pointer cannot hover, and none under reduced motion */
@media (pointer:coarse){ .vcard{transform:none !important} }

/* =========================================== 13. the interactive moment */

/* The showroom sits inside the contrast band but keeps the PAGE's surface -
   a dark stage inset into the light band, and a light one inset into the dark
   band. That is deliberate, and it means the band's flipped text colour is the
   wrong way up in here: it was landing #1a1d20 type on a #1a1d20 panel in dark
   mode and #f1f4f6 on #ffffff in light, so the questions and their answers
   were invisible in both. The page palette comes back for everything inside. */
.widen{
  position:relative;
  margin-top:44px;
  border:1px solid var(--line);
  background:var(--canvas-2);
  color:var(--text-primary);
  --accent:var(--accent-page);
  overflow:hidden;
  user-select:none;
  -webkit-user-select:none;
}
.widen__stage{
  position:relative;height:clamp(190px,26vw,290px);overflow:hidden;
  display:grid;place-items:center;
}
.widen__wall{
  position:absolute;top:0;bottom:0;width:36%;
  background:var(--wall);
  border-inline-end:1px solid var(--line-strong);
  transition:transform .12s linear;
  will-change:transform;
}
.widen__wall--l{inset-inline-start:0;transform:translateX(calc(var(--p,0) * -104%))}
.widen__wall--r{inset-inline-end:0;border-inline-end:0;border-inline-start:1px solid var(--line-strong);
  transform:translateX(calc(var(--p,0) * 104%))}
.widen__cars{
  display:flex;align-items:flex-end;gap:10px;justify-content:center;
  padding-inline:14px;
}
.widen__car{
  width:34px;height:20px;flex:0 0 auto;
  background:var(--line-strong);
  clip-path:polygon(0 100%,10% 44%,30% 20%,70% 20%,90% 44%,100% 100%);
  opacity:0;transform:translateY(10px);
  transition:opacity .35s var(--ease),transform .35s var(--ease-out);
}
.widen__car.on{opacity:.9;transform:none}
.widen__car.on:nth-child(3n){background:var(--accent);opacity:.55}
.widen__readout{
  position:absolute;inset-block-end:12px;inset-inline-start:16px;z-index:3;
  font-family:var(--mono);font-size:.72rem;letter-spacing:.12em;color:var(--accent);
}
.widen__hold{
  position:absolute;inset-block-end:12px;inset-inline-end:16px;z-index:3;
  font-family:var(--mono);font-size:.68rem;letter-spacing:.14em;text-transform:uppercase;
  color:var(--text-tertiary);
}
.widen__bar{
  position:absolute;inset-inline:0;bottom:0;height:2px;background:var(--accent);
  transform-origin:inline-start;transform:scaleX(var(--p,0));
  transition:transform .12s linear;
}
.widen__answers{display:grid;gap:1px;background:var(--line);margin-top:1px}
.widen__answer{
  background:var(--canvas-2);padding:22px;
  opacity:0;transform:translateY(14px);
  transition:opacity .6s var(--ease-out),transform .6s var(--ease-out);
}
/* NOT ".done": the entrance system uses that class to retire stagger delays,
   and the two collided, which revealed the answers before anyone pressed.

   NOT the hold state either. This class is the one-way door: the first hold
   that reaches the end puts it on and nothing ever takes it off, so the three
   answers stay up while the walls behind them are opened and closed as many
   times as anyone likes. The hold itself is carried entirely by --p. */
.widen.is-revealed .widen__answer{opacity:1;transform:none}
.widen.is-revealed .widen__answer:nth-child(2){transition-delay:120ms}
.widen.is-revealed .widen__answer:nth-child(3){transition-delay:240ms}
.widen__q{font-weight:600;font-size:1.1rem;margin-bottom:10px}
.widen__a{color:var(--text-secondary);font-size:1.03rem;font-weight:600;line-height:1.68;max-width:54ch}

@media (min-width:820px){ .widen__answers{grid-template-columns:repeat(3,minmax(0,1fr))} }

/* =============================================== 14. the route line (SVG) */

.route-wrap{position:relative}

.route{position:absolute;pointer-events:none;overflow:visible}
.route path{
  fill:none;stroke:var(--accent);stroke-width:1.5;opacity:.5;
  stroke-dasharray:var(--len,1200);
  stroke-dashoffset:calc(var(--len,1200) * (1 - var(--draw,0)));
}

/* The line takes the shape the steps are actually in, and the breakpoint it
   turns on is the steps' own - not a guess about the device. A row gets a line
   across the top of it; a column gets one running down beside it, from step
   one to step four. Both are in the DOM and both are measured; the one the
   layout is not using is hidden rather than removed, so a phone turned on its
   side has the other already drawn and nothing has to be re-armed. */
.route--h{ inset-inline:0;top:-26px;height:40px }
/* height is stated rather than left to a second inset: an <svg> is a replaced
   element, and one given a width and left to size itself takes the height its
   own viewBox asks for - 30 times the width here - rather than the box it was
   told to stretch to. */
.route--v{ inset-inline-start:0;top:0;width:24px;height:100% }
@media (max-width:899.98px){
  .route--h{ visibility:hidden }
  /* the room the vertical line stands in, beside the column */
  .steps{ padding-inline-start:44px }
}
@media (min-width:900px){ .route--v{ visibility:hidden } }

/* Non-uniform scaling thins a near-vertical stroke by the box's horizontal
   scale, which for a 40-unit viewBox drawn 24px wide is .6 - so the vertical
   line is authored at the width that lands on the same hairline the row's
   line does. */
.route--v path{ stroke-width:2.5 }

/* Right to left, the line travels the way the steps do: step one is on the
   right, so the line starts there and runs to the left. Mirroring the box
   rather than rewriting the path turns the drawing with it - the path's start
   point is the right-hand end, so it still draws from step one - and it does
   the same for the vertical line, which keeps its lean on the correct side of
   a column that now sits against the right edge. */
html[dir="rtl"] .route{ transform:scaleX(-1) }

.steps{display:grid;gap:clamp(20px,3vw,34px);position:relative}
@media (min-width:900px){ .steps{grid-template-columns:repeat(4,minmax(0,1fr))} }
.step{position:relative;padding-top:30px}
.step__n{
  font-family:var(--mono);font-size:.7rem;letter-spacing:.18em;color:var(--accent);
  position:absolute;top:0;inset-inline-start:0;
}
.step__t{
  font-family:var(--display);font-variation-settings:"wdth" 110,"wght" 700;
  text-transform:uppercase;font-size:1.06rem;line-height:1.1;margin-bottom:10px;
}
.step__d{color:var(--text-secondary);font-size:1.03rem;font-weight:600;line-height:1.65;max-width:36ch}

/* ================================================== 15. stats and marquee */

.stats{display:grid;gap:1px;background:var(--line);border:1px solid var(--line)}
@media (min-width:760px){ .stats{grid-template-columns:repeat(3,minmax(0,1fr))} }
.stat{background:var(--canvas-2);padding:clamp(22px,3vw,34px)}
.section--light .stats{background:var(--light-line);border-color:var(--light-line)}
.section--light .stat{background:var(--light)}
.stat__v{
  font-family:var(--display);font-variation-settings:"wdth" 118,"wght" 700;
  font-size:clamp(1.7rem,1rem + 2.4vw,2.8rem);line-height:1;
}
.stat__l{margin-top:10px}

.rail{display:flex;gap:clamp(10px,1.6vw,18px);overflow-x:auto;scroll-snap-type:x mandatory;
  padding-bottom:8px;scrollbar-width:thin}
.rail > *{flex:0 0 min(78vw,320px);scroll-snap-align:start}
@media (min-width:900px){
  .rail{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));overflow:visible}
  .rail > *{flex:initial}
}

.logowall{display:grid;gap:1px;background:var(--line);border:1px solid var(--line)}
@media (min-width:560px){ .logowall{grid-template-columns:repeat(3,minmax(0,1fr))} }
@media (min-width:900px){ .logowall{grid-template-columns:repeat(5,minmax(0,1fr))} }
.logowall__i{
  background:var(--canvas-2);aspect-ratio:16/9;
  display:grid;place-items:center;align-content:center;gap:8px;padding:18px;
  text-align:center;
  transition:background var(--dur) var(--ease);
}
.logowall__i:hover{background:var(--panel-2)}
.logowall__i img{max-height:44px;width:auto;opacity:.6;
  transition:filter var(--dur) var(--ease),opacity var(--dur) var(--ease)}
.logowall__i:hover img{opacity:1}
/* Hovering shows the mark as its owner drew it, and then moves it off the
   ground it is standing on - because a brand's own colours land wherever they
   land, and simply dropping the treatment left a dark mark darker still on
   the dark theme. Only the automatic treatment has anything to drop. */
.logowall__i:hover .blogo--auto{filter:var(--logo-filter-hi)}
.logowall__t{
  font-family:var(--display);font-variation-settings:"wdth" 112,"wght" 700;
  text-transform:uppercase;font-size:1rem;color:var(--text-tertiary);
  transition:color var(--dur) var(--ease);
}
.logowall__i:hover .logowall__t{color:var(--text-primary)}
/* Show more. The categories taken off the homepage row wait at the end of the
   wall, hidden, and come in under the button. The tile's own display would
   otherwise beat the hidden attribute. */
.logowall__i[hidden]{display:none}
.logowall__i.is-shown{animation:pageIn .5s var(--ease-out) both}
.logowall__more{display:flex;justify-content:center;margin-top:22px}

/* The catalogue, browsing one category: its name and what it is, standing on
   a blue rule at the reading edge of the header. */
.catintro{
  margin-top:clamp(22px,3vw,34px);
  padding-inline-start:18px;
  border-inline-start:2px solid var(--accent);
  max-width:70ch;
}
.catintro__h{
  font-family:var(--display);font-variation-settings:"wdth" 112,"wght" 700;
  text-transform:uppercase;font-size:clamp(1.2rem,1rem + .9vw,1.6rem);line-height:1.1;
}
.catintro__d{margin-top:10px}

/* ==================================================== 16. filters + forms */

.field{display:block;margin-bottom:16px}
.field__l{display:block;font-family:var(--mono);font-size:.73rem;letter-spacing:.14em;
  text-transform:uppercase;color:var(--text-tertiary);margin-bottom:8px}
.input,.select,.textarea{
  width:100%;padding:13px 15px;
  background:var(--canvas-2);
  border:1px solid var(--line-strong);
  color:var(--text-primary);
  transition:border-color var(--dur) var(--ease),background var(--dur) var(--ease);
}
.input:focus,.select:focus,.textarea:focus{border-color:var(--accent);outline:none;background:var(--panel)}
.textarea{min-height:118px;resize:vertical}
.select{appearance:none;
  background-image:var(--select-arrow);
  background-repeat:no-repeat;background-position:right 14px center;padding-inline-end:38px}
[dir="rtl"] .select{background-position:left 14px center}
/* A field that has nothing to offer is hidden with the attribute, and the
   display above was overriding it: the trim and colour selects stood empty
   under every request form before a vehicle was even chosen. */
.field[hidden]{display:none}

/* ---- the vehicle box: the catalogue and its search in one ----------- */
/* It looks like the select it replaced - the same box, the same arrow - and
   opens into a list in the form's own panel colours. */
.vpick{position:relative}
.vpick__box{position:relative}
.vpick__q{
  background-image:var(--select-arrow);
  background-repeat:no-repeat;background-position:right 14px center;padding-inline-end:44px;
  text-overflow:ellipsis;
}
[dir="rtl"] .vpick__q{background-position:left 14px center}
.vpick.has-pick .vpick__q,.vpick__q:focus:not(:placeholder-shown){background-image:none}
.vpick__q::placeholder{color:var(--text-tertiary);opacity:1}
.vpick__x{
  position:absolute;top:50%;inset-inline-end:5px;transform:translateY(-50%);
  width:36px;height:36px;display:grid;place-items:center;color:var(--text-tertiary);
  transition:color var(--dur) var(--ease);
}
.vpick__x:hover{color:var(--text-primary)}
.vpick__x[hidden]{display:none}
.vpick__list{
  position:absolute;z-index:30;inset-inline:0;top:calc(100% + 4px);
  max-height:min(320px,48vh);overflow-y:auto;overscroll-behavior:contain;
  margin:0;padding:6px 0;list-style:none;
  background:var(--panel);
  border:1px solid var(--line-strong);
  box-shadow:var(--card-shadow);
}
.vpick__list[hidden]{display:none}
.vpick__o{
  padding:10px 15px;cursor:pointer;
  color:var(--text-secondary);font-size:.98rem;font-weight:600;line-height:1.4;
  border-inline-start:2px solid transparent;
}
html[dir="rtl"] .vpick__o{line-height:1.7}
.vpick__o.is-active{background:var(--panel-2);color:var(--text-primary);border-inline-start-color:var(--accent)}
.vpick__o[aria-selected="true"]{color:var(--accent)}
.vpick__none{padding:10px 15px 4px;color:var(--text-tertiary);font-size:.92rem;line-height:1.5}
.vpick__o--use{color:var(--accent)}
.vpick__more{
  display:inline-block;margin:0 0 16px;padding:2px 0;text-align:start;
  color:var(--accent);font-size:.92rem;font-weight:600;line-height:1.5;
  text-decoration:underline;text-underline-offset:4px;text-decoration-thickness:1px;
}
.vpick__more:hover{color:var(--text-primary)}
.vpick__more[hidden]{display:none}
/* On paper the deepened blue lands at 4.2:1 on the canvas - under the line
   for text this size - so the link takes the hover blue, which clears it. */
:root[data-theme="light"] .vpick__more{color:var(--accent-hover)}

.filters{display:grid;gap:12px}
@media (min-width:700px){ .filters{grid-template-columns:repeat(3,minmax(0,1fr))} }
@media (min-width:1080px){ .filters{grid-template-columns:repeat(4,minmax(0,1fr))} }

.filterbar{
  position:sticky;top:var(--nav-h);z-index:40;
  background:var(--nav-bg);backdrop-filter:blur(12px);
  border-bottom:1px solid var(--line);
  padding-block:16px;
}

/* ---- the bar folds ---------------------------------------------------- */
/* Sticky means the bar is there for every scroll of the catalogue, and on a
   phone that was a third of the screen spent on a form while the visitor was
   looking at cars. So the bar is in two halves. .filterbar__bar - what is
   filtering, how many cars, the way back into the filters - never leaves.
   .filterbar__fold - the search, the sort, and on a wide screen the eight
   selects - rolls up the moment the bar pins itself under the navigation, and
   unrolls at the top of the page or on the chip.

   The fold is tied to the pin rather than to a scroll distance: at the moment
   it happens the bar is exactly where it sits in the page, so the cards below
   simply close the gap and nothing jumps under the reader. catalog.js measures
   the two heights into --fold-h and --filters-h so the roll runs to the real
   height rather than to a guess, and visibility follows the roll so a folded
   field is out of the tab order rather than invisibly in it. */
.filterbar__row{display:flex;flex-wrap:wrap;gap:12px;align-items:flex-end}
.filterbar__fold{
  flex:1 1 440px;min-width:0;
  display:flex;flex-wrap:wrap;gap:12px;align-items:flex-end;
}
.filterbar__fold .field{margin-bottom:0;min-width:0}
.filterbar__fold .field:first-child{flex:1 1 240px}
.filterbar__fold .field:last-child{flex:0 1 200px}
.filterbar__bar{flex:1 1 auto;display:flex;flex-wrap:wrap;gap:12px;align-items:center}

.filterbar__fold,.filterbar .filters{
  overflow:hidden;
  transition:max-height .4s var(--ease),opacity .28s var(--ease),visibility 0s;
}
.filterbar__fold{max-height:var(--fold-h,400px)}
.filterbar .filters{max-height:var(--filters-h,900px);margin-top:16px}

.filterbar.is-folded .filterbar__fold,
.filterbar.is-folded .filters{
  max-height:0;opacity:0;visibility:hidden;margin-top:0;
  transition:max-height .4s var(--ease),opacity .2s var(--ease),
             margin-top .4s var(--ease),visibility 0s linear .4s;
}
.filterbar.is-folded .filterbar__fold{flex-basis:0;flex-grow:0}

/* The mark catalog.js watches to know the bar has pinned. One pixel, pulled
   back out of the flow so it adds nothing to the page. */
.filterbar__mark{height:1px;margin-bottom:-1px}

@media (max-width:699px){
  .filterbar__fold{display:grid;gap:12px}
  .filterbar__bar{gap:10px}
  .chipbtn__t{max-width:11ch}
}

@media (prefers-reduced-motion: reduce){
  .filterbar__fold,.filterbar .filters,
  .filterbar.is-folded .filterbar__fold,
  .filterbar.is-folded .filters,
  .chipbtn--fold .chipbtn__caret{transition:none}
}

.results{transition:opacity .3s var(--ease)}
.results.is-loading{opacity:.35}

.chipbtn{
  display:inline-flex;align-items:center;gap:8px;
  padding:9px 14px;border:1px solid var(--line-strong);
  font-family:var(--mono);font-size:.72rem;letter-spacing:.1em;text-transform:uppercase;
  color:var(--text-secondary);
  transition:border-color var(--dur) var(--ease),color var(--dur) var(--ease),background var(--dur) var(--ease);
}
.chipbtn:hover{border-color:var(--accent);color:var(--text-primary)}
.chipbtn.is-on{background:var(--accent-muted);border-color:var(--accent);color:var(--text-primary)}

/* The chip that folds it by hand: a caret pointing at what pressing it does,
   and, while the search is folded away, the words being searched for. */
.chipbtn--fold{max-width:100%}
.chipbtn--fold .chipbtn__caret{flex:0 0 auto;transition:transform var(--dur) var(--ease)}
.chipbtn--fold[aria-expanded="true"] .chipbtn__caret{transform:rotate(180deg)}
.chipbtn__t{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:18ch}

/* mobile filter drawer */
.drawer{
  position:fixed;inset:0;z-index:120;display:none;
}
.drawer.is-open{display:block}
.drawer__veil{position:absolute;inset:0;background:var(--veil);backdrop-filter:blur(3px)}
.drawer__panel{
  position:absolute;inset-inline:0;bottom:0;max-height:86vh;overflow-y:auto;
  background:var(--canvas-2);border-top:1px solid var(--line);
  padding:22px var(--gutter) 30px;
  transform:translateY(100%);
  transition:transform .42s var(--ease-out);
}
.drawer.is-open .drawer__panel{transform:none}

/* =========================================================== 17. footer */

.footer{
  background:var(--canvas-2);
  border-top:1px solid var(--line);
  padding-block:clamp(50px,7vw,84px) 34px;
}
.footer__grid{display:grid;gap:clamp(28px,4vw,52px)}
@media (min-width:820px){ .footer__grid{grid-template-columns:minmax(0,1.4fr) minmax(0,1fr) minmax(0,1fr) minmax(0,1.2fr)} }
.footer__h{font-family:var(--mono);font-size:.73rem;letter-spacing:.16em;text-transform:uppercase;
  color:var(--text-tertiary);margin-bottom:14px}
.footer a{color:var(--text-secondary);transition:color var(--dur) var(--ease)}
/* full strength, not the accent: the blue is darker than secondary text on
   the dark theme and lighter than it on the light one, so a link that hovered
   to it moved with the page in both. This is the pair the navigation, the
   spec nav, the chips, the trims and the swatches already use. */
.footer a:hover{color:var(--text-primary)}
/* The details a visitor reaches us through - the WhatsApp numbers, the email,
   the handle and the address's map link - answer the pointer in the company's
   own blue: #4d99ce exactly, the blue of the mark, in both themes, with a halo
   kept well short of a glow. Only those links carry the class, so the footer's
   navigation, its headings, its logo and everything outside the footer keep
   the hover they had. */
.footer .footer__contact,
.footer .footer__contact .footer__addr{
  transition:color var(--dur) var(--ease),text-shadow var(--dur) var(--ease);
}
.footer .footer__contact:hover,
.footer .footer__contact:focus-visible,
.footer .footer__contact:hover .footer__addr,
.footer .footer__contact:focus-visible .footer__addr{
  color:var(--accent-bright);
  text-shadow:0 0 14px rgba(77,153,206,.35);
}
.footer__base{
  margin-top:clamp(34px,5vw,56px);padding-top:22px;border-top:1px solid var(--line);
  display:flex;flex-wrap:wrap;gap:14px;justify-content:space-between;
  font-size:.86rem;font-weight:500;color:var(--text-tertiary);
}

/* ======================================= 18. vehicle detail page pieces */

.vhero{position:relative;min-height:74svh;display:flex;align-items:flex-end;overflow:hidden}
.vhero__stage{position:absolute;inset:0;
  background:radial-gradient(80% 60% at 50% 30%, rgba(77,153,206,.13), transparent 70%),
             linear-gradient(180deg,#1b1f24,#131619)}
.vhero__img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;
  will-change:transform}
/* Two scrims, not one. The vertical gradient alone was tuned against the dark
   placeholder backdrop; a real daylight photograph defeats it and the small
   text over the picture drops under the contrast floor. The horizontal one
   anchors to the side the text actually sits on and dies out by 78 percent, so
   the vehicle itself stays bright and the words stay readable on any photo. */
.vhero__scrim{position:absolute;inset:0;
  background:
    linear-gradient(to right,
      rgba(10,11,14,.88) 0%, rgba(10,11,14,.70) 26%,
      rgba(10,11,14,.20) 56%, rgba(10,11,14,0) 78%),
    linear-gradient(to bottom,
      rgba(10,11,14,.60) 0%, rgba(10,11,14,.10) 38%, rgba(10,11,14,.90) 100%)}
[dir="rtl"] .vhero__scrim{
  background:
    linear-gradient(to left,
      rgba(10,11,14,.88) 0%, rgba(10,11,14,.70) 26%,
      rgba(10,11,14,.20) 56%, rgba(10,11,14,0) 78%),
    linear-gradient(to bottom,
      rgba(10,11,14,.60) 0%, rgba(10,11,14,.10) 38%, rgba(10,11,14,.90) 100%)}
/* the designed state for a vehicle with no photograph yet */
.vhero__mark{position:absolute;inset:0;display:grid;place-items:center;pointer-events:none}
.vhero__mark .vplaceholder{position:static;background:none;width:min(560px,58vw);aspect-ratio:240/96}
.vhero__mark .vplaceholder svg{width:100%;opacity:.5}
.vhero__mark .vplaceholder__tag{display:none}
.vhero__body{position:relative;z-index:2;
  padding-block:calc(var(--nav-h) + 40px) clamp(36px,6vw,64px);
  text-shadow:var(--tshadow)}
/* The same local scrim the hero captions use, so the headline clears the
   contrast floor over a bright photograph and not only over a dark one. It
   fades out well inside its own box, so there is no visible edge. */
.vhero__body::before{
  content:"";position:absolute;inset:-14% 30% -14% -60%;z-index:-1;pointer-events:none;
  background:radial-gradient(ellipse 68% 64% at 42% 50%,
    rgba(6,8,12,.62) 0%, rgba(6,8,12,.42) 48%, rgba(6,8,12,0) 74%);
}
[dir="rtl"] .vhero__body::before{ inset:-14% -60% -14% 30%;
  background:radial-gradient(ellipse 68% 64% at 58% 50%,
    rgba(6,8,12,.62) 0%, rgba(6,8,12,.42) 48%, rgba(6,8,12,0) 74%) }
.vhero__model{
  font-family:var(--display);font-variation-settings:"wdth" 116,"wght" 700;
  text-transform:uppercase;font-size:clamp(2.1rem,1.2rem + 4.6vw,4.6rem);line-height:.98;margin-top:12px;
}

.specnav{
  position:sticky;top:var(--nav-h);z-index:38;
  background:var(--nav-bg);backdrop-filter:blur(12px);
  border-block:1px solid var(--line);
}
.specnav__list{display:flex;gap:4px;overflow-x:auto;scrollbar-width:none}
.specnav__list::-webkit-scrollbar{display:none}
.specnav__a{
  white-space:nowrap;padding:15px 15px;font-family:var(--mono);
  font-size:.7rem;letter-spacing:.13em;text-transform:uppercase;color:var(--text-tertiary);
  border-bottom:2px solid transparent;
  transition:color var(--dur) var(--ease),border-color var(--dur) var(--ease);
}
.specnav__a:hover{color:var(--text-primary)}
.specnav__a.is-on{color:var(--accent);border-bottom-color:var(--accent)}

.specs{display:grid;gap:1px;background:var(--line);border:1px solid var(--line)}
@media (min-width:620px){ .specs{grid-template-columns:repeat(2,minmax(0,1fr))} }
@media (min-width:1000px){ .specs{grid-template-columns:repeat(4,minmax(0,1fr))} }
.spec{background:var(--canvas-2);padding:20px}
.spec__l{font-family:var(--mono);font-size:.70rem;letter-spacing:.14em;text-transform:uppercase;
  color:var(--text-tertiary)}
.spec__v{font-family:var(--display);font-variation-settings:"wdth" 112,"wght" 700;
  font-size:1.28rem;margin-top:8px;line-height:1}
.spec__v small{font-family:var(--body);font-size:.72rem;font-weight:400;color:var(--text-tertiary);
  margin-inline-start:5px}

.featlist{display:grid;gap:10px}
@media (min-width:700px){ .featlist{grid-template-columns:repeat(2,minmax(0,1fr))} }
.feat{display:flex;gap:11px;align-items:flex-start;color:var(--text-secondary);font-size:1.03rem;font-weight:600;line-height:1.55}
.feat::before{content:"";flex:0 0 auto;width:8px;height:8px;margin-top:8px;
  background:var(--accent);clip-path:polygon(0 0,100% 0,100% 100%)}
[dir="rtl"] .feat::before{clip-path:polygon(0 0,100% 0,0 100%)}

.gallery{display:grid;gap:clamp(8px,1.2vw,14px);
  grid-template-columns:repeat(auto-fill,minmax(min(100%,240px),1fr))}
.gallery__i{position:relative;aspect-ratio:4/3;overflow:hidden;background:var(--panel);cursor:zoom-in}
.gallery__i img{width:100%;height:100%;object-fit:cover;
  transition:transform .6s var(--ease-out);will-change:transform}
.gallery__i:hover img{transform:scale(1.06)}

.lightbox{position:fixed;inset:0;z-index:150;display:none;background:var(--lightbox-bg)}
.lightbox.is-open{display:grid;place-items:center}
.lightbox__img{max-width:92vw;max-height:86vh;object-fit:contain;
  opacity:0;transform:scale(.985);
  transition:opacity .4s var(--ease),transform .4s var(--ease-out)}
.lightbox.is-ready .lightbox__img{opacity:1;transform:none}
.lightbox__x{position:absolute;top:18px;inset-inline-end:18px;width:44px;height:44px;
  display:grid;place-items:center;color:var(--text-secondary)}
.lightbox__nav{position:absolute;top:50%;transform:translateY(-50%);
  width:52px;height:52px;display:grid;place-items:center;color:var(--text-secondary);
  background:var(--nav-bg);border:1px solid var(--line-strong)}
.lightbox__nav--p{inset-inline-start:14px}
.lightbox__nav--n{inset-inline-end:14px}

/* ============================== 18b. trims, colours and brand marks */

/* ---- the trim selector -------------------------------------------- */
/* A band of its own directly under the hero, because choosing the trim is the
   first decision a customer makes and everything below it answers to that
   choice. It is only ever drawn when there is more than one trim: a vehicle
   with a single specification never sees it, and the page is the page it
   always was. */

.trimbar{
  position:relative;z-index:1;
  background:var(--canvas-2);
  border-block:1px solid var(--line);
  padding-block:clamp(18px,2.4vw,26px);
}
.trimbar__l{display:block;margin-bottom:12px}
.trimbar__list{display:flex;flex-wrap:wrap;gap:8px}

.trim{
  padding:11px 20px;
  font-family:var(--mono);font-size:.72rem;letter-spacing:.13em;text-transform:uppercase;
  color:var(--text-secondary);
  background:var(--canvas);
  border:1px solid var(--line-strong);
  clip-path:polygon(0 0, calc(100% - 10px) 0, 100% 10px, 100% 100%, 0 100%);
  transition:color var(--dur) var(--ease),
             border-color var(--dur) var(--ease),
             background var(--dur) var(--ease);
}
[dir="rtl"] .trim{ clip-path:polygon(10px 0, 100% 0, 100% 100%, 0 100%, 0 10px) }
.trim:hover{ color:var(--text-primary); border-color:var(--accent) }

/* The chosen trim is said three ways at once - a filled ground, its own border
   and a heavier weight - so it stays unmistakable in both themes and does not
   rely on colour alone to be read. */
.trim.is-on{
  background:var(--accent);
  border-color:var(--accent);
  color:var(--on-accent);
  font-weight:600;
}
.trimbar__d{ margin-top:16px;max-width:62ch }
.trimbar__d:empty{ display:none }

/* ---- the colours ---------------------------------------------------- */

.colours{ display:grid;gap:clamp(20px,3vw,34px);margin-top:26px;align-items:start }
@media (min-width:860px){
  .colours{ grid-template-columns:minmax(0,1.3fr) minmax(0,1fr) }
}
.colours__stage{
  position:relative;overflow:hidden;
  aspect-ratio:16/10;
  border:1px solid var(--line);
  background:var(--card-stage);
  clip-path:polygon(0 0, calc(100% - var(--cut)) 0, 100% var(--cut), 100% 100%, 0 100%);
}
[dir="rtl"] .colours__stage{
  clip-path:polygon(var(--cut) 0, 100% 0, 100% 100%, 0 100%, 0 var(--cut));
}
.colours__stage img,
.colours__stage picture{ width:100%;height:100%;object-fit:cover }

/* ---- the video and the 3D view ---------------------------------------

   One stage for both, cut like the colour stage. It is dark in either theme,
   because a film or a 3D scene is, and the label on its button is set light
   for that reason. Nothing plays or loads until the button is pressed; the
   still underneath is the video's own thumbnail or the vehicle's photograph. */

.mstage{
  position:relative;overflow:hidden;
  margin-top:26px;
  aspect-ratio:16/9;
  border:1px solid var(--line);
  background:#121417;
  clip-path:polygon(0 0, calc(100% - var(--cut)) 0, 100% var(--cut), 100% 100%, 0 100%);
}
[dir="rtl"] .mstage{
  clip-path:polygon(var(--cut) 0, 100% 0, 100% 100%, 0 100%, 0 var(--cut));
}
/* a phone-shaped video stays phone-shaped, and never taller than the screen */
.mstage--tall{
  aspect-ratio:9/16;
  width:min(400px, 100%, calc(80vh * 9 / 16));
  margin-inline:auto;
}
/* a 3D scene is turned with a finger, so on a phone it gets the room to be */
@media (max-width:640px){
  .mstage--3d{ aspect-ratio:4/5; max-height:78vh }
}

.mstage__still,
.mstage__still picture{ position:absolute;inset:0 }
.mstage__still img{ width:100%;height:100%;object-fit:cover }
.mstage__still.is-dim img{ opacity:.4 }
.mstage__still::after{
  content:'';position:absolute;inset:0;
  background:linear-gradient(180deg, rgba(8,10,13,.05) 30%, rgba(8,10,13,.6) 100%);
}

.mstage__go{
  position:absolute;inset:0;width:100%;
  display:flex;flex-direction:column;align-items:center;justify-content:center;gap:14px;
  background:transparent;border:0;cursor:pointer;
  color:#f1f4f6;
}
.mstage__ico{
  display:grid;place-items:center;
  width:76px;height:76px;
  background:var(--hot);color:var(--hot-ink);
  clip-path:polygon(0 0, calc(100% - 14px) 0, 100% 14px, 100% 100%, 0 100%);
  transition:transform .2s var(--ease-out), background .2s var(--ease-out);
}
[dir="rtl"] .mstage__ico{ clip-path:polygon(14px 0, 100% 0, 100% 100%, 0 100%, 0 14px) }
.mstage__l{
  font-size:.95rem;font-weight:600;letter-spacing:.02em;
  text-shadow:0 1px 14px rgba(0,0,0,.7);
}
@media (hover:hover){
  .mstage__go:hover .mstage__ico{ transform:scale(1.06); background:var(--hot-hover) }
}
.mstage__go:focus-visible{ outline:2px solid var(--accent); outline-offset:-8px }
.mstage.is-busy .mstage__ico{ animation:mstage-wait .8s var(--ease) infinite alternate }
@keyframes mstage-wait{ to{ opacity:.45 } }

.mstage.is-live .mstage__still,
.mstage.is-live .mstage__go{ display:none }
.mstage__frame{
  position:absolute;inset:0;
  display:block;width:100%;height:100%;
  border:0;background:#000;
}
model-viewer.mstage__frame{ background:#121417 }

.mstage:fullscreen{
  clip-path:none;aspect-ratio:auto;width:100%;height:100%;max-height:none;margin:0;border:0;
}
.mstage:-webkit-full-screen{
  clip-path:none;aspect-ratio:auto;width:100%;height:100%;max-height:none;margin:0;border:0;
}

.mstage__bar{ display:flex;flex-wrap:wrap;align-items:center;gap:10px;margin-top:14px }
.mstage--tall + .mstage__bar{ justify-content:center }
.mstage__hint{ margin-inline-end:auto }
@media (max-width:640px){
  .mstage__hint{ flex-basis:100% }
}
@media (prefers-reduced-motion:reduce){
  .mstage__ico{ transition:none }
  .mstage.is-busy .mstage__ico{ animation:none }
}

.swatches{ display:flex;flex-wrap:wrap;gap:10px }
.swatch{
  display:inline-flex;align-items:center;gap:11px;
  padding:8px;padding-inline-end:16px;
  background:var(--canvas-2);
  border:1px solid var(--line-strong);
  color:var(--text-secondary);
  font-size:.92rem;font-weight:600;
  transition:color var(--dur) var(--ease),
             border-color var(--dur) var(--ease),
             background var(--dur) var(--ease);
}
.swatch__c{
  width:28px;height:28px;flex:0 0 auto;
  border:1px solid var(--line-strong);
  clip-path:polygon(0 0, calc(100% - 6px) 0, 100% 6px, 100% 100%, 0 100%);
}
[dir="rtl"] .swatch__c{ clip-path:polygon(6px 0, 100% 0, 100% 100%, 0 100%, 0 6px) }
.swatch:hover{ color:var(--text-primary);border-color:var(--accent) }
/* Chosen says itself with a ring around the chip as well as the border and the
   text, so a swatch of almost any colour still reads as selected. */
.swatch.is-on{
  color:var(--text-primary);
  border-color:var(--accent);
  background:var(--accent-muted);
}
.swatch.is-on .swatch__c{
  box-shadow:0 0 0 2px var(--canvas-2), 0 0 0 4px var(--accent);
}
.swatch:focus-visible{ outline:2px solid var(--accent);outline-offset:2px }

.colours__n{
  margin-top:20px;
  font-family:var(--display);font-variation-settings:"wdth" 114,"wght" 700;
  text-transform:uppercase;font-size:1.25rem;line-height:1.1;
}
.colours__d{ margin-top:8px;font-size:1rem }
.colours__d:empty{ display:none }

/* ---- the feature showcase ------------------------------------------- */
/* The vehicle's features, once any of them has a picture: one feature at a
   time on a large stage, the section's other pictured features in a list
   beside it, the sections as tabs above, and every feature without a picture
   listed under the stage.

   It is a theatre of its own - dark in both themes, because a photograph
   reads best on dark, and in the light theme that makes it the page's
   contrast band. Its colours are stated here, once, so everything inside it
   reads them the right way up, the way the light band does.

   Motion is opacity and transform only: the dissolve, the slow push-in, the
   caption rising and the sweep are all things the compositor does on its
   own. A phone gets native scrolling with snap points rather than any of it. */

.fx{
  --fx-bg:          #101215;
  --fx-stage:       #0b0d10;
  --text-primary:   #f1f4f6;
  --text-secondary: #b6bfc7;
  --text-tertiary:  #8a939c;
  --line:           #2a3036;
  --line-strong:    #434b53;
  --accent:         var(--accent-bright);
  --fx-cut:         calc(var(--cut) * 1.6);
  background:var(--fx-bg);
  color:var(--text-primary);
  padding-block:clamp(64px,7vw,104px) clamp(56px,6.5vw,96px);
}
.fx .shell{position:relative}
.fx__glow{
  position:absolute;inset:0;pointer-events:none;
  background:
    radial-gradient(52% 42% at 34% 64%, rgba(77,153,206,.13), rgba(77,153,206,0) 72%),
    radial-gradient(36% 30% at 88% 18%, rgba(77,153,206,.06), rgba(77,153,206,0) 72%);
}
[dir="rtl"] .fx__glow{transform:scaleX(-1)}
.fx__amb{
  position:absolute;inset:0;pointer-events:none;overflow:hidden;opacity:.34;
  -webkit-mask-image:radial-gradient(60% 52% at 40% 64%, #000 0%, rgba(0,0,0,.55) 48%, transparent 78%);
          mask-image:radial-gradient(60% 52% at 40% 64%, #000 0%, rgba(0,0,0,.55) 48%, transparent 78%);
}
[dir="rtl"] .fx__amb{
  -webkit-mask-image:radial-gradient(60% 52% at 60% 64%, #000 0%, rgba(0,0,0,.55) 48%, transparent 78%);
          mask-image:radial-gradient(60% 52% at 60% 64%, #000 0%, rgba(0,0,0,.55) 48%, transparent 78%);
}
.fx__amb i{
  position:absolute;inset:8% 4% -6%;background:center / cover no-repeat;
  filter:blur(72px) saturate(1.35);opacity:0;transition:opacity 1.3s var(--ease);
}
.fx__amb i.is-on{opacity:1}

.fx__head{display:grid;gap:12px;margin-bottom:clamp(22px,2.6vw,32px)}
.fx__h{font-size:clamp(1.8rem,1rem + 2.6vw,3.2rem);max-width:none}
html[dir="rtl"] .fx__h{line-height:1.3}

/* ---- the sections ---- */
.fx__tabs{position:relative;margin-bottom:clamp(20px,2.6vw,30px);border-bottom:1px solid var(--line)}
.fx__tablist{
  position:relative;display:flex;gap:clamp(2px,.8vw,10px);
  overflow-x:auto;overscroll-behavior-x:contain;scrollbar-width:none;
}
.fx__tablist::-webkit-scrollbar{display:none}
.fx__tab{
  position:relative;display:inline-flex;align-items:baseline;gap:8px;white-space:nowrap;
  padding:14px clamp(10px,1.3vw,16px) 16px;
  font-family:var(--mono);font-size:.74rem;letter-spacing:.15em;text-transform:uppercase;
  color:var(--text-tertiary);transition:color var(--dur) var(--ease);
}
.fx__tab b{font-weight:500;font-size:.62rem;letter-spacing:.06em;color:var(--text-tertiary);
  transition:color var(--dur) var(--ease)}
.fx__tab:hover,.fx__tab.is-on{color:var(--text-primary)}
.fx__tab.is-on b{color:var(--accent)}
.fx__tab:focus-visible{outline:2px solid var(--accent);outline-offset:-3px}
.fx__ink{
  position:absolute;left:0;bottom:0;width:0;height:2px;pointer-events:none;
  background:var(--accent);box-shadow:0 0 14px rgba(77,153,206,.55);
  transition:transform .55s var(--ease-out),width .55s var(--ease-out);
}
.fx__solo{margin-bottom:22px;padding-bottom:14px;border-bottom:1px solid var(--line)}
/* Arabic letters are joined, and spacing them out pulls the joins apart. */
html[dir="rtl"] :is(.fx__tab, .fx__tab b, .fx__no, .fx__item-n, .fx__swipe, .fx__solo .mono-label, .fx__more-l){
  letter-spacing:0;
}
html[dir="rtl"] .fx__tab{font-size:.9rem}

.fx__panel[hidden]{display:none}
.fx__panel.is-on{animation:fxPanel .7s var(--ease-out) both}
@keyframes fxPanel{ from{opacity:0;transform:translateY(12px)} to{opacity:1;transform:none} }

/* ---- the stage ---- */
.fx__show{display:grid;gap:clamp(16px,2vw,26px)}
@media (min-width:1000px){
  .fx__show{grid-template-columns:minmax(0,1fr) minmax(250px,31%)}
  .fx__show--one{grid-template-columns:minmax(0,1fr)}
}

.fx__stage{position:relative;outline:none;touch-action:pan-y;--fx-par:0px}
/* a hairline of light along the Canora cut */
.fx__stage::before{
  content:"";position:absolute;z-index:5;pointer-events:none;height:1px;
  top:calc(var(--fx-cut) / 2);right:calc(var(--fx-cut) * -.2071);width:calc(var(--fx-cut) * 1.4142);
  background:linear-gradient(90deg, rgba(77,153,206,0), var(--accent) 50%, rgba(77,153,206,0));
  box-shadow:0 0 10px rgba(77,153,206,.6);transform:rotate(45deg);opacity:.9;
}
[dir="rtl"] .fx__stage::before{right:auto;left:calc(var(--fx-cut) * -.2071);transform:rotate(-45deg)}
.fx__stage:focus-visible{outline:2px solid var(--accent);outline-offset:5px}
.fx__track,
.fx__sweep{
  clip-path:polygon(0 0, calc(100% - var(--fx-cut)) 0, 100% var(--fx-cut), 100% 100%, 0 100%);
}
[dir="rtl"] .fx__track,
[dir="rtl"] .fx__sweep{
  clip-path:polygon(var(--fx-cut) 0, 100% 0, 100% 100%, 0 100%, 0 var(--fx-cut));
}
.fx__track{position:relative;aspect-ratio:16/10;max-height:80svh;overflow:hidden;background:var(--fx-stage)}

.fx__slide{position:absolute;inset:0;margin:0;opacity:0;visibility:hidden;z-index:0}
/* The picture going away stays whole underneath until the new one covers it,
   so a change is a dissolve from one picture into the next, never a dip. */
.fx__slide.is-was{opacity:1;visibility:visible;z-index:1}
.fx__slide.is-on{opacity:1;visibility:visible;z-index:2;animation:fxFade .9s var(--ease) both}
@keyframes fxFade{ from{opacity:0} to{opacity:1} }

.fx__frame{position:absolute;inset:0;overflow:hidden}
/* Taller than the frame, so the parallax never shows an edge. The small copy
   is its background, standing in until the full picture lands. */
.fx__media{
  position:absolute;inset:-5% 0;background:var(--fx-stage) center / cover no-repeat;
  transform:translate3d(0,var(--fx-par),0);
}
.fx__media picture{display:block;width:100%;height:100%}
.fx__img{
  display:block;width:100%;height:100%;object-fit:cover;opacity:0;
  transition:opacity .7s var(--ease);
  user-select:none;-webkit-user-drag:none;pointer-events:none;
}
.fx__img.is-in{opacity:1}
.fx__slide.is-on .fx__img{animation:fxPush 11s var(--ease-out) both}
@keyframes fxPush{ from{transform:scale(1.1)} to{transform:scale(1.02)} }

.fx__scrim{
  position:absolute;inset:0;pointer-events:none;
  background:
    linear-gradient(to top, rgba(6,8,11,.88) 0%, rgba(6,8,11,.46) 26%, rgba(6,8,11,0) 54%),
    linear-gradient(to right, rgba(6,8,11,.42) 0%, rgba(6,8,11,0) 46%);
}
[dir="rtl"] .fx__scrim{
  background:
    linear-gradient(to top, rgba(6,8,11,.88) 0%, rgba(6,8,11,.46) 26%, rgba(6,8,11,0) 54%),
    linear-gradient(to left, rgba(6,8,11,.42) 0%, rgba(6,8,11,0) 46%);
}

/* The caption sits on the picture; its colours are the hero's, whatever the theme. */
.fx__cap{
  position:absolute;z-index:3;inset-inline:clamp(20px,3vw,42px);bottom:clamp(66px,7vw,90px);
  display:grid;gap:10px;max-width:min(640px,72%);pointer-events:none;text-shadow:var(--tshadow);
}
.fx__show--one .fx__cap{bottom:clamp(22px,3vw,40px)}
.fx__no{justify-self:start;font-family:var(--mono);font-size:.74rem;letter-spacing:.2em;color:rgba(241,244,246,.72)}
/* The caption going away goes at once; only its picture stays under the new one. */
.fx__slide.is-was .fx__cap{opacity:0;transition:opacity .18s var(--ease)}
.fx__no b{font-weight:500;color:var(--accent)}
.fx__t{
  font-family:var(--display);font-variation-settings:"wdth" 116,"wght" 700;text-transform:uppercase;
  font-size:clamp(1.5rem,1rem + 2.1vw,2.9rem);line-height:1.02;color:#fff;overflow-wrap:break-word;
}
html[dir="rtl"] .fx__t{font-weight:700;line-height:1.35}
.fx__slide.is-on .fx__no{animation:fxRise .8s var(--ease-out) .1s both}
.fx__slide.is-on .fx__t{animation:fxRise 1s var(--ease-out) .2s both}
@keyframes fxRise{ from{opacity:0;transform:translateY(18px)} to{opacity:1;transform:none} }

/* the sweep: a faint light along the Canora diagonal, once per change */
.fx__sweep{position:absolute;inset:0;z-index:3;overflow:hidden;pointer-events:none}
.fx__sweep::before{
  content:"";position:absolute;top:-25%;bottom:-25%;left:-45%;width:42%;opacity:0;
  background:linear-gradient(90deg, rgba(120,180,225,0), rgba(120,180,225,.13) 42%,
    rgba(200,230,250,.26) 50%, rgba(120,180,225,.13) 58%, rgba(120,180,225,0));
  transform:skewX(-24deg);
}
[dir="rtl"] .fx__sweep::before{left:auto;right:-45%;transform:skewX(24deg)}
.fx__stage.is-sweep .fx__sweep::before{animation:fxSweep 1.15s var(--ease) both}
[dir="rtl"] .fx__stage.is-sweep .fx__sweep::before{animation-name:fxSweepRtl}
@keyframes fxSweep{
  0%{opacity:0;transform:translateX(0) skewX(-24deg)}
  18%{opacity:1}
  100%{opacity:0;transform:translateX(400%) skewX(-24deg)}
}
@keyframes fxSweepRtl{
  0%{opacity:0;transform:translateX(0) skewX(24deg)}
  18%{opacity:1}
  100%{opacity:0;transform:translateX(-400%) skewX(24deg)}
}

/* ---- where am I: progress and the two arrows ---- */
.fx__hud{
  position:absolute;z-index:4;inset-inline:clamp(20px,3vw,42px);bottom:clamp(18px,2.4vw,28px);
  display:flex;align-items:center;gap:10px;
}
.fx__bars{display:flex;gap:6px;flex:1 1 auto;max-width:420px;margin-inline-end:auto}
.fx__bars i{position:relative;flex:1 1 0;height:2px;overflow:hidden;background:rgba(255,255,255,.24)}
.fx__bars i::after{
  content:"";position:absolute;inset:0;background:var(--accent);
  transform:scaleX(0);transform-origin:left;transition:transform .6s var(--ease-out);
}
[dir="rtl"] .fx__bars i::after{transform-origin:right}
.fx__bars i.is-on::after{transform:scaleX(1)}
.fx__bars--line i::after{transform:scaleX(var(--fx-p,0))}
.fx__arrow{
  flex:0 0 auto;width:46px;height:46px;display:grid;place-items:center;color:#fff;
  background:rgba(10,12,15,.55);border:1px solid rgba(255,255,255,.24);
  -webkit-backdrop-filter:blur(6px);backdrop-filter:blur(6px);
  clip-path:polygon(0 0, calc(100% - 10px) 0, 100% 10px, 100% 100%, 0 100%);
  transition:background .3s var(--ease),border-color .3s var(--ease),color .3s var(--ease),transform .18s var(--ease-out);
}
[dir="rtl"] .fx__arrow{clip-path:polygon(10px 0, 100% 0, 100% 100%, 0 100%, 0 10px)}
.fx__arrow:hover{background:var(--accent);border-color:var(--accent);color:#0d1013}
.fx__arrow:active{transform:scale(.95)}
.fx__arrow:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
.fx__arrow--p svg,
[dir="rtl"] .fx__arrow--n svg{transform:scaleX(-1)}
[dir="rtl"] .fx__arrow--p svg{transform:none}

/* ---- the section's pictured features, beside the stage ---- */
.fx__rail{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:2px}
@media (min-width:1000px){
  /* As tall as the stage and no taller: it scrolls inside itself. */
  .fx__rail{height:0;min-height:100%;overflow-y:auto;overscroll-behavior:contain;scrollbar-width:thin;
    scrollbar-color:var(--line-strong) transparent}
}
.fx__item{
  position:relative;width:100%;display:grid;grid-template-columns:auto minmax(0,1fr) 78px;gap:14px;
  align-items:center;padding:11px 14px;text-align:start;color:var(--text-secondary);
  border-inline-start:2px solid var(--line);
  transition:background .35s var(--ease),color .35s var(--ease),border-color .35s var(--ease);
}
.fx__item:hover{color:var(--text-primary);background:rgba(255,255,255,.035)}
.fx__item.is-on{
  color:var(--text-primary);border-inline-start-color:var(--accent);
  background:linear-gradient(90deg, rgba(77,153,206,.14), rgba(77,153,206,0) 85%);
}
[dir="rtl"] .fx__item.is-on{background:linear-gradient(270deg, rgba(77,153,206,.14), rgba(77,153,206,0) 85%)}
.fx__item:focus-visible{outline:2px solid var(--accent);outline-offset:-2px}
.fx__item-n{font-family:var(--mono);font-size:.7rem;letter-spacing:.12em;color:var(--text-tertiary);
  transition:color .35s var(--ease)}
.fx__item.is-on .fx__item-n{color:var(--accent)}
.fx__item-t{font-weight:600;font-size:.98rem;line-height:1.35;overflow-wrap:anywhere}
html[dir="rtl"] .fx__item-t{line-height:1.7}
.fx__item-th{display:block;width:78px;aspect-ratio:4/3;overflow:hidden;background:var(--fx-stage);
  opacity:.7;transition:opacity .35s var(--ease)}
.fx__item-th img{width:100%;height:100%;object-fit:cover;transition:transform .6s var(--ease-out)}
.fx__item:hover .fx__item-th,
.fx__item.is-on .fx__item-th{opacity:1}
@media (hover:hover){ .fx__item:hover .fx__item-th img{transform:scale(1.08)} }

/* A tablet: the list runs under the stage as a strip of small pictures. */
@media (min-width:760px) and (max-width:999px){
  .fx__rail{flex-direction:row;gap:10px;overflow-x:auto;scrollbar-width:none;padding-bottom:2px}
  .fx__rail::-webkit-scrollbar{display:none}
  .fx__rail li{flex:0 0 200px}
  .fx__item{grid-template-columns:auto minmax(0,1fr);padding:0 0 10px;border-inline-start:0;
    border-bottom:2px solid var(--line);background:none}
  .fx__item.is-on{border-bottom-color:var(--accent);background:none}
  .fx__item-th{grid-column:1 / -1;grid-row:1;width:100%;margin-bottom:4px}
}

/* ---- a section with no feature pictures, but with its photo ---- */
.fx__banner{
  position:relative;aspect-ratio:21/9;overflow:hidden;background:var(--fx-stage);
  clip-path:polygon(0 0, calc(100% - var(--fx-cut)) 0, 100% var(--fx-cut), 100% 100%, 0 100%);
}
[dir="rtl"] .fx__banner{clip-path:polygon(var(--fx-cut) 0, 100% 0, 100% 100%, 0 100%, 0 var(--fx-cut))}
.fx__banner picture,.fx__banner img{display:block;width:100%;height:100%;object-fit:cover}
.fx__banner::after{content:"";position:absolute;inset:0;pointer-events:none;
  background:linear-gradient(to top, rgba(6,8,11,.82), rgba(6,8,11,0) 58%)}
.fx__banner-t{
  position:absolute;z-index:1;inset-inline-start:clamp(20px,3vw,42px);bottom:clamp(18px,2.6vw,32px);
  font-family:var(--display);font-variation-settings:"wdth" 116,"wght" 700;text-transform:uppercase;
  font-size:clamp(1.4rem,1rem + 1.6vw,2.4rem);line-height:1.05;color:#fff;text-shadow:var(--tshadow);
}
html[dir="rtl"] .fx__banner-t{font-weight:700;line-height:1.35}

/* ---- every feature without a picture ---- */
.fx__more{margin-top:clamp(28px,3.6vw,46px)}
.fx__banner + .fx__more{margin-top:clamp(24px,3vw,36px)}
.fx__panel > .fx__more:first-child{margin-top:0}
.fx__more-l{display:block;margin-bottom:18px}
.fx__list{list-style:none;margin:0;padding:0;display:grid;gap:12px 32px}
@media (min-width:700px){ .fx__list{grid-template-columns:repeat(2,minmax(0,1fr))} }
@media (min-width:1100px){ .fx__list{grid-template-columns:repeat(3,minmax(0,1fr))} }

.fx__swipe{display:none}

/* ---- a phone: a strip the thumb drags ---- */
@media (max-width:759px){
  /* The sections run edge to edge and fade out at the screen's edges. */
  .fx__tablist{
    margin-inline:calc(var(--gutter) * -1);padding-inline:var(--gutter);
    -webkit-mask-image:linear-gradient(90deg, transparent 0, #000 var(--gutter), #000 calc(100% - var(--gutter)), transparent 100%);
            mask-image:linear-gradient(90deg, transparent 0, #000 var(--gutter), #000 calc(100% - var(--gutter)), transparent 100%);
  }
  .fx__show{gap:0}
  .fx__stage{touch-action:auto}
  .fx__track{
    display:flex;gap:12px;aspect-ratio:auto;max-height:none;background:none;clip-path:none;
    overflow-x:auto;overflow-y:hidden;overscroll-behavior-x:contain;scrollbar-width:none;
    scroll-snap-type:x mandatory;scroll-padding-inline:var(--gutter);
    margin-inline:calc(var(--gutter) * -1);padding-inline:var(--gutter);
  }
  .fx__track::-webkit-scrollbar{display:none}
  .fx__slide,
  .fx__slide.is-on,
  .fx__slide.is-was{
    position:relative;inset:auto;flex:0 0 86%;min-width:0;opacity:1;visibility:visible;
    z-index:auto;animation:none;scroll-snap-align:start;
  }
  .fx__show--one .fx__slide{flex-basis:100%}
  .fx__frame{
    position:relative;aspect-ratio:4/3;background:var(--fx-stage);transition:opacity .45s var(--ease);
    clip-path:polygon(0 0, calc(100% - var(--cut)) 0, 100% var(--cut), 100% 100%, 0 100%);
  }
  [dir="rtl"] .fx__frame{clip-path:polygon(var(--cut) 0, 100% 0, 100% 100%, 0 100%, 0 var(--cut))}
  .fx__slide:not(.is-on) .fx__frame{opacity:.5}
  .fx__media{inset:0;transform:none}
  .fx__slide.is-on .fx__img{animation:none}
  .fx__scrim,.fx__sweep,.fx__arrow,.fx__rail,.fx__amb,.fx__stage::before{display:none}
  .fx__cap{position:static;max-width:none;gap:6px;padding:14px 2px 0;text-shadow:none;transition:opacity .45s var(--ease)}
  .fx__slide:not(.is-on) .fx__cap{opacity:.45}
  .fx__slide.is-on .fx__no,
  .fx__slide.is-on .fx__t{animation:none}
  .fx__no{color:var(--text-tertiary)}
  .fx__t{font-size:clamp(1.15rem,.9rem + 1.6vw,1.5rem);line-height:1.12;color:var(--text-primary)}
  html[dir="rtl"] .fx__t{line-height:1.5}
  .fx__hud{position:static;margin-top:18px}
  .fx__bars{max-width:none;margin:0}
  .fx__bars i{background:var(--line-strong)}
  .fx__swipe{
    display:flex;align-items:center;gap:8px;margin-top:12px;transition:opacity .5s var(--ease);
  }
  .fx__swipe::after{
    content:"";width:22px;height:1px;background:currentColor;
    animation:fxNudge 1.8s var(--ease) infinite;
  }
  .fx__swipe.is-gone{opacity:0}
  .fx__banner{aspect-ratio:16/10}
}
@keyframes fxNudge{ 0%,100%{transform:translateX(0)} 50%{transform:translateX(8px)} }
@keyframes fxNudgeRtl{ 0%,100%{transform:translateX(0)} 50%{transform:translateX(-8px)} }
[dir="rtl"] .fx__swipe::after{animation-name:fxNudgeRtl}

body.paused .fx__img,
body.paused .fx__swipe::after{animation-play-state:paused}

@media (prefers-reduced-motion: reduce){
  .fx__slide.is-on,
  .fx__slide.is-on .fx__img,
  .fx__slide.is-on .fx__no,
  .fx__slide.is-on .fx__t,
  .fx__panel.is-on,
  .fx__swipe::after{animation:none}
  .fx__sweep{display:none}
  .fx__media{transform:none}
}

/* ---- brand marks, in both themes ------------------------------------ */
/* Three ways a brand mark can be drawn, chosen per brand in the dashboard.
   'auto' is one file put through the greyscale treatment the site has always
   used - it goes dark on a bright page and light on a dark one, from a single
   upload. 'files' is a real second artwork for a mark a filter cannot do
   justice to. 'plain' leaves a full-colour mark exactly as its owner drew it. */

.blogo{ max-height:44px;width:auto;object-fit:contain }

/* A brand mark shown large - on the brands grid and at the top of a brand's
   own page - rather than at logo-wall size. The plate is what sets the size;
   the mark fills it and keeps its own proportions, so nothing is stretched. */
.brandplate{
  position:absolute;inset:0;
  display:grid;place-items:center;
  padding:16%;
}
.brandplate--wide{ position:relative;inset:auto;padding:8% }
.brandplate .blogo,
.brandplate .blogo--files,
.brandplate .blogo--files img{
  max-height:100%;max-width:100%;width:auto;height:auto;
}
.blogo--auto{ filter:var(--logo-filter) }
.blogo--files{ display:inline-block;line-height:0 }
.blogo--files img{ max-height:44px;width:auto;object-fit:contain }
/* Dark is the default theme, so the dark-mode artwork is the one on show
   until the page says otherwise. */
.blogo__l{ display:none }
.blogo__d{ display:block }
:root[data-theme="light"] .blogo__l{ display:block }
:root[data-theme="light"] .blogo__d{ display:none }

/* ---- the brand conveyor --------------------------------------------- */
/* One continuous run of brands, right to left. It is a line of names moving
   through the page, not a row of boxes sitting on it: the hero opens on a line
   of cars that never ends, and this is the same line, further down, carrying
   the marques instead.

   That is the whole of the treatment. There is no card, no card ground and no
   divider between one brand and the next - a hairline cut at 45 degrees stands
   between them instead, the same angle the logo is built from, so the one
   piece of furniture on the strip is the company's own geometry. The band is
   nothing but a wash of the page's blue with a rule above and below it, and
   both rules fade out towards the ends exactly where the names do. Nothing
   here is a slab dropped on the canvas; it is the canvas, with a light
   passing behind it.

   The palette is stated once, as a small set of names of its own, and every
   rule below reads a name rather than a colour: one block for the dark
   reading, one restating it for the light, and nothing nested inside has to
   know which of the two it is in.

   The ground is two stacked layers rather than one gradient, because a
   gradient is the one thing that cannot be transitioned: each theme paints its
   own and the theme change cross-fades them, so the band turns with the page
   instead of snapping while everything around it fades.

   The travel is a CSS animation on the track, not a script: the list is in the
   DOM exactly twice and the keyframe moves the track by the width of one copy,
   so at the end of every cycle the frame on screen is pixel for pixel the
   frame at the start and there is no seam to see. It runs on the compositor,
   which is why it cannot stutter, cannot drift and cannot stop halfway. The
   only thing site.js does is measure one copy and hand the width and the
   duration back, so the speed is the same whether there are four brands or
   forty. */

.marquee{
  position:relative;
  margin-top:30px;
  overflow:hidden;
  isolation:isolate;

  /* The whole strip is laid out left to right in every language, and this is
     the line that does it. Right to left is the direction of travel the design
     asks for everywhere; the brands are not a sentence and an Arabic page that
     mirrored them would run them backwards past the reader.

     It also has to be on the box that clips, not only on the track inside it.
     In a right-to-left page an overflowing flex track is placed against its
     container's RIGHT edge, so everything it carries hangs off to the left -
     and the animation, which only ever travels left, walked the whole run off
     the screen and left the strip empty a cycle in. Stated here, the track
     starts flush left with the run ahead of it, exactly as it does in English. */
  direction:ltr;

  /* The strip's palette, in the dark reading. */
  --sky-text:   #e9f1f8;
  --sky-dim:    #7e8a95;
  --sky-lit:    rgba(190,225,255,.78);
  --sky-line:   rgba(233,241,248,.26);   /* the cut between two brands */
  --sky-accent: var(--accent-bright);    /* the focus ring */
  --sky-wash:   rgba(77,153,206,.10);    /* what the lit name sits in */

  /* A mark is lit for the ground it lies on: lifted towards the light on a
     dark band, pressed down towards the ink on a bright one. Each hover state
     is the same treatment, one step further. */
  --mark-auto:     grayscale(1) brightness(1.55) opacity(.82);
  --mark-auto-hi:  grayscale(1) brightness(2.15);
  --mark-plain:    saturate(.45) brightness(1.06) opacity(.82);
  --mark-plain-hi: saturate(1) brightness(1.12);
  --mark-files:    opacity(.85);
  --mark-files-hi: opacity(1);

  /* one copy of the list, and how long it takes to travel it. site.js writes
     both; the fallbacks keep the strip moving if it never gets to run. */
  --run: 2400px;
  --dur: 92s;

  color:var(--sky-text);
}

/* The two grounds. Both are always painted; which one is on show is a matter
   of opacity, and that is the whole of the cross-fade. Each carries its own
   two rules with it, because a rule that fades at its ends is a gradient too,
   and it has to turn with the wash it belongs to. They sit under everything,
   because the viewport above them is z-index 1. */
.marquee::before,
.marquee::after{
  content:"";
  position:absolute;
  inset:0;
  z-index:0;
  pointer-events:none;
  background-repeat:no-repeat;
  background-position:top,bottom,center;
  background-size:100% 1px,100% 1px,100% 100%;
}
.marquee::before{
  background-image:
    linear-gradient(to right,transparent 0,rgba(233,241,248,.13) 20%,
      rgba(233,241,248,.13) 80%,transparent 100%),
    linear-gradient(to right,transparent 0,rgba(233,241,248,.13) 20%,
      rgba(233,241,248,.13) 80%,transparent 100%),
    radial-gradient(120% 170% at 50% 50%,rgba(77,153,206,.075) 0%,
      rgba(77,153,206,.028) 45%,rgba(77,153,206,0) 72%);
  opacity:1;
}
.marquee::after{
  background-image:
    linear-gradient(to right,transparent 0,rgba(18,23,27,.14) 20%,
      rgba(18,23,27,.14) 80%,transparent 100%),
    linear-gradient(to right,transparent 0,rgba(18,23,27,.14) 20%,
      rgba(18,23,27,.14) 80%,transparent 100%),
    radial-gradient(120% 170% at 50% 50%,rgba(43,122,176,.07) 0%,
      rgba(43,122,176,.025) 45%,rgba(43,122,176,0) 72%);
  opacity:0;
}

/* ------------------------------------------------- the strip, in daylight */
/* The same line, on paper. The cut becomes ink rather than light, the glow
   becomes the page's own deepened blue - a halo on paper is a whisper,
   exactly as --neon is - and every mark is pressed down towards the ink
   instead of lifted off it. */
:root[data-theme="light"] .marquee{
  --sky-text:   #12171b;
  --sky-dim:    #4b555e;
  --sky-lit:    rgba(43,122,176,.9);
  --sky-line:   rgba(18,23,27,.22);
  --sky-accent: var(--accent-deep);
  --sky-wash:   rgba(43,122,176,.09);

  --mark-auto:     grayscale(1) brightness(.55) contrast(1.15) opacity(.85);
  --mark-auto-hi:  grayscale(1) brightness(.34) contrast(1.2);
  --mark-plain:    saturate(.55) brightness(.98) opacity(.85);
  /* a mark in its own colours still has to be pressed towards the ink here
     rather than lifted: it was brightness(1) against a resting .98, which
     made it the one hover on the strip that moved with the page. */
  --mark-plain-hi: saturate(1) brightness(.9);
  --mark-files:    opacity(.88);
  --mark-files-hi: opacity(1);
}
:root[data-theme="light"] .marquee::before{ opacity:0 }
:root[data-theme="light"] .marquee::after { opacity:1 }

/* The ends dissolve into the page rather than being cut off by a hard edge,
   so a name leaving the strip is never chopped in half - and the wrap, which
   happens out at the edge, happens where the eye has the least to hold on to. */
.marquee__vp{
  position:relative;
  z-index:1;
  --marquee-fade:clamp(64px,11vw,220px);
  -webkit-mask-image:linear-gradient(to right,transparent 0,#000 var(--marquee-fade),
    #000 calc(100% - var(--marquee-fade)),transparent 100%);
  mask-image:linear-gradient(to right,transparent 0,#000 var(--marquee-fade),
    #000 calc(100% - var(--marquee-fade)),transparent 100%);
}

/* No gap. Every name carries its own air as padding and its own cut as a
   pseudo-element, which is what keeps the wrap exact: with nothing between the
   copies, one copy's width is precisely half the track, and every item is
   composed identically whether it is the first in the run or the last.

   direction:ltr is restated here rather than only inherited from .marquee,
   because this is the box whose children it orders and the rule is the one
   thing on the strip that must not be mirrored. */
.marquee__track{
  display:flex;
  align-items:stretch;
  gap:0;
  width:max-content;
  direction:ltr;
  will-change:transform;
  animation:brandRun var(--dur) linear infinite;
}
@keyframes brandRun{
  from{ transform:translate3d(0,0,0) }
  to  { transform:translate3d(calc(var(--run) * -1),0,0) }
}

/* Pointing anywhere at the strip holds it, so a name can be read and clicked.
   It is the animation that pauses, not a script that stops: the name under the
   pointer stays exactly where it is and picks the travel back up from there,
   with nothing to catch up on and no jump when it does. */
.marquee:hover  .marquee__track,
.marquee:focus-within .marquee__track{ animation-play-state:paused }

/* Once site.js is driving the strip it moves the track itself, frame by frame,
   so a hand can take it: dragged with a mouse, swiped on a touchpad or with a
   finger. The animation above is then only the fallback for a page whose
   script never ran. pan-y keeps an up-and-down swipe that starts on the strip
   scrolling the page, and hands a sideways one to the strip. */
.marquee--driven .marquee__track{ animation:none }
.marquee--driven .marquee__vp{
  touch-action:pan-y;
  overscroll-behavior-x:contain;
  cursor:grab;
}
.marquee--driven .marquee__i{
  cursor:inherit;
  -webkit-user-drag:none;
  -webkit-user-select:none;
  user-select:none;
}
.marquee--driven .marquee__i img{ -webkit-user-drag:none }
.marquee.is-dragging .marquee__vp{ cursor:grabbing }

.marquee__i{
  position:relative;
  flex:0 0 auto;
  display:grid;
  align-content:center;
  justify-items:center;
  gap:clamp(6px,.7vw,9px);
  padding:clamp(30px,3.6vw,44px) clamp(30px,3.9vw,58px);
  min-height:clamp(122px,12.6vw,150px);
  text-decoration:none;
  color:inherit;
  transition:opacity .45s var(--ease);
}
.marquee__i:focus-visible{ outline:2px solid var(--sky-accent);outline-offset:-8px }

/* The cut, standing between one brand and the next: a hairline turned through
   45 degrees, the logo's own angle, softest at both of its ends. Every item
   carries one at its leading edge rather than only the ones with a neighbour,
   so all of them are composed identically - and the one at the head of the run
   falls inside the mask, where there is nothing to see anyway. */
.marquee__i::before{
  content:"";
  position:absolute;
  inset-inline-start:0;
  top:50%;
  width:1px;
  height:clamp(24px,2.6vw,32px);
  background:linear-gradient(to bottom,transparent,var(--sky-line),transparent);
  transform:translate(-50%,-50%) rotate(45deg);
}

/* What the lit name sits in: a soft pool of the page's blue with no edge to it
   anywhere. It is behind the name and the maker, both of which stand on a
   z-index of their own. */
.marquee__i::after{
  content:"";
  position:absolute;
  inset:12% 4%;
  z-index:0;
  background:radial-gradient(58% 62% at 50% 46%,var(--sky-wash) 0%,transparent 72%);
  opacity:0;
  transition:opacity .5s var(--ease);
}
.marquee__i:hover::after,
.marquee__i:focus-visible::after{ opacity:1 }

/* Pointed at, the strip steps back and lets one name through. Everything dims,
   the one under the pointer does not, and that is the only thing on the strip
   that says "this one" - which is exactly as much as a brand strip should say.
   The lit rule comes second on purpose: it carries the same weight as the
   dimming rule and has to win. */
.marquee:hover .marquee__i,
.marquee:focus-within .marquee__i{ opacity:.3 }
.marquee .marquee__i:hover,
.marquee .marquee__i:focus-visible{ opacity:1 }
/* While it is being dragged the whole strip is in hand, so nothing on it dims. */
.marquee.is-dragging .marquee__i{ opacity:1 }

/* ---------------------------------------------------------------- the mark */

.bmark{
  position:relative;
  z-index:1;
  display:grid;
  place-items:center;
  min-height:clamp(32px,3.5vw,42px);
}

/* A brand that has artwork shows it, given the treatment its ground asks for:
   lifted off the dark band, pressed down onto the bright one. --mark-filter is
   the one place a mode's treatment is stated, and hover restates it a step
   further.

   An SVG has no size of its own to fall back on, so both dimensions are
   pinned rather than left to `auto`: object-fit does the fitting, and a
   vector mark lands at exactly the height a raster one does. */
.marquee__i .blogo:not(.blogo--files),
.marquee__i .blogo--files img{
  max-height:clamp(32px,4vw,46px);
  height:clamp(32px,4vw,46px);
  max-width:100%;
  width:auto;
  object-fit:contain;
  object-position:center;
  filter:var(--mark-filter,none);
  transition:filter .45s var(--ease);
}
/* The two-artwork wrapper is a box, not a mark: the treatment belongs to the
   image inside it, or it would be applied twice over. */
.marquee__i .blogo--files{ filter:none;max-height:none;height:auto }
.marquee__i .blogo--auto  { --mark-filter:var(--mark-auto) }
.marquee__i .blogo--plain { --mark-filter:var(--mark-plain) }
.marquee__i .blogo--files { --mark-filter:var(--mark-files) }

.marquee__i:hover .blogo--auto,
.marquee__i:focus-visible .blogo--auto{ --mark-filter:var(--mark-auto-hi) }
.marquee__i:hover .blogo--plain,
.marquee__i:focus-visible .blogo--plain{ --mark-filter:var(--mark-plain-hi) }
.marquee__i:hover .blogo--files,
.marquee__i:focus-visible .blogo--files{ --mark-filter:var(--mark-files-hi) }

/* A brand with no artwork is set in the site's own display face, at the size
   the strip is really built around: most of these marques have no mark to give
   us, so a wordmark is the strip's ordinary state rather than its fallback,
   and it is the page's own headline voice one size down. Lit, it takes the
   site's neon - the same halo the headlines wear - and nothing else. */
.bword{
  font-family:var(--display);
  font-variation-settings:"wdth" 108,"wght" 700;
  text-transform:uppercase;
  font-size:clamp(1.12rem,.92rem + .95vw,1.72rem);
  letter-spacing:.008em;
  line-height:1;
  text-align:center;
  color:var(--sky-text);
  opacity:.74;
  transition:opacity .4s var(--ease),text-shadow .45s var(--ease);
}
.marquee__i:hover .bword,
.marquee__i:focus-visible .bword{
  opacity:1;
  text-shadow:var(--neon);
}

/* ---------------------------------------------------------------- the name */

.bmeta{
  position:relative;
  z-index:1;
  display:grid;
  justify-items:center;
  gap:5px;
  text-align:center;
}
.bmeta__n,
.bmeta__m{
  font-family:var(--mono);
  max-width:100%;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
  transition:color .35s var(--ease),opacity .35s var(--ease),
             text-shadow .35s var(--ease);
}
.bmeta__n{
  font-size:clamp(.66rem,.6rem + .2vw,.78rem);
  color:var(--sky-text);
  opacity:.74;
}
.bmeta__m{
  font-size:.55rem;
  letter-spacing:.24em;
  text-transform:uppercase;
  color:var(--sky-dim);
  opacity:.66;
}
.marquee__i:hover .bmeta__n,
.marquee__i:focus-visible .bmeta__n{ opacity:1;text-shadow:var(--neon) }
.marquee__i:hover .bmeta__m,
.marquee__i:focus-visible .bmeta__m{ opacity:1;color:var(--sky-lit) }

/* A finger cannot hover, so on a touch screen the strip travels, nothing dims
   and the names are simply tapped. Holding the animation on :hover there would
   leave it stopped after a tap, with nothing to tell it to start again. */
@media (hover: none){
  .marquee:hover .marquee__track{ animation-play-state:running }
  .marquee:hover .marquee__i{ opacity:1 }
}

/* No JavaScript, or a reader who has asked for less motion: the conveyor
   becomes a plain scrollable strip. Every name is still there, still lit by
   its own hover, and still reachable - it simply does not travel on its own. */
.marquee--static .marquee__track{ animation:none;transform:none !important }
.marquee--static .marquee__vp{ overflow-x:auto;scrollbar-width:thin }
@media (prefers-reduced-motion: reduce){
  .marquee__vp{ overflow-x:auto;scrollbar-width:thin }
  .marquee__track{ animation:none !important;transform:none !important }
  .marquee__i::after{ transition:none }
}



/* ======================================================== 19. utilities */

.stack-sm > * + *{margin-top:12px}
.stack   > * + *{margin-top:22px}
.stack-lg> * + *{margin-top:clamp(30px,4vw,54px)}
.center{text-align:center}
.muted{color:var(--text-secondary)}
.flex{display:flex}
.wrap{flex-wrap:wrap}
.gap{gap:14px}
.mt-lg{margin-top:clamp(30px,4vw,54px)}
.hide{display:none !important}

.split{display:grid;gap:clamp(26px,4vw,60px)}
@media (min-width:900px){
  .split{grid-template-columns:minmax(0,1fr) minmax(0,1fr);align-items:center}
  .split--wide{grid-template-columns:minmax(0,1.15fr) minmax(0,.85fr)}
}

.imgframe{position:relative;overflow:hidden;border:1px solid var(--line)}
.imgframe img{width:100%;height:100%;object-fit:cover}

/* a row of text aligns on the baseline, not on centred boxes */
.baseline{display:flex;align-items:baseline;gap:12px;flex-wrap:wrap}

/* ============================================= 20. mobile navigation */

@media (max-width:900px){
  .burger{display:flex}
  .nav__links{
    position:fixed;inset:var(--nav-h) 0 auto;
    flex-direction:column;align-items:flex-start;gap:0;
    background:var(--nav-solid);
    backdrop-filter:blur(16px);
    border-bottom:1px solid var(--line);
    padding:14px var(--gutter) 24px;
    margin:0;
    transform:translateY(-8px);
    opacity:0;visibility:hidden;
    transition:opacity .3s var(--ease),transform .3s var(--ease-out),visibility .3s;
  }
  .nav__links.is-open{opacity:1;visibility:visible;transform:none}
  .nav__link{width:100%;padding-block:13px;font-size:1.02rem;border-bottom:1px solid var(--line)}
  .langs{margin:16px 0 0}
}

/* ======================================= 21. reduced motion, honoured fully */

@media (prefers-reduced-motion: reduce){
  *,*::before,*::after{
    animation-duration:.001ms !important;
    animation-iteration-count:1 !important;
    transition-duration:.001ms !important;
    transition-delay:0s !important;
    scroll-behavior:auto !important;
  }
  .reveal,.stagger .s-item{opacity:1 !important;transform:none !important}
  .widen__wall--l{transform:translateX(-104%) !important}
  .widen__wall--r{transform:translateX(104%) !important}
  .widen__car{opacity:.9 !important;transform:none !important}
  .widen__answer{opacity:1 !important;transform:none !important}
  .widen__bar{transform:scaleX(1) !important}
  .route path{stroke-dashoffset:0 !important}
  .env,.stars span{animation:none !important}
  .vcard{transform:none !important}
  /* positional transforms are re-applied per breakpoint, never blanket-killed */
  .band{opacity:1}
}

/* paused off-screen and on hidden tabs. animation-play-state does not
   inherit, so this hits every element and pseudo-element directly. */
body.paused *,
body.paused *::before,
body.paused *::after{ animation-play-state:paused !important }

/* decorations never collide with content on short screens */
@media (max-height:620px){ .stars{display:none} }

/* ================================================== 22. page transitions */
/* One consistent transition across the whole site, so navigating between
   home, the catalogue, a vehicle and a brand never snaps. */

.page-in .page{ animation:pageIn .5s var(--ease-out) both }
@keyframes pageIn{ from{opacity:0;transform:translateY(10px)} to{opacity:1;transform:none} }

.page-out .page{ opacity:0;transform:translateY(-6px);
  transition:opacity .26s var(--ease),transform .26s var(--ease) }

@media (prefers-reduced-motion: reduce){
  .page-in .page{animation:none}
  .page-out .page{opacity:1 !important;transform:none !important}
}


/* ================================================== 22b. the opening title */
/* The first thing a visitor sees, for as long as the page underneath needs to
   be ready and not one moment longer.

   It is a title card, not a spinner. The company mark is wiped in from below,
   a wheel crosses the frame behind it right to left at the speed something
   heavy actually moves, a hairline runs under the mark while the page loads,
   and then the whole card lifts away and the home page rises into its place.

   Three rules keep it from ever being in the way:

   - It is timed against the page rather than against a stopwatch. The moment
     the page has drawn AND the mark has had its minimum on screen, it leaves.
     A fast connection sees the short version of the same animation, not a wait
     invented to finish it.
   - It plays once a session. The second page a visitor opens does not replay
     it - the site's ordinary page transition covers that - and neither does a
     reload. Come back tomorrow and it is there again, because it is the front
     door and a front door should be seen on the way in.
   - It cannot get stuck. canora.js clears it when the page is ready, and a
     hard timeout clears it even if nothing else ever runs.

   Everything animated here is a transform, an opacity or a mask position, so
   none of it lands on the main thread while the page underneath is building. */

.intro{
  position:fixed;
  inset:0;
  z-index:400;
  display:grid;
  place-items:center;
  overflow:hidden;
  /* Its own ground, stated here rather than borrowed from the theme: the card
     is the brand's dark, in both themes, the same way the hero is. */
  background:
    radial-gradient(120% 90% at 50% 42%, #1a2027 0%, #12161b 46%, #0c0f13 100%),
    #0c0f13;
  color:#e9f1f8;
  --intro-travel:120vw;
  --intro-roll:-900deg;
  --intro-wheel:clamp(62px,8.2vw,106px);
  /* Where the floor is. The mark sits above it and the wheel runs along it,
     both measured from the same line, so the composition holds together at
     every screen size instead of the line cutting through the wordmark. */
  --intro-floor:calc(50% + clamp(104px,16vh,176px));
}
/* Nothing behind it scrolls while it is up, and nothing behind it is read. */
html.intro-on,
html.intro-on body{ overflow:hidden }

/* The floor the wheel runs on: one hairline, lit in the middle, so the wheel
   has somewhere to be rather than floating in the dark. */
.intro__road{
  position:absolute;
  inset-inline:0;
  top:var(--intro-floor);
  height:1px;
  background:linear-gradient(to right,
    transparent 0%, rgba(233,241,248,.16) 22%,
    rgba(77,153,206,.42) 50%,
    rgba(233,241,248,.16) 78%, transparent 100%);
  transform:scaleX(.2);
  opacity:0;
  animation:introRoad .9s var(--ease-out) .06s both;
}
@keyframes introRoad{
  from{ opacity:0;transform:scaleX(.2) }
  to  { opacity:1;transform:scaleX(1) }
}

.intro__stage{
  position:relative;
  z-index:2;
  display:grid;
  justify-items:center;
  gap:clamp(14px,2vw,22px);
  padding-inline:24px;
  /* Lifted clear of the floor line, so the wheel passes beneath the mark
     rather than through the word. */
  transform:translateY(calc(clamp(104px,16vh,176px) * -0.42));
}

/* The mark, wiped up into view from its own baseline rather than faded in. A
   fade is a page loading; a wipe is a title. */
/* The mask image is twice the height of the mark and black across its bottom
   half, so aligning it to the top hides the mark and sliding it down to the
   bottom uncovers it from the baseline up. */
.intro__logo{
  display:block;
  width:clamp(92px,13vw,148px);
  height:auto;
  -webkit-mask-image:linear-gradient(to top,#000 50%,transparent 50%);
  mask-image:linear-gradient(to top,#000 50%,transparent 50%);
  -webkit-mask-size:100% 200%;
  mask-size:100% 200%;
  -webkit-mask-position:0 0;
  mask-position:0 0;
  animation:introMark .82s var(--ease-out) .08s both;
}
@keyframes introMark{
  from{ -webkit-mask-position:0 0;mask-position:0 0;
        opacity:0;transform:translateY(10px) scale(.96) }
  55% { opacity:1 }
  to  { -webkit-mask-position:0 100%;mask-position:0 100%;
        opacity:1;transform:none }
}

.intro__word{
  font-family:var(--display);
  font-variation-settings:"wdth" 118,"wght" 700;
  text-transform:uppercase;
  font-size:clamp(1.5rem,.9rem + 2.2vw,2.6rem);
  letter-spacing:.16em;
  text-indent:.16em;          /* the tracking pushes right; this recentres it */
  line-height:1;
  opacity:0;
  animation:introWord .8s var(--ease-out) .3s both;
}
@keyframes introWord{
  from{ opacity:0;letter-spacing:.34em;transform:translateY(6px) }
  to  { opacity:1;letter-spacing:.16em;transform:none }
}

/* The hairline under the mark. It is a real measure of the wait rather than a
   loop pretending to be one: canora.js pushes it to 1 the moment the page has
   drawn, and this is what it travels through on the way there. */
.intro__bar{
  position:relative;
  width:clamp(120px,18vw,190px);
  height:1px;
  background:rgba(233,241,248,.14);
  overflow:hidden;
  opacity:0;
  animation:introFade .5s var(--ease-out) .5s both;
}
.intro__bar::after{
  content:"";
  position:absolute;inset:0;
  transform-origin:left center;
  transform:scaleX(var(--p,0));
  background:linear-gradient(to right,rgba(77,153,206,.5),var(--accent-bright));
  transition:transform .5s var(--ease-out);
}
@keyframes introFade{ from{opacity:0} to{opacity:1} }

/* ---------------------------------------------------------------- the wheel */
/* Behind the mark, on the hairline, crossing the frame once. The roll is real:
   canora.js works out how far the wheel has to travel and turns it exactly as
   far as that distance would turn a wheel of its size, so it grips the floor
   instead of sliding along it. */
.intro__wheel{
  position:absolute;
  z-index:1;
  left:50%;
  top:var(--intro-floor);
  width:var(--intro-wheel);
  height:var(--intro-wheel);
  margin-inline-start:calc(var(--intro-wheel) / -2);
  /* Its whole height above the floor, so the tyre meets the line rather than
     straddling it. */
  margin-top:calc(var(--intro-wheel) * -1);
  animation:introWheel 1.34s cubic-bezier(.32,0,.5,1) .16s both;
}
.intro__wheel svg{ width:100%;height:100%;display:block }
@keyframes introWheel{
  from{ transform:translate3d(calc(var(--intro-travel) / 2),0,0) rotate(0deg) }
  to  { transform:translate3d(calc(var(--intro-travel) / -2),0,0) rotate(var(--intro-roll)) }
}

/* The light it drags behind it. Widest at speed, gone by the time it stops
   being a wheel and starts being a shape. */
.intro__wake{
  position:absolute;
  z-index:0;
  left:50%;
  top:calc(var(--intro-floor) - var(--intro-wheel) * .5);
  width:min(52vw,520px);
  height:2px;
  margin-inline-start:calc(min(52vw,520px) / -2);
  background:linear-gradient(to right,
    transparent 0%, rgba(77,153,206,.34) 62%, rgba(190,225,255,.5) 100%);
  filter:blur(1.5px);
  opacity:0;
  animation:introWake 1.34s cubic-bezier(.32,0,.5,1) .16s both;
}
@keyframes introWake{
  0%  { opacity:0;   transform:translate3d(calc(var(--intro-travel) / 2),0,0) scaleX(.3) }
  22% { opacity:.85 }
  78% { opacity:.5 }
  100%{ opacity:0;   transform:translate3d(calc(var(--intro-travel) / -2),0,0) scaleX(1) }
}

/* ------------------------------------------------------------- the way out */
/* The card lifts and the page is already there underneath it, so the join is a
   dissolve rather than a cut. .page-in does the other half. */
.intro.is-out{
  opacity:0;
  transform:scale(1.035);
  transition:opacity .58s var(--ease), transform .72s var(--ease-out);
  pointer-events:none;
}

/* The second page of a session, and any reload: the mark alone, held for a
   moment, with no wheel and no wipe. The brand is still the first thing seen;
   it simply does not perform. */
.intro--brief .intro__wheel,
.intro--brief .intro__wake,
.intro--brief .intro__road{ display:none }
.intro--brief .intro__logo{ animation:introFade .3s var(--ease-out) both }
.intro--brief .intro__word{ animation:introFade .3s var(--ease-out) .05s both }

/* A reader who has asked for less motion gets the card and nothing that
   travels: the mark and the word are simply there, and the card dissolves. */
@media (prefers-reduced-motion: reduce){
  .intro__wheel,
  .intro__wake,
  .intro__road{ display:none }
  .intro__logo,
  .intro__word,
  .intro__bar{ animation:introFade .25s linear both }
  .intro.is-out{ transition:opacity .3s linear;transform:none }
}

/* ==========================================================================
   23. THE NEON
   A glow, not a tube. Two soft halos in the brand blue at low alpha sitting
   under the glyph, so the letterform stays perfectly sharp and the light reads
   as depth rather than decoration. It never animates on its own; it only
   strengthens a little under the cursor. In light mode it is a whisper, because
   a glow on paper is a stain if you push it.
   ========================================================================== */

.vcard__brand,
.vcard__model,
.logowall__t,
.neon{
  text-shadow:var(--neon);
  transition:text-shadow var(--dur) var(--ease), color var(--dur) var(--ease);
}
.vhero__model{ text-shadow:var(--tshadow), var(--neon-strong) }
.neon--strong{ text-shadow:var(--neon-strong) }

.vcard:hover .vcard__model,
.vcard:hover .vcard__brand,
.logowall__i:hover .logowall__t,
a:hover > .neon{ text-shadow:var(--neon-strong) }

/* Over the light contrast band the glow would muddy the type, so it lifts off. */
.section--light .logowall__t,
.section--light .neon{ text-shadow:none }

@media (prefers-reduced-motion: reduce){
  .vcard__brand,.vcard__model,.logowall__t,.neon{ transition:none }
}

/* ==========================================================================
   24. THE THEME SWITCH
   ========================================================================== */

.themer{
  display:inline-flex;align-items:center;
  border:1px solid var(--line-strong);
  background:transparent;
  padding:3px;gap:2px;
  margin-inline-start:10px;
  clip-path:polygon(0 0, calc(100% - 8px) 0, 100% 8px, 100% 100%, 0 100%);
}
[dir="rtl"] .themer{ clip-path:polygon(8px 0, 100% 0, 100% 100%, 0 100%, 0 8px) }
.themer__b{
  display:grid;place-items:center;
  width:30px;height:26px;
  color:var(--text-tertiary);
  transition:color var(--dur) var(--ease), background var(--dur) var(--ease);
}
.themer__b:hover{ color:var(--text-primary) }
.themer__b[aria-pressed="true"]{
  color:var(--accent);
  background:var(--accent-muted);
}
.themer__b svg{width:15px;height:15px}
@media (pointer:coarse){ .themer__b{width:40px;height:38px} }

/* ==========================================================================
   25. FOOTER: address and social
   ========================================================================== */

.footer__addr{
  display:flex;gap:10px;align-items:flex-start;
  color:var(--text-secondary);font-weight:500;
  margin-top:14px;max-width:34ch;line-height:1.6;
}
.footer__addr svg{flex:0 0 auto;margin-top:3px;color:var(--accent)}

.social{display:flex;gap:8px;margin-top:16px;flex-wrap:wrap}
.social__a{
  display:grid;place-items:center;
  width:40px;height:40px;
  border:1px solid var(--line-strong);
  color:var(--text-secondary);
  clip-path:polygon(0 0, calc(100% - 9px) 0, 100% 9px, 100% 100%, 0 100%);
  transition:color var(--dur) var(--ease),
             border-color var(--dur) var(--ease),
             background var(--dur) var(--ease);
}
[dir="rtl"] .social__a{ clip-path:polygon(9px 0, 100% 0, 100% 100%, 0 100%, 0 9px) }
/* the frame and the wash carry the blue; the glyph itself goes to full
   strength, for the same reason the footer's links do */
.social__a:hover{
  color:var(--text-primary);
  border-color:var(--accent);
  background:var(--accent-muted);
}
/* In the footer the icons are contact details like the rest of that column,
   so they take the same blue: the mark's own, glyph and frame, and a halo on
   the glyph alone, because the cut corner clips anything drawn outside it. */
.footer .social__a svg{ transition:filter var(--dur) var(--ease) }
.footer .social__a:hover,
.footer .social__a:focus-visible{
  color:var(--accent-bright);
  border-color:var(--accent-bright);
  background:rgba(77,153,206,.12);
}
.footer .social__a:hover svg,
.footer .social__a:focus-visible svg{ filter:drop-shadow(0 0 5px rgba(77,153,206,.45)) }
@media (pointer:coarse){ .social__a{width:44px;height:44px} }

/* ==========================================================================
   26. THE LOGO PLATE
   The About section shows the company mark rather than a photograph. It sits
   on a designed plate with the Canora cut, at its native square ratio, so it is
   never stretched and never soft.
   ========================================================================== */

.logoplate{
  position:relative;
  aspect-ratio:4/3;
  display:grid;place-items:center;
  border:1px solid var(--line);
  background:
    radial-gradient(62% 52% at 50% 42%, var(--accent-muted), transparent 70%),
    var(--card-stage);
  overflow:hidden;
}
/* The About page shows the mark across the full width of the page rather than
   beside a column of text, so the plate widens and the mark inside it is held
   to a size that keeps it a mark rather than a billboard. */
.logoplate--wide{ aspect-ratio:21/9 }
.logoplate--wide .logoplate__img{ width:min(26%, 260px) }
@media (max-width:700px){
  .logoplate--wide{ aspect-ratio:16/9 }
  .logoplate--wide .logoplate__img{ width:min(44%, 220px) }
}
.logoplate__img{
  width:min(58%, 300px);
  height:auto;
  aspect-ratio:1/1;
  object-fit:contain;
  filter:drop-shadow(0 10px 30px rgba(77,153,206,.22));
}
:root[data-theme="light"] .logoplate__img{
  filter:drop-shadow(0 10px 26px rgba(43,122,176,.20));
}
/* the 45 degree corner brackets, drawn not decorated */
.logoplate::before,
.logoplate::after{
  content:"";position:absolute;width:34px;height:34px;pointer-events:none;
  border:1px solid var(--accent);opacity:.42;
}
.logoplate::before{ top:16px;inset-inline-start:16px;border-width:1px 0 0 1px }
.logoplate::after{ bottom:16px;inset-inline-end:16px;border-width:0 1px 1px 0 }
.logoplate__word{
  position:absolute;inset-block-end:18px;
  font-family:var(--mono);font-size:.68rem;letter-spacing:.22em;
  text-transform:uppercase;color:var(--text-tertiary);
}

/* A long unbroken word must never push a grid cell wider than its column.
   Paired with the minmax(0,1fr) columns above, this makes horizontal overflow
   structurally impossible rather than something to keep re-checking. */
.stat,.spec,.step,.feat,.widen__answer,.vcard__body,.footer__grid > *{
  min-width:0;
}
.stat__l,.spec__l,.mono-label,.vcard__meta,.footer__addr,.kicker{
  overflow-wrap:break-word;
}

/* Three columns of display type never fit inside half a split. Wherever the
   stats sit beside a headline they stack into a list, which reads better than
   three cramped columns and cannot clip. Full-width stats keep their row. */
.split .stats{ grid-template-columns:minmax(0,1fr) }
.split .stat{ display:flex;align-items:baseline;gap:16px;flex-wrap:wrap }
.split .stat__v{ font-size:clamp(1.5rem,1rem + 1.4vw,2rem);flex:0 0 auto }
.split .stat__l{ margin-top:0;flex:1 1 12ch }

/* On a phone the eight filters belong in the drawer, not stacked down the page
   pushing the cars out of sight. The FILTERS button exists for exactly this.
   Scoped to .js so that without JavaScript the filters stay visible and the
   plain form still works. */
@media (max-width:699px){
  .js .filterbar .filters{ display:none }
  .js .drawer .filters{ display:grid }
}

/* ==========================================================================
   27. THE THREE SECRETS
   Hidden rewards, found in things that were already on the page: the logo
   plate, a vehicle's photograph, and the end of the route line. Nothing in
   this section draws anything until eggs.js has armed an egg the dashboard
   switched on, so with all three off the site is pixel for pixel the site it
   was. What a discovery shows is a card in the site's own language - the
   cut, the mono kicker, the hairline, the display face - and a moment that
   belongs to where it was found. No confetti, no burst, nothing that loops.
   ========================================================================== */

/* ------------------------------------------------ the line on the request form */
/* A reward already found on this device, attached to the request. */
.req-reward{margin-top:14px;align-items:center;flex-wrap:wrap;gap:8px 10px}
.req-reward:not([hidden]){display:flex}
.req-reward__i{
  font-family:var(--mono);font-size:.72rem;letter-spacing:.12em;text-transform:uppercase;
  color:var(--text-primary);border:1px solid var(--accent);background:var(--accent-muted);
  padding:5px 10px;
}

/* ------------------------------------------------------------------ the card */
.egg{
  position:fixed;z-index:180;inset-inline:0;bottom:0;
  display:flex;justify-content:center;
  padding:0 16px calc(16px + env(safe-area-inset-bottom, 0px));
  pointer-events:none;
  /* The shadow is a filter on the wrapper, because the card's cut corner is a
     clip-path and would throw a box-shadow away. */
  filter:drop-shadow(0 26px 44px rgba(0,0,0,.55));
}
:root[data-theme="light"] .egg{ filter:drop-shadow(0 22px 40px rgba(31,45,58,.24)) }
@media (min-width:760px){ .egg{ padding-bottom:28px } }

.egg__card{
  pointer-events:auto;position:relative;overflow:hidden;
  width:min(100%, 446px);
  padding:24px 24px 22px;
  background:var(--canvas-2);
  border:1px solid var(--line-strong);
  clip-path:polygon(0 0, calc(100% - var(--cut)) 0, 100% var(--cut), 100% 100%, 0 100%);
  animation:eggIn .56s var(--ease-out) both;
}
[dir="rtl"] .egg__card{ clip-path:polygon(var(--cut) 0, 100% 0, 100% 100%, 0 100%, 0 var(--cut)) }

/* the hairline along the top, drawn in on arrival */
.egg__rule{
  position:absolute;top:0;inset-inline:0;height:1px;
  background:linear-gradient(to right, transparent, var(--accent) 22%, var(--accent) 78%, transparent);
  transform:scaleX(0);
  animation:eggRule .8s var(--ease-out) .08s both;
}
.egg__pin{ display:none }
.egg__light{ position:absolute;inset:0;pointer-events:none;opacity:0 }

.egg__kicker{
  font-family:var(--mono);font-size:.7rem;font-weight:500;letter-spacing:.2em;
  text-transform:uppercase;color:var(--accent);
}
.egg__h{
  margin-top:10px;
  font-family:var(--display);font-variation-settings:"wdth" 114,"wght" 700;
  text-transform:uppercase;font-size:clamp(1.3rem,1.05rem + 1vw,1.7rem);
  line-height:1.06;letter-spacing:-.005em;max-width:18ch;
}
html[dir="rtl"] .egg__h{ line-height:1.35;max-width:none }
.egg__offer{
  margin-top:10px;font-size:1.02rem;font-weight:600;line-height:1.55;color:var(--text-secondary);
}
.egg__code{
  margin-top:16px;display:grid;grid-template-columns:minmax(0,1fr) auto;align-items:center;
  gap:4px 12px;padding:11px 11px 11px 14px;
  background:var(--canvas);border:1px solid var(--line);
}
[dir="rtl"] .egg__code{ padding:11px 14px 11px 11px }
.egg__code-l{
  grid-column:1 / -1;font-family:var(--mono);font-size:.64rem;letter-spacing:.16em;
  text-transform:uppercase;color:var(--text-tertiary);
}
.egg__code-v{
  font-family:var(--mono);font-size:1.12rem;letter-spacing:.12em;color:var(--text-primary);
  -webkit-user-select:all;user-select:all;overflow-wrap:anywhere;
  text-align:start;
}
[dir="rtl"] .egg__code-v{ text-align:end }
.egg__copy{
  min-height:38px;padding:8px 14px;
  font-family:var(--mono);font-size:.68rem;letter-spacing:.14em;text-transform:uppercase;
  color:var(--text-primary);border:1px solid var(--line-strong);
  transition:border-color .2s var(--ease-out),color .2s var(--ease-out),background .2s var(--ease-out);
}
.egg__copy:hover{ border-color:var(--accent);background:var(--hover-veil) }
.egg__copy.is-done{ border-color:var(--hot);color:var(--hot) }
.egg__note{ margin-top:12px;font-size:.88rem;line-height:1.55;color:var(--text-tertiary) }
.egg__acts{ margin-top:18px;display:flex;flex-wrap:wrap;gap:10px }
.egg__acts .btn{ padding:12px 20px;font-size:.84rem }
@media (max-width:420px){ .egg__acts .btn{ flex:1 1 auto } }

/* everything inside rises in order behind the card */
.egg__kicker,.egg__h,.egg__offer,.egg__code,.egg__note,.egg__acts{
  animation:eggRise .5s var(--ease-out) both;
}
.egg__kicker{ animation-delay:.1s }
.egg__h{ animation-delay:.16s }
.egg__offer{ animation-delay:.22s }
.egg__code{ animation-delay:.28s }
.egg__note{ animation-delay:.33s }
.egg__acts{ animation-delay:.38s }

.egg.is-out .egg__card{ animation:eggOut .34s var(--ease) both }

@keyframes eggIn{ from{opacity:0;transform:translateY(18px)} to{opacity:1;transform:none} }
@keyframes eggOut{ from{opacity:1;transform:none} to{opacity:0;transform:translateY(12px)} }
@keyframes eggRise{ from{opacity:0;transform:translateY(8px)} to{opacity:1;transform:none} }
@keyframes eggRule{ from{transform:scaleX(0)} to{transform:scaleX(1)} }

/* 01, the mark: the kicker's tracking settles the way the title card's word does */
.egg--1 .egg__kicker{ animation:eggTrack .8s var(--ease-out) .1s both }
@keyframes eggTrack{ from{opacity:0;letter-spacing:.42em} to{opacity:1;letter-spacing:.2em} }

/* 02, the drive: the card arrives from the side the reading starts on, and a
   headlight passes over it */
.egg--2 .egg__card{ animation-name:eggInSide }
[dir="rtl"] .egg--2 .egg__card{ animation-name:eggInSideRtl }
.egg--2 .egg__rule{ transform-origin:left center }
[dir="rtl"] .egg--2 .egg__rule{ transform-origin:right center }
.egg--2 .egg__light{
  inset:0 auto 0 0;width:60%;
  background:linear-gradient(100deg, transparent 0%, rgba(160,205,240,.10) 45%, rgba(233,241,248,.16) 52%, transparent 100%);
  animation:eggBeam 1.1s var(--ease-out) .12s both;
}
[dir="rtl"] .egg--2 .egg__light{ inset:0 0 0 auto;animation-name:eggBeamRtl }
:root[data-theme="light"] .egg--2 .egg__light{
  background:linear-gradient(100deg, transparent 0%, rgba(43,122,176,.07) 45%, rgba(43,122,176,.11) 52%, transparent 100%);
}
@keyframes eggInSide{ from{opacity:0;transform:translate3d(-22px,10px,0)} to{opacity:1;transform:none} }
@keyframes eggInSideRtl{ from{opacity:0;transform:translate3d(22px,10px,0)} to{opacity:1;transform:none} }

/* 03, the route: the hairline is drawn from where the reading starts, and ends
   on the same point of light the line ended on */
.egg--3 .egg__rule{ transform-origin:left center;animation-duration:1s }
[dir="rtl"] .egg--3 .egg__rule{ transform-origin:right center }
.egg--3 .egg__pin{
  display:block;position:absolute;top:-3px;inset-inline-end:22%;
  width:7px;height:7px;background:var(--accent);transform:rotate(45deg);
  opacity:0;animation:eggFade .4s var(--ease-out) .9s both;
}
@keyframes eggFade{ from{opacity:0} to{opacity:1} }

/* ------------------------------------------------------- 01 · the logo plate */
.logoplate.egg-armed{
  -webkit-user-select:none;user-select:none;
  touch-action:manipulation;-webkit-tap-highlight-color:transparent;
}
/* The corner marks answer a third, fourth tap - barely. Unset, this is the
   plate's own .42. */
.logoplate.egg-armed::before,
.logoplate.egg-armed::after{
  opacity:calc(.42 + var(--egg-taps, 0) * .16);
  transition:opacity .35s var(--ease);
}
.egg-sheen{
  position:absolute;inset:-30%;pointer-events:none;opacity:0;
  background:linear-gradient(115deg, transparent 40%, rgba(190,225,255,.15) 50%, transparent 60%);
  transform:translate3d(-60%,0,0);
}
:root[data-theme="light"] .egg-sheen{
  background:linear-gradient(115deg, transparent 40%, rgba(43,122,176,.12) 50%, transparent 60%);
}
.egg-found--mark .egg-sheen{ animation:eggSheen .82s var(--ease-out) both }
[dir="rtl"] .egg-found--mark .egg-sheen{ animation-name:eggSheenRtl }
.egg-found--mark::before,
.egg-found--mark::after{ animation:eggBracket .82s var(--ease-out) both }
.egg-found--mark .logoplate__img{ animation:eggMark .82s var(--ease-out) both }
@keyframes eggSheen{
  0%{opacity:0;transform:translate3d(-60%,0,0)} 25%{opacity:1} 100%{opacity:0;transform:translate3d(60%,0,0)}
}
@keyframes eggSheenRtl{
  0%{opacity:0;transform:translate3d(60%,0,0)} 25%{opacity:1} 100%{opacity:0;transform:translate3d(-60%,0,0)}
}
@keyframes eggBracket{ 0%{opacity:.42;transform:none} 40%{opacity:1;transform:scale(1.22)} 100%{opacity:.42;transform:none} }
@keyframes eggMark{ 0%{transform:none} 40%{transform:scale(1.03)} 100%{transform:none} }

/* ---------------------------------------------------- 02 · the vehicle hero */
.vhero.egg-armed .vhero__stage,
.vhero.egg-armed .vhero__scrim{ -webkit-touch-callout:none }
.vhero.egg-holding{ -webkit-user-select:none;user-select:none }

/* the hairline along the foot of the picture, while the press is held */
.egg-gauge{
  position:absolute;z-index:3;inset-inline:0;bottom:0;height:2px;pointer-events:none;
  background:linear-gradient(to right, rgba(77,153,206,.3), var(--accent-bright));
  transform:scaleX(0);transform-origin:left center;opacity:0;
  transition:transform .35s var(--ease-out),opacity .35s var(--ease);
}
[dir="rtl"] .egg-gauge{
  transform-origin:right center;
  background:linear-gradient(to left, rgba(77,153,206,.3), var(--accent-bright));
}
.egg-holding .egg-gauge{
  transform:scaleX(1);opacity:1;
  transition:transform 1.15s linear,opacity .2s var(--ease);
}
.egg-found--drive .egg-gauge{ animation:eggGauge .9s var(--ease) both }
@keyframes eggGauge{ from{transform:scaleX(1);opacity:1} to{transform:scaleX(1);opacity:0} }

/* a headlight crossing the photograph, over the scrim and under the words */
.egg-beam{
  position:absolute;z-index:1;inset-block:0;inset-inline-start:0;width:46%;
  pointer-events:none;opacity:0;
  background:linear-gradient(100deg, transparent 0%, rgba(160,205,240,.12) 42%, rgba(233,241,248,.2) 52%, transparent 100%);
  transform:translate3d(-100%,0,0);
}
.egg-found--drive .egg-beam{ animation:eggBeam .9s var(--ease-out) both }
[dir="rtl"] .egg-found--drive .egg-beam{ animation-name:eggBeamRtl }
@keyframes eggBeam{
  0%{opacity:0;transform:translate3d(-100%,0,0)} 20%{opacity:1} 100%{opacity:0;transform:translate3d(230%,0,0)}
}
@keyframes eggBeamRtl{
  0%{opacity:0;transform:translate3d(100%,0,0)} 20%{opacity:1} 100%{opacity:0;transform:translate3d(-230%,0,0)}
}

/* ----------------------------------------------------- 03 · the route's end */
/* Placed on the last point of whichever line the layout is showing: the row's
   path ends 20/1200 of the width from the far edge, 4px down; the column's
   ends 4.8px in from its side, 1180/1200 of the way down. Logical insets, so
   right to left - where the line itself is mirrored - it lands on the end
   there too. The box is a comfortable 44px target around a 7px point. */
.egg-end{
  position:absolute;z-index:2;width:44px;height:44px;padding:0;
  top:-18px;inset-inline-end:calc(100% * 20 / 1200 - 22px);
  opacity:0;pointer-events:none;cursor:pointer;
  -webkit-tap-highlight-color:transparent;
  transition:opacity .7s var(--ease);
}
@media (max-width:899.98px){
  .egg-end{ top:calc(100% * 1180 / 1200 - 22px);inset-inline-end:auto;inset-inline-start:-17.2px }
}
.egg-end::before,
.egg-end::after{ content:"";position:absolute;left:50%;top:50%;pointer-events:none }
.egg-end::before{
  width:7px;height:7px;margin:-3.5px 0 0 -3.5px;
  background:var(--accent);transform:rotate(45deg);
  box-shadow:0 0 0 3px var(--accent-muted), 0 0 10px var(--accent-glow);
}
.egg-end::after{
  width:18px;height:18px;margin:-9px 0 0 -9px;
  border:1px solid var(--accent);opacity:0;transform:rotate(45deg) scale(.4);
}
.egg-lit .egg-end{ opacity:1;pointer-events:auto }
.egg-lit .egg-end::before{ animation:eggPin 2.8s var(--ease) infinite }
body.paused .egg-lit .egg-end::before{ animation-play-state:paused }
.egg-found--route .egg-end{ opacity:1 }
.egg-found--route .egg-end::after{ animation:eggRing .8s var(--ease-out) .72s both }
@keyframes eggPin{ 0%,100%{opacity:.55} 50%{opacity:1} }
@keyframes eggRing{
  from{opacity:.9;transform:rotate(45deg) scale(.4)} to{opacity:0;transform:rotate(45deg) scale(2.4)}
}

/* the light that runs the road: one short dash, carried from start to end */
.route path.egg-comet{
  opacity:1;
  stroke:var(--accent);
  stroke-dasharray:90 var(--len,1200);
  stroke-dashoffset:90;
  animation:eggComet 1s var(--ease-out) forwards;
}
@keyframes eggComet{ from{stroke-dashoffset:90} to{stroke-dashoffset:calc(var(--len,1200) * -1)} }

/* A reader who has asked for less motion: the card simply appears, and the
   moments on the page do not happen at all (eggs.js skips them too). */
@media (prefers-reduced-motion: reduce){
  .egg__card,.egg__kicker,.egg__h,.egg__offer,.egg__code,.egg__note,.egg__acts,
  .egg__rule,.egg__pin{ animation:eggFade .2s linear both !important }
  .egg__rule{ transform:none }
  .egg.is-out .egg__card{ animation:eggOut .2s linear both !important }
  .egg__light,.egg-sheen,.egg-beam,.route path.egg-comet{ display:none }
  .egg-gauge{ transition:none }
  .egg-lit .egg-end::before{ animation:none }
}

/* ==========================================================================
   The two lines the site says about itself.

   A notice, not a decoration: it appears only when the database could not be
   reached, which is the one case where an empty catalogue would otherwise read
   as a company with nothing to sell. It sits under the navigation, in the
   site's own type and its own accent, and takes no more room than it needs.
   ========================================================================== */

.sysnote{
  width:100%;
  max-width:var(--shell);
  margin:calc(var(--nav-h) + 18px) auto 0;
  padding:14px 18px;
  display:flex;
  flex-wrap:wrap;
  align-items:baseline;
  gap:4px 12px;
  border:1px solid var(--line);
  border-inline-start:3px solid var(--accent);
  border-radius:2px;
  background:var(--panel);
}
/* Every page that has a hero puts its own top padding under the navigation,
   so the notice above one needs none of its own. */
.has-dark-hero .sysnote{margin-top:calc(var(--nav-h) + 12px)}

.sysnote__h{
  font-family:var(--mono);
  font-size:.76rem;
  font-weight:500;
  letter-spacing:.12em;
  text-transform:uppercase;
  color:var(--accent);
}
.sysnote__d{
  color:var(--text-secondary);
  font-size:.95rem;
  line-height:1.55;
}

@media (max-width:700px){
  .sysnote{margin-inline:var(--gutter);width:auto}
}

/* --------------------------------------------------- the rest of the list
   The catalogue and a brand page answer one page of results at a time. This
   is the end of that page: how far through the list the visitor is, and the
   way to the next one. It is only ever drawn when there is more to show. */

.results__more{
  display:flex;
  flex-direction:column;
  align-items:center;
  gap:14px;
  padding-block:clamp(34px,5vw,56px);
}
.results__shown{color:var(--text-tertiary)}
.results__failed{color:var(--accent);margin:0}


/* ==========================================================================
   28. SEARCH AND COMPARISON

   The vehicle search's suggestions (search.js), the Compare buttons and the
   bar that collects them (compare.js), the chosen-filter chips on the
   catalogue, and the comparison page itself (pages/compare.js).

   One colour carries every "this is chosen" and "this differs" in here: the
   Canora green, --hot, the site's single action colour. Nothing new is added
   to the palette. Every side is a logical property, so Arabic and Kurdish
   mirror without rules of their own, except where a drawn arrow has to turn.
   ========================================================================== */

/* ---- the Compare button on a card ------------------------------------- */
/* On the picture's lower corner - the upper ones hold the Featured badge and
   the Canora cut - in the badge's own frosted treatment, and filled with the
   green once the vehicle is chosen. */
.vcmp{
  position:absolute;z-index:4;
  inset-block-end:12px;inset-inline-end:12px;
  display:inline-flex;align-items:center;gap:7px;
  min-height:34px;padding:7px 12px;
  font-family:var(--mono);font-size:.62rem;font-weight:500;letter-spacing:.14em;text-transform:uppercase;
  color:var(--text-primary);
  background:var(--badge-bg);
  border:1px solid var(--line-strong);
  backdrop-filter:blur(6px);
  cursor:pointer;
  transition:background var(--dur) var(--ease),border-color var(--dur) var(--ease),color var(--dur) var(--ease);
}
.vcmp:hover{border-color:var(--hot)}
.vcmp:focus-visible{outline:2px solid var(--hot);outline-offset:2px}
.vcmp[aria-pressed="true"]{background:var(--hot);border-color:var(--hot);color:var(--hot-ink)}
.vcmp__i{flex:0 0 auto}
.vcmp__tick,
.vcmp[aria-pressed="true"] .vcmp__plus,
.vhero__cmp.is-on .vcmp__plus{display:none}
.vcmp[aria-pressed="true"] .vcmp__tick,
.vhero__cmp.is-on .vcmp__tick{display:inline}
@media (pointer:coarse){ .vcmp{min-height:40px;padding:9px 13px} }

/* the vehicle page's own button, among the hero's two */
.vhero__cmp{gap:9px}
.vhero__cmp.is-on{border-color:var(--hot);color:var(--hot)}

/* ---- the magnifier in the menu ----------------------------------------- */
.navsearch{
  order:2;flex:0 0 auto;
  display:grid;place-items:center;width:40px;height:40px;
  color:var(--text-secondary);
  border:1px solid transparent;
  transition:color var(--dur) var(--ease),border-color var(--dur) var(--ease);
}
.navsearch:hover,.navsearch[aria-expanded="true"]{color:var(--text-primary);border-color:var(--line-strong)}
@media (max-width:900px){
  .navsearch{margin-inline-start:auto;width:44px;height:44px}
  .burger{order:3;margin-inline-start:4px}
}

.navsearch__panel{
  position:fixed;inset-inline:0;top:var(--nav-h);z-index:99;
  background:var(--nav-solid);backdrop-filter:blur(16px);
  border-bottom:1px solid var(--line);
  padding-block:16px;
  opacity:0;transform:translateY(-6px);
  transition:opacity .25s var(--ease),transform .3s var(--ease-out);
}
.navsearch__panel.is-open{opacity:1;transform:none}
.navsearch__panel[hidden]{display:none}
.navsearch__inner{display:flex;gap:12px;align-items:center;justify-content:center}
.navsearch__form{flex:1 1 auto;min-width:0;max-width:760px}
.navsearch__box{position:relative}
.navsearch__glass{position:absolute;inset-inline-start:14px;top:24px;transform:translateY(-50%);
  color:var(--text-tertiary);pointer-events:none}
.navsearch__q{padding-inline-start:42px;height:48px}
.navsearch__x{flex:0 0 auto}

/* ---- the suggestions --------------------------------------------------- */
.srch{position:relative}
.srch__pop{
  position:absolute;z-index:60;inset-inline:0;top:calc(100% + 6px);
  min-width:min(100%,300px);
  max-height:min(460px,64vh);overflow-y:auto;overscroll-behavior:contain;
  background:var(--panel);border:1px solid var(--line-strong);
  box-shadow:var(--card-shadow);
}
.srch__pop[hidden]{display:none}
.srch__state{
  display:flex;flex-wrap:wrap;align-items:center;gap:6px 10px;margin:0;
  padding:12px 15px;color:var(--text-tertiary);font-size:.92rem;line-height:1.55;
}
.srch__state[hidden]{display:none}
.srch__state--none{flex-direction:column;align-items:flex-start;gap:2px}
.srch__state--none strong{color:var(--text-secondary);font-weight:600}
.srch__state--error{color:var(--text-secondary);border-inline-start:3px solid var(--accent)}
.srch__spin{
  width:14px;height:14px;flex:0 0 auto;border-radius:50%;
  border:2px solid var(--line-strong);border-top-color:var(--hot);
  animation:srch-spin .8s linear infinite;
}
@keyframes srch-spin{to{transform:rotate(360deg)}}
.srch__list{list-style:none;margin:0;padding:6px 0;transition:opacity .2s var(--ease)}
.srch__list:empty{display:none}
.srch__list.is-stale{opacity:.45}
.srch__o{
  display:flex;align-items:center;gap:12px;
  padding:9px 14px;cursor:pointer;
  border-inline-start:2px solid transparent;
}
.srch__o.is-active{background:var(--panel-2);border-inline-start-color:var(--hot)}
.srch__img{
  flex:0 0 64px;width:64px;height:40px;overflow:hidden;
  display:grid;place-items:center;
  background:var(--card-stage);color:var(--line-strong);
}
.srch__img img{width:100%;height:100%;object-fit:cover}
.srch__img svg{width:70%;height:auto}
.srch__txt{min-width:0;display:flex;flex-direction:column;gap:2px}
.srch__b{font-family:var(--mono);font-size:.6rem;letter-spacing:.16em;text-transform:uppercase;color:var(--accent)}
.srch__m{font-weight:600;color:var(--text-primary);line-height:1.3;overflow-wrap:anywhere}
.srch__meta{display:flex;flex-wrap:wrap;gap:2px 8px;font-size:.8rem;color:var(--text-tertiary);line-height:1.4}
.srch__meta i{font-style:normal;opacity:.5}
.srch__o--all{
  justify-content:space-between;
  margin-top:4px;padding-block:12px;border-top:1px solid var(--line);
  font-family:var(--mono);font-size:.68rem;letter-spacing:.12em;text-transform:uppercase;color:var(--accent);
}
[dir="rtl"] .srch__o--all svg{transform:scaleX(-1)}
html[dir="rtl"] .srch__m,html[dir="rtl"] .srch__state{line-height:1.7}

/* Room for a picture, a name and a line of details, on a wide screen. */
@media (min-width:700px){ .catsearch .srch__pop{min-width:420px} }

/* The catalogue's search sits in the bar's fold, which clips while it rolls.
   While the suggestions are open the fold lets them out. */
.catsearch{position:relative}
.filterbar:not(.is-folded) .filterbar__fold:has(.srch.is-open){overflow:visible}

/* ---- the chosen filters, as chips --------------------------------------- */
.fchips{display:flex;flex-wrap:wrap;gap:8px;margin-top:14px}
.fchips[hidden]{display:none}
.filterbar.is-folded .fchips{flex-wrap:nowrap;overflow-x:auto;scrollbar-width:none;margin-top:10px}
.filterbar.is-folded .fchips::-webkit-scrollbar{display:none}
.fchip{
  flex:0 0 auto;max-width:100%;
  display:inline-flex;align-items:center;gap:8px;
  padding:6px 10px;padding-inline-start:12px;
  border:1px solid var(--hot);
  background:rgba(81,196,128,.12);
  background:color-mix(in srgb,var(--hot) 12%,transparent);
  color:var(--text-primary);font-size:.84rem;font-weight:600;line-height:1.35;
  transition:background var(--dur) var(--ease);
}
.fchip:hover{background:color-mix(in srgb,var(--hot) 24%,transparent)}
.fchip:focus-visible{outline:2px solid var(--hot);outline-offset:2px}
.fchip__t{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:32ch}
.fchip svg{flex:0 0 auto;opacity:.75}
#clear-filters[hidden]{display:none}

/* ---- the bar at the foot of the screen ---------------------------------- */
body.has-ctray{padding-bottom:96px}
.ctray{
  position:fixed;z-index:90;
  inset-inline:var(--gutter);bottom:max(14px,env(safe-area-inset-bottom));
  max-width:560px;margin-inline:auto;
  background:var(--nav-solid);backdrop-filter:blur(14px);
  border:1px solid var(--line-strong);box-shadow:var(--card-shadow);
  transform:translateY(16px);opacity:0;
  transition:transform .4s var(--ease-out),opacity .3s var(--ease);
}
.ctray.is-in{transform:none;opacity:1}
.ctray__bar{display:flex;align-items:center;gap:10px;padding:10px}
.ctray__toggle{
  flex:1 1 auto;min-width:0;
  display:flex;align-items:center;gap:12px;
  padding:4px 6px;text-align:start;color:var(--text-primary);
}
.ctray__toggle:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
.ctray__thumbs{display:flex;gap:4px;flex:0 0 auto}
.ctray__thumb{display:block;width:40px;height:26px;overflow:hidden;background:var(--card-stage);border:1px solid var(--line)}
.ctray__thumb img{width:100%;height:100%;object-fit:cover;display:block}
.ctray__thumb--empty{background:transparent;border-style:dashed}
.ctray__label{display:flex;flex-direction:column;min-width:0;line-height:1.3}
.ctray__label strong{font-family:var(--mono);font-size:.68rem;font-weight:500;letter-spacing:.14em;text-transform:uppercase}
.ctray__n{font-size:.84rem;color:var(--text-tertiary);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.ctray__caret{flex:0 0 auto;margin-inline-start:auto;color:var(--text-tertiary);transition:transform var(--dur) var(--ease)}
.ctray.is-expanded .ctray__caret{transform:rotate(180deg)}
.ctray__go{flex:0 0 auto;padding:12px 18px}
.ctray__go.is-off{opacity:.5;cursor:not-allowed}
.ctray__panel{padding:12px 12px 10px;border-bottom:1px solid var(--line)}
.ctray__panel[hidden]{display:none}
.ctray__list{list-style:none;margin:0;padding:0;display:grid;gap:8px}
.ctray__row{display:flex;align-items:center;gap:12px}
.ctray__pic{flex:0 0 auto;width:56px;height:36px;overflow:hidden;background:var(--card-stage)}
.ctray__pic img{width:100%;height:100%;object-fit:cover;display:block}
.ctray__ph{display:block;width:100%;height:100%}
.ctray__name{flex:1 1 auto;min-width:0;font-weight:600;line-height:1.35;overflow-wrap:anywhere}
.ctray__name small{display:block;font-size:.8rem;font-weight:500;color:var(--text-tertiary)}
.ctray__x{
  flex:0 0 auto;width:38px;height:38px;display:grid;place-items:center;
  color:var(--text-tertiary);border:1px solid transparent;
  transition:color var(--dur) var(--ease),border-color var(--dur) var(--ease);
}
.ctray__x:hover{color:var(--text-primary);border-color:var(--line-strong)}
.ctray__foot{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:10px;margin-top:12px}
.ctray__need{margin:0;font-size:.88rem;color:var(--text-secondary)}
@media (max-width:560px){
  .ctray{inset-inline:10px;bottom:max(10px,env(safe-area-inset-bottom))}
  .ctray__thumbs{display:none}
  .ctray__go{padding:11px 14px}
}

/* ---- the fourth vehicle's window ----------------------------------------- */
.cdlg{position:fixed;inset:0;z-index:160;display:grid;place-items:center;padding:var(--gutter)}
.cdlg__veil{position:absolute;inset:0;background:var(--veil);backdrop-filter:blur(3px);opacity:0;transition:opacity .3s var(--ease)}
.cdlg__panel{
  position:relative;width:min(100%,480px);max-height:calc(100vh - 40px);overflow-y:auto;
  padding:26px;background:var(--canvas-2);border:1px solid var(--line-strong);box-shadow:var(--card-shadow);
  opacity:0;transform:translateY(10px);
  transition:opacity .3s var(--ease),transform .4s var(--ease-out);
}
.cdlg.is-open .cdlg__veil,.cdlg.is-open .cdlg__panel{opacity:1;transform:none}
.cdlg__h{
  margin-top:10px;
  font-family:var(--display);font-variation-settings:"wdth" 112,"wght" 700;
  text-transform:uppercase;font-size:1.3rem;line-height:1.15;
}
.cdlg__d{margin-top:10px;color:var(--text-secondary);line-height:1.6}
.cdlg__list{list-style:none;margin:18px 0 0;padding:0;display:grid;gap:8px}
.cdlg__row{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:10px 12px;background:var(--panel);border:1px solid var(--line)}
.cdlg__name{min-width:0;font-weight:600;line-height:1.35;overflow-wrap:anywhere}
.cdlg__name small{display:block;font-size:.82rem;font-weight:500;color:var(--text-tertiary)}
.cdlg__keep{width:100%;margin-top:18px}
html[dir="rtl"] .cdlg__h{line-height:1.4}

/* ---- the comparison page ------------------------------------------------- */
.cmp-top{padding-top:calc(var(--nav-h) + clamp(46px,7vw,92px));padding-bottom:clamp(18px,3vw,30px)}
.cmp-wrap{padding-bottom:clamp(30px,5vw,60px)}
.cmp-foot{padding-block:clamp(26px,4vw,44px) 0}
.cmp-warranty{
  max-width:80ch;margin:0;padding-inline-start:14px;
  border-inline-start:2px solid var(--line-strong);
  color:var(--text-tertiary);font-size:.92rem;line-height:1.65;
}
.cmp-notice{
  margin:0 0 18px;padding:12px 16px;
  background:var(--panel);border:1px solid var(--line);border-inline-start:3px solid var(--hot);
  color:var(--text-secondary);line-height:1.55;
}

/* the switches and the key */
.cmp-tools{
  display:flex;flex-wrap:wrap;align-items:center;gap:12px 24px;
  padding:6px 0 18px;margin-bottom:22px;border-bottom:1px solid var(--line);
}
.cmp-switch{position:relative;display:inline-flex;align-items:center;gap:10px;cursor:pointer;
  font-weight:600;font-size:.95rem;color:var(--text-secondary)}
.cmp-switch input{position:absolute;inset-inline-start:0;top:50%;width:38px;height:22px;margin:0;
  transform:translateY(-50%);opacity:0;cursor:pointer}
.cmp-switch__t{
  position:relative;flex:0 0 auto;width:38px;height:22px;border-radius:999px;
  background:var(--canvas-2);border:1px solid var(--line-strong);
  transition:background .25s var(--ease),border-color .25s var(--ease);
}
.cmp-switch__t::after{
  content:"";position:absolute;top:3px;inset-inline-start:3px;width:14px;height:14px;border-radius:50%;
  background:var(--text-tertiary);
  transition:transform .25s var(--ease-out),background .25s var(--ease);
}
.cmp-switch input:checked + .cmp-switch__t{background:var(--hot);border-color:var(--hot)}
.cmp-switch input:checked + .cmp-switch__t::after{background:var(--hot-ink);transform:translateX(16px)}
[dir="rtl"] .cmp-switch input:checked + .cmp-switch__t::after{transform:translateX(-16px)}
.cmp-switch input:focus-visible + .cmp-switch__t{outline:2px solid var(--accent);outline-offset:2px}
.cmp-switch input:disabled,.cmp-switch input:disabled ~ span{cursor:not-allowed;opacity:.5}
.cmp-switch:hover .cmp-switch__t{border-color:var(--text-tertiary)}
.cmp-legend{display:flex;flex-wrap:wrap;gap:8px 18px;margin:0;margin-inline-start:auto;padding:0;list-style:none;
  font-size:.84rem;color:var(--text-tertiary)}
.cmp-legend li{display:inline-flex;align-items:center;gap:8px}

/* The three markers. A difference is the Canora triangle in green, a gap is
   an open dashed ring - present, but hollow - and figures that cannot be
   lined up are a hollow diamond in the site's blue. Shape as well as colour,
   so none of them depends on telling colours apart. */
.cmp-mark{display:inline-block;flex:0 0 auto;width:9px;height:9px}
.cmp-mark--diff{background:var(--hot);clip-path:polygon(0 0,100% 0,100% 100%)}
[dir="rtl"] .cmp-mark--diff{clip-path:polygon(0 0,100% 0,0 100%)}
.cmp-mark--gap{border:1.5px dashed var(--text-tertiary);border-radius:50%}
.cmp-mark--apart{width:8px;height:8px;border:1.5px solid var(--accent);transform:rotate(45deg)}

/* the columns: the label column, then one per vehicle, then the empty one */
.cmp-grid{--lw:minmax(150px,1.05fr);position:relative}
.cmp-head,.cmp-row,.cmp-mini__in{
  display:grid;
  grid-template-columns:var(--lw) repeat(var(--cols),minmax(0,1fr));
  column-gap:clamp(10px,1.6vw,22px);
}
.cmp-head{align-items:stretch;padding-bottom:22px}

.cmp-car{display:flex;flex-direction:column;min-width:0;background:var(--panel);border:1px solid var(--line)}
.cmp-car__stage{position:relative;display:block;aspect-ratio:16/10;overflow:hidden;background:var(--card-stage)}
.cmp-car__stage picture,.cmp-car__img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}
.cmp-car__body{flex:1 1 auto;display:flex;flex-direction:column;gap:8px;padding:14px 14px 16px}
.cmp-car__brand{font-family:var(--mono);font-size:.64rem;letter-spacing:.16em;text-transform:uppercase;color:var(--accent)}
.cmp-car__model{
  font-family:var(--display);font-variation-settings:"wdth" 112,"wght" 700;
  text-transform:uppercase;font-size:clamp(1rem,.9rem + .5vw,1.3rem);line-height:1.1;overflow-wrap:anywhere;
}
.cmp-car__model a{transition:color var(--dur) var(--ease)}
.cmp-car__model a:hover{color:var(--accent)}
.cmp-car__trim{margin:4px 0 0;font-weight:600;line-height:1.4}
.cmp-car__trim .field__l{margin-bottom:6px}
.cmp-car__trim .select{padding:10px 12px;padding-inline-end:34px;font-size:.92rem}
.cmp-car__acts{display:flex;flex-wrap:wrap;gap:6px;margin-top:auto;padding-top:8px}
.cmp-car__acts .chipbtn{padding:7px 10px;font-size:.64rem}
.cmp-car--busy{opacity:.6}
.cmp-car--busy .cmp-car__stage{background:var(--panel-2)}
.cmp-car--find{gap:12px;padding:14px;justify-content:flex-start}
.cmp-car--add{background:transparent;border-style:dashed;border-color:var(--line-strong)}
.cmp-add{display:flex;flex-direction:column;justify-content:center;gap:10px;height:100%;padding:16px}
.cmp-add__plus{display:grid;place-items:center;width:40px;height:40px;border:1px solid var(--line-strong);color:var(--hot)}
.cmp-add__hint{margin:0;font-size:.84rem;line-height:1.5;color:var(--text-tertiary)}
.cmp-find .field__l{margin-bottom:8px}
.cmp-find .input{padding:11px 13px}
.cmp-empty{display:grid;gap:18px;max-width:640px;padding-block:clamp(10px,3vw,30px)}
.cmp-empty .h-section{font-size:clamp(1.4rem,1rem + 1.6vw,2.1rem)}
.cmp-empty .btn{justify-self:start}

/* Names that stay in view while the rows scroll: they appear only once the
   cars have gone up under the navigation, and take no room until then. */
.cmp-mini{position:sticky;top:var(--nav-h);z-index:6;height:0}
.cmp-mini__in{
  margin-inline:calc(var(--gutter) * -1);padding:9px var(--gutter);
  background:var(--nav-solid);backdrop-filter:blur(12px);border-bottom:1px solid var(--line);
  opacity:0;visibility:hidden;transform:translateY(-6px);
  transition:opacity .25s var(--ease),transform .3s var(--ease-out),visibility 0s linear .3s;
}
.cmp-mini.is-on .cmp-mini__in{opacity:1;visibility:visible;transform:none;
  transition:opacity .25s var(--ease),transform .3s var(--ease-out)}
.cmp-mini__c{min-width:0;font-weight:600;font-size:.9rem;line-height:1.3;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.cmp-mini__c span{display:block;font-family:var(--mono);font-size:.58rem;letter-spacing:.16em;text-transform:uppercase;color:var(--accent)}
.cmp-mini__c small{display:block;font-size:.76rem;font-weight:500;color:var(--text-tertiary);overflow:hidden;text-overflow:ellipsis}

/* the sections */
.cmp-sec{border-top:1px solid var(--line)}
.cmp-sec__h{
  display:flex;align-items:center;justify-content:space-between;gap:12px;
  padding:20px 0 14px;cursor:pointer;list-style:none;
}
.cmp-sec__h::-webkit-details-marker{display:none}
.cmp-sec__h h2{
  font-family:var(--display);font-variation-settings:"wdth" 112,"wght" 700;
  text-transform:uppercase;font-size:clamp(1.05rem,.95rem + .5vw,1.35rem);line-height:1.15;
}
html[dir="rtl"] .cmp-sec__h h2{line-height:1.4}
.cmp-sec__h:focus-visible{outline:2px solid var(--accent);outline-offset:4px}
.cmp-sec__caret{flex:0 0 auto;color:var(--text-tertiary);transition:transform var(--dur) var(--ease)}
.cmp-sec:not([open]) .cmp-sec__caret{transform:rotate(-90deg)}
[dir="rtl"] .cmp-sec:not([open]) .cmp-sec__caret{transform:rotate(90deg)}
.cmp-sec__rows{padding-bottom:12px}
.cmp-sec__empty{margin:0;padding:4px 0 20px;color:var(--text-tertiary)}
.cmp-sec__note{max-width:80ch;margin:0 0 20px;font-size:.86rem;line-height:1.6;color:var(--text-tertiary)}

.cmp-row{position:relative;align-items:start;padding:11px 0;border-top:1px solid var(--line)}
.cmp-row[hidden],.cmp-sub[hidden]{display:none}
.cmp-row--lead{border-top:0;padding-top:0}
.cmp-row__l{
  min-width:0;display:block;padding-top:3px;
  font-family:var(--mono);font-size:.7rem;letter-spacing:.12em;text-transform:uppercase;
  color:var(--text-tertiary);
}
.cmp-row__l .cmp-mark{margin-inline-end:9px;vertical-align:.08em}
.cmp-row__l .cmp-mark--apart{margin-inline:1px 10px}
.cmp-row--equip .cmp-row__l,
.cmp-row--colours .cmp-row__l{
  padding-top:0;font-family:var(--body);font-size:.95rem;font-weight:600;letter-spacing:0;text-transform:none;
  color:var(--text-secondary);line-height:1.45;
}
.cmp-row--colours .cmp-row__l{font-family:var(--mono);font-size:.7rem;font-weight:500;letter-spacing:.12em;text-transform:uppercase;color:var(--text-tertiary)}
.cmp-row__note{
  display:block;margin-top:5px;font-family:var(--body);font-size:.8rem;font-weight:500;letter-spacing:0;text-transform:none;
  line-height:1.5;color:var(--text-tertiary);
}
html[dir="rtl"] .cmp-row__l,html[dir="rtl"] .cmp-cell{line-height:1.7}

/* A row whose vehicles differ is washed, very lightly, in the green, from the
   label's side; the marker beside the label says the same thing in shape. */
.cmp-row--diff{background:linear-gradient(90deg,rgba(81,196,128,.09),transparent 72%)}
[dir="rtl"] .cmp-row--diff{background:linear-gradient(270deg,rgba(81,196,128,.09),transparent 72%)}

.cmp-cell{min-width:0;font-size:.98rem;font-weight:600;line-height:1.45;color:var(--text-primary);overflow-wrap:anywhere}
.cmp-cell small{font-size:.78rem;font-weight:500;color:var(--text-tertiary)}
.cmp-na,.cmp-napp,.cmp-no{font-size:.86rem;font-weight:500;color:var(--text-tertiary)}
.cmp-napp{opacity:.8}
.cmp-nodata{color:var(--text-tertiary)}
.cmp-muted{color:var(--text-secondary);font-weight:500}
.cmp-yes{display:inline-flex;color:var(--hot)}
.cmp-sub{padding:18px 0 4px}
.cmp-sub__h{font-family:var(--mono);font-size:.72rem;letter-spacing:.16em;text-transform:uppercase;color:var(--accent)}
.cmp-swatches{list-style:none;margin:0;padding:0;display:grid;gap:6px;font-size:.9rem;font-weight:500}
.cmp-swatches li{display:flex;align-items:center;gap:8px}
.cmp-sw{flex:0 0 auto;width:14px;height:14px;background:var(--panel-2);border:1px solid var(--line-strong)}

/* Phones: the labels sit over their values, the cars share the width, and
   the empty column becomes a box of its own under them. */
@media (max-width:760px){
  .cmp-head,.cmp-row,.cmp-mini__in{grid-template-columns:repeat(var(--cars),minmax(0,1fr));column-gap:10px}
  .cmp-head{row-gap:12px}
  .cmp-head__l,.cmp-mini__l,.cmp-void{display:none}
  .cmp-car--add{grid-column:1 / -1}
  .cmp-row{row-gap:6px}
  .cmp-row__l{grid-column:1 / -1}
  .cmp-car__body{padding:10px}
  .cmp-car__acts .chipbtn{padding:6px 8px;font-size:.6rem;letter-spacing:.06em}
  .cmp-car__trim .select{font-size:.84rem;padding:8px 10px;padding-inline-end:28px}
  .cmp-cell{font-size:.9rem}
  .cmp-legend{margin-inline-start:0}
}

@media (prefers-reduced-motion: reduce){
  .srch__spin{animation-duration:2.4s}
  .ctray,.cdlg__panel,.navsearch__panel,.cmp-mini__in{transition:none}
}
