/* ==========================================================================
   Granit Invest — main.css
   Jedini vizuelni stylesheet projekta. Bez inline stilova u HTML/PHP fajlovima.
   Struktura:
     1. Tokeni (dark + light tema)
     2. Baza / reset / tipografija
     3. Layout (container, section, rule)
     4. Header i navigacija
     5. Footer
     6. Komponente (kartice, statistika, badge, galerija, forma, lightbox)
     7. Stranice (specifičnosti)
     8. Keyframes
     9. Responsive
   ========================================================================== */

/* ---------- 0. FONTOVI --------------------------------------------------- */

/* Montserrat — naslovi, navigacija, UI. Karla — tekst.
   woff2 pokriva savremene pregledače, ttf ostaje legacy fallback. */

@font-face {
  font-display: swap;
  font-family: 'Montserrat';
  font-style: normal;
  font-weight: 200;
  src: url('/assets/font/montserrat/montserrat-v31-latin_latin-ext-200.woff2') format('woff2'),
       url('/assets/font/montserrat/montserrat-v31-latin_latin-ext-200.ttf') format('truetype');
}

@font-face {
  font-display: swap;
  font-family: 'Montserrat';
  font-style: normal;
  font-weight: 300;
  src: url('/assets/font/montserrat/montserrat-v31-latin_latin-ext-300.woff2') format('woff2'),
       url('/assets/font/montserrat/montserrat-v31-latin_latin-ext-300.ttf') format('truetype');
}

@font-face {
  font-display: swap;
  font-family: 'Montserrat';
  font-style: normal;
  font-weight: 400;
  src: url('/assets/font/montserrat/montserrat-v31-latin_latin-ext-regular.woff2') format('woff2'),
       url('/assets/font/montserrat/montserrat-v31-latin_latin-ext-regular.ttf') format('truetype');
}

@font-face {
  font-display: swap;
  font-family: 'Montserrat';
  font-style: normal;
  font-weight: 500;
  src: url('/assets/font/montserrat/montserrat-v31-latin_latin-ext-500.woff2') format('woff2'),
       url('/assets/font/montserrat/montserrat-v31-latin_latin-ext-500.ttf') format('truetype');
}

@font-face {
  font-display: swap;
  font-family: 'Montserrat';
  font-style: normal;
  font-weight: 600;
  src: url('/assets/font/montserrat/montserrat-v31-latin_latin-ext-600.woff2') format('woff2'),
       url('/assets/font/montserrat/montserrat-v31-latin_latin-ext-600.ttf') format('truetype');
}

@font-face {
  font-display: swap;
  font-family: 'Montserrat';
  font-style: normal;
  font-weight: 700;
  src: url('/assets/font/montserrat/montserrat-v31-latin_latin-ext-700.woff2') format('woff2'),
       url('/assets/font/montserrat/montserrat-v31-latin_latin-ext-700.ttf') format('truetype');
}

@font-face {
  font-display: swap;
  font-family: 'Montserrat';
  font-style: normal;
  font-weight: 800;
  src: url('/assets/font/montserrat/montserrat-v31-latin_latin-ext-800.woff2') format('woff2'),
       url('/assets/font/montserrat/montserrat-v31-latin_latin-ext-800.ttf') format('truetype');
}

@font-face {
  font-display: swap;
  font-family: 'Karla';
  font-style: normal;
  font-weight: 300;
  src: url('/assets/font/karla/karla-v33-latin_latin-ext-300.woff2') format('woff2'),
       url('/assets/font/karla/karla-v33-latin_latin-ext-300.ttf') format('truetype');
}

@font-face {
  font-display: swap;
  font-family: 'Karla';
  font-style: normal;
  font-weight: 400;
  src: url('/assets/font/karla/karla-v33-latin_latin-ext-regular.woff2') format('woff2'),
       url('/assets/font/karla/karla-v33-latin_latin-ext-regular.ttf') format('truetype');
}

@font-face {
  font-display: swap;
  font-family: 'Karla';
  font-style: normal;
  font-weight: 500;
  src: url('/assets/font/karla/karla-v33-latin_latin-ext-500.woff2') format('woff2'),
       url('/assets/font/karla/karla-v33-latin_latin-ext-500.ttf') format('truetype');
}

@font-face {
  font-display: swap;
  font-family: 'Karla';
  font-style: normal;
  font-weight: 600;
  src: url('/assets/font/karla/karla-v33-latin_latin-ext-600.woff2') format('woff2'),
       url('/assets/font/karla/karla-v33-latin_latin-ext-600.ttf') format('truetype');
}

/* ---------- 0. IKONE (Phosphor Light) ------------------------------------ */

@font-face {
  font-family: "Phosphor-Light";
  /* Podskup: samo 37 glifova koje .ph-* pravila ispod zaista koriste.
     Pun Phosphor-Light je 152 KiB i stoji na kritičnoj putanji, a ikona
     hamburgera je LCP element. Podskup se pravi iz Phosphor-Light.woff2
     preko pyftsubset; kad se doda nova .ph-* ikona, podskup mora ponovo. */
  src: url("/assets/phosphor/Phosphor-Light-gi-3.woff2") format("woff2");
  font-weight: normal;
  font-style: normal;
  font-display: swap;
}

.ph-light {
  font-family: "Phosphor-Light";
  font-style: normal;
  font-weight: normal;
  font-variant: normal;
  line-height: 1;
  letter-spacing: 0;
  speak: never;
  text-transform: none;
  flex: none;
  color: var(--color-accent-ink);
  font-size: 15px;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

.ph-arrow-down::before { content: "\e03e"; }
.ph-arrow-square-out::before { content: "\e5de"; }
.ph-arrows-out::before { content: "\e0a2"; }
.ph-bicycle::before { content: "\e0d6"; }
.ph-buildings::before { content: "\e102"; }
.ph-car::before { content: "\e112"; }
.ph-caret-left::before { content: "\e138"; }
.ph-caret-right::before { content: "\e13a"; }
.ph-check::before { content: "\e182"; }
.ph-clock::before { content: "\e19a"; }
.ph-elevator::before { content: "\ecc0"; }
.ph-envelope-simple::before { content: "\e218"; }
.ph-facebook-logo::before { content: "\e226"; }
.ph-file-arrow-down::before { content: "\e232"; }
.ph-file-text::before { content: "\e23a"; }
.ph-fork-knife::before { content: "\e262"; }
.ph-handshake::before { content: "\e582"; }
.ph-house-line::before { content: "\e2c4"; }
.ph-headset::before { content: "\e584"; }
.ph-instagram-logo::before { content: "\e2d0"; }
.ph-linkedin-logo::before { content: "\e2ee"; }
.ph-list::before { content: "\e2f0"; }
.ph-lock-key::before { content: "\e2fe"; }
.ph-map-pin::before { content: "\e316"; }
.ph-moon::before { content: "\e330"; }
.ph-paper-plane-tilt::before { content: "\e398"; }
.ph-play::before { content: "\e3d0"; }
.ph-phone::before { content: "\e3b8"; }
.ph-plug-charging::before { content: "\eb5c"; }
.ph-seal-check::before { content: "\e606"; }
.ph-shield-check::before { content: "\e40c"; }
.ph-shower::before { content: "\e776"; }
.ph-sparkle::before { content: "\e6a2"; }
.ph-sun::before { content: "\e472"; }
.ph-tree::before { content: "\e6da"; }
.ph-wrench::before { content: "\e5d4"; }
.ph-x::before { content: "\e4f6"; }
.ph-youtube-logo::before { content: "\e4fc"; }

/* ---------- Video (thumb + play, ugradnja tek na klik) ------------------- */

/* .video je okvir, ne dugme: iframe koji stize posle klika ne sme da zavrsi
   unutar <button> (button ne sme da sadrzi interaktivni sadrzaj). */
.video {
  position: relative;
  margin-block-start: 40px;
  inline-size: 100%;
  border-radius: var(--radius-media);
  overflow: hidden;
  aspect-ratio: 800 / 450;

  & .video__thumb {
    inline-size: 100%;
    block-size: 100%;
    object-fit: cover;
    filter: grayscale(1);
    transition: filter .4s ease, transform .6s ease;

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

  & iframe {
    inline-size: 100%;
    block-size: 100%;
    border: 0;
  }

  &:hover .video__thumb {
    filter: grayscale(0);
    transform: scale(1.02);
  }

  /* U svetloj temi fotografija stoji u boji, a sivi se na hover — isto pravilo
     kao kod .media-frame, .media-card i .hero__slide. Bez ovoga je naslovna
     slika videa ostajala crno-bela i u svetloj temi. */
  [data-theme="light"] & .video__thumb {
    filter: grayscale(0);
  }

  [data-theme="light"] &:hover .video__thumb {
    filter: grayscale(1);
  }

  &:hover .video__play {
    background: var(--color-accent);
  }

  /* Dugme prekriva ceo okvir; thumb i play ikonica su ispod njega. */
  & .video__trigger {
    position: absolute;
    inset: 0;
    inline-size: 100%;
    block-size: 100%;
    padding: 0;
    border: none;
    background: none;
    cursor: pointer;

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

  & .video__play {
    position: absolute;
    inset-block-start: 50%;
    inset-inline-start: 50%;
    transform: translate(-50%, -50%);
    inline-size: 84px;
    block-size: 84px;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 50%;
    /* Akcentni krug sa belim trouglom, isti jezik kao badgevi. Ranije je bio
       25% crne sa ikonicom u --gi-white, a taj token u svetloj temi postaje
       #0F0F0F, pa se trougao gubio na svetloj fotografiji. Bela je zato
       fiksna, a podloga ide iz akcenta i radi u obe teme. */
    background: color-mix(in srgb, var(--color-accent) 90%, transparent);
    -webkit-backdrop-filter: blur(2px);
    backdrop-filter: blur(2px);
    transition: background .3s ease, transform .3s ease;

    & .ph-light {
      font-size: 34px;
      color: var(--gi-white-fixed);
    }
  }

  @media (max-width: 760px) {
    & .video__play {
      inline-size: 60px;
      block-size: 60px;

      & .ph-light {
        font-size: 24px;
      }
    }
  }
}


/* ---------- 1. TOKENI ---------------------------------------------------- */

:root {
  /* brend */
  --color-accent: #E87510;
  /* Akcenat kada je mastilo na podlozi strane. Na tamnoj temi je isti kao
     osnovni; na svetloj mora da bude tamniji, jer #ff8316 na #F4F2EE daje
     kontrast 2.21:1, daleko ispod 4.5:1 koliko traži sitan tekst. */
  --color-accent-ink: #E87510;
  --color-accent-soft: rgba(232, 117, 16, .5);
  --color-accent-light: #FFE7C4;

  /* površine — dark tema (podrazumevana) */
  --gi-bg: #121212;
  --gi-panel: #161616;
  --gi-strip: #161616;
  --gi-footer: #0D0D0D;
  --gi-heroBg: #101010;
  --gi-headerBg: rgba(18, 18, 18, .7);
  --gi-headerShadow: 0 8px 20px rgba(0, 0, 0, .65);
  /* Senka kartice objekta. U tamnoj temi kontrast nosi crno, jer je podloga
     stranice svetlija od same senke; u svetloj nosi siva. */
  --gi-panelShadow: 1px 1px 8px rgba(0, 0, 0, .6);
  --gi-menuBg: rgba(18, 18, 18, .92);

  /* tekst — naslov i pasus dele istu boju u obe teme */
  --gi-text: #E7E7E9;
  --gi-white: #FFFFFF;
  --gi-muted: #E7E7E9;
  --gi-nav: #C9C9C9;
  --gi-dim: #A9A9A9;
  --gi-faint: #8a8a8a;
  --gi-label: #EDEDED;
  --gi-sub: #DADADA;

  /* linije i efekti */
  --gi-line0: rgba(255, 255, 255, .06);
  --gi-line1: rgba(255, 255, 255, .07);
  --gi-line2: rgba(255, 255, 255, .08);
  --gi-line3: rgba(255, 255, 255, .09);
  --gi-inputline: rgba(255, 255, 255, .28);
  --gi-watermark: rgba(255, 255, 255, .025);

  /* konstante — iste u obe teme.
     Belo preko fotografija, scrima i akcenta ne sme da prati temu kao
     --gi-white; ink stoji na akcentnoj podlozi; error boji stanje forme. */
  --gi-white-fixed: #FFFFFF;
  --gi-ink-on-accent: #0B0B0B;
  --color-error: #D9534F;
  /* Jedina zelena na sajtu, rezervisana za WhatsApp. Brend zelena servisa
     (#25D366) pada na 1.98:1 sa belim glifom i tuče se sa akcentom. */
  --gi-whatsapp: #1F7A45;

  /* tipografija — fluidne skale */
  --fs-xxs: clamp(0.6875rem, calc(0.665rem + 0.1vw), 0.75rem);
  --fs-xs: clamp(0.7188rem, calc(0.6963rem + 0.1vw), 0.7813rem);
  --fs-s: clamp(0.75rem, calc(0.7275rem + 0.1vw), 0.8125rem);
  --fs-sm: clamp(0.7813rem, calc(0.7475rem + 0.15vw), 0.875rem);
  /* Globalna skala pasusa. 14.7px na 360px širine, 16.8px (1.05rem) od
     1280px naviše. */
  --fs-base: clamp(0.9188rem, calc(0.8674rem + 0.228vw), 1.05rem);
  --fs-md: clamp(0.85rem, calc(0.7913rem + 0.261vw), 1rem);
  /* 15.6px na 360px širine, 17.6px (1.1rem) od 1280px naviše. */
  --fs-lead: clamp(0.975rem, calc(0.9261rem + 0.217vw), 1.1rem);
  --fs-lg: clamp(1.1688rem, calc(1.0881rem + 0.359vw), 1.375rem);
  --fs-xl: clamp(1.4375rem, calc(1.3394rem + 0.435vw), 1.6875rem);
  --fs-2xl: clamp(1.5938rem, calc(1.4837rem + 0.489vw), 1.875rem);
  --fs-3xl: clamp(1.375rem, 3vw, 1.875rem);
  --fs-hero: clamp(2.75rem, 6vw, 4.75rem);

  /* tipografija — uloge koje dele istu skalu na vise komponenti.
     Menjaju se ovde jednom, ne u svakoj komponenti ponaosob. */
  /* Naslov stranice: 24px na 360px širine, 30px od 1280px naviše. Isti nivo
     nose i naslovi kartica objekata, pa mera stoji na jednom mestu. */
  --fs-h1: clamp(1.5rem, calc(1.3533rem + 0.652vw), 1.875rem);
  /* Pogodnosti u karticama i ispod glavne slike: 13.1px na 360px širine,
     15px od 1280px naviše. Ista rampa i isti odnos kao --fs-base. */
  --fs-feature: clamp(0.8203rem, calc(0.7745rem + 0.204vw), 0.9375rem);
  /* Navigacija i skip link: 10.9px na 360px širine, 12.5px od 1280px naviše. */
  --fs-nav: clamp(0.6836rem, calc(0.6454rem + 0.170vw), 0.7812rem);
  /* Spiskovi u futeru: 12.6px → 14.4px. */
  --fs-footer: clamp(0.7875rem, calc(0.7435rem + 0.196vw), 0.9rem);
  /* Potpis i pravne oznake u donjem redu futera: 10.5px → 12px. */
  --fs-legal: clamp(0.6562rem, calc(0.6196rem + 0.163vw), 0.75rem);
  --fs-title: clamp(1.275rem, calc(1.1869rem + 0.391vw), 1.5rem);
  --fs-title-sm: clamp(1.0625rem, calc(0.9894rem + 0.326vw), 1.25rem);
  --fs-field: clamp(0.7438rem, calc(0.6925rem + 0.228vw), 0.875rem);
  --fs-meta: clamp(0.6375rem, calc(0.5938rem + 0.196vw), 0.75rem);

  /* razmaci */
  --space-1: 4px;
  --space-2: 8px;
  --space-3: 14px;
  --space-4: 22px;
  --space-5: 32px;
  --space-6: 50px;
  --space-7: 64px;
  --space-8: 80px;
  --space-9: 96px;
  --space-10: 110px;

  /* radijusi */
  --radius-s: 3px;
  --radius-m: 8px;
  /* Jedan radijus za sve slike i kartice — kartica je merilo. */
  --radius-media: 5px;
  --radius-pill: 24px;

  /* mere */
  --wrap: 1240px;
  --wrap-pad: 32px;
  --notch: 10px;

  /* Jedna kriva za sva stanja na prelazak mišem: sporo kreće, sporo staje.
     Ulazak je nešto duži od izlaska, jer se povratak u mirno stanje ne gleda. */
  --ease: cubic-bezier(.4, 0, .2, 1);
  /* Klizna kriva: krene mekano pa dugo usporava. Polazi od one sa prezentacije
     Javora (.16, 1, .3, 1), samo upola blaža — početni nagib je y1/x1, sa 6.25
     spušten na 3.125, pa pokret nema trzaj na startu. */
  --ease-slide: cubic-bezier(.32, 1, .5, 1);
  --dur-in: .28s;
  --dur-out: .18s;

  /* Stvarna visina fiksnog hedera. Telo je rezerviše, pa razmak koji prvi blok
     doda jeste razmak koji se stvarno vidi ispod navigacije. Vrednost mora da
     prati min-block-size na .site-header__inner na svakoj širini. */
  --header-h: 55px;

  @media (min-width: 761px) {
    --header-h: 70px;
  }
}

[data-theme="light"] {
  --gi-bg: #F4F2EE;
  --gi-panel: #FFFFFF;
  --gi-strip: #EAE7E1;
  --gi-footer: #F4F2EF;
  --gi-heroBg: #DDDAD4;
  --gi-headerBg: rgba(244, 242, 238, .7);
  --gi-headerShadow: 0 8px 20px rgba(0, 0, 0, .1);
  --gi-panelShadow: 1px 1px 8px #e2e2e2;
  --gi-menuBg: rgba(244, 242, 238, .92);
  /* Akcenat je u lite temi svetliji, da na beloj podlozi drži isti kontrast
     kao #E87510 na tamnoj. */
  --color-accent: #ff8316;
  /* Naslovi i sitan akcentni tekst idu u brend narandžastu, isto kao ostatak
     akcenta. Ranije je ovde stajala potamnjena #A94E00 i naslovi su u lite
     temi izgledali braon. Pločica badge-a i dalje ima svoj tamniji ton, jer
     tamo tekst stoji na beloj podlozi. */
  --color-accent-ink: #ff8316;
  --gi-text: #181818;
  --gi-white: #0F0F0F;
  --gi-muted: #181818;
  --gi-nav: #4E4E4E;
  --gi-dim: #5C5C5C;
  --gi-faint: #6A6A6A;
  --gi-label: #2B2B2B;
  --gi-sub: #454545;
  --gi-line0: rgba(0, 0, 0, .06);
  --gi-line1: rgba(0, 0, 0, .08);
  --gi-line2: rgba(0, 0, 0, .13);
  --gi-line3: rgba(0, 0, 0, .17);
  --gi-inputline: rgba(0, 0, 0, .42);
  --gi-watermark: rgba(0, 0, 0, .035);
}

/* ---------- 2. BAZA ----------------------------------------------------- */

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

html {
  scrollbar-gutter: stable;

  @media (prefers-reduced-motion: no-preference) {
    scroll-behavior: smooth;
  }
  overflow-x: clip;
}

body {
  margin: 0;
  /* Heder je fixed i ne zauzima mesto u toku, pa telo mora da rezerviše
     njegovu visinu. Ranije je stajalo 40px, manje od hedera, i prvi blok je
     ulazio ispod navigacije: od 100px razmaka videlo se 62. */
  padding-block-start: var(--header-h);
  background: var(--gi-bg);
  color: var(--gi-text);
  font-family: 'Montserrat', sans-serif;
  -webkit-font-smoothing: antialiased;
  overflow-x: clip;
}

body.is-home {
  padding-block-start: 0;
}

img,
svg,
video {
  display: block;
}

/* Slike se ne prevlače i ne selektuju: bez ovoga se fotografija lako slučajno
   odvuče iz stranice, a na dodiru to izgleda kao da se raspao raspored. */
img {
  user-select: none;
  -webkit-user-drag: none;
}

a {
  color: var(--gi-text);
  text-decoration: none;
  transition: color .2s ease;

  &:hover {
    color: var(--color-accent);
  }

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

button {
  font-family: inherit;
}

/* Adresa je obican tekst: browser default italic se ne koristi nigde. */
address {
  font-style: normal;
}

/* Eksponent ne sme da razvuce prored reda. */
sup {
  font-size: .7em;
  line-height: 0;
  vertical-align: super;
}


/* tekstualni nivoi */
/* Karla je tekstualni font: nosi ga pasus, ne naslovi i UI. */
/* Svi naslovi imaju istu tezinu. Klase ispod nose samo velicinu i razmak;
   nijedna ne propisuje tezinu, pa se nivoi ne mogu razici. */
:is(h1, h2, h3, h4, h5, h6) {
  font-weight: 500;
}

/* Tekst u telu. Pasus i stavka tekstualne liste su ista stvar i dele jednu
   deklaraciju — .icon-list nosi ikone i kolone, a veličinu dobija odavde, ne
   iz sopstvenog pravila. Ostale liste (.stats, .ref-list, .media-row, galerije)
   nisu tekst nego kontejneri za kartice i slike, pa ih ovo namerno ne dira:
   `li` bez sužavanja nasleđuje prored i boju u naslove unutar kartica. */
p,
.icon-list > li {
  font-family: 'Karla', sans-serif;
  font-size: var(--fs-base);
  line-height: 1.5;
  color: var(--gi-muted);
  font-weight: 300;
  text-wrap: pretty;
}

/* Razmak ispod nosi samo pasus; liste svoj razmak rešavaju kroz gap. */
p {
  margin: 0 0 var(--space-4);

  &:last-child {
    margin-bottom: 0;
  }
}

/* Futer nije lista stavki nego <address> i <div>; nosi samo pismo i veličinu,
   da se tekst u njemu ne razilazi sa ostatkom sajta. */
.footer-list {
  font-family: 'Karla', sans-serif;
  font-size: var(--fs-base);
}

/* Broj kolona zadaje sama lista u markapu: data-cols="2|3|4". */
.icon-list[data-cols="2"] { grid-template-columns: repeat(2, minmax(0, 1fr)); }
/* Prva kolona nosi kratke podatke, druga dugačke — na pola-pola prva zjapi
   prazna, a duži red se prelama. Mobilni prag ih ionako spaja u jednu. */
.icon-list[data-cols="40-60"] { grid-template-columns: 40% 60%; }
.icon-list[data-cols="3"] { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.icon-list[data-cols="4"] { grid-template-columns: repeat(4, minmax(0, 1fr)); }

/* Jedna klasa za sve liste sa ikonicom.
   Kolone se same broje prema širini: kratke stavke daju dve ili tri,
   duge stavke ostaju u jednoj. Ikona je isti kvadrat bez obzira na to
   da li dolazi iz Phosphor fonta ili iz assets/ico. */
.icon-list {
  list-style: none;
  /* Spisak se odvaja od teksta iznad sebe; razmak ispod njega nosi ono što
     dolazi posle, ne sam spisak. */
  margin: 20px 0 0;
  padding: 0;
  display: grid;
  grid-template-columns: 1fr;
  gap: 6px 12px;
  line-height: 1.5;
  color: var(--gi-muted);
  font-weight: 300;

  & li {
    display: flex;
    align-items: flex-start;
    gap: 12px;

    /* Na prelazak mišem tekst klizne udesno, ikona ostaje na mestu — isto kao
       na javor.granitinvest.rs. */
    & > span {
      transition: transform 1s var(--ease-slide);
    }

    &:hover > span {
      transform: translateX(10px);
    }

    @media (prefers-reduced-motion: reduce) {
      & > span,
      &:hover > span {
        transition: none;
        transform: none;
      }
    }
  }

  & a {
    color: inherit;

    &:hover {
      color: var(--gi-text);
      text-decoration: underline;
      text-decoration-color: var(--color-accent);
      text-underline-offset: 3px;
    }
  }

  /* Ikona zauzima isti prostor iz oba izvora. Kutija je visoka tačno jedan red
     teksta (1lh), pa glif stoji u sredini prvog reda — i kod stavki koje se
     prelome u dva reda ostaje uz prvi, a ne u sredini cele stavke. Da bi 1lh
     bio red teksta a ne red ikone, ikona uzima veličinu i prored od teksta. */
  & :is(img, .ph-light) {
    inline-size: 1lh;
    block-size: 1lh;
    flex: none;
    display: grid;
    place-items: center;
    font-size: 1em;
    line-height: inherit;
  }

  /* U linku ikona teče uz tekst, pa podvlaka staje ispod teksta. Kutija je i
     ovde visoka jedan red, a `vertical-align: top` je poklapa sa redom umesto
     da je pomera pikselima. */
  & a :is(img, .ph-light) {
    display: inline-grid;
    margin-inline-end: 12px;
    vertical-align: top;
  }
}

/* Kartice objekata na preglednim stranicama i liste ispod glavne slike na
   stranici objekta nose sitniji tekst od pasusa. Mera stoji na samoj stavci,
   pa je uzimaju i tekst i ikona: kutija ikone i dalje meri jedan red. */
:is(.panel, .project) .icon-list > li {
  font-size: var(--fs-feature);
}

/* Servisna lista u zaglavlju stranice: ikona stoji u kvadratu sa istim zasekom
   koji nosi badž. Namerno suženo na .page-head, jer ista klasa opslužuje i
   kontakt i futer, gde je stavka link i podvlaka mora da stane ispod teksta, i
   liste pogodnosti na stranicama objekata, koje idu do 14 stavki i nose <img>
   ikone sa narandžastom upisanom u sam SVG. */
.page-head > .icon-list,
.project .icon-list:has(~ figure.figure--framed) {
  gap: 18px 48px;

  & li {
    align-items: center;
    gap: 16px;
  }

  & .ph-light {
    inline-size: 40px;
    block-size: 40px;
    display: grid;
    place-items: center;
    margin-block-start: 0;
    color: var(--gi-text);
    border: 1px solid color-mix(in srgb, var(--color-accent) 35%, transparent);
    clip-path: polygon(var(--notch) 0, 100% 0, 100% calc(100% - var(--notch)), calc(100% - var(--notch)) 100%, 0 100%, 0 var(--notch));
    transition: border-color var(--dur-out) var(--ease),
                background var(--dur-out) var(--ease);

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

  & li:hover .ph-light {
    border-color: var(--color-accent);
    background: color-mix(in srgb, var(--color-accent) 8%, transparent);
    transition-duration: var(--dur-in);
  }
}


/* .lead je isti pasus, samo krupniji uvodni nivo. */
/* Lead je uvek <p> i deli mu boju u obe teme; boju zato ne postavlja sam. */
.lead {
  font-family: 'Karla', sans-serif;
  margin: 0 0 var(--space-4);
  font-size: var(--fs-lead);
  line-height: 1.4;
  font-weight: 300;
  text-wrap: pretty;
}


p a {
  color: inherit;
  text-decoration: underline;
  text-decoration-color: var(--color-accent-soft);
  text-underline-offset: 3px;
}

/* Isti hover za svaki link u tekstu, listi ili futeru. */
p a:hover {
  color: var(--gi-text);
  text-decoration: underline;
  text-decoration-color: var(--color-accent);
  text-underline-offset: 3px;
}

/* ---------- 3. LAYOUT --------------------------------------------------- */

/* Tekst ostaje čitljiv čitačima ekrana, a ne zauzima mesto na ekranu.
   Koristi se za naslove i opise koje vizuelni raspored već nosi slikom. */
.u-visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

.container {
  max-inline-size: var(--wrap);
  margin-inline: auto;
  padding-inline: var(--wrap-pad);
}

.section {
  /* Bez razmaka odozgo, na svakoj širini. Otkad .page-head nosi svojih 30px
     odozdo, sekcija ispod njega ne treba da dodaje ništa — inače se dva
     razmaka sabiraju. */
  padding-block-start: 0;

  /* Odozdo, samo na naslovnoj i samo na desktopu: 80px odvaja mrežu osnovnih
     kartica od sekcija za stambene i poslovne objekte. Ide kao padding, ne
     margina — margina bi se sklopila sa marginom prvog bloka ispod i razmak bi
     ostao manji od traženog.

     Vezano za naslovnu, jer na pregledima ista klasa drži kartice objekata i
     iza njih ne dolazi nova sekcija nego traka klijenata; tamo je padding
     pravio 270px praznine umesto 110. */
  @media (min-width: 1030px) {
    body.is-home & {
      padding-block-end: 80px;
    }
  }
}

/* Ovi modifikatori su samostalne utility klase u postojećem HTML-u. */
.section--tight {
  padding-block-start: 60px;
}

/* Prvi blok ispod hero slidera na naslovnoj. Nosi 50px preko uobičajenog
   razmaka sekcije, da se sadržaj odvoji od fotografije koja se smenjuje. */
.section--intro {
  position: relative;
  z-index: 0;
  /* Isti razmak gore i dole. Traženih 100px odozdo pada na --space-9, koji je
     96px — najbliži korak skale, pa mera ostaje u sistemu umesto da uđe kao
     usamljen piksel. Odozgo je otpalo +50px kojim se blok odvajao od hero
     slajdera. */
  padding-block: var(--space-9);
}

.section-title {
  margin: 0 0 12px;
  font-size: var(--fs-3xl);
}

/* Jedina mera za sve linije u projektu. Ranije su postojala četiri pravila:
   ovo sa 10px, dva sa 30px vezana za naslov ispred, i futersko sa 23px. Onih
   10px nije bilo nigde na ekranu — svaka linija stoji ili iza naslova ili u
   futeru — pa su tri pravila držala jednu vrednost i jedno mrtvo slovo. */
hr {
  border: none;
  inline-size: 56px;
  block-size: 1px;
  margin: 0 0 30px;
  background: var(--color-accent);
}

/* dvokolonski uvod: simbol + tekst */
.intro-grid {
  display: grid;
  grid-template-columns: minmax(0, 220px) minmax(0, 1fr);
  gap: var(--space-7);
  align-items: start;
}

.intro-symbol {
  inline-size: 140px;
  /* width/height atributi na <img> su presentational hint; bez ovoga bi
     visina ostala 200px iz atributa i znak bi bio razvucen. */
  block-size: auto;

  /* Uspon ima samo naslovna. */
  body.is-home & {
    animation: symUp 1s linear both;
    animation-timeline: view();
    animation-range: entry 0% cover 100%;

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

[data-theme="light"] :is(.intro-symbol, .card-label__mark) {
  filter: brightness(0) invert(79%);
}

/* Pečat u pozadini. Jedna veličina i jedan položaj na svim stranicama —
   početna je ranije imala 492px/-245px, a sve ostale 378px/-150px kroz
   varijantu koja više ne postoji. */
.seal-bg {
  position: absolute;
  z-index: -1;
  right: 30px;
  inset-block-start: -121px;
  inline-size: 243px;
  block-size: 243px;
  opacity: .5;
  filter: brightness(0) invert(23.9%);
  pointer-events: none;
  user-select: none;
  animation: spinSlow 120s linear infinite;

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

  [data-theme="light"] & {
    filter: brightness(0) invert(83.9%);
  }

}

/* ---------- 4. HEADER --------------------------------------------------- */

/* Prvi tab stop na strani: preskače 9 kontrola hedera do <main id="sadrzaj">.
   Ostaje u toku fokusa (transform, ne display/visibility), a z-index je iznad
   hedera (50) i otvorenog mobilnog menija (60). */
.skip-link {
  position: fixed;
  inset-block-start: 0;
  inset-inline-start: var(--wrap-pad);
  z-index: 70;
  padding: 10px 18px;
  background: rgb(169 78 0 / .96);
  clip-path: polygon(var(--notch) 0, 100% 0, 100% calc(100% - var(--notch)), calc(100% - var(--notch)) 100%, 0 100%, 0 var(--notch));
  color: var(--gi-white-fixed);
  font-size: var(--fs-nav);
  font-weight: 600;
  letter-spacing: .06em;
  line-height: 1;
  transform: translateY(-150%);
  transition: transform .2s ease;

  /* Bez klizanja: link i dalje uskače na fokus, samo trenutno. */
  @media (prefers-reduced-motion: reduce) {
    transition: none;
  }

  &:focus {
    transform: translateY(14px);
  }

  /* Globalno a:hover boji tekst u akcenat; ovde bi pao kontrast na fillu. */
  &:hover {
    color: var(--gi-white-fixed);
  }
}

/* Cilj skip linka. tabindex="-1" ga čini programski fokusabilnim da fokus
   stvarno pređe na sadržaj; okvir se ne crta jer se tu ne stiže tabom. */
#sadrzaj:focus {
  outline: none;
}

.site-header {
  position: fixed;
  inset-block-start: 0;
  inset-inline: 0;
  z-index: 50;

  /* Jedina animacija koja namerno ostaje i pod reduced-motion: vezana je za
     poziciju skrola, ne za vreme, i menja samo podlogu i mastilo. Ništa se
     ne pomera, a gašenje bi ostavilo heder bez čitljive podloge nad hero
     fotografijom. */
  animation: headerDark linear both;
  animation-timeline: scroll(root);
  animation-range: 0px 260px;

  body:not(.is-home) & {
    animation-name: headerSolid;
    box-shadow: var(--gi-headerShadow);
  }

  [data-theme="light"] & {
    animation-name: headerDarkLight;
  }

  [data-theme="light"] body:not(.is-home) & {
    animation-name: headerSolidLight;
  }

  & .site-header__inner {
    max-inline-size: var(--wrap);
    margin-inline: auto;
    padding: 0px var(--wrap-pad);
    min-block-size: 55px;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 24px;

    @media (min-width: 761px) {
      min-block-size: 70px;
    }
  }
}

.brand {
  display: flex;
  align-items: center;
  gap: 12px;
  color: var(--gi-white);

  & .brand__logo {
    display: block;
    inline-size: 140px;

    @media (min-width: 761px) {
      inline-size: 150px;
    }

    & svg {
      display: block;
      inline-size: 100%;
      block-size: auto;
    }

  }
}

/* Natpis u logotipu prati mastilo hedera; nema zasebnu boju ni drugi fajl. */
.brand__logo .st1 {
  fill: var(--gi-white);
}

/* Svetla tema na naslovnoj: dok heder stoji nad tamnom hero fotografijom,
   mastilo mora da bude svetlo. Stanje nosi atribut, ne @keyframes — scroll
   driven animacija primenjuje samo prave osobine, custom property-je tiho
   preskače, pa je `--gi-nav` u keyframe-u bio bez ikakvog efekta.
   Podrazumevano stanje je „nad slikom“, pa nema treptaja pre nego što se JS
   izvrši; atribut stiže tek kad se odskroluje. */
html.js[data-theme="light"] body.is-home .site-header:not([data-scrolled]):not(:has(.site-nav[data-open="true"])) {
  --gi-white: #FFFFFF;

  /* Ispod 1030px navigacija je sklopljena u meni i nije nad slikom —
     svetlo treba samo logotipu i burgeru, koji idu na --gi-white. */
  @media (min-width: 1030px) {
    --gi-nav: #E6E6E6;
  }
}

.site-nav {
  display: flex;
  align-items: center;
  gap: 14px 22px;
  flex-wrap: wrap;
  justify-content: flex-end;
}

.nav-link {
  font-size: var(--fs-nav);
  font-weight: 500;
  white-space: nowrap;
  color: var(--gi-nav);
  padding-block: 6px;
  border-block-end: 1px solid transparent;

  &[aria-current="page"] {
    color: var(--gi-white);
  }

  @media (min-width: 1030px) {
    &:not(.lang-link) {
      background: linear-gradient(var(--color-accent) 0 0) left bottom / 0 1px no-repeat;
      transition: color .2s ease, background-size .45s cubic-bezier(.23, 1, .32, 1);

      &:hover {
        color: var(--gi-nav);
      }

      &:is(:focus-visible, [aria-current="page"]) {
        background-size: 100% 1px;
      }

      &[aria-current="page"]:hover {
        color: var(--gi-white);
      }
    }
  }

  @media (min-width: 1030px) and (hover: hover) and (pointer: fine) {
    &:not(.lang-link):hover {
      background-size: 100% 1px;
    }
  }
}

.nav-cta {
  position: relative;
  font-size: var(--fs-nav);
  font-weight: 600;
  white-space: nowrap;
  color: var(--gi-nav);
  border: 0;
  padding: 8px 16px;
  clip-path: polygon(var(--notch) 0, 100% 0, 100% calc(100% - var(--notch)), calc(100% - var(--notch)) 100%, 0 100%, 0 var(--notch));
  transition: color var(--dur-out) var(--ease),
              background var(--dur-out) var(--ease);

  /* Isto stanje kao ostala dugmad: podloga se puni akcentom na 8%. Ranije je
     hover samo prigušivao tekst, pa je jedino dugme u navigaciji na prelazak
     mišem postajalo slabije umesto jače. */
  &:hover {
    color: var(--gi-white);
    background: color-mix(in srgb, var(--color-accent) 8%, transparent);
    transition-duration: var(--dur-in);
  }

  /* Kad si na toj stranici, dugme ostaje upaljeno. Stoji posle :hover, pa
     tekuća stranica zadržava jače stanje i dok je miš preko njega.
     `aria-current="page"` postavlja inc/header.php. */
  &[aria-current="page"] {
    color: var(--gi-white);
    background: color-mix(in srgb, var(--color-accent) 14%, transparent);
  }

  &::before {
    content: "";
    position: absolute;
    inset: 0;
    opacity: .7;
    background: conic-gradient(from var(--ctaAng),
        var(--color-accent-soft) 0deg,
        var(--color-accent-soft) 210deg,
        var(--color-accent) 296deg,
        var(--color-accent-light) 332deg,
        var(--color-accent) 350deg,
        var(--color-accent-soft) 360deg);
    clip-path: polygon(var(--notch) 0, 100% 0, 100% calc(100% - var(--notch)), calc(100% - var(--notch)) 100%, 0 100%, 0 var(--notch));
    padding: 1.5px;
    -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
    -webkit-mask-composite: xor;
    mask-composite: exclude;
    pointer-events: none;
    animation: ctaSpin 6.6s linear infinite;

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

.icon-button {
  cursor: pointer;
  background: none;
  border: none;
  color: var(--gi-nav);
  font-size: var(--fs-md);
  font-weight: 700;
  line-height: 1;
  padding: 0;
  inline-size: 28px;
  block-size: 24px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 2px;
  white-space: nowrap;
  transition: color .2s ease;
  position: relative;

  /* Nevidljivo prošireno polje dodira: kutija ostaje 28×24 da raspored
     hedera ne mrdne, a prst dobija 28×44.

     Širi se samo po visini. Inline širenje je izbačeno jer razmak do
     susednog ENG linka nije stalan: na 1030–1110px se gap navigacije
     spusti na 12px, a .lang-link ima margin-inline-start: -10px, pa
     između kutija ostane 2px. Dva polja od po 6px tu se preklope i
     ENG — koji se crta kasnije — pokupi klik unutar same kutije teme. */
  &::before {
    content: '';
    position: absolute;
    inset-block: -10px;
    inset-inline: 0;
  }

  &:hover {
    color: var(--color-accent);
  }

  & .ph-light {
    font-size: 18px;
    color: inherit;
  }

  & .ph-moon {
    display: none;
  }

  [data-theme="light"] & .ph-sun {
    display: none;
  }

  [data-theme="light"] & .ph-moon {
    display: block;
  }
}

/* Jezički prekidač je nav link; širina mu je stalna da alati ne skaču
   kada se ENG zameni sa SRB. */
.lang-link {
  margin-inline-start: -10px;
  display: inline-block;
  min-inline-size: 30px;
  text-align: end;
  position: relative;

  /* Isto prošireno polje dodira kao na .icon-button — samo po visini. */
  &::before {
    content: '';
    position: absolute;
    inset-block: -10px;
    inset-inline: 0;
  }
}

.burger {
  display: none;
  cursor: pointer;
  background: none;
  border: 1px solid var(--gi-line3);
  color: var(--gi-text);
  font-size: clamp(0.9563rem, calc(0.89rem + 0.293vw), 1.125rem);
  line-height: 1;
  padding: 5px 12px;
  border-radius: var(--radius-s);
  align-items: center;
  justify-content: center;
}

/* Tri crte koje se na otvorenom meniju sklope u krstić. Stanje nosi
   aria-expanded, koje skripta već postavlja pri svakom otvaranju, pa ovde nema
   ni reda novog JS-a. Animiraju se samo transform i opacity — pomeranje kroz
   inset-block-start bi izbacilo pokret sa kompozitora. */
.burger__bars {
  position: relative;
  display: block;
  inline-size: 22px;
  block-size: 16px;

  & > span {
    position: absolute;
    inset-inline: 0;
    block-size: 1.5px;
    background: currentColor;
    transition: transform var(--dur-in) var(--ease-slide),
                opacity var(--dur-out) var(--ease);
  }

  & > span:nth-child(1) { inset-block-start: 0; }
  & > span:nth-child(2) { inset-block-start: 7.25px; }
  & > span:nth-child(3) { inset-block-start: 14.5px; }

  /* Boja i dalje odgovara na dodir; nestaje samo pokret. */
  @media (prefers-reduced-motion: reduce) {
    & > span {
      transition: opacity var(--dur-out) var(--ease);
    }
  }
}

.burger[aria-expanded="true"] .burger__bars {
  & > span:nth-child(1) {
    transform: translateY(7.25px) rotate(45deg);
  }

  /* Srednja se skuplja ka sredini umesto da samo nestane, pa se krstić sklapa
     iz tri crte a ne iz dve preko jedne koja je istrunula na mestu. */
  & > span:nth-child(2) {
    opacity: 0;
    transform: scaleX(.2);
  }

  & > span:nth-child(3) {
    transform: translateY(-7.25px) rotate(-45deg);
  }
}

/* ---------- 5. FOOTER --------------------------------------------------- */

.clients {
  margin-block-start: var(--space-10);
  background: var(--gi-strip);
  overflow: hidden;

  & .clients__viewport {
    max-inline-size: var(--wrap);
    margin-inline: auto;
    padding: 30px var(--wrap-pad);
    -webkit-mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent);
    mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent);
  }

  /* Traka nosi 2x isti set logotipa i pomera se tačno za jedan set, pa je
     prelaz između krugova neprimetan.

     Pomak je zadat u pikselima, ne kao -50%. Procenat se računa iz izmerene
     širine trake, pa zavisi od lejauta: promašuje čim se bilo šta u traci
     promeni, a uz to sprečava da se animacija prebaci na kompozitor, jer se
     mora ponovo razrešiti iz lejauta u svakom frejmu. Traka se pomera oko pola
     piksela po frejmu, pa se to crtanje na glavnoj niti vidi kao trzaj.

     Zato i logotip ima zadatu širinu: kutija je uvek --logo-w, bez obzira na to
     šta SVG prijavi kao sopstvenu veličinu, pa pomak ne može da se raziđe sa
     rasporedom. */
  & .clients__track {
    --logo-w: 80px;
    --logo-gap: 56px;
    /* Broj logotipa u jednom setu — markap u inc/clients.php nosi dva ista. */
    --logo-count: 10;
    --marquee-shift: calc((var(--logo-w) + var(--logo-gap)) * var(--logo-count));

    display: flex;
    align-items: center;
    gap: var(--logo-gap);
    inline-size: max-content;
    animation: marquee 70s linear infinite;

    /* Traka stoji na početku prvog seta. */
    @media (prefers-reduced-motion: reduce) {
      animation: none;
    }

    & img {
      inline-size: var(--logo-w);
      block-size: 42px;
      flex: none;
      filter: brightness(0) invert(1);
      opacity: .9;
      transition: transform var(--dur-in) var(--ease),
                  opacity var(--dur-in) var(--ease);

      /* Logo pod mišem malo naraste i dođe do pune vidljivosti. */
      &:hover {
        transform: scale(1.12);
        opacity: 1;
      }

      @media (prefers-reduced-motion: reduce) {
        &:hover {
          transform: none;
        }
      }

      [data-theme="light"] & {
        filter: brightness(0);
        opacity: .8;
      }
    }
  }
}

.site-footer {
  background: var(--gi-footer);

  & .footer-grid {
    max-inline-size: var(--wrap);
    margin-inline: auto;
    padding: 100px var(--wrap-pad) 50px;
    display: grid;
    /* Brend, kontakt, pečat, katalozi, napomene. Širine su izmerene po najdužem
       sadržaju: adresi treba 197px u jednom redu, napomenama 173px, pečatu 206px.
       Odnos 2-3-4-2-3 daje 147/221/295/147/221 i pečat ostaje u sredini, jer je
       sa svake njegove strane po pet jedinica. */
    grid-template-columns:
      minmax(0, 2fr) minmax(0, 3fr) minmax(0, 4fr) minmax(0, 2fr) minmax(0, 3fr);
    gap: 36px;
    align-items: start;
  }

  /* Linija ispod naslova kolone u futeru je kraća od one u zaglavljima strana. */
  /* Naslov kolone u futeru nije naslov dokumenta nego etiketa grupe linkova:
     kao h2 je pravio četiri lažne sekcije u outline-u, a na kontaktu su bile
     i jedine h2 na strani. Grupa svoje pristupačno ime i dalje dobija preko
     aria-labelledby, koji sme da pokazuje na bilo koji element. Ove četiri
     deklaracije su ono što je <h2> dobijao od pismo/težina/boja pravila. */
  .footer-title {
    margin: 0 0 10px;
    font-family: 'Montserrat', sans-serif;
    font-size: var(--fs-footer);
    font-weight: 500;
    color: var(--gi-text);
  }

  /* Futerska linija je kraća od naslovnih; razmak deli sa svima ostalima. */
  & hr {
    inline-size: 35px;
  }

  & .footer-list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 14px;
    /* Spiskovi u futeru stoje na fiksnoj meri, ne na fluidnoj skali pasusa. */
    font-size: var(--fs-footer);
    color: var(--gi-muted);
    font-weight: 300;

    /* Napomene stoje kao i ostali spiskovi u futeru; dugme za podešavanje
       privatnosti nasleđuje pismo, pa se ne razlikuje od veza oko sebe. */
    &.footer-list--notices {
      align-items: start;
    }

    &.footer-list--catalogues {
      font-weight: 200;
    }

    & a:hover {
      color: var(--gi-text);
      text-decoration: underline;
      text-decoration-color: var(--color-accent);
      text-underline-offset: 3px;
    }
  }

  & .footer-seal {
    display: flex;
    justify-content: center;
  }


  /* Pečat kreće naopako i uspravi se tačno kad se strana doskroluje do dna.

     Kraj opsega je 100% skrola — dno strane — pa je završno stanje isto na
     svakoj strani. Početak je zadat u pikselima pre tog kraja, ne u procentu, i
     tu je razlika: sa opsegom u procentima (npr. 72% 100%) dužina strane
     određuje brzinu, pa je isti okret trošio 3029px skrola na naslovnoj a 336px
     na 404 — deset puta brže na kratkoj strani. Fiksnih 820px pre dna daje isti
     put svuda: pola okreta na 820px je 0.22° po pikselu, na svakoj strani.

     Na stranama kraćim od 820px skrola početak opsega pada pre nule, pa je
     pečat na vrhu strane zatečen već delimično okrenut i odatle nastavlja istom
     brzinom do dna. Kratka strana tako pokazuje manji deo okreta — ne isti
     okret brže.

     Krivulja je linearna. Kod animacije vezane za skrol kriva ne raspoređuje
     vreme nego put: raniji ease-out je trošio 87% okreta na prvoj polovini
     opsega, pa je pečat odskočio pa dopuzao. */
  & .seal {
    inline-size: 206px;
    block-size: 206px;
    opacity: .7;
    transition: opacity var(--dur-in) var(--ease);
    animation: pecatSettle linear both;
    animation-timeline: scroll(root);
    animation-range: calc(100% - 820px) 100%;

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

    /* Na prelazak mišem pečat dođe do pune vidljivosti — jedini efekat koji ima,
       pa je namerno sitan. Rotaciju nosi pecatSettle i ne dira se. */
    &:hover {
      opacity: 1;
    }

    [data-theme="light"] & {
      content: url("../assets/brand/granirinvest-pecat-light.svg");
      opacity: .8;
      
      &:hover {
        opacity: 1;
      }
    }
  }

  & .social {
    max-inline-size: var(--wrap);
    margin-inline: auto;
    padding: 4px var(--wrap-pad) 60px;
    display: flex;
    gap: 15px;
    flex-wrap: wrap;
    justify-content: center;
    align-items: center;
  }

  & .social__link {
    display: flex;
    align-items: center;
    gap: 10px;
    color: var(--gi-sub);
    font-size: var(--fs-legal);
    font-weight: 300;
    line-height: 1;

    /* Isto stanje kao kutija ikone i dugme: blaga podloga, ivica ostaje. */
    &:hover .social__icon {
      background: color-mix(in srgb, var(--color-accent) 8%, transparent);
      opacity: 1;
      transition-duration: var(--dur-in);
    }

    &:hover > span:last-child {
      color: var(--gi-text);
      text-decoration: underline;
      text-decoration-color: var(--color-accent);
      text-underline-offset: 3px;
    }
  }

  & .social__icon {
    inline-size: 32px;
    block-size: 32px;
    flex: none;
    display: flex;
    align-items: center;
    justify-content: center;
    border: 1px solid var(--color-accent);
    clip-path: polygon(8px 0, 100% 0, 100% calc(100% - 8px), calc(100% - 8px) 100%, 0 100%, 0 8px);
    background: none;
    opacity: .7;
    transition: background var(--dur-out) var(--ease),
                opacity var(--dur-out) var(--ease);

    & svg,
    & .ph-light {
      color: var(--gi-white);
    }

    & .ph-light {
      font-size: 16px;
    }
  }

  /* Linija prati sirinu sajta, ne ceo ekran: nosi je sam wrap. */
  & .footer-bottom {
    max-inline-size: var(--wrap);
    margin-inline: auto;
    /* Bočno ostaje --wrap-pad, isti kao na .footer-grid: bez njega bi potpis
       ispao 32px levlje od kolona iznad. */
    padding: 30px var(--wrap-pad) 50px;
    border-block-start: 1px solid var(--gi-line1);
    display: grid;
    /* Pravne napomene su se preselile u sam grid, pa donji red nosi samo
       potpis levo i autora desno. */
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    align-items: center;
    gap: 16px;
    font-size: var(--fs-legal);
    color: var(--gi-faint);

    & a {
      color: var(--gi-faint);

      &:hover {
        color: var(--gi-text);
        text-decoration: underline;
        text-decoration-color: var(--color-accent);
        text-underline-offset: 3px;
      }
    }

    & > span:last-child {
      text-align: end;
    }
  }

  /* Dugme stoji u spisku pravnih napomena, pa mora da izgleda kao veze oko
     sebe: boju i pismo nasleđuje, a ne uzima prigušeni ton iz donjeg reda
     futera, gde je stajalo ranije. */
  & .footer-legal__button {
    border: 0;
    padding: 0;
    background: none;
    color: inherit;
    font: inherit;
    text-align: start;
    cursor: pointer;

    &:hover,
    &:focus-visible {
      color: var(--gi-text);
      text-decoration: underline;
      text-decoration-color: var(--color-accent);
      text-underline-offset: 3px;
    }
  }

  @media (max-width: 760px) {
    /* Jedna kolona: naslovi, linije i spiskovi idu po sredini, jer u koloni
       široj od svog sadržaja poravnanje ulevo ostavlja praznu desnu polovinu. */
    & .footer-grid {
      grid-template-columns: 1fr;
      padding-block: 80px 40px;
      text-align: center;

      & hr {
        margin-inline: auto;
      }

      /* Spisak pravnih napomena je jedini sa align-items: start, da se dugme
         za podešavanje privatnosti ne razvuče na celu kolonu i ne dobije
         ogromnu površinu za klik. U jednoj koloni to znači da je jedini
         poravnat ulevo dok su ostala četiri po sredini. */
      & .footer-list--notices {
        align-items: center;
      }
    }

    /* Četiri mreže u dva reda po dva. Kolone se hvataju za sadržaj a par se
       centrira, pa je unutar svake kolone tekst poravnat ulevo i imena stoje
       jedno ispod drugog. */
    & .social {
      display: grid;
      grid-template-columns: repeat(2, auto);
      justify-content: center;
      justify-items: start;
      gap: 18px 28px;
    }

    & .footer-bottom {
      grid-template-columns: 1fr;
      text-align: center;
      /* Traka sa brzim akcijama stoji fiksirano preko dna i prekrivala je
         potpis kad se strana doskroluje do kraja. Njena visina plus vazduh. */
      padding-block-end: 120px;

      & > span:last-child {
        text-align: center;
      }
    }

  }
}

/* Heder je fiksiran preko vrha, pa cilj sidra mora da mu izmakne — inače
   naslov forme završi ispod hedera. Visina hedera je 78px. */
:target {
  scroll-margin-block-start: 94px;
}

/* ---------- mobilne brze akcije ---------- */

/* Tri dugmeta sa punim labelama staju tek preko ~419px, pa poziv i WhatsApp
   idu kao ikonice a jedini pun CTA ostaje upit. Tako bar stane u jedan red do
   280px i tek ispod toga prelama, bez posebnog breakpointa. */
.mobile-quick-actions {
  display: none;
  position: fixed;
  z-index: 75;
  inset-inline: 0;
  inset-block-end: 0;
  /* Četiri kolone umesto flex reda: ikonice drže svoje mesto bez obzira na
     dužinu labele upita, a upit uvek završava uz desnu ivicu. Treća kolona je
     prazna i služi kao razmak između ikonica i dugmeta. Procenti su od
     unutrašnjosti trake, pa padding sa strane ostaje netaknut. */
  grid-template-columns: minmax(44px, 15%) minmax(44px, 15%) 10% minmax(0, 1fr);
  align-items: center;
  /* Traka seda uz same ivice, pa razmak od ruba nose paddingom, ne položajem.
     Dole se dodaje sigurna zona telefona, sa strane ostaje isti --wrap-pad kao
     na sadržaju iznad, pa su dugmad poravnata sa strankom. */
  padding: 10px var(--wrap-pad);
  padding-block-end: max(10px, env(safe-area-inset-bottom));
  background: color-mix(in srgb, var(--gi-panel) 75%, transparent);
  box-shadow: 0 12px 30px rgba(0, 0, 0, .28);
  backdrop-filter: blur(10px) saturate(1.15);
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  /* Ulazi odozdo naviše, izlazi nadole — istim trajanjima i krivom kao ostatak
     sajta, ulaz duži od izlaza. */
  transform: translate3d(0, 18px, 0);
  transition: opacity var(--dur-out) var(--ease-slide),
              transform var(--dur-out) var(--ease-slide),
              visibility 0s linear var(--dur-out);

  @media (prefers-reduced-motion: reduce) {
    transform: none;
    transition: opacity var(--dur-out) var(--ease),
                visibility 0s linear var(--dur-out);
  }

  @media (max-width: 760px) {
    display: grid;
  }

  &.is-visible {
    opacity: 1;
    visibility: visible;
    pointer-events: auto;
    transform: translate3d(0, 0, 0);
    transition-duration: var(--dur-in);
    transition-delay: 0s;
  }

  /* Samo u traci: upit ide velikim slovima i u srednjoj težini, da se po
     težini izjednači sa dve ikonice pored sebe. Isto dugme na stranama
     ostaje u svojoj kanonskoj meri. */
  & .button-alt {
    /* Preskače praznu kolonu razmaka i popunjava svojih 60%, pa desna ivica
       dugmeta prati desnu ivicu trake. */
    grid-column: 4;
    inline-size: 100%;
    justify-content: center;
    /* 12.25px na 360px širine, 14px od 1280px naviše — ista rampa i isti odnos
       kao --fs-base. Stoji ovde, a ne kao token, jer je mera ovog jednog
       dugmeta. */
    font-size: clamp(0.7656rem, calc(0.7228rem + 0.190vw), 0.875rem);
    text-transform: uppercase;
    font-weight: 500;
  }

  /* Ikonice ostaju centrirane u svojim ćelijama, a razmak između njih se
     udvostručuje kroz po 6px margine ka sredini: margina ulazi u centriranje,
     pa svaka ikonica odmakne 3px na svoju stranu. Hvatanje za ivice ćelija
     ovde ne radi — na 320px bi se ikonice preklopile, a na 760px razmakle na
     preko 120px. */
  & .is-call {
    justify-self: center;
    margin-inline-end: 6px;
  }

  & .is-whatsapp {
    justify-self: center;
    margin-inline-start: 6px;
  }
}

/* Panel privatnosti i otvoreni meni sede preko bara, pa se tada sklanja. */
body:has(.privacy-panel:not([hidden])) .mobile-quick-actions,
body:has(.site-nav[data-open="true"]) .mobile-quick-actions {
  display: none;
}

.mobile-quick-action {
  flex: 1 1 0;
  min-inline-size: 0;
  min-block-size: 44px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: .6875rem .75rem;
  border-radius: 100px;
  font-size: var(--fs-xxs);
  line-height: 1.1;
  letter-spacing: .06em;
  text-transform: uppercase;
  font-weight: 500;
  text-decoration: none;
  white-space: nowrap;

  /* .ph-light je globalno u akcentnoj boji, a ovde bi koverta bila narandžasta
     na narandžastom. Glif prati boju svog dugmeta. */
  & i {
    flex: none;
    font-size: 1rem;
    color: inherit;
  }

  &:focus-visible {
    outline: 2px solid var(--color-accent);
    outline-offset: 2px;
  }
}

.mobile-quick-action--icon {
  flex: 0 0 44px;
  inline-size: 44px;
  padding: 0;
  gap: 0;

  & i {
    font-size: 1.25rem;
  }

  & svg {
    flex: none;
    inline-size: 20px;
    block-size: 20px;
  }
}

/* Poziv je outline, WhatsApp nosi zelenu, upit nosi akcenat. Površina drži
   hijerarhiju, boja drži prepoznavanje. */
.mobile-quick-action.is-call {
  border: 1px solid var(--gi-white-fixed);
  background: var(--gi-white-fixed);
  color: var(--gi-ink-on-accent);
}

[data-theme="light"] .mobile-quick-action.is-call {
  border-color: var(--gi-line2);
  background: var(--gi-panel);
  color: var(--gi-text);
}

.mobile-quick-action.is-whatsapp {
  border: 1px solid var(--gi-whatsapp);
  background: var(--gi-whatsapp);
  color: var(--gi-white-fixed);
}

/* Upit u traci više ne nosi nijednu klasu trake — samo .button-alt, u istoj
   meri kao bilo gde drugde na sajtu. Dok je bio i .mobile-quick-action, uzimao
   je flex: 1 1 0 i razvlačio se preko pola trake, pa zasečeni ugao nije mogao
   da se pročita. Poziv i WhatsApp ostaju okrugle ikonice. */

.privacy-panel {
  position: fixed;
  z-index: 80;
  inset-inline: max(20px, calc((100vw - var(--wrap)) / 2 + var(--wrap-pad)));
  inset-block-end: 20px;
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 20px 36px;
  align-items: end;
  padding: 28px 30px;
  border: 1px solid var(--gi-line2);
  border-radius: var(--radius-m);
  background: color-mix(in srgb, var(--gi-panel) 92%, transparent);
  box-shadow: 0 18px 60px rgba(0, 0, 0, .24);
  backdrop-filter: blur(14px) saturate(1.15);
  opacity: 0;
  transform: translateY(8px);
  transition: opacity .2s ease, transform .2s ease;

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

  &[hidden] {
    display: none;
  }

  &.is-open {
    opacity: 1;
    transform: none;
  }

  & .privacy-panel__copy {
    max-inline-size: 850px;

    & h2 {
      margin: 0 0 8px;
      font-size: var(--fs-md);
    }

    & p {
      margin: 0;
      font-size: var(--fs-sm);
    }
  }

  & .privacy-panel__actions {
    display: flex;
    gap: 20px;
    flex-wrap: wrap;
    justify-content: flex-end;

    /* Dugmići su ovde za petinu manji od kanonske mere iz .button-alt. Panel je
       traka pri dnu ekrana i puna veličina je u njoj pretežak potez. Skalira se
       cela geometrija, ne samo slog — padding, razmak ikone i zasek — da oblik
       ostane isti, samo manji. */
    & :is(.button, .button-alt) {
      --notch: 12.8px;
      font-size: calc(var(--fs-xs) * .8);
      padding: 9.6px 16px;
      gap: 8px;
    }
  }

  @media (max-width: 760px) {
    inset-inline: 12px;
    inset-block-end: 12px;
    grid-template-columns: 1fr;
    gap: 18px;
    padding: 24px 22px 22px;

    & .privacy-panel__actions {
      justify-content: flex-start;

      & :is(.button, .button-alt) {
        justify-content: center;
        inline-size: 100%;
      }
    }
  }
}

/* Samo tipografija i širina pravnog teksta. Kontejner, položaj i razmak odozgo
   nosi .page-head, koju stranica takođe nosi u markapu. */
.legal-page {
  & :is(.legal-page__header, .legal-page__sections) {
    max-inline-size: 920px;
  }

  & :is(.legal-page__eyebrow, .legal-page__updated) {
    font-family: inherit;
    font-size: var(--fs-xs);
    font-weight: 600;
    letter-spacing: .08em;
    color: var(--color-accent-ink);
  }

  & .legal-page__updated {
    margin-block-end: 18px;
    letter-spacing: .02em;
    color: var(--gi-faint);
  }

  & .legal-page__sections {
    display: grid;
    gap: 34px;
    padding-block: 54px 20px;
  }

  & .legal-page__section {
    & h2 {
      margin: 0 0 10px;
      font-size: var(--fs-xl);
    }

    & :is(p, li) {
      font-family: 'Karla', sans-serif;
      font-size: var(--fs-base);
      line-height: 1.55;
      color: var(--gi-muted);
      font-weight: 300;
    }

    & ul {
      margin: 0;
      padding-inline-start: 22px;
    }
  }
}

/* ---------- 6. KOMPONENTE ---------------------------------------------- */

/* hero (naslovna) */
.hero {
  position: relative;
  z-index: 1;
  block-size: 100vh;
  block-size: 100svh;
  overflow: hidden;
  background: var(--gi-heroBg);

  & .hero__slides {
    position: absolute;
    inset: 0;
    overflow: hidden;
    /* Kadar se zumira dok hero odlazi sa ekrana. Napredak je vezan za skrol,
       ne za vreme: opseg 0–100svh je isto što i ScrollTrigger
       start: "top top" / end: "bottom top", samo bez JS-a. Mekoća ivica ne
       ide odavde nego sa .hero__scrim::before, da sredina ostane oštra. */
    animation: heroScrollZoom linear both;
    animation-timeline: scroll(root block);
    animation-range: 0 100svh;

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

  & .hero__slide {
    position: absolute;
    inset: 0;
    inline-size: 100%;
    block-size: 100%;
    object-fit: cover;
    opacity: 0;
    animation: heroFadeFour 24s infinite;

    /* Fotografije su u boji; tamna tema ih ispira u crno-belo, svetla ih vraća.
       Prelaz je duži od kartičnog (.4s) jer se ovde menja ceo ekran, pa nagla
       promena deluje kao da je slika zamenjena a ne obojena. */
    filter: grayscale(1);
    transition: filter .8s var(--ease);

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

    /* Slajdovi kreću iz opacity: 0, pa bez animacije prvi kadar mora sam
       da se upali; ostali ostaju skriveni. */
    @media (prefers-reduced-motion: reduce) {
      animation: none;

      &:first-child {
        opacity: 1;
      }
    }

    /* Isto važi i bez JS-a: kadrove 2–4 puni js/main.js iz data-src, pa bi bez
       njega smena vodila u prazan hero. Tada stoji samo prvi kadar. */
    html:not(.js) & {
      animation: none;

      &:first-child {
        opacity: 1;
      }
    }

    &.hero__slide--2 {
      animation-delay: 6s;
    }

    &.hero__slide--3 {
      animation-delay: 12s;
    }

    &.hero__slide--4 {
      animation-delay: 18s;
    }
  }

  & .hero__scrim {
    position: absolute;
    inset: 0;
    /* Dva sloja. Gornji je uzak, gasi se na 100px i postoji samo da navigacija
       ima podlogu dok heder stoji proziran nad fotografijom — na svetloj temi
       bela slova preko vedrog neba inače nemaju za šta da se uhvate. Donji je
       zastor cele slike, isti kao pre. Visina je fiksnih 100px, taman preko
       hedera od 70px na desktopu i 55px na telefonu. */
    background:
      linear-gradient(180deg, rgba(11, 11, 11, .5) 0, rgba(11, 11, 11, 0) 100px),
      linear-gradient(180deg, rgba(11, 11, 11, .55) 0%, rgba(11, 11, 11, .15) 45%, rgba(11, 11, 11, .92) 100%);
    pointer-events: none;

    /* Periferna mekoća: mute se samo leva i desna ivica, sredina ostaje
       oštra. Ide preko backdrop-filter, a ne filter na slici, da bi hvatao
       kadar koji je trenutno u smeni bez obzira koji je. Maska ga gradijentom
       drži uz ivice; sloj stoji iznad fotografije a ispod naslova, jer je
       .hero__scrim u markupu između .hero__slides i .hero__body. */
    &::before {
      content: '';
      position: absolute;
      inset: 0;
      /* Polazno stanje je čisto: bez skrola nema mekoće. */
      -webkit-backdrop-filter: blur(0);
      backdrop-filter: blur(0);
      -webkit-mask-image: linear-gradient(to right, #000 0%, transparent 20%, transparent 80%, #000 100%);
      mask-image: linear-gradient(to right, #000 0%, transparent 20%, transparent 80%, #000 100%);
      animation: heroEdgeBlur linear both;
      animation-timeline: scroll(root block);
      animation-range: 0 100svh;

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

  & .hero__body {
    position: absolute;
    inset-inline: 0;
    inset-block-end: 130px;
    pointer-events: none;
    /* Naslov na skrol odlazi uvis i gasi se u mekoći, suprotno od fotografije
       koja putuje nadole — otud osećaj dubine. Opseg je kraći od herovog, da
       naslov ispari pre nego što sekcija ispod stigne pod njega. Animacija ide
       na .hero__body, a ne na .hero__title span, da se ne sudari sa rise koji
       ti isti elementi troše na ulazu. */
    animation: heroTitleOut linear both;
    animation-timeline: scroll(root block);
    animation-range: 0 70svh;

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

  & .hero__title {
    margin: 0;
    font-size: var(--fs-hero);
    line-height: 1.08;
    font-weight: 400;
    color: var(--gi-white-fixed);
    text-shadow: 0 2px 30px rgba(0, 0, 0, .5);

    & span {
      display: block;
      animation: rise .8s ease both;

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

    & span:nth-child(2) {
      animation-delay: .12s;
    }

    & span:nth-child(3) {
      color: var(--color-accent);
      animation-delay: .24s;
    }
  }

  /* Strelica stoji nad tamnom hero fotografijom u obe teme, pa boju uzima od
     --gi-white-fixed; --gi-white u lite temi postaje crno i strelica nestane. */
  & .hero__scroll {
    position: absolute;
    left: 50%;
    inset-block-end: 40px;
    transform: translateX(-50%);
    pointer-events: none;
    color: var(--gi-white-fixed);
    transition: opacity .60s ease;

    /* Skrol iz hera gasi strelicu; atribut postavlja js/main.js. */
    &[data-hidden] {
      opacity: 0;
    }

    & .ph-light {
      display: block;
      /* Upola manja nego ranije: poziv na skrol ne treba da se takmiči sa
         naslovom hera. Pa vraćena za petinu, da se ipak primeti. */
      font-size: 20.4px;
      /* .ph-light bazno nosi akcentnu boju, ovde strelica mora ostati bela. */
      color: var(--gi-white-fixed);
      animation: floatCue 3s cubic-bezier(.45, 0, .55, 1) infinite;
      will-change: transform, opacity;

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

    /* Na niskom viewportu strelica bi sela na sadržaj, osim na telefonu gde
       hero i dalje drži punu visinu. */
    @media (max-height: 780px) {
      display: none;
    }

    @media (max-width: 760px),
    (max-width: 900px) and (max-height: 500px) and (orientation: landscape) {
      display: block;
      bottom: max(8px, env(safe-area-inset-bottom));
    }
  }

  @media (max-width: 760px) {
    & .hero__title {
      font-size: clamp(2.25rem, 11vw, 3.25rem);
    }
  }
}

/* Proba ulaza na pet kartica naslovne. Atribut postavlja js/main.js kad mreža
   prvi put uđe u kadar, pa se ulaz odigra jednom i ne ponavlja se pri promeni
   smera skrola. Trajanje 1s je podrazumevano iz animate.css. Zamena na
   fadeInDown je promena jedne reči. */
[data-reveal] > .media-card {
  opacity: 0;
}

[data-reveal="in"] > .media-card {
  animation: fadeInUp 1s both;

  &:nth-child(2) {
    animation-delay: .15s;
  }

  &:nth-child(3) {
    animation-delay: .3s;
  }
}

/* medija kartica */
.card-grid {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: var(--space-7);

  &.card-grid--3 {
    grid-template-columns: repeat(3, 1fr);
  }

  &.card-grid--wide-left {
    grid-template-columns: 1.4fr 1fr;
    margin-block-start: var(--space-6);
  }

  &.card-grid--labelled {
    grid-template-columns: 0.85fr 1fr 1fr;
    align-items: stretch;
  }

  &.card-grid--3-wide {
    grid-template-columns: 1fr 1fr 1.3fr;
    gap: 40px;
  }

  @media (min-width: 761px) and (max-width: 1100px) {
    &.card-grid--wide-left {
      grid-template-columns: repeat(2, 1fr);
    }

    &.card-grid--labelled {
      grid-template-columns: 1fr;
      row-gap: 34px;

      & > .media-card--feature {
        grid-column: auto;
      }
    }

    &.card-grid--3-wide {
      grid-template-columns: 1fr;
    }
  }

  @media (min-width: 761px) and (max-width: 899px) {
    &.card-grid--3 {
      grid-template-columns: repeat(2, 1fr);
    }
  }

  @media (max-width: 760px) {
    gap: 28px;

    &.card-grid--3,
    &.card-grid--wide-left,
    &.card-grid--labelled,
    &.card-grid--3-wide {
      grid-template-columns: 1fr;
    }

    &.card-grid--3-wide {
      gap: 28px;
    }

    /* Kada se sve složi u jednu kolonu, granica između dve mreže je samo još
       jedan razmak između kartica. Onih 50px sa širokog ekrana pravilo je rupu
       veću od ostalih — između PRODAJE i REFERENCI 50px, svuda drugde 28. */
    &.card-grid--wide-left {
      margin-block-start: 28px;
    }
  }
}

/* Jedan okvir za sve slike na sajtu: foto-traka, reference, paneli, stranice
   objekata i galerije. Kartica (.media-card) nosi isti radijus, pa se slika i
   kartica svuda ponašaju isto — razlikuje ih samo visina. */
.media-frame {
  position: relative;
  display: block;
  overflow: hidden;
  border-radius: var(--radius-media);
  margin: 0;

  & > img {
    display: block;
    inline-size: 100%;
    /* Bez zadate visine okvira procenat se računa kao auto, pa isti okvir
       radi i za kadrirane (fiksna visina) i za slobodne slike. */
    block-size: 100%;
    object-fit: cover;
    filter: grayscale(1);
    transition: filter .6s ease, transform .6s ease;

    @media (prefers-reduced-motion: reduce) {
      transition: filter .6s ease;
    }
  }

  &:hover > img {
    filter: grayscale(0);
    transform: scale(1.04);
  }

  [data-theme="light"] & > img {
    filter: grayscale(0);
  }

  [data-theme="light"] &:hover > img {
    filter: grayscale(1);
  }
}

/* Tehnički crteži — 3D prikazi i osnove sprata — dele okvir i lightbox sa
   fotografijama, ali ne i njihovu obradu: bez crno-belog filtera i bez
   uvećanja na hover. Mora stajati posle .media-frame jer se oslanja na
   redosled pri istoj specifičnosti. */
.media-frame--plain {
  & > img,
  &:hover > img {
    filter: none;
    transform: none;
  }

  [data-theme="light"] & > img,
  [data-theme="light"] &:hover > img {
    filter: none;
  }
}

.media-card {
  position: relative;
  block-size: 400px;
  border-radius: var(--radius-media);
  overflow: hidden;
  border: 0 solid transparent;
  transition: transform .3s ease, border-color .3s ease;

  @media (prefers-reduced-motion: reduce) {
    transition: border-color .3s ease;
  }

  &:hover {
    border-color: color-mix(in srgb, var(--color-accent) 60%, transparent);
  }

  & > img {
    position: absolute;
    inset: 0;
    inline-size: 100%;
    block-size: 100%;
    object-fit: cover;
    filter: grayscale(1);
    transform: scale(1.08);
    transition: filter 500ms cubic-bezier(.22, .61, .36, 1) 1000ms, transform 1.5s cubic-bezier(.22, .61, .36, 1);

    @media (prefers-reduced-motion: reduce) {
      transition: filter 500ms cubic-bezier(.22, .61, .36, 1) 1000ms;
    }
  }

  &:hover > img {
    filter: grayscale(0);
    transform: scale(1);
    transition: filter 1.5s cubic-bezier(.22, .61, .36, 1), transform 1.5s cubic-bezier(.22, .61, .36, 1);

    @media (prefers-reduced-motion: reduce) {
      transition: filter 1.5s cubic-bezier(.22, .61, .36, 1);
    }
  }

  [data-theme="light"] & > img {
    filter: grayscale(0);
  }

  [data-theme="light"] &:hover > img {
    filter: grayscale(1);
    transform: scale(1);
  }

  &.media-card--color > img,
  &.media-card--color:hover > img,
  [data-theme="light"] &.media-card--color > img,
  [data-theme="light"] &.media-card--color:hover > img {
    filter: none;
  }

  /* Slika unutar linka na kartici ponude prati isto ponašanje. */
  & .feature-link > img {
    filter: grayscale(1);
    transform: scale(1.08);
    transition: filter 500ms cubic-bezier(.22, .61, .36, 1) 1000ms, transform 1.5s cubic-bezier(.22, .61, .36, 1);

    @media (prefers-reduced-motion: reduce) {
      transition: filter 500ms cubic-bezier(.22, .61, .36, 1) 1000ms;
    }
  }

  &:hover .feature-link > img {
    filter: grayscale(0);
    transform: scale(1);
    transition: filter 1.5s cubic-bezier(.22, .61, .36, 1), transform 1.5s cubic-bezier(.22, .61, .36, 1);

    @media (prefers-reduced-motion: reduce) {
      transition: filter 1.5s cubic-bezier(.22, .61, .36, 1);
    }
  }

  [data-theme="light"] & .feature-link > img {
    filter: grayscale(0);
  }

  [data-theme="light"] &:hover .feature-link > img {
    filter: grayscale(1);
    transform: scale(1);
  }

  /* Aktuelna ponuda se ističe: slika je uvek u boji, ostaje samo zum,
     a tri kadra se smenjuju istim ritmom kao hero slajder. */
  &.media-card--aktuelno img,
  &.media-card--aktuelno:hover img,
  [data-theme="light"] &.media-card--aktuelno img,
  [data-theme="light"] &.media-card--aktuelno:hover img {
    filter: none;
  }

  &.media-card--aktuelno img {
    opacity: 0;
    animation: heroFade 18s infinite;

    /* Kao hero: prvi kadar stoji, smena se ne vrti. */
    @media (prefers-reduced-motion: reduce) {
      animation: none;

      &:first-of-type {
        opacity: 1;
      }
    }

    &:nth-of-type(2) {
      animation-delay: 6s;
    }

    &:nth-of-type(3) {
      animation-delay: 12s;
    }
  }

  & .media-card__scrim {
    position: absolute;
    inset: 0;
    background: linear-gradient(180deg, rgba(11, 11, 11, 0) 45%, rgba(11, 11, 11, .9) 100%);
    pointer-events: none;
  }

  & .media-card__link {
    position: absolute;
    inset: 0;
    padding: 18px 22px 35px 35px;
    display: flex;
    flex-direction: column;
    justify-content: flex-end;
  }

  &.media-card--feature {
    grid-column: 2 / span 2;
  }

  & .media-card__caption {
    position: absolute;
    inset-inline: 0;
    inset-block-end: 0;
    padding: 18px 22px 35px 35px;
  }

  &.media-card--320 {
    block-size: 320px;
  }

  /* Sav sadrzaj istaknute JAVOR kartice zivi u jednom linku. */
  &.media-card--feature .feature-link {
    &::before {
      content: "";
      position: absolute;
      inset: 0;
      z-index: -1;
      background: linear-gradient(180deg, rgba(11, 11, 11, 0) 45%, rgba(11, 11, 11, .9) 100%);
      pointer-events: none;

      /* Na telefonu ceo tekst sedi nisko — naslov počinje na 61% visine
         kartice — a jedan prelaz sa početkom na 45% mu daje samo 0.26
         zasićenja. Ovde je zastor pun od dna do polovine, a iznad polovine se
         gubi, pa gornja trećina fotografije ostaje čista. */
      @media (max-width: 760px) {
        background: linear-gradient(180deg,
            rgba(11, 11, 11, 0) 22%,
            rgba(11, 11, 11, .45) 50%,
            rgba(11, 11, 11, .72) 72%,
            rgba(11, 11, 11, .95) 100%);
      }
    }

    & > img {
      position: absolute;
      inset: 0;
      z-index: -2;
      inline-size: 100%;
      block-size: 100%;
      object-fit: cover;
    }

    & h2,
    & p {
      margin: 0;
      font-family: 'Montserrat', sans-serif;
    }

    & > dl {
      min-inline-size: 0;
    }
  }

  @media (max-width: 760px) {
    block-size: 260px;

    &.media-card--320 {
      block-size: 260px;
    }

    &.media-card--feature {
      grid-column: auto;
      block-size: 440px;
    }
  }
}

/* Poslovni prostor: Green Square je fiksan, treći slot smenjuje dve kartice. */
.business-card-slider {
  display: grid;
  isolation: isolate;

  & > .media-card {
    grid-area: 1 / 1;
    visibility: hidden;
    opacity: 0;
    transform: translate3d(7%, 0, 0);
    animation: businessCardSlide 10s cubic-bezier(.77, 0, .175, 1) infinite;
    will-change: transform, opacity;

    /* Smena staje: prva kartica stoji, druga ostaje sakrivena. */
    @media (prefers-reduced-motion: reduce) {
      animation: none;
      transform: none;

      &:first-of-type {
        visibility: visible;
        opacity: 1;
      }
    }

    &:nth-of-type(2) {
      animation-delay: -5s;
    }
  }
}

@keyframes businessCardSlide {
  0%, 45% {
    visibility: visible;
    opacity: 1;
    transform: translate3d(0, 0, 0);
  }

  50% {
    visibility: visible;
    opacity: 0;
    transform: translate3d(-7%, 0, 0);
  }

  50.01%, 94.99% {
    visibility: hidden;
    opacity: 0;
    transform: translate3d(-7%, 0, 0);
  }

  95% {
    visibility: hidden;
    opacity: 0;
    transform: translate3d(7%, 0, 0);
  }

  95.01% {
    visibility: visible;
    opacity: 0;
    transform: translate3d(7%, 0, 0);
  }

  100% {
    visibility: visible;
    opacity: 1;
    transform: translate3d(0, 0, 0);
  }
}

/* Naslov i podnaslov kartice stoje i na <span>, pa im block treba.
   .card-meta je uvek <p> i ne ulazi ovde. */
.card-title,
.card-sub {
  display: block;
  /* Naslovi kartica su h2/h3 elementi: gasi podrazumevane heading margine
     da zamena taga (span -> h3) ne pomeri raspored. */
  margin: 0;
}

.card-title {
  font-size: var(--fs-2xl);
  color: var(--gi-white-fixed);
}


.card-sub {
  font-size: var(--fs-md);
  font-weight: 400;
  color: var(--color-accent);
}

.card-meta {
  margin-block-start: 4px;
  font-size: var(--fs-meta);
  font-weight: 400;
  color: #E4E4E4;
  text-shadow: 0 1px 8px rgba(0, 0, 0, .85);
}

/* kolona sa naslovom sekcije uz kartice */
.card-label {
  position: relative;
  min-block-size: 400px;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;

  & .card-label__mark {
    inline-size: 180px;
    position: absolute;
    inset-block-start: 0;
    inset-inline-start: 0;
    block-size: auto;

  }

  & .card-label__link {
    position: relative;
    display: block;
    color: var(--color-accent-ink);

    /* Boju nasleđuje od .card-label__link, koje je već postavlja. */
    & span {
      display: block;
      font-size: var(--fs-lg);
      font-weight: 400;
      line-height: 1.2;
      letter-spacing: .03em;
    }
  }

  @media (max-width: 1100px) {
    min-block-size: 0;

    & .card-label__mark {
      display: none;
    }
  }
}

.feature-link {
  position: absolute;
  inset: 0;
  padding: 18px 35px 35px;
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 30px;

  @media (max-width: 760px) {
    flex-direction: column;
    align-items: flex-start;
    justify-content: flex-end;
    gap: 18px;
  }
}

.badge {
  --badge-accent: #A94E00;
  position: absolute;
  inset-block-start: 22px;
  inset-inline-end: 24px;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 8px 16px;
  min-block-size: 25px;
  background: rgb(228 105 0 / 90%);
  -webkit-backdrop-filter: blur(2px);
  backdrop-filter: blur(2px);
  clip-path: polygon(var(--notch) 0, 100% 0, 100% calc(100% - var(--notch)), calc(100% - var(--notch)) 100%, 0 100%, 0 var(--notch));
  font-size: var(--fs-xxs);
  font-weight: 400;
  letter-spacing: .01em;
  color: var(--gi-white-fixed);
  line-height: 1;

  &:hover {
    color: var(--gi-white-fixed);
  }

  /* Klik prima samo badge koji jeste link; span ne hvata pokazivač. */
  &:not(a) {
    pointer-events: none;
  }

  /* Tačkica i puls idu na akcentni badge, a ne na najavu. Vezani su za vrstu
     badge-a, ne za to da li je element link — isti badge stoji i kao <a> na
     kartici i kao <span> unutar linka na fotografiji. */
  &:not(.badge-soon)::before {
    content: "";
    inline-size: 8px;
    block-size: 8px;
    border-radius: 50%;
    background: var(--gi-white-fixed);
  }

  &:not(.badge-soon)::after {
    content: "";
    position: absolute;
    inset-inline-start: 16px;
    inset-block-start: calc(50% - 4px);
    inline-size: 8px;
    block-size: 8px;
    border: 1px solid var(--gi-white-fixed);
    border-radius: 50%;
    opacity: 0;
    transform: scale(.92);
    pointer-events: none;
    animation: startPulse .7s cubic-bezier(.23, 1, .32, 1) infinite;

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

  &.badge-soon {
    gap: 0;
    background: rgb(255 255 255 / .96);
    color: var(--badge-accent);

    &:hover {
      color: var(--badge-accent);
    }
  }
}

.badge-stack {
  position: absolute;
  inset-block-start: 22px;
  inset-inline-end: 24px;
  z-index: 1;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 15px;
  pointer-events: none;

  & > .badge {
    position: relative;
    inset: auto;
  }

  & > a.badge {
    pointer-events: auto;
  }
}

.stat-row {
  margin: 0;
  align-self: flex-end;
  display: flex;
  gap: 18px;
  flex-wrap: wrap;
  align-items: flex-end;
  justify-content: flex-end;

  /* Broj i njegova oznaka počinju u istoj vertikali. Centriranje je uži broj
     uvlačilo u odnosu na dužu oznaku iznad — "3.300€" je stajao desetak
     piksela udesno od "CENA STANOVA BEZ PDV PO m² OD". */
  & > div {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
  }

  & dd {
    margin: 0;
    font-size: var(--fs-xl);
    font-weight: 600;
    color: var(--gi-white-fixed);
    line-height: 1;
    white-space: nowrap;
    text-shadow: 0 1px 12px rgba(0, 0, 0, .85);
  }

  & dt {
    font-size: clamp(0.4813rem, calc(0.4494rem + 0.141vw), 0.5625rem);
    font-weight: 600;
    letter-spacing: .12em;
    color: #E6E6E6;
    margin-block-end: 7px;
    line-height: 1.35;
    white-space: nowrap;
    text-align: left;
    align-self: stretch;
    text-shadow: 0 1px 8px rgba(0, 0, 0, .9);
  }

  @media (max-width: 760px) {
    align-self: flex-start;
    justify-content: flex-start;
    gap: 20px;

    /* Na telefonu ostaju samo cena i završetak radova. Broj stanova, lamele i
       nivoi garaže su podaci za koje se ulazi u karticu; ovde su pravili drugi
       red preko fotografije. Redosled u markup-u je stambene jedinice, lamele,
       garaža, cena, završetak — prve tri odlaze. */
    & > div:nth-child(-n+3) {
      display: none;
    }
  }
}


/* ---------- 7. STRANICE ------------------------------------------------- */

/* Zaglavlje unutrašnje stranice — jedini nosilac geometrije prvog bloka u
   <main>. Svaka stranica ga nosi uz .container, a varijanta (.page-head--offer,
   .contact-grid, .project, .legal-page, .notice) dolazi pored i opisuje samo ono
   po čemu se ta stranica stvarno razlikuje: raspored kolona i tipografiju.
   Nijedna varijanta ne sme ponovo da postavi kontejner, položaj ni razmak
   odozgo — inače se vraćamo na šest različitih rastera. */
.page-head {
  position: relative;
  z-index: 0;
  /* Telo je već rezervisalo visinu hedera, pa je ovo razmak koji se stvarno
     vidi ispod navigacije. Na telefonu i tabletu ostaje 30px; 60px je samo za
     desktop, od širine na kojoj navigacija prestaje da bude hamburger. */
  padding-block-start: 30px;
  /* Zaglavlje strane se odvaja od prvog bloka ispod sebe na svakoj širini.
     Sekcija ispod njega nema svoj razmak odozgo, pa je ovo ceo odmak. */
  margin-block-end: 60px;

  @media (min-width: 1030px) {
    padding-block-start: 60px;
  }

  /* Kada su simbol i sadrzaj direktna deca sekcije, sekcija je sama dvokolonski grid. */
  &:has(> .intro-symbol):not(.contact-grid) {
    display: grid;
    grid-template-columns: minmax(0, 200px) minmax(0, 1fr);
    column-gap: var(--space-7);
    align-items: start;

    & > :not(.intro-symbol, .seal-bg) {
      grid-column: 2;
      min-inline-size: 0;
    }

    & > .intro-symbol {
      grid-column: 1;
      grid-row: 1 / span 5;
      margin-block-start: 8px;
    }

  }

  &.page-head--offer {
    display: grid;
    grid-template-columns: 60% minmax(0, 40%);
    align-items: start;

    & > :not(.seal-bg) {
      grid-column: 1;
      min-inline-size: 0;
    }
  }

  @media (max-width: 1100px) {
    &.page-head--offer {
      grid-template-columns: 1fr;

      & > :not(.seal-bg) {
        grid-column: 1;
      }
    }
  }

  @media (max-width: 760px) {
    &:has(> .intro-symbol):not(.contact-grid) {
      grid-template-columns: 1fr;

      & > :not(.intro-symbol, .seal-bg) {
        grid-column: 1;
      }
    }
  }
}

/* lista sa ikonicama */

/* panel objekta (poslovni prostor / stambeni objekti) */
.panel {
  background: var(--gi-panel);
  /* Ivica je do sada bila 0 i providna, pa se `border-color` na hover nikad
     nije video. Sada je prava linija u istom tonu kao ostale na sajtu. */
  border: 1px solid var(--gi-line1);
  border-radius: var(--radius-media);
  box-shadow: var(--gi-panelShadow);
  padding: 44px;
  display: grid;
  grid-template-columns: 1fr 1.05fr;
  gap: 0 44px;
  align-items: start;
  transition: border-color var(--dur-out) var(--ease);

  /* Razmak nosi svaka kartica odozdo, a ne tek druga po redu odozgo. Tako je
     jedno pravilo dovoljno bez obzira koliko ih ima na strani, i poslednja
     odvaja sekciju od onoga što dolazi ispod. */
  margin-block-end: 60px;

  & > :not(.panel__media) {
    grid-column: 1;
  }

  &:hover {
    border-color: color-mix(in srgb, var(--color-accent) 45%, transparent);
  }


  /* Dugme se hvata za dno kartice umesto da pluta odmah ispod spiska. Kartica
     je dvokolonska samo od 1101px naviše — tamo visinu diktira fotografija u
     desnoj koloni, pa je ispod spiska ostajala praznina i dugme je stajalo na
     različitoj visini od kartice do kartice, zavisno od broja pogodnosti.
     Fotografija pokriva osam redova, pa dugme ide u poslednji od njih i
     poravnava se na njegov kraj. */
  @media (min-width: 1101px) {
    & > .button-alt {
      grid-row: 8;
      align-self: end;
      justify-self: start;
    }
  }

  /* Naslov kartice je isti nivo kao naslov stranice. */
  & .panel__title {
    margin: 0 0 10px;
    font-size: var(--fs-h1);
  }

  /* Kartica se ponaša kao jedna celina: prelazak mišem bilo gde po njoj, a ne
     samo po slici, pokreće smenu fotografija i skida sivilo. Kadrovi stoje
     jedan preko drugog i uvek se vrte, ali su zaustavljeni dok kartica miruje —
     negativna kašnjenja drže prvi kadar na vrhu u tom zaustavljenom stanju, a
     kad miš ode animacija se zamrzne na tekućem kadru umesto da odskoči. */
  & .panel__media {
    grid-column: 2;
    grid-row: 1 / span 8;
    block-size: 400px;

    & > img {
      position: absolute;
      inset: 0;
      animation: panelFadeFive 20s linear infinite;
      animation-play-state: paused;

      &:nth-child(2) { animation-delay: -16s; }
      &:nth-child(3) { animation-delay: -12s; }
      &:nth-child(4) { animation-delay: -8s; }
      &:nth-child(5) { animation-delay: -4s; }

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

        &:not(:first-child) {
          opacity: 0;
        }
      }
    }
  }

  &:hover .panel__media > img {
    animation-play-state: running;
    filter: grayscale(0);
    transform: scale(1.04);
  }

  /* U svetloj temi fotografija ostaje u boji i na hover — crno-belo je potez
     tamne teme. Bez ovoga bi je pregazilo pravilo iz .media-frame. */
  [data-theme="light"] &:hover .panel__media > img {
    filter: grayscale(0);
  }

  /* Na dodiru hover ne postoji, pa smenu pokreće atribut koji js/main.js
     postavlja kad kartica uđe u vidno polje. Sivilo i uvećanje ostaju samo na
     pokazivaču — na telefonu nema šta da ih vrati u mirno stanje. */
  @media (hover: none) {
    &[data-slider="in"] .panel__media > img {
      animation-play-state: running;
    }
  }

  & .button-alt {
    justify-self: start;
    margin-block-start: 30px;
  }

  @media (max-width: 760px) {
    grid-template-columns: 1fr;
    padding: 26px 20px;

    /* U jednoj koloni fotografija je padala na dno kartice, iza spiska
       pogodnosti i dugmeta — posetilac je do nje stizao tek pošto pročita sve.
       Redosled u markupu ostaje netaknut zbog čitača ekrana; menja se samo
       vizuelni red: naslov, linija, adresa, pa slika. */
    & > .panel__title {
      order: 1;
    }

    & > hr {
      order: 2;
    }

    /* Razmak do fotografije nosi sama fotografija; adresina donja margina bi se
       nadovezala na nju i razmak bi bio 52px umesto 28. */
    & > .place {
      order: 3;
      margin-block-end: 0;
    }

    & .panel__media {
      order: 4;
      grid-column: 1;
      grid-row: auto;
      margin-block: 28px;
      block-size: 260px;
    }

    & > :not(.panel__title, hr, .place, .panel__media) {
      order: 5;
    }
  }

  @media (min-width: 761px) and (max-width: 1100px) {
    grid-template-columns: 1fr;

    & .panel__media {
      grid-column: 1;
      grid-row: auto;
      margin-block-start: 28px;
    }
  }
}

/* Pasus sa ikonicom. Klasa nosi samo raspored ikone i razmak ispod; pismo,
   veličinu, prored i težinu daje globalno pravilo za <p>. */
.place {
  display: flex;
  gap: 10px;
  align-items: center;
  margin-block-end: 24px;
  inline-size: fit-content;

  & svg,
  & .ph-light {
    flex: none;
  }

  &.place--lg {
    gap: 9px;
    margin-block-end: 26px;
  }
}

@media (max-width: 760px) {
  .icon-list[data-cols] {
    grid-template-columns: 1fr;
  }

  .intro-symbol {
    display: none;
  }
}


/* stranica objekta (projekat) — samo raspored simbol/tekst; vrh nosi .page-head */
.project {
  padding-block-end: 40px;
  display: grid;
  /* Ista prva kolona kao u .page-head (200px), da telo strane počne u istoj
     vertikali kao naslov iznad njega. Ranije je ovde stajalo 220px i telo je
     ispadalo 20px udesno. */
  grid-template-columns: minmax(0, 200px) minmax(0, 1fr);
  column-gap: var(--space-7);
  align-items: start;

  & > * {
    grid-column: 2;
    min-inline-size: 0;
  }

  /* Zaglavlje nosi istu klasu kao na ostalim stranama; .page-head sam pravi
     dvokolonski raster kad u sebi ima simbol, pa ovde ostaje samo da se
     razvuče preko obe kolone .project rastera. */
  & > .page-head {
    grid-column: 1 / -1;
  }

  @media (max-width: 760px) {
    grid-template-columns: 1fr;

    & > * {
      grid-column: 1;
    }
  }
}

/* Jedini naslov stranice. 24px na 360px širine, 30px od 1280px naviše.
   Nema klase: svaka stranica nosi go <h1>, pa je naslov svuda isti. Na
   početnoj taj naslov stoji ispod hero naslova i zato je <h2>; .main-title mu
   daje istu tipografiju bez lomljenja hijerarhije zaglavlja. */
h1,
.main-title {
  margin: 0 0 12px;
  font-size: var(--fs-h1);
}

.project-kind {
  /* Sledeći stepen skale iznad --fs-sm, koji je na 14px bio presitan. */
  font-size: var(--fs-md);
  color: var(--gi-sub);
  margin: 0 0 8px;
}

/* Spiskovi u telu strane objekta razmak nose odozdo, ne odozgo: iznad njih
   uvek stoji fotografija koja svoj odmak već ima. Zaglavlje je izuzeto — tamo
   spisak stoji na istom razmaku kao na poslovnom prostoru i stambenim
   objektima, jer je to isti blok. Ograničeno na .project da ne pomeri iste
   liste u futeru, na kontaktu i na pregledima. */
.project .icon-list:not(.page-head > *) {
  margin-block: 0 30px;
}

.figure--framed {
  margin-block-end: 30px;
}

.block {
  margin-block-start: 60px;

  & .block__title {
    font-size: var(--fs-title-sm);
    margin: 0 0 6px;
  }
}

/* Red medija na stranicama objekata: 3D prikaz i osnove tipskog sprata.
   Broj kolona na desktopu zadaje sam markap preko data-cols, isto kao kod
   .icon-list. Na tabletu i mobilnom uvek dve u redu. */
.media-row {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 14px;
}

@media (min-width: 1101px) {
  .media-row[data-cols="2"] { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .media-row[data-cols="3"] { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .media-row[data-cols="4"] { grid-template-columns: repeat(4, minmax(0, 1fr)); }
  .media-row[data-cols="5"] { grid-template-columns: repeat(5, minmax(0, 1fr)); }
}

/* Sličice u jednakom kadru umesto u sopstvenom odnosu stranica. Uspravne
   fotografije inače razvuku red u visinu; ovako red ostaje nizak, a ceo
   kadar se vidi u lajtboksu. Odnos je isti kao kod .video. */
.media-row[data-ratio="16-9"] .media-frame {
  aspect-ratio: 800 / 450;
}

/* Red dugmadi ispod teksta. Na mobilnom idu jedno ispod drugog, punom
   širinom; centriranje teksta već nosi sama klasa dugmeta. */
.actions {
  display: flex;
  flex-wrap: wrap;
  gap: 14px;
  margin-block-start: var(--space-6);

  @media (max-width: 760px) {
    flex-direction: column;
    align-items: stretch;
  }
}

/* Dugme nosi svoj font, prelom i podvlaku. Bez ove tri deklaracije nasleđuje
   ih od kontejnera, pa isto dugme sa istom klasom izgleda različito: u
   <article> je Montserrat/41px/bez podvlake, a u <p> postaje Karla/44.7px sa
   podvlakom, jer `p` (linija 448) nosi Karlu, a `p a` (linija 539) podvlaku. */
.button,
.button-alt {
  --notch: 16px;
  display: inline-flex;
  gap: 10px;
  align-items: center;
  border: 1px solid var(--color-accent);
  font-family: 'Montserrat', sans-serif;
  font-size: var(--fs-xs);
  font-weight: 400;
  line-height: normal;
  text-decoration: none;
  padding: 12px 20px;
  clip-path: polygon(var(--notch) 0, 100% 0, 100% calc(100% - var(--notch)), calc(100% - var(--notch)) 100%, 0 100%, 0 var(--notch));
  cursor: pointer;
  transition: background var(--dur-out) var(--ease),
              border-color var(--dur-out) var(--ease),
              color var(--dur-out) var(--ease),
              transform .12s var(--ease);

  /* Boja ostaje kao povratna informacija; nestaje samo pomeraj. */
  @media (prefers-reduced-motion: reduce) {
    transition: background var(--dur-out) var(--ease),
                border-color var(--dur-out) var(--ease),
                color var(--dur-out) var(--ease);
  }

  & .ph-light {
    font-size: 17px;
    color: currentColor;
  }

  &:active {
    transform: scale(.98);
  }

  &:focus-visible {
    outline: 2px solid var(--color-accent);
    outline-offset: 3px;
    box-shadow: inset 0 0 0 2px var(--gi-text);
  }

  @media (max-width: 760px) {
    justify-content: center;
    text-align: center;
  }
}

.button {
  background: var(--color-accent);
  color: var(--gi-ink-on-accent);

  /* Isto hover stanje kao .button-alt: puna podloga se povlači na akcenat od 8%,
     tekst prelazi na boju teksta stranice da ostane čitljiv na toj podlozi.
     Ranije je dugme išlo na potpuno providno sa narandžastim tekstom.
     `p a:hover` nosi specifičnost 0,1,2, pa se podvlaka gasi ovde. */
  &:hover {
    background: color-mix(in srgb, var(--color-accent) 8%, transparent);
    color: var(--gi-text);
    text-decoration: none;
    transition-duration: var(--dur-in);
  }
}

.button-alt {
  background: transparent;
  color: var(--gi-text);

  /* Isto stanje kao kutija ikone i futer: podloga se blago puni, ivica i tekst
     ostaju. Ranije je dugme postajalo puno narandžasto sa belim tekstom, jedini
     tako glasan hover na sajtu.

     Dugme je <a>, pa `a:hover` (0,1,1) nosi akcentnu boju i jači je od same
     klase (0,1,0): bez ovog `color` tekst bi na hover postajao narandžast.
     Ovde je 0,2,0, pa boja i podvlaka ostaju kakve jesu. */
  &:hover {
    background: color-mix(in srgb, var(--color-accent) 8%, transparent);
    color: var(--gi-text);
    text-decoration: none;
    transition-duration: var(--dur-in);
  }
}

/* Dugme koje već u mirovanju stoji na hover podlozi. Na zamućenoj traci pri
   dnu ekrana potpuno providno dugme se ne vidi, a puna narandžasta je pretežak
   potez pored dve ikonice. Hover ostaje osetan jer ide na dvostruko jaču
   podlogu, pa dugme i dalje odgovara na dodir. */
/* Dugme samo sebe gura uz desnu ivicu, bez omotača. Blok umesto inline-flex
   da bi auto margina radila, a širina ostaje po sadržaju. Razmak nosi prema
   onome što dolazi ispod. Na mobilnom se vraća u pun red kao ostala dugmad. */
.button-alt--end {
  display: flex;
  inline-size: fit-content;
  margin-inline-start: auto;
  margin-block-end: 100px;

  /* Na telefonu se vraća u pun red kao ostala dugmad, ali mora da se odvoji od
     galerije iznad — na desktopu tog razmaka nema jer dugme stoji sa strane. */
  @media (max-width: 760px) {
    inline-size: auto;
    margin-inline-start: 0;
    margin-block-start: 40px;
    justify-content: center;
  }
}

.button-alt--soft {
  background: color-mix(in srgb, var(--color-accent) 8%, transparent);

  &:hover {
    background: color-mix(in srgb, var(--color-accent) 16%, transparent);
  }
}

.map {
  inline-size: 100%;
  block-size: 380px;
  border: 0;
  border-radius: var(--radius-media);
}

/* forma upita */
.form-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 28px 40px;

  &.form-grid--wide {
    gap: 34px 40px;
  }

  @media (max-width: 760px) {
    grid-template-columns: 1fr;
  }
}

.field {
  display: flex;
  flex-direction: column;
  gap: 10px;

  &.field--full {
    margin-block-start: 28px;
  }

  &.field--gap {
    margin-block-start: 34px;
  }
}

.form-label {
  font-size: var(--fs-s);
  font-weight: 500;
  color: var(--gi-label);
}

.required {
  color: var(--color-accent-ink);
}

.form-control {
  background: transparent;
  border: none;
  border-block-end: 1px solid var(--gi-inputline);
  color: var(--gi-text);
  padding: 9px 2px;
  font-family: inherit;
  font-size: var(--fs-field);
  transition: border-color .25s ease;

  &:focus {
    outline: none;
    border-block-end-color: var(--color-accent);
  }

  &[aria-invalid="true"] {
    border-color: var(--color-error);
    outline: 2px solid color-mix(in srgb, var(--color-error) 34%, transparent);
    outline-offset: 3px;
  }

  @media (max-width: 760px) {
    font-size: max(1rem, 16px);
  }
}

textarea.form-control {
  resize: vertical;
}

.form-trap {
  position: absolute;
  inline-size: 1px;
  block-size: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.form-consent {
  margin-block-start: 24px;
  display: grid;
  grid-template-columns: 20px minmax(0, 1fr);
  align-items: start;
  gap: 12px;
  color: var(--gi-muted);
  font-size: var(--fs-sm);
  line-height: 1.6;

  & :is(.form-consent__control, .form-consent__box) {
    grid-column: 1;
    grid-row: 1;
    inline-size: 16px;
    block-size: 16px;
    margin-block-start: 3px;
  }

  & .form-consent__control {
    z-index: 1;
    margin-inline: 0;
    opacity: 0;
    cursor: pointer;

    &[aria-invalid="true"] + .form-consent__box {
      border-color: var(--color-error);
      outline: 2px solid color-mix(in srgb, var(--color-error) 34%, transparent);
      outline-offset: 3px;
    }

    &:focus-visible + .form-consent__box {
      outline: 2px solid var(--color-accent);
      outline-offset: 3px;
    }

    &:checked + .form-consent__box {
      border-color: var(--color-accent);
      background: var(--color-accent);

      &::after {
        opacity: 1;
        animation: consent-check .8s ease both;

        /* Kvačica se pojavi cela odmah: osnovne mere su već pun oblik. */
        @media (prefers-reduced-motion: reduce) {
          animation: none;
        }
      }
    }
  }

  & .form-consent__box {
    position: relative;
    border: 1px solid var(--gi-inputline);
    background: transparent;
    pointer-events: none;
    transition:
      border-color .16s ease,
      background-color .16s ease;

    &::after {
      content: "";
      position: absolute;
      inset-block-start: 9px;
      inset-inline-start: 3px;
      inline-size: 5px;
      block-size: 9px;
      border-block-start: 2px solid var(--gi-white-fixed);
      border-inline-end: 2px solid var(--gi-white-fixed);
      opacity: 0;
      transform: scaleX(-1) rotate(135deg);
      transform-origin: left top;
    }
  }

  @media (hover: hover) and (pointer: fine) {
    &:hover .form-consent__box {
      border-color: var(--color-accent);
    }
  }

  & .form-consent__copy {
    grid-column: 2;
    grid-row: 1;

    & label {
      cursor: pointer;
    }

    & a {
      color: inherit;
      text-decoration: underline;
      text-decoration-color: var(--color-accent-soft);
      text-underline-offset: 3px;

      &:hover {
        color: var(--gi-text);
        text-decoration-color: var(--color-accent);
      }
    }
  }
}

@keyframes consent-check {
  0% {
    inline-size: 0;
    block-size: 0;
  }

  25% {
    inline-size: 5px;
    block-size: 0;
  }

  50% {
    inline-size: 5px;
    block-size: 9px;
  }
}

.form-recaptcha-note {
  margin: 14px 0 0;
  color: var(--gi-faint);
  font-size: var(--fs-xxs);
  line-height: 1.55;
}

.form-status {
  margin: 18px 0 0;
  padding: 12px 14px;
  border-inline-start: 3px solid var(--color-accent);
  background: color-mix(in srgb, var(--color-accent) 10%, transparent);
  color: var(--gi-text);
  font-size: var(--fs-sm);
  line-height: 1.5;

  /* Stanje dok upit putuje: prigusenije od poruke o gresci ili uspehu. */
  &.form-status--pending {
    color: var(--gi-muted);
  }

  &.form-status--error {
    border-inline-start-color: var(--color-error);
    background: color-mix(in srgb, var(--color-error) 12%, transparent);
  }
}

/* Forma na strani objekta. Linija bloka iznad nje nosi svojih 30px, a susedne
   margine u običnom toku se sklapaju — pobeđuje veća, pa je 60px ovde ono što
   se stvarno vidi kao odmak od linije. Kontakt je izuzet: tamo forma nije u
   .project i razmak joj drži sam raster strane. */
.project .contact-form {
  margin-block-start: 60px;
}

.contact-form[aria-busy="true"] .button {
  cursor: wait;
  opacity: .68;
}

.form-actions {
  margin-block-start: 30px;

  /* Na telefonu dugme uzima celu širinu forme i tekst mu ide po sredini.
     Dugme široko po sadržaju stoji uz levu ivicu i ne izgleda kao završetak
     forme čija su sva polja puna širina. */
  @media (max-width: 760px) {
    & :is(.button, .button-alt) {
      inline-size: 100%;
      justify-content: center;
    }
  }
}

@media (max-width: 760px) {
  .map {
    block-size: 300px;
  }
}


p strong {
  color: var(--gi-text);
  font-weight: 600;
}


/* galerija foto-traka (o nama) */
.photo-row {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 30px;

  @media (max-width: 1100px) {
    grid-template-columns: repeat(2, 1fr);
  }
}

/* Izgled dolazi iz .media-frame; ovde je samo kadar. */
.photo {
  block-size: 190px;

  /* Bez sopstvenog sloja Chrome ume da propusti ponovno crtanje slike kad
     dekodiranje padne posle prvog kadra, pa okvir ostane prazan do sledeceg
     repaint-a. .media-card isti efekat dobija preko scale(1.08). */
  & > img {
    transform: translateZ(0);
  }
}

/* brojači */

/* Podaci vise na jednoj liniji koja počinje od godine osnivanja. Linija nije
   jedan element nego segment po ćeliji: kada se raster na užem ekranu prelomi u
   dva ili tri reda, svaki red dobije svoju liniju bez ijednog dodatnog pravila.
   Zato među kolonama nema razmaka — razmak nosi padding unutar ćelije, pa se
   segmenti spajaju u neprekidnu liniju. */
.stats__since {
  margin: 0 0 14px;
  font-size: var(--fs-xxs);
  font-weight: 600;
  letter-spacing: .12em;
  color: var(--gi-sub);
}

.stats {
  display: grid;
  grid-template-columns: repeat(6, minmax(0, 1fr));
  column-gap: 0;
  row-gap: 44px;
  list-style: none;
  margin: 0;
  padding: 0;

  & .stats__item {
    position: relative;
    padding: 26px 10px 0;
    text-align: center;
  }

  & .stats__item::before {
    content: "";
    position: absolute;
    inset-block-start: 0;
    inset-inline: 0;
    block-size: 1px;
    background: var(--gi-line2);
  }

  /* Pločica sa zasečenim uglovima sedi na liniji, ne ispod nje. Dvostruko šira
     nego visoka, pa leži u smeru ose umesto da je preseca. Isti rez kao na
     značkama i dugmadima, samo bez sadržaja: clip-path na pseudoelementu ne
     traži ni sliku ni glif, pa sekcija ne dodaje nijedan zahtev. */
  & .stats__item::after {
    --notch: 3px;
    content: "";
    position: absolute;
    inset-block-start: -4px;
    inset-inline-start: 50%;
    translate: -50% 0;
    inline-size: 18px;
    block-size: 9px;
    background: var(--color-accent);
    clip-path: polygon(var(--notch) 0, 100% 0, 100% calc(100% - var(--notch)), calc(100% - var(--notch)) 100%, 0 100%, 0 var(--notch));
  }

  & .stats__value {
    display: block;
    font-size: clamp(1.875rem, 3vw, 2.5rem);
    font-weight: 500;
    color: var(--gi-white);
    font-variant-numeric: tabular-nums;
  }

  & .stats__label {
    display: block;
    font-size: var(--fs-xxs);
    font-weight: 600;
    color: var(--color-accent-ink);
    margin-block-start: 10px;
  }

  @media (max-width: 760px) {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    row-gap: 32px;
  }

  @media (min-width: 761px) and (max-width: 1100px) {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}

/* Odometar. Kolona nosi deset cifara i uvek putuje istih devet redova, jer je
   tražena cifra poslednja u nizu — zato se sve cifre zaustave u isti čas bez
   obzira na vrednost. U mirovanju stoji na kraju niza, pa bez JS-a i pri
   isključenom pokretu broj prosto stoji tačan. */
.odo {
  display: inline-flex;
  block-size: 1em;
  line-height: 1;
  overflow: hidden;
  vertical-align: baseline;

  & .odo__d {
    display: block;
    block-size: 1em;
    overflow: hidden;
  }

  & .odo__reel {
    display: block;
    transform: translateY(-9em);

    & > span {
      display: block;
      block-size: 1em;
    }
  }
}

.stats[data-rolled="true"] .odo__reel {
  animation: odoRoll .9s cubic-bezier(.22, 1, .36, 1) both;
  /* Cifre kreću redom s leva, pa broj deluje kao da se sleže, a ne kao da
     šest brojača krene odjednom. */
  animation-delay: calc(var(--i, 0) * 45ms);
}

@keyframes odoRoll {
  from { transform: translateY(0); }
  to { transform: translateY(-9em); }
}

@media (prefers-reduced-motion: reduce) {
  .stats[data-rolled="true"] .odo__reel {
    animation: none;
  }
}

/* Poruka na celoj strani (hvala, 404) — samo centriranje i visina. Širinu,
   bočni razmak i vrh nose .container i .page-head, isto kao na ostalim
   stranicama; ranije je ovo pravilo pisalo svoj kontejner i ispadalo iz rastera. */
.notice {
  /* Poruka je jedini sadržaj strane, pa stoji u sredini svog bloka a ne uz
     njegov vrh. Visinu drži samo min-block-size — nikakav padding, jer bi svaki
     pomerao sadržaj sa sredine i dodavao se na tih 500px. Ovim se gasi i
     padding-block-start koji .page-head daje svim ostalim stranama. */
  padding-block: 0;
  min-block-size: 500px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;

  /* Samo prikazna veličina broja/pozdrava; težinu nasleđuje od h1. */
  & h1 {
    margin: 0 0 14px;
    font-size: clamp(3.5rem, 7vw, 4rem);
    line-height: 1;
  }

  & h2 {
    margin: 0 0 30px;
    font-size: var(--fs-base);
  }

  & > p {
    max-inline-size: 560px;
    margin: 0;
    line-height: 1.9;
    color: var(--gi-muted);
    font-weight: 300;
    text-wrap: pretty;
  }

  /* Razmak nosi red dugmadi, ne svako dugme, da na desktopu stoje jedno
     pored drugog bez dodatnog odmicanja između njih. */
  & .actions {
    margin-block-start: 36px;
    justify-content: center;
  }

}

/* reference */
.ref-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 52px 40px;

  /* Jedinstven obrazac kartica na SR i EN stranici sa referencama. */
  & > article {
    display: grid;
    align-content: start;

    & .ref-figure {
      margin-block-end: 18px;
    }

    & .ref-title,
    & .ref-title > a {
      color: var(--color-accent-ink);
    }

    & .ref-title {
      margin-block-end: 4px;
    }

    & .ref-kind {
      margin-block-end: 8px;
    }

    & .ref-kind,
    & .ref-place {
      font-size: var(--fs-sm);
      line-height: 1.45;
    }

    & .ref-place {
      margin-block-end: 14px;
    }
  }

  @media (max-width: 760px) {
    grid-template-columns: 1fr;
  }
}

/* Ostaje ravan selector: dodatni .ref-card nivo menja specifičnost u odnosu
   na .ref-grid > article pravila i time menja vertikalni ritam kartica. */
.ref-card__header {
  display: grid;
  gap: 4px;
  margin-block-end: 8px;

  & .ref-title,
  & .ref-kind {
    margin: 0;
  }
}

.ref-figure {
  block-size: 300px;
  margin-block-end: 20px;

  @media (max-width: 760px) {
    block-size: 220px;
  }
}

.ref-title {
  margin: 0 0 5px;
  font-size: var(--fs-title-sm);
  color: var(--color-accent-ink);
}

.ref-kind {
  /* <h3>, pa nosi Montserrat kao i ostali naslovi — nista ga ne gazi. */
  margin: 0 0 12px;
  font-size: var(--fs-xxs);
  color: var(--gi-sub);
}

.ref-place {
  /* Isti razlog kao kod .ref-list__place: tekst mora da ostane inline tok.
     Uvlacenje = sirina ikonice (14px) + njena margina (4px). Ako se margina
     menja, ova dva broja moraju da je prate, inace prvi red ne stoji u
     ravni sa prelomljenim redovima. */
  padding-inline-start: 18px;
  text-indent: -18px;
  margin: 0 0 14px;
  color: var(--gi-muted);
  font-weight: 400;

  & svg,
  & .ph-light {
    margin-inline-end: 4px;
    text-indent: 0;
  }

  & .ph-light {
    font-size: 14px;
  }
}

.ref-list {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 32px 40px;
  list-style: none;
  margin: 0;
  padding: 0;

  & .ref-list__item {
    border-block-start: 1px solid color-mix(in srgb, var(--color-accent) 28%, transparent);
    padding-block-start: 20px;
  }

  & .ref-list__title {
    display: block;
    margin: 0 0 5px;
    font-size: var(--fs-md);
    color: var(--color-accent-ink);
  }

  & .ref-list__kind {
    margin: 0 0 10px;
    font-size: var(--fs-xs);
    color: var(--gi-sub);
  }

  & .ref-list__place {
    /* Isto resenje kao .ref-place: nije flex, jer u flex kontejneru svaki
       inline element u tekstu (<sup>, <a>, <strong>) postaje zaseban flex
       item i dobije `gap` — tako se eksponent u „4.276m²“ odvajao od broja.
       Ikonica ostaje u toku teksta i sedi na osnovnoj liniji, pa je
       poravnata sama. Uvlacenje = sirina ikonice (14px) + njena margina. */
    padding-inline-start: 18px;
    text-indent: -18px;
    margin: 0;
    color: var(--gi-muted);
    font-weight: 400;

    & svg,
    & .ph-light {
      margin-inline-end: 4px;
      text-indent: 0;
    }

    & .ph-light {
      font-size: 14px;
    }
  }

  @media (max-width: 760px) {
    grid-template-columns: 1fr;
  }
}

.note-more {
  margin: 48px 0 0;
  font-style: italic;
  color: var(--color-accent-ink);
  font-weight: 500;
}


/* kontakt */
.contact-grid {
  display: grid;
  grid-template-columns: minmax(0, 380px) minmax(0, 1fr);
  gap: 0 72px;
  align-items: start;

  & > .intro-symbol {
    grid-column: 1;
    grid-row: 1;
  }

  & > address {
    grid-column: 1;
  }

  & > .contact-intro {
    grid-column: 2;
    grid-row: 1;

    /* Uvodni pasus je poslednji u svom omotaču, pa mu globalno pravilo
       p:last-child skida donju marginu — bez ovoga adresa ispod njega kreće na
       0px. Razmak je ovde, a ne na .contact-intro, jer sam omotač nosi mesto u
       rasteru i njegova margina bi pomerila ceo blok. */
    & > p:last-child {
      margin-block-end: 70px;
    }
  }

  & > .contact-form-wrap {
    grid-column: 2;
    grid-row: 2;
  }

  & dl {
    margin: 0;
  }

  /* Naslov grupe kontakata; dl ovde ima samo tu jednu vrstu dt. */
  & dt {
    margin: 0 0 14px;
    font-size: var(--fs-field);
    font-weight: 400;
    color: var(--gi-white);
  }

  & dd {
    margin: 0 0 32px;
  }

  @media (max-width: 760px) {
    grid-template-columns: 1fr;
    gap: 40px;

    & > .contact-intro { grid-column: 1; grid-row: 1; }
    & > address { grid-column: 1; grid-row: 2; }
    & > .contact-form-wrap { grid-column: 1; grid-row: 3; }
  }

  @media (min-width: 761px) and (max-width: 1100px) {
    grid-template-columns: 1fr;
    gap: 44px;

    & > .intro-symbol { display: none; }
    & > .contact-intro { grid-column: 1; grid-row: 1; }
    & > address { grid-column: 1; grid-row: 2; }
    & > .contact-form-wrap { grid-column: 1; grid-row: 3; }
  }
}

.form-footer {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 12px;
  margin-block-start: 36px;

  /* align-items: stretch već razvlači dugme na punu širinu; ostaje da mu se
     slog centrira, jer .button poravnava sadržaj ulevo. */
  @media (max-width: 760px) {
    align-items: stretch;

    & :is(.button, .button-alt) {
      justify-content: center;
    }
  }
}

.form-hint {
  margin: 0;
  font-size: var(--fs-xs);
  color: var(--gi-faint);
}

/* ---------- 8. KEYFRAMES ------------------------------------------------ */

@property --ctaAng {
  syntax: "<angle>";
  inherits: false;
  initial-value: 0deg;
}

/* Smena pet kadrova u kartici objekta: ciklus od 20s, svaki kadar miruje 3.2s
   pa se pretapa 0.8s. Kašnjenja su negativna, pa u zaustavljenom stanju prvi
   kadar stoji na vrhu, a ostali su već prošli svoj vidljivi deo ciklusa. */
@keyframes panelFadeFive {
  0%, 16% { opacity: 1; }
  20%, 96% { opacity: 0; }
  100% { opacity: 1; }
}

@keyframes ctaSpin {
  to {
    --ctaAng: 360deg;
  }
}

/* Odlazak hera na skrol: uvećanje plus putovanje nadole. Pomak je tu zato što
   hero odlazi uvis, pa bi u vidljivom pojasu ostao samo donji deo fotografije;
   spuštanjem slike u tom pojasu ostaje njen centar. 24svh je ispod zaliha koje
   daje zum — scale(1.54) preko 100svh visine viri 27svh gore i dole, pa se uz
   gornju ivicu ne otvara prazan pojas. Bez filtera: mekoća pada samo na
   periferiju, sa .hero__scrim::before. */
@keyframes heroScrollZoom {
  to {
    transform: translateY(24svh) scale(1.54);
  }
}

/* Naslov na skrol: uvis, u mekoću i u ništa. Tri osobine kreću u tri trenutka,
   pa svaka ima svoje stajanje: pomak ide od prvog piksela, gašenje čeka 40%,
   blur čeka polovinu. CSS interpolira svaku osobinu nezavisno, pa je za sve
   dovoljan jedan kadar. */
@keyframes heroTitleOut {
  0% {
    transform: translateY(0);
    opacity: 1;
    filter: blur(0px);
  }

  40% {
    opacity: 1;
  }

  50% {
    filter: blur(0px);
  }

  100% {
    transform: translateY(-90px);
    opacity: 0;
    filter: blur(9px);
  }
}

/* Periferna mekoća raste iz nule kako skrol odmiče; polazno stanje je oštro. */
@keyframes heroEdgeBlur {
  to {
    -webkit-backdrop-filter: blur(16px);
    backdrop-filter: blur(16px);
  }
}

/* fadeInUp i fadeInDown, preuzeti iz animate.css bez uvlačenja biblioteke.
   Vrednosti su iščitane iz njenog CSS-a, ne prepisane po sećanju. Pomak je
   100% visine samog elementa — na kartici od 400px to je 400px puta, što je
   namerno ostavljeno kako original i stoji; ako bude preveliko, menja se taj
   jedan broj. */
@keyframes fadeInUp {
  from {
    opacity: 0;
    transform: translate3d(0, 100%, 0);
  }

  to {
    opacity: 1;
    transform: translateZ(0);
  }
}

@keyframes fadeInDown {
  from {
    opacity: 0;
    transform: translate3d(0, -100%, 0);
  }

  to {
    opacity: 1;
    transform: translateZ(0);
  }
}

@keyframes rise {
  from {
    opacity: 0;
    transform: translateY(26px);
  }

  to {
    opacity: 1;
    transform: none;
  }
}

@keyframes spinSlow {
  from {
    transform: rotate(0deg);
  }

  to {
    transform: rotate(360deg);
  }
}

@keyframes pecatSettle {
  from {
    transform: rotate(-180deg);
  }

  to {
    transform: rotate(0deg);
  }
}

@keyframes symUp {
  from {
    transform: translateY(260px);
  }

  to {
    transform: translateY(0);
  }
}

@keyframes heroFade {
  0% {
    opacity: 0;
  }

  5.56% {
    opacity: 1;
  }

  33.3% {
    opacity: 1;
  }

  38.9% {
    opacity: 0;
  }

  100% {
    opacity: 0;
  }
}

/* Ciklus je 24s, slajdovi su na 6s razmaka. Pretapanje traje 1.2s, što je 5%
   ciklusa: kadar se pali od 0 do 5%, stoji pun do 25%, pa se gasi do 30%.
   Odlazak jednog i dolazak sledećeg padaju u isti prozor, jer sledeći kreće
   tačno kad prethodni stigne do 25%. */
[data-theme="light"] .hero__slide {
  filter: grayscale(0);
}

@keyframes heroFadeFour {
  0% {
    opacity: 0;
  }

  5% {
    opacity: 1;
  }

  25% {
    opacity: 1;
  }

  30% {
    opacity: 0;
  }

  100% {
    opacity: 0;
  }
}

/* Strelica se penje i gasi u ciklusu; vrhunac providnosti je 0.5, pa poziv
   ostaje prisutan a ne dominira nad fotografijom. */
@keyframes floatCue {

  0% {
    transform: translateY(-5px);
    opacity: 0;
  }

  18% {
    opacity: .5;
  }

  82% {
    opacity: .5;
  }

  100% {
    transform: translateY(11px);
    opacity: 0;
  }
}

@keyframes startPulse {
  0% {
    opacity: .48;
    transform: scale(.92);
  }

  100% {
    opacity: 0;
    transform: scale(2.35);
  }
}

@keyframes marquee {
  to {
    transform: translateX(calc(-1 * var(--marquee-shift)));
  }
}

/* Mastilo se ne dira ovde: scroll-driven animacija ne primenjuje custom
   property-je (obična vremenska ih primenjuje, ova ne), pa je `--gi-nav` u
   keyframe-u bio mrtvo slovo. U tamnoj temi ionako nije ni bilo potrebno —
   navigacija je već svetla. Svetla tema to rešava kroz navInkLight & co. */
@keyframes headerDark {
  from {
    background: rgba(18, 18, 18, 0);
    backdrop-filter: blur(0px);
    /* nula kao dužina, ne `none`, da senka može da se interpolira */
    box-shadow: 0 0 0 rgba(0, 0, 0, 0);
  }

  to {
    background: var(--gi-headerBg);
    backdrop-filter: blur(20px) saturate(1.4);
    box-shadow: var(--gi-headerShadow);
  }
}

@keyframes headerDarkLight {
  from {
    background: rgba(244, 242, 238, 0);
    backdrop-filter: blur(0px);
    box-shadow: 0 0 0 rgba(0, 0, 0, 0);
  }

  to {
    background: var(--gi-headerBg);
    backdrop-filter: blur(20px) saturate(1.4);
    box-shadow: var(--gi-headerShadow);
  }
}

@keyframes headerSolid {
  from {
    background: var(--gi-bg);
    backdrop-filter: blur(0px);
  }

  to {
    background: var(--gi-headerBg);
    backdrop-filter: blur(20px) saturate(1.4);
  }
}

@keyframes headerSolidLight {
  from {
    background: var(--gi-bg);
    backdrop-filter: blur(0px);
  }

  to {
    background: var(--gi-headerBg);
    backdrop-filter: blur(20px) saturate(1.4);
  }
}

/* Nema globalnog reduced-motion reseta. Svaka animacija i svaka tranzicija
   koja pomera element nose svoj `@media (prefers-reduced-motion: reduce)`
   tamo gde su deklarisane, pa se specifičnost poklapa sama i `!important`
   nije potreban. Boja i opacity ostaju kao povratna informacija; gasi se
   samo kretanje. Novi animirani element mora doneti svoj blok — nema
   globalnog hvatača koji bi ga pokrio. */

/* ---------- 9. RESPONSIVE ---------------------------------------------- */

/* Sklanja element ispod mobilnog praga. Na telefonu upit već nosi traka
   .mobile-quick-actions, pa se dugme u sadržaju ne ponavlja. Stoji ovde, a ne
   uz .u-visually-hidden, jer komponente koje skriva (.button-alt) postavljaju
   svoj `display` kasnije u fajlu i pri istoj težini bi ga nadjačale. */
@media (max-width: 760px) {
  .u-desktop-only {
    display: none;
  }
}

@media (min-width: 761px) and (max-width: 1100px) {
  :root {
    --wrap-pad: 26px;
  }
}

@media (min-width: 1030px) and (max-width: 1110px) {
  .site-nav {
    gap: 8px 12px;
  }
}

@media (max-width: 1029px) {
  html:not(.js) .site-header__inner {
    flex-wrap: wrap;
  }

  html:not(.js) .site-nav {
    flex: 0 0 100%;
    display: grid;
    grid-template-columns: 1fr auto auto;
    column-gap: 24px;
    align-items: center;
    padding-block: 8px 16px;
  }

  html:not(.js) .nav-link:not(.lang-link),
  html:not(.js) .nav-cta {
    grid-column: 1 / -1;
    padding: 12px 2px;
    border-block-end: 1px solid var(--gi-line0);
    clip-path: none;
    text-align: end;
  }

  html:not(.js) .nav-cta::before {
    display: none;
  }

  html:not(.js) .icon-button,
  html:not(.js) .lang-link {
    margin-block-start: 14px;
  }

  html:not(.js) .icon-button {
    grid-column: 2;
  }

  html:not(.js) .lang-link {
    grid-column: 3;
  }

  .js .burger {
    display: inline-flex;
    border: none;
    color: var(--gi-white);
    font-size: 1.5rem;
    padding: 0;
    inline-size: 44px;
    block-size: 44px;
    margin-inline-end: -8px;
  }

  .js .site-header:has(.site-nav[data-open="true"]) {
    animation: none;
    background: var(--gi-menuBg);
    backdrop-filter: blur(20px) saturate(1.4);
    -webkit-backdrop-filter: blur(20px) saturate(1.4);
  }

  .js .site-nav[data-open="false"] {
    display: none;
  }

  .js .site-nav[data-open="true"] {
    position: absolute;
    inset-block-start: 100%;
    inset-inline: 0;
    display: grid;
    grid-template-columns: 1fr auto auto;
    align-items: center;
    gap: 2px 26px;
    background: var(--gi-menuBg);
    backdrop-filter: blur(20px) saturate(1.4);
    -webkit-backdrop-filter: blur(20px) saturate(1.4);
    padding: 6px var(--wrap-pad) 28px;
    border-block-end: 1px solid var(--gi-line1);
    box-shadow: 0 24px 44px rgba(0, 0, 0, .28);
    z-index: 60;

    & .nav-link:not(.lang-link),
    & .nav-cta {
      grid-column: 1 / -1;
      padding: 17px 2px;
      border-block-end: 1px solid var(--gi-line0);
      text-align: right;
      font-size: 0.9375rem;
    }

    & .nav-cta {
      clip-path: none;
      color: var(--gi-nav);
      font-weight: 600;

      &::before {
        display: none;
      }
    }

    /* Dodirno polje ≥44px: 14px padding oko sadržaja, margina smanjena sa
       20 na 6 da glif ostane na istoj visini. Inline padding raste ulevo,
       pa desna ivica ne mrda. */
    & .icon-button,
    & .lang-link {
      margin: 6px 0 0;
      padding: 14px 0 14px 26px;
      font-size: 0.9375rem;
      block-size: auto;
      inline-size: auto;
    }

    & .icon-button {
      grid-column: 2;
    }

    & .lang-link {
      grid-column: 3;
    }
  }
}

@media (min-width: 761px) and (max-width: 1029px) {
  .js .burger {
    order: 2;
  }

  .js .site-nav[data-open="false"] {
    display: contents;

    & > :not(.nav-cta, .icon-button, .lang-link) {
      display: none;
    }

    & > .nav-cta {
      order: 1;
      margin-inline-start: auto;
    }

    & > .icon-button {
      order: 3;
    }

    & > .lang-link {
      order: 4;
    }
  }
}

@media (max-width: 760px) {
  :root {
    --wrap-pad: 20px;
  }

  .seal-bg {
    display: none;
  }

  .intro-grid {
    grid-template-columns: 1fr;
  }

}

/* ---------- 6b. GALERIJA I LIGHTBOX ------------------------------------- */


.gallery--columns {
  list-style: none;
  margin: 0;
  padding: 0;
  columns: 3;
  column-gap: 14px;

  & li {
    break-inside: avoid;
    margin-block-end: 14px;
  }

  @media (min-width: 761px) and (max-width: 1100px) {
    columns: 2;
  }

  @media (max-width: 760px) {
    columns: 2;
  }

}

.is-lightbox-open {
  overflow: hidden;
}

.lightbox {
  position: fixed;
  inset: 0;
  z-index: 2000;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(8, 8, 8, .95);

  &[hidden] {
    display: none;
  }

  & .lightbox__img {
    max-inline-size: 88vw;
    max-block-size: 84vh;
    object-fit: contain;
    border-radius: var(--radius-media);
    box-shadow: 0 20px 70px rgba(0, 0, 0, .6);
  }

  & :is(.lightbox__close, .lightbox__nav) {
    position: absolute;
    background: none;
    border: none;
    color: var(--gi-white-fixed);
    cursor: pointer;
    line-height: 1;
    user-select: none;

    & .ph-light {
      font-size: inherit;
      color: inherit;
    }
  }

  & .lightbox__close {
    inset-block-start: 22px;
    inset-inline-end: 28px;
    font-size: clamp(1.8063rem, calc(1.6813rem + 0.554vw), 2.125rem);
  }

  & .lightbox__nav {
    inset-block-start: 50%;
    transform: translateY(-50%);
    font-size: clamp(2.7625rem, calc(2.5719rem + 0.848vw), 3.25rem);
    padding: 10px 16px;

    &.lightbox__nav--prev {
      inset-inline-start: 20px;
    }

    &.lightbox__nav--next {
      inset-inline-end: 20px;
    }
  }

  & .lightbox__count {
    position: absolute;
    inset-block-end: 26px;
    inset-inline: 0;
    margin: 0;
    text-align: center;
    color: var(--color-accent);
    font-size: var(--fs-sm);
    font-weight: 600;
  }
}
