/* ==========================================================================
   SIM MASTER — HOMEPAGE SECTIONS (in page order)
   ========================================================================== */

/* ---- Hero -------------------------------------------------------------- */

.hero {
    position: relative;
    isolation: isolate;
    display: flex;
    align-items: flex-end;
    /*
      The header is sticky and occupies its own row in normal flow, so the
      hero starts --header-h down the page. Sizing it to a bare 100svh
      therefore made it 100svh + 85px tall overall and pushed the CTA row
      below the fold on short viewports (the English copy is longer, so it
      showed there first). Subtracting the header keeps the whole hero — CTAs
      included — inside the first screen.
    */
    min-height: min(46rem, calc(100svh - var(--header-h)));
    /*
      Padding scales with viewport HEIGHT as well as width. The --space-*
      tokens only track width, so on a short-but-wide screen (a 1280x720
      laptop) they resolved to 144px top / 96px bottom and pushed the CTA row
      off the bottom of the hero. The vh terms shrink the padding on short
      viewports and are capped so tall screens are unchanged.
    */
    padding-block:
      min(var(--space-3xl), 14vh)
      min(var(--space-2xl), 9vh);
    overflow: hidden;
    background: var(--surface-void);
  }

  /* ---------------------------------------------------------------- media */

  .hero__media {
    position: absolute;
    inset: 0;
    z-index: -1;
  }

  .hero__poster {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    /*
      Calibrated against the real 4032x3024 source, not guessed. Because the
      photo is 4:3 and the hero containers are not, `cover` crops on exactly
      one axis per viewport — and it is a DIFFERENT axis each time:

        · wide desktop hero  -> crops vertically only, so X is inert and only
                                Y decides what you see
        · tall phone hero    -> crops horizontally only, so Y is inert and only
                                X decides what you see

      That is why a single pair works for both. Y 42% frames the lit row of
      simulators in the upper-middle band (the lounge below it falls under the
      bottom fade); X 62% lands the phone's narrow slice on the drivers at
      their monitors rather than on empty room.
    */
    object-position: 62% 42%;
  }

  /*
    The phone <source> is already cropped to almost exactly the hero's own
    aspect ratio, so there is barely anything left for `cover` to trim — a
    plain centre keeps the framing the crop was designed around.
  */
  @media (max-width: 48rem) {
    .hero__poster {
      object-position: 50% 50%;
    }
  }

  /*
    The grade. The source is a dim room shot with strong green LED spill, so
    it is pushed into the brand palette: a strong left-to-right fade for text
    legibility (the copy sits on the left, the action on the right), a
    deep-navy duotone floor, a cyan cool cast from the top-right, a red warm
    kick from the left, then a heavy bottom ramp that guarantees contrast
    regardless of what is underneath.
  */
  .hero__grade {
    position: absolute;
    inset: 0;
    background:
      linear-gradient(90deg, var(--surface-void) 0%, rgba(4, 9, 11, 0.92) 28%, rgba(4, 9, 11, 0.58) 48%, rgba(4, 9, 11, 0.18) 68%, transparent 84%),
      linear-gradient(to top, var(--surface-void) 2%, rgba(4, 9, 11, 0.86) 24%, rgba(0, 35, 41, 0.34) 58%, rgba(0, 20, 24, 0.55) 100%),
      radial-gradient(ellipse 70% 60% at 82% 12%, rgba(0, 201, 255, 0.22), transparent 62%),
      radial-gradient(ellipse 60% 70% at 6% 78%, rgba(245, 20, 15, 0.2), transparent 60%),
      linear-gradient(105deg, rgba(0, 35, 41, 0.7) 0%, rgba(0, 35, 41, 0.15) 45%, rgba(0, 0, 0, 0.6) 100%);
    mix-blend-mode: normal;
  }

  /* Very faint horizontal ruling — reads as a telemetry display, not scanline
     kitsch, because it is nearly invisible until you look for it. */
  .hero__scanlines {
    position: absolute;
    inset: 0;
    background: repeating-linear-gradient(
      to bottom,
      rgba(0, 201, 255, 0.035) 0 1px,
      transparent 1px 4px
    );
    opacity: 0.6;
    mix-blend-mode: overlay;
  }

  /* ---------------------------------------------------------------- copy */

  .hero__inner {
    position: relative;
    width: 100%;
  }

  .hero__eyebrow {
    display: flex;
    align-items: center;
    gap: var(--space-xs);
    margin-bottom: var(--space-md);
    font-family: var(--font-mono);
    font-size: var(--fs-mono-label);
    font-weight: 500;
    letter-spacing: var(--tracking-mono);
    text-transform: uppercase;
    color: var(--text-accent);
  }

  .hero__title {
    margin: 0;
    /*
      --fs-display only tracks viewport WIDTH, so on a wide-but-short screen
      it resolved to ~137px on a 660px-tall viewport — two lines of headline
      alone ate 253px and pushed the CTA row off-screen. The vh term caps the
      headline against the height it actually has to live in; on normal-ratio
      screens the width value is still the smaller of the two and nothing
      changes.
    */
    font-size: min(var(--fs-display), 15.5vh);
    font-weight: 800;
    line-height: var(--lh-tight);
    letter-spacing: var(--tracking-display);
    text-transform: uppercase;
    text-wrap: balance;
  }

  .hero__title-line {
    display: block;
  }

  /* The second word is drawn as an outline so the huge type stays light and
     the image keeps showing through the headline. */
  .hero__title-line--outline {
    color: transparent;
    -webkit-text-stroke: clamp(1px, 0.14vw, 2px) var(--action-text);
    text-shadow: 0 0 3rem rgba(232, 19, 14, 0.35);
  }

  @supports not (-webkit-text-stroke: 1px black) {
    .hero__title-line--outline {
      color: var(--action-text);
    }
  }

  .hero__body {
    max-width: 42ch;
    margin-top: var(--space-md);
    color: rgba(244, 247, 248, 0.82);
  }

  .hero__actions {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-sm);
    margin-top: var(--space-lg);
  }

  /* -------------------------------------------------------------- scroll */

  .hero__scroll {
    position: absolute;
    bottom: 0;
    left: 50%;
    transform: translateX(-50%);
    width: 1px;
    height: 4rem;
  }

  .hero__scroll:focus-visible {
    outline: 2px solid var(--focus-ring);
    outline-offset: 6px;
  }

  @media (max-width: 60rem) {
    .hero__scroll {
      display: none;
    }
  }

  .hero__scroll-line {
    position: absolute;
    inset: 0;
    overflow: hidden;
    background: linear-gradient(to bottom, transparent, var(--action-text));
    animation: scroll-cue 2.4s var(--ease-in-out) infinite;
  }

  @keyframes scroll-cue {
    0% {
      transform: translateY(-100%);
    }
    60%,
    100% {
      transform: translateY(100%);
    }
  }

  @media (prefers-reduced-motion: reduce) {
    .hero__scroll-line {
      animation: none;
      opacity: 0.5;
    }
  }

/* ---- Partners ---------------------------------------------------------- */

.partners {
    padding-block: var(--space-2xl);
    border-bottom: 1px solid var(--line-faint);
    background: var(--surface-base);
  }

  .partners__title {
    margin-bottom: var(--space-xl);
    font-family: var(--font-mono);
    font-size: var(--fs-caption);
    font-weight: 500;
    letter-spacing: var(--tracking-mono);
    text-transform: uppercase;
    text-align: center;
    color: var(--text-muted);
  }

  .marquee {
    position: relative;
    overflow: hidden;
    /* Logos fade out at both edges instead of being hard-cut. */
    mask-image: linear-gradient(to right, transparent, #000 8rem, #000 calc(100% - 8rem), transparent);
    -webkit-mask-image: linear-gradient(to right, transparent, #000 8rem, #000 calc(100% - 8rem), transparent);
  }

  .marquee__track {
    display: flex;
    width: max-content;
    animation: marquee 46.67s linear infinite;
  }

  @keyframes marquee {
    to {
      transform: translate3d(-50%, 0, 0);
    }
  }

  /*
    `ul.marquee__run`, not `.marquee__run` — the a11y list-reset in base.css
    (`ul[role="list"] { padding: 0 }`) is an element+attribute selector, which
    outranks a bare class selector regardless of source order. That silently
    zeroed the padding-right this rule sets, which is what creates the gap
    between the end of one run and the start of the next; the two runs sat
    flush with no seam between them. Matching its specificity here restores
    the seam, decided correctly by source order since this file loads after
    base.css.
  */
  ul.marquee__run {
    display: flex;
    align-items: center;
    gap: clamp(2.5rem, 1rem + 4vw, 5rem);
    margin: 0;
    /* Same value as `gap` above — the trailing edge is the seam between this
       run and the next one, and it needs to match every other gap in the
       strip, not be its own smaller number. */
    padding: 0 clamp(2.5rem, 1rem + 4vw, 5rem) 0 0;
    list-style: none;
  }

  .marquee__item img {
    height: clamp(1.75rem, 1.2rem + 1.6vw, 2.75rem);
    width: auto;
    object-fit: contain;
    /* Logos arrive in mixed colour treatments; desaturating at rest unifies
       the row, and full colour returns on hover. Aspect ratio untouched. */
    filter: grayscale(1) brightness(1.7) contrast(0.9);
    opacity: 0.55;
    transition: filter var(--dur-base) var(--ease-out), opacity var(--dur-base) var(--ease-out);
  }

  .marquee__item:hover img {
    filter: none;
    opacity: 1;
  }

  /*
    The desaturate-at-rest/colour-on-hover treatment depends on hover, which
    touch devices do not have — logos would sit permanently grey with no way
    to see their real colour. Below the breakpoint where the site switches to
    touch-first navigation, skip the treatment entirely and show them as-is.
  */
  @media (max-width: 48rem) {
    .marquee__item img {
      filter: none;
      opacity: 1;
    }
  }

  @media (prefers-reduced-motion: reduce) {
    .marquee {
      overflow-x: auto;
      mask-image: none;
      -webkit-mask-image: none;
      scrollbar-width: thin;
    }

    .marquee__track {
      animation: none;
    }

    /* Without the animation the duplicate run is pure noise. */
    .marquee__run[aria-hidden="true"] {
      display: none;
    }
  }

/* ---- About + statistics ------------------------------------------------ */

.about {
    background:
      radial-gradient(ellipse 80% 50% at 15% 0%, rgba(0, 35, 41, 0.9), transparent 60%),
      var(--surface-base);
  }

  .about__inner {
    display: grid;
    gap: var(--space-2xl);
    align-items: center;
  }

  @media (min-width: 62rem) {
    .about__inner {
      grid-template-columns: minmax(0, 0.85fr) minmax(0, 1fr);
      gap: var(--space-3xl);
    }
  }

  /* ---------------------------------------------------------------- media */

  .about__media {
    position: relative;
    max-width: 32rem;
  }

  .about__frame {
    position: relative;
    overflow: hidden;
    border-radius: var(--radius-md);
    border: 1px solid var(--line-soft);
  }

  .about__frame img {
    width: 100%;
    height: auto;
    aspect-ratio: 562 / 791;
    object-fit: cover;
    transition: transform 1.2s var(--ease-out);
  }

  .about__media:hover .about__frame img {
    transform: scale(1.03);
  }

  /* Cyan corner brackets — the "instrument frame" motif. */
  .about__frame::after {
    content: "";
    position: absolute;
    inset: 0.75rem;
    border: 1px solid var(--line-soft);
    border-radius: var(--radius-sm);
    pointer-events: none;
    mask-image: linear-gradient(45deg, #000 0 18%, transparent 18% 82%, #000 82% 100%);
    -webkit-mask-image: linear-gradient(45deg, #000 0 18%, transparent 18% 82%, #000 82% 100%);
  }

  .about__badge {
    position: absolute;
    right: clamp(-1rem, -2vw, 0rem);
    bottom: clamp(1.5rem, 4vw, 3rem);
    display: grid;
    justify-items: center;
    gap: 0.1rem;
    width: clamp(7rem, 5rem + 6vw, 9.5rem);
    aspect-ratio: 1;
    place-content: center;
    border-radius: 50%;
    background: radial-gradient(circle at 40% 30%, var(--surface-panel), var(--surface-void));
    border: 1px solid var(--line-strong);
    box-shadow: var(--shadow-glow-cyan);
    text-align: center;
  }

  .about__badge-since,
  .about__badge-label {
    font-family: var(--font-mono);
    font-size: var(--fs-mono-label);
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--text-accent);
  }

  .about__badge-label {
    max-width: 6rem;
    line-height: 1.2;
    color: var(--text-muted);
  }

  .about__badge-years {
    font-family: var(--font-display);
    font-size: clamp(2rem, 1.4rem + 2vw, 3rem);
    font-weight: 800;
    line-height: 1;
    color: var(--text-warm);
  }

  /* ----------------------------------------------------------------- copy */

  .about__title {
    margin: var(--space-sm) 0 var(--space-md);
    font-size: var(--fs-h2);
    font-weight: 800;
    line-height: var(--lh-snug);
    text-transform: uppercase;
  }

  .about__cta {
    margin-top: var(--space-lg);
  }

  /* ---------------------------------------------------------------- stats */

  .stats {
    display: grid;
    gap: 1px;
    margin: var(--space-3xl) 0 0;
    padding: 0;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    background: var(--line-faint);
    border: 1px solid var(--line-faint);
    border-radius: var(--radius-md);
    overflow: hidden;
  }

  @media (min-width: 52rem) {
    .stats {
      grid-template-columns: repeat(4, minmax(0, 1fr));
    }
  }

  .stat {
    display: grid;
    gap: 0.35rem;
    padding: var(--space-lg) var(--space-md);
    background: var(--surface-base);
    text-align: center;
    transition: background-color var(--dur-base) var(--ease-out);
  }

  .stat:hover {
    background: var(--surface-raised);
  }

  .stat__value {
    display: flex;
    align-items: baseline;
    justify-content: center;
    gap: 0.1rem;
    margin: 0;
    font-family: var(--font-numeric);
    font-size: var(--fs-stat);
    font-weight: 700;
    line-height: 1;
    /* Rajdhani is wider than the condensed display face, so the tight
       negative tracking that suited Saira would crowd it here. */
    letter-spacing: 0;
    color: var(--color-white);
    /* Tabular figures stop the count-up jittering the layout. */
    font-variant-numeric: tabular-nums;
  }

  .stat__suffix {
    font-size: 0.5em;
    color: var(--action-text);
  }

  .stat__label {
    font-family: var(--font-mono);
    font-size: var(--fs-mono-label);
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--text-muted);
  }

/* ---- Services ---------------------------------------------------------- */

.services {
    background: var(--surface-void);
    border-block: 1px solid var(--line-faint);
  }

  .services__head {
    display: grid;
    gap: var(--space-lg);
    margin-bottom: var(--space-2xl);
  }

  @media (min-width: 62rem) {
    /*
    Top-aligned, not bottom-aligned. With `align-items: end` the two columns
    shared a baseline, so whenever the right-hand lede was taller than the
    eyebrow+title block it grew UPWARDS and its first line floated above the
    section heading. Aligning to the start and pushing the lede down by the
    eyebrow's own line box keeps its first line level with the title instead.
    The offset is derived from the same tokens the eyebrow and title use, so
    it tracks the fluid type scale rather than being a magic number.
  */
  .services__head {
      grid-template-columns: minmax(0, 1fr) minmax(0, 1.15fr);
      gap: var(--space-3xl);
      align-items: start;
    }

    .services__lede {
      margin-top: calc(var(--fs-mono-label) * 1.7 + var(--space-sm));
    }
  }

  .services__title {
    margin-top: var(--space-sm);
    font-size: var(--fs-h2);
    font-weight: 800;
    line-height: var(--lh-snug);
    text-transform: uppercase;
  }

  .services__lede {
    max-width: 62ch;
  }

  .services__grid {
    display: grid;
    gap: var(--space-md);
    margin: 0;
    padding: 0;
    list-style: none;
  }

  @media (min-width: 40rem) {
    .services__grid {
      grid-template-columns: repeat(2, minmax(0, 1fr));
    }
    /* Asymmetric on tablet: the third card spans, so the grid never reads as
       three identical boxes in a row. */
    .services__grid > :last-child {
      grid-column: 1 / -1;
    }
  }

  @media (min-width: 62rem) {
    .services__grid {
      grid-template-columns: repeat(3, minmax(0, 1fr));
    }
    .services__grid > :last-child {
      grid-column: auto;
    }
  }

  /* ----------------------------------------------------------------- card */

  .service__card {
    position: relative;
    display: flex;
    flex-direction: column;
    height: 100%;
    background: linear-gradient(170deg, var(--surface-raised), var(--surface-base));
    border: 1px solid var(--line-faint);
    border-radius: var(--radius-md);
    overflow: hidden;
    transition:
      border-color var(--dur-base) var(--ease-out),
      transform var(--dur-base) var(--ease-out),
      box-shadow var(--dur-base) var(--ease-out);
  }

  .service__card:hover,
  .service__card:focus-within {
    border-color: var(--line-strong);
    transform: translateY(-4px);
    box-shadow: var(--shadow-lg);
  }

  .service__media {
    position: relative;
    overflow: hidden;
    aspect-ratio: 16 / 10;
    background: var(--surface-inset);
  }

  .service__media img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    transition: transform 900ms var(--ease-out), filter var(--dur-base) var(--ease-out);
    filter: saturate(0.85) brightness(0.82);
  }

  .service__card:hover .service__media img,
  .service__card:focus-within .service__media img {
    transform: scale(1.06);
    filter: saturate(1) brightness(0.95);
  }

  .service__media::after {
    content: "";
    position: absolute;
    inset: 0;
    background: linear-gradient(to top, var(--surface-base) 2%, rgba(4, 9, 11, 0.35) 45%, transparent 75%);
  }

  .service__body {
    display: flex;
    flex-direction: column;
    gap: var(--space-xs);
    flex: 1;
    padding: var(--space-lg);
  }

  /*
    Description reads above the title visually, while the <h3> stays first in
    the DOM. Done with flex order rather than by reordering the markup so the
    heading still comes first for screen readers, heading navigation and
    search engines. Safe here because the card holds exactly one focusable
    element (the stretched link inside the heading), so there is no confusing
    mismatch between visual and tab order.
  */
  .service__text {
    order: -1;
  }

  .service__name {
    margin: 0;
    font-size: var(--fs-h4);
    font-weight: 700;
    line-height: 1.2;
    letter-spacing: 0.02em;
    text-transform: uppercase;
  }

  .service__link {
    color: inherit;
    text-decoration: none;
  }

  /* Stretched link: the card is a click target, the link is the a11y target. */
  .service__link::after {
    content: "";
    position: absolute;
    inset: 0;
    z-index: 2;
  }

  .service__link:focus-visible {
    outline: none;
  }

  .service__card:focus-within {
    outline: 2px solid var(--focus-ring);
    outline-offset: 3px;
  }

  .service__text {
    flex: 1;
    margin: 0;
    font-size: var(--fs-body-sm);
    color: var(--text-secondary);
  }

  .service__card:hover .link-arrow svg {
    transform: translateX(0.35rem);
  }

/* ---- Sim Racing Srbija ------------------------------------------------- */

.srs {
    position: relative;
    isolation: isolate;
    overflow: hidden;
  }

  .srs__bg {
    position: absolute;
    inset: 0;
    z-index: -1;
  }

  .srs__bg img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    object-position: center 35%;
  }

  /*
    The whole photo should read, not just its right edge — the old version was
    a hard left-to-right wall (opaque at 8%, still 90% opaque past the middle)
    that hid most of the team behind a dark panel. This keeps a soft dark pool
    behind the copy block only (radial, anchored where the text actually
    sits), plus a light overall bottom weight for the CTA/links row, and
    leaves the rest of the frame close to full brightness.
  */
  .srs__grade {
    position: absolute;
    inset: 0;
    background:
      linear-gradient(180deg, rgba(0, 10, 12, 0.1) 0%, rgba(0, 10, 12, 0.24) 70%, rgba(0, 10, 12, 0.5) 100%),
      radial-gradient(ellipse 55% 75% at 22% 42%, rgba(0, 10, 12, 0.72), transparent 62%);
  }

  .srs__inner {
    position: relative;
  }

  .srs__copy {
    max-width: 46rem;
  }

  .srs__title {
    margin: var(--space-sm) 0 var(--space-2xs);
    font-size: var(--fs-h1);
    font-weight: 800;
    line-height: var(--lh-tight);
    letter-spacing: var(--tracking-display);
    text-transform: uppercase;
  }

  .srs__subtitle {
    /*
      NO max-width: the owner wants this on a single row under the heading,
      and a 40ch cap was breaking a ~57-character line into two. It is
      constrained by .srs__copy (46rem) instead, which is wide enough to fit
      it on one line from roughly the tablet breakpoint up; below that it
      still wraps normally, which is correct — never force nowrap here.
    */
    margin: 0 0 var(--space-md);
    font-family: var(--font-display);
    font-size: var(--fs-h4);
    font-weight: 600;
    letter-spacing: 0.03em;
    text-transform: uppercase;
    color: var(--text-primary);
  }

  .srs__body {
    max-width: 60ch;
    color: var(--text-secondary);
    text-wrap: pretty;
  }

  .srs__actions {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-sm);
    margin-top: var(--space-xl);
  }

  .srs__links {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-sm) var(--space-lg);
    margin: var(--space-md) 0 0;
    /* Indent to the buttons' label, not their box edge: the CTAs above carry
       1.75rem + 1px border of horizontal padding, so a flush-left link list
       reads as sitting further left than the button text. */
    padding: 0 0 0 calc(1.75rem + 1px);
    list-style: none;
  }

  /*
    Plain TEXT links, at the owner's request — they used to carry a bordered
    pill (padding + border + radius + hover fill), which read as two small
    buttons competing with the real CTA above them. They now fall through to
    the base .link-arrow: mono caption type in --text-accent, going white on
    hover with the arrow sliding right. Do not re-add a border or background
    here; the whole point is that the text itself is the target.
  */

/* ---- Professional rigs ------------------------------------------------- */

.rigs {
    position: relative;
    isolation: isolate;
    background: var(--color-black);
  }

  .rigs__head {
    margin-bottom: var(--space-2xl);
  }

  .rigs__title {
    margin-top: var(--space-sm);
    font-size: var(--fs-h2);
    font-weight: 800;
    line-height: var(--lh-snug);
    text-transform: uppercase;
  }

  .rigs__title-sub {
    display: block;
    margin-top: 0.2rem;
    font-size: 0.44em;
    font-weight: 600;
    letter-spacing: 0.1em;
    color: var(--text-accent);
  }

  /*
    Full-width rows, not a 3-up card grid.

    Each rig gets the whole shell so its photo can actually be looked at and
    its specs can be read at body size. Sides alternate down the stack:

      Standard   text left  / media right
      Triple     media left / text right
      Motion     text left  / media right
      VR         media left / text right

    Markup order inside every card is media-then-body, which is also the
    single-column phone order (photo first, then read about it). The swap is
    presentational only, applied with `order` above the two-column breakpoint,
    so the reading order never changes.
  */
  .rigs__list {
    display: grid;
    gap: var(--space-xl);
    margin: 0;
    padding: 0;
    list-style: none;
  }

  /* ------------------------------------------------------------------ row */

  .rig__card {
    display: grid;
    gap: var(--space-lg);
    padding: var(--space-lg);
    background: linear-gradient(175deg, var(--surface-panel), var(--surface-void) 70%);
    border: 1px solid var(--line-faint);
    border-radius: var(--radius-md);
    transition: border-color var(--dur-base) var(--ease-out);
  }

  .rig__card:hover {
    border-color: var(--line-strong);
  }

  @media (min-width: 62rem) {
    .rig__card {
      grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
      align-items: center;
      gap: var(--space-3xl);
      padding: var(--space-xl);
    }

    .rigs__list > .rig:nth-child(odd) .rig__body {
      order: -1;
    }
  }

  .rig__media {
    position: relative;
    display: grid;
    place-items: center;
    /*
      The source photos have very different aspect ratios (the standard rig is
      portrait, the other two nearly square). A fixed ratio plus contain gives
      every row an identical media height so the stack reads evenly.
    */
    /*
      Square, not 4/3. The photos are portrait or near-square, so a landscape
      frame left wide empty gutters either side of every one of them.
    */
    aspect-ratio: 1 / 1;
    padding: var(--space-sm);
    overflow: hidden;
    border-radius: var(--radius-sm);
    background: var(--surface-void);
  }

  .rig__media img {
    width: 100%;
    height: 100%;
    object-fit: contain;
    /* Product shots arrive on different backgrounds; a shared drop shadow
       makes them sit on the same surface. */
    filter: drop-shadow(0 1.5rem 2rem rgba(0, 0, 0, 0.6));
    transition: transform var(--dur-slow) var(--ease-out);
  }

  .rig__card:hover .rig__media img {
    transform: scale(1.03);
  }

  /*
    No hover zoom on the video row. The rule above targets `img`, so it scaled
    the poster but not the <video> stacked on top of it — the enlarged poster
    edges appeared from behind the clip and read as a duplicate copy of it.
    Scaling both would fix the desync, but a clip that is already playing does
    not need a zoom on top; leaving it still is the better answer.
  */
  .rig__card:hover .rig__media--video img {
    transform: none;
  }

  .rig__body {
    display: flex;
    flex-direction: column;
    gap: var(--space-sm);
    padding: 0;
  }

  .rig__name {
    margin: 0;
    font-size: var(--fs-h3);
    font-weight: 700;
    letter-spacing: 0.03em;
    text-transform: uppercase;
    color: var(--text-warm);
  }

  .rig__text {
    margin: 0;
    max-width: 56ch;
    font-size: var(--fs-body);
    color: var(--text-secondary);
  }

  /* ---------------------------------------------------------------- specs */

  .rig__specs {
    margin-top: var(--space-2xs);
    padding-top: var(--space-sm);
    border-top: 1px solid var(--line-faint);
  }

  .rig__specs-label {
    margin: 0 0 var(--space-2xs);
    font-family: var(--font-mono);
    font-size: var(--fs-mono-label);
    letter-spacing: var(--tracking-mono);
    text-transform: uppercase;
    color: var(--text-muted);
  }

  .rig__specs ul {
    display: grid;
    gap: 0.55rem;
    margin: 0;
    padding: 0;
    list-style: none;
  }

  .rig__specs li {
    display: grid;
    grid-template-columns: 2.25rem 1fr;
    align-items: start;
    gap: var(--space-2xs);
    font-size: var(--fs-body-sm);
    line-height: 1.45;
    color: var(--text-primary);
  }

  .rig__spec-icon {
    width: auto;
    height: 1.125rem;
    /* The MOZA wordmark is much wider than the square icons; without the
       extra room object-fit shrinks it until it is unreadable. */
    max-width: 2.25rem;
    object-fit: contain;
    opacity: 0.9;
    /* Icons ship white already; this only harmonises the few that are not. */
    filter: brightness(1.6);
  }

  .rig__spec-dot {
    width: 5px;
    height: 5px;
    margin-top: 0.55rem;
    margin-left: 0.35rem;
    border-radius: 50%;
    background: var(--action);
  }

  .rig__cta {
    margin-top: var(--space-2xs);
  }

/* ---- Motion Rig video media --------------------------------------------
   The Motion Rig is a normal .rig row now — same card, same .rig__specs list
   as the photo rows. All that is special is the media: a 9:16 clip instead of
   a product photo, so it needs its own sizing inside the shared square frame.
   ------------------------------------------------------------------------ */

  /*
    The video frame is NOT square like the photo frames — it takes the clip's
    own cropped shape (480/660) and is narrowed to 72.73% of the column, which
    makes its HEIGHT come out equal to the square photo frames' height
    (0.7273w x 660/480 = w). So the row keeps the stack's rhythm while the clip
    fills its frame edge to edge instead of floating in a square with gutters.
  */
  .rig__media--video {
    aspect-ratio: 480 / 660;
    width: 72.73%;
    justify-self: center;
    padding: 0;
    /* The visible dark ring around the clip. */
    --video-border: 0.4rem;
  }

  /*
    Both media pinned to the SAME inset box, so they are always pixel-identical
    and the poster can never peek out from behind the clip.

    Two earlier attempts failed and are worth not repeating:
      · the poster was `position: absolute; inset: 0` while the video was a
        normal grid item — absolute resolves against the PADDING box, in-flow
        against the CONTENT box, so they came out 200x275 vs 219x302 and the
        poster's uncropped top showed above the clip as a stray band;
      · sizing either of them with a percentage height does not work at all
        here, because a height derived from the parent's `aspect-ratio` is not
        a definite height for percentage resolution — `height: 100%` silently
        fell back to auto and the intrinsic width took over.
    `inset` sidesteps both: all four offsets are definite lengths.

    The inset itself IS the visible border — a thin ring of the frame's dark
    ground around the clip.

    These live on the two-class selector because the poster is an <img> inside
    .rig__media, and `.rig__media img` (0,1,1) would otherwise win and force
    object-fit back to `contain`.
  */
  .rig__media--video .motion__poster,
  .rig__media--video .motion__video {
    position: absolute;
    top: var(--video-border);
    left: var(--video-border);
    display: block;
    /*
      Explicit width/height, NOT `inset` with auto sizing. For a replaced
      element (<img>, <video>) `width: auto; height: auto` ignores the inset
      offsets and falls back to the intrinsic size, so both media snapped back
      to the source's 9:16 and overflowed the frame. Percentages here are safe
      precisely because these are absolutely positioned: they resolve against
      the frame's padding box, which is definite.
    */
    width: calc(100% - var(--video-border) * 2);
    height: calc(100% - var(--video-border) * 2);
    /*
      The frame is already the cropped shape, so `cover` only has to trim the
      top ~22% of the 9:16 source — the ceiling and roof beams — and
      `object-position: 50% 100%` anchors the bottom so the whole trim comes
      off the top.
    */
    object-fit: cover;
    object-position: 50% 100%;
    border-radius: var(--radius-sm);
    /* The photo rows use a drop-shadow to seat product shots on the surface;
       the clip has its own frame, so it does not need one. */
    filter: none;
  }

  /* The poster sits underneath and is covered once the clip actually starts,
     so a blocked or still-loading autoplay never shows an empty box. */
  .motion__video {
    z-index: 1;
    opacity: 0;
    transition: opacity var(--dur-slow) var(--ease-out);
  }

  .motion__video.is-playing {
    opacity: 1;
  }

  @media (prefers-reduced-motion: reduce) {
    .motion__video {
      transition: none;
    }
  }

/* ---- Wheel gallery ----------------------------------------------------- */

.wheels {
    background: var(--surface-void);
    border-block: 1px solid var(--line-faint);
  }

  .wheels__head {
    display: grid;
    gap: var(--space-lg);
    margin-bottom: var(--space-2xl);
  }

  @media (min-width: 62rem) {
    /*
    Top-aligned, not bottom-aligned. With `align-items: end` the two columns
    shared a baseline, so whenever the right-hand lede was taller than the
    eyebrow+title block it grew UPWARDS and its first line floated above the
    section heading. Aligning to the start and pushing the lede down by the
    eyebrow's own line box keeps its first line level with the title instead.
    The offset is derived from the same tokens the eyebrow and title use, so
    it tracks the fluid type scale rather than being a magic number.
  */
  .wheels__head {
      grid-template-columns: minmax(0, 1fr) minmax(0, 1.1fr);
      gap: var(--space-3xl);
      align-items: start;
    }

    .wheels__lede {
      margin-top: calc(var(--fs-mono-label) * 1.7 + var(--space-sm));
    }
  }

  .wheels__title {
    margin-top: var(--space-sm);
    font-size: var(--fs-h2);
    font-weight: 800;
    line-height: var(--lh-snug);
    text-transform: uppercase;
  }

  .wheels__lede {
    max-width: 58ch;
  }

  .wheels__grid {
    display: grid;
    gap: 1px;
    margin: 0;
    padding: 0;
    list-style: none;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    background: var(--line-faint);
    border: 1px solid var(--line-faint);
    border-radius: var(--radius-md);
    overflow: hidden;
  }

  @media (min-width: 34rem) {
    .wheels__grid {
      grid-template-columns: repeat(3, minmax(0, 1fr));
    }
  }

  @media (min-width: 50rem) {
    .wheels__grid {
      grid-template-columns: repeat(4, minmax(0, 1fr));
    }
  }

  @media (min-width: 76rem) {
    .wheels__grid {
      grid-template-columns: repeat(8, minmax(0, 1fr));
    }
  }

  /* ----------------------------------------------------------------- tile */

  .wheel-tile figure {
    display: grid;
    gap: var(--space-2xs);
    height: 100%;
    margin: 0;
    padding: var(--space-md) var(--space-sm) var(--space-sm);
    background: var(--surface-base);
    transition: background-color var(--dur-base) var(--ease-out);
  }

  .wheel-tile:hover figure {
    background: var(--surface-raised);
  }

  .wheel-tile__frame {
    position: relative;
    display: grid;
    place-items: center;
  }

  /* Cyan floor glow appears under the rim on hover — it reads as a lit
     display case rather than a hover-highlight rectangle. */
  .wheel-tile__frame::before {
    content: "";
    position: absolute;
    inset: 12% 12% 6%;
    border-radius: 50%;
    background: radial-gradient(circle, rgba(232, 19, 14, 0.3), transparent 68%);
    opacity: 0;
    transition: opacity var(--dur-base) var(--ease-out);
  }

  .wheel-tile:hover .wheel-tile__frame::before {
    opacity: 1;
  }

  .wheel-tile__frame img {
    position: relative;
    width: 100%;
    max-width: 8.5rem;
    height: auto;
    transition: transform var(--dur-slow) var(--ease-spring);
  }

  .wheel-tile:hover .wheel-tile__frame img {
    transform: rotate(-14deg) scale(1.06);
  }

  .wheel-tile figcaption {
    display: grid;
    gap: 0.1rem;
    text-align: center;
  }

  .wheel-tile__name {
    /* Two lines' worth of space so the discipline labels stay on a shared
       baseline whether or not a model name wraps. */
    min-height: 2.6em;
    font-size: var(--fs-caption);
    line-height: 1.3;
    color: var(--text-secondary);
  }

  .wheel-tile__discipline {
    font-family: var(--font-mono);
    font-size: var(--fs-mono-label);
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--text-secondary);
  }

  @media (prefers-reduced-motion: reduce) {
    .wheel-tile:hover .wheel-tile__frame img {
      transform: none;
    }
  }

/* ---- Games ------------------------------------------------------------- */

.games {
    background: linear-gradient(to bottom, var(--surface-base), var(--surface-void));
  }

  .games__head {
    display: grid;
    gap: var(--space-lg);
    margin-bottom: var(--space-2xl);
  }

  @media (min-width: 62rem) {
    /*
    Top-aligned, not bottom-aligned. With `align-items: end` the two columns
    shared a baseline, so whenever the right-hand lede was taller than the
    eyebrow+title block it grew UPWARDS and its first line floated above the
    section heading. Aligning to the start and pushing the lede down by the
    eyebrow's own line box keeps its first line level with the title instead.
    The offset is derived from the same tokens the eyebrow and title use, so
    it tracks the fluid type scale rather than being a magic number.
  */
  .games__head {
      grid-template-columns: minmax(0, 1fr) minmax(0, 1.1fr);
      gap: var(--space-3xl);
      align-items: start;
    }

    .games__lede {
      margin-top: calc(var(--fs-mono-label) * 1.7 + var(--space-sm));
    }
  }

  .games__title {
    margin-top: var(--space-sm);
    font-size: var(--fs-h2);
    font-weight: 800;
    line-height: var(--lh-snug);
    text-transform: uppercase;
  }

  .games__lede {
    max-width: 60ch;
  }

  .games__grid {
    display: grid;
    gap: var(--space-sm);
    margin: 0;
    padding: 0;
    list-style: none;
    grid-template-columns: repeat(auto-fill, minmax(min(100%, 15rem), 1fr));
  }

  /* ----------------------------------------------------------------- card */

  .game__card {
    position: relative;
    height: 100%;
    border: 1px solid var(--line-faint);
    border-radius: var(--radius-md);
    overflow: hidden;
    background: var(--surface-inset);
    transition: border-color var(--dur-base) var(--ease-out), transform var(--dur-base) var(--ease-out);
  }

  .game__card:hover {
    border-color: var(--line-strong);
    transform: translateY(-3px);
  }

  .game__media {
    position: relative;
    aspect-ratio: 16 / 7;
    overflow: hidden;
  }

  .game__media img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    filter: saturate(0.9) brightness(0.86);
    transition: transform var(--dur-slow) var(--ease-out), filter var(--dur-base) var(--ease-out);
  }

  .game__card:hover .game__media img {
    transform: scale(1.05);
    filter: saturate(1.05) brightness(1);
  }

  .game__media::after {
    content: "";
    position: absolute;
    inset: 0;
    background: linear-gradient(to top, var(--surface-inset), transparent 55%);
  }

  .game__meta {
    display: grid;
    gap: 0.35rem;
    padding: var(--space-sm) var(--space-md) var(--space-md);
  }

  .game__title {
    margin: 0;
    font-size: 1rem;
    font-weight: 700;
    letter-spacing: 0.03em;
    text-transform: uppercase;
    color: var(--text-primary);
  }

  .game__tags {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem;
    margin: 0;
    font-family: var(--font-mono);
    font-size: var(--fs-mono-label);
    letter-spacing: 0.1em;
    text-transform: uppercase;
  }

  .game__genre {
    color: var(--text-accent);
  }

  .game__platform {
    padding-left: 0.5rem;
    border-left: 1px solid var(--line-soft);
    color: var(--text-muted);
  }

  /*
    Homepage-only: the owner asked for the red genre label under each game
    to go, keeping just the platform ("PC / Xbox"). .game__platform's
    border-left + padding-left exist to sit next to that genre badge, so
    with nothing before it in the flex row they'd read as a stray vertical
    line floating in front of the text. Cleared here, scoped to the
    homepage via the intro-only body attribute, since /usluge/ and
    /iznajmljivanje-simulatora/ still show both genre and platform and were
    not asked to change.
  */
  [data-with-intro] .game__platform,
  [data-page="simulatori"] .game__platform,
  [data-page="iznajmljivanje"] .game__platform {
    padding-left: 0;
    border-left: 0;
  }

/* ---- FAQ --------------------------------------------------------------- */

.faq {
    background: var(--surface-void);
    border-top: 1px solid var(--line-faint);
  }

  .faq__inner {
    display: grid;
    gap: var(--space-2xl);
    align-items: start;
  }

  @media (min-width: 62rem) {
    .faq__inner {
      grid-template-columns: minmax(0, 20rem) minmax(0, 1fr);
      gap: var(--space-3xl);
    }

    .faq__aside {
      position: sticky;
      top: calc(var(--header-h) + var(--space-xl));
    }
  }

  .faq__title {
    margin: var(--space-sm) 0 var(--space-md);
    font-size: var(--fs-h2);
    font-weight: 800;
    line-height: var(--lh-snug);
    text-transform: uppercase;
  }

  .faq__help {
    margin-bottom: var(--space-md);
    font-size: var(--fs-body-sm);
    color: var(--text-secondary);
  }


  /* ----------------------------------------------------------------- list */

  .faq__list {
    display: grid;
  }

  .faq__item {
    border-top: 1px solid var(--line-faint);
  }

  .faq__item:last-child {
    border-bottom: 1px solid var(--line-faint);
  }

  .faq__q {
    margin: 0;
    font-size: inherit;
  }

  .faq__trigger {
    display: grid;
    grid-template-columns: 6px 1fr auto;
    align-items: center;
    gap: var(--space-sm);
    width: 100%;
    /* Comfortable target on touch without becoming a giant row on desktop. */
    padding: var(--space-md) 0;
    text-align: left;
    color: var(--text-primary);
    transition: color var(--dur-fast) var(--ease-out);
  }

  .faq__trigger:hover {
    color: var(--action-text);
  }

  .faq__trigger:focus-visible {
    outline: 2px solid var(--focus-ring);
    outline-offset: -2px;
  }

  /*
    A bullet, not a number. Sized and coloured to match .rig__spec-dot so the
    two list markers on the page read as the same design element.
  */
  .faq__bullet {
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: var(--action);
    transition: transform var(--dur-base) var(--ease-out), background-color var(--dur-fast) var(--ease-out);
  }

  .faq__trigger:hover .faq__bullet,
  .faq__trigger[aria-expanded="true"] .faq__bullet {
    background: var(--action-text);
    transform: scale(1.5);
  }

  .faq__q-text {
    font-family: var(--font-display);
    font-size: var(--fs-h4);
    font-weight: 600;
    letter-spacing: 0.01em;
    line-height: 1.25;
  }

  /* Plus → minus, drawn from two rules so it needs no icon font. */
  .faq__icon {
    position: relative;
    display: block;
    width: 1rem;
    height: 1rem;
    flex-shrink: 0;
  }

  .faq__icon i {
    position: absolute;
    top: 50%;
    left: 0;
    width: 100%;
    height: 1.5px;
    background: currentColor;
    transition: transform var(--dur-base) var(--ease-out), opacity var(--dur-fast) var(--ease-out);
  }

  .faq__icon i:last-child {
    transform: rotate(90deg);
  }

  .faq__trigger[aria-expanded="true"] .faq__icon i:last-child {
    transform: rotate(0deg);
    opacity: 0;
  }

  .faq__trigger[aria-expanded="true"] {
    color: var(--action-text);
  }

  .faq__panel {
    /* Indent matches the bullet column + gap so answers line up under the
       question text rather than under the marker. */
    padding: 0 0 var(--space-lg) calc(6px + var(--space-sm));
    animation: faq-open var(--dur-base) var(--ease-out);
  }

  .faq__panel[hidden] {
    display: none;
  }

  .faq__panel p {
    max-width: 62ch;
    margin: 0;
    color: var(--text-secondary);
    text-wrap: pretty;
  }

  @keyframes faq-open {
    from {
      opacity: 0;
      transform: translateY(-0.4rem);
    }
  }

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

/* ---- News -------------------------------------------------------------- */

.news {
    background: linear-gradient(to bottom, var(--surface-void), var(--surface-base));
    border-top: 1px solid var(--line-faint);
  }

  .news__head {
    display: flex;
    flex-wrap: wrap;
    justify-content: space-between;
    align-items: end;
    gap: var(--space-md);
    margin-bottom: var(--space-2xl);
  }

  .news__title {
    margin-top: var(--space-sm);
    font-size: var(--fs-h2);
    font-weight: 800;
    line-height: var(--lh-snug);
    text-transform: uppercase;
  }

  .news__grid {
    display: grid;
    gap: var(--space-md);
    margin: 0;
    padding: 0;
    list-style: none;
    grid-template-columns: repeat(auto-fit, minmax(min(100%, 18rem), 1fr));
  }

  /* ----------------------------------------------------------------- card */

  .post__card {
    position: relative;
    display: flex;
    flex-direction: column;
    height: 100%;
    background: var(--surface-raised);
    border: 1px solid var(--line-faint);
    border-radius: var(--radius-md);
    overflow: hidden;
    transition: border-color var(--dur-base) var(--ease-out), transform var(--dur-base) var(--ease-out);
  }

  .post__card:hover,
  .post__card:focus-within {
    border-color: var(--line-strong);
    transform: translateY(-3px);
  }

  .post__card:focus-within {
    outline: 2px solid var(--focus-ring);
    outline-offset: 3px;
  }

  .post__media {
    position: relative;
    aspect-ratio: 16 / 9;
    overflow: hidden;
    background: var(--surface-inset);
  }

  .post__media img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    transition: transform var(--dur-slow) var(--ease-out);
  }

  .post__card:hover .post__media img {
    transform: scale(1.05);
  }

  .post__category {
    position: absolute;
    top: var(--space-sm);
    left: var(--space-sm);
    padding: 0.2rem 0.55rem;
    background: rgba(0, 0, 0, 0.65);
    border: 1px solid var(--line-soft);
    border-radius: var(--radius-xs);
    font-family: var(--font-mono);
    font-size: var(--fs-mono-label);
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--action-text);
  }

  .post__body {
    display: flex;
    flex-direction: column;
    gap: var(--space-2xs);
    flex: 1;
    padding: var(--space-lg);
  }

  .post__date {
    font-family: var(--font-mono);
    font-size: var(--fs-mono-label);
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--text-muted);
  }

  .post__title {
    margin: 0;
    font-size: var(--fs-h4);
    font-weight: 700;
    line-height: 1.2;
    letter-spacing: 0.01em;
    text-transform: uppercase;
  }

  .post__title a {
    color: inherit;
    text-decoration: none;
  }

  .post__title a::after {
    content: "";
    position: absolute;
    inset: 0;
  }

  .post__title a:focus-visible {
    outline: none;
  }

  .post__excerpt {
    flex: 1;
    margin: 0;
    font-size: var(--fs-body-sm);
    color: var(--text-secondary);
  }

  .post__card:hover .link-arrow svg {
    transform: translateX(0.35rem);
  }

/* ---- Final CTA --------------------------------------------------------- */

.final {
    position: relative;
    isolation: isolate;
    padding-block: var(--space-3xl);
    overflow: hidden;
    text-align: center;
  }

  .final__bg {
    position: absolute;
    inset: 0;
    z-index: -1;
    display: grid;
    place-items: center;
    overflow: hidden;
  }

  /*
    Two layers: the centre photo, then a grade that pushes it back far enough
    for white text to sit on it. A line-art wheel used to sit on top of both —
    removed at the owner's request, it read as a stray red ring behind the
    title rather than a background detail.
  */
  .final__photo {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    /* The rigs sit low-left in this frame; bias the crop towards them. */
    object-position: 45% 62%;
  }

  .final__grade {
    position: absolute;
    inset: 0;
    background:
      linear-gradient(to bottom, rgba(4, 9, 11, 0.95) 0%, rgba(0, 20, 24, 0.88) 42%, rgba(4, 9, 11, 0.96) 100%),
      radial-gradient(ellipse 62% 72% at 50% 48%, rgba(245, 20, 15, 0.22), transparent 66%);
  }

  .final__inner {
    display: grid;
    justify-items: center;
    gap: var(--space-md);
  }

  .final__title {
    max-width: 20ch;
    margin: 0;
    font-size: var(--fs-h1);
    font-weight: 800;
    line-height: var(--lh-tight);
    letter-spacing: var(--tracking-display);
    text-transform: uppercase;
  }

  .final__body {
    max-width: 48ch;
    margin: 0;
    font-size: var(--fs-body-lg);
    color: var(--text-secondary);
    text-wrap: pretty;
  }

  .final__actions {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: var(--space-sm);
    margin-top: var(--space-sm);
  }

