Files
GoNtech/web/static/css/main.css
T

1316 lines
37 KiB
CSS
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/* osnovna podešavanja */
*, *::before, *::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
html {
background: var(--pozadina);
}
body {
font-family: system-ui, -apple-system, sans-serif;
background: var(--pozadina);
color: var(--tekst-glavni);
}
/* layout */
.raspored {
display: flex;
height: 100vh;
overflow: hidden;
}
/* bez tranzicije pri inicijalnom učitavanju skupljenog sidebara */
.sidebar-init-skupljen .sidebar {
width: 60px;
overflow: hidden;
transition: none;
}
.sidebar-init-skupljen .sidebar .logo-zona {
opacity: 0;
width: 0;
pointer-events: none;
transition: none;
}
.sidebar-init-skupljen .sidebar .nav-oznaka,
.sidebar-init-skupljen .sidebar .nav-stavka span {
opacity: 0;
pointer-events: none;
transition: none;
}
/* sidebar */
.sidebar {
width: 220px;
background: var(--sidebar-pozadina);
display: flex;
flex-direction: column;
transition: width 0.28s cubic-bezier(.4,0,.2,1);
overflow: hidden;
flex-shrink: 0;
}
.sidebar.skupljen {
width: 60px;
overflow: hidden;
}
/* vrh sidebara — logo zona */
.sidebar-vrh {
display: flex;
align-items: center;
height: 72px;
padding: 0 12px;
gap: 10px;
border-bottom: 0.5px solid var(--ivica);
flex-shrink: 0;
}
/* hamburger dugme */
.hamburger {
background: none;
border: none;
cursor: pointer;
color: var(--tekst-jak);
padding: 6px;
border-radius: 6px;
display: flex;
align-items: center;
justify-content: center;
transition: background 0.2s;
flex-shrink: 0;
}
.hamburger:hover {
background: var(--pozadina-hover);
}
/* logo zona */
.logo-zona {
display: flex;
align-items: center;
gap: 10px;
overflow: hidden;
opacity: 1;
transition: opacity 0.28s, width 0.28s;
width: 160px;
}
.sidebar.skupljen .logo-zona {
opacity: 0;
width: 0;
pointer-events: none;
}
.logo-naziv {
color: var(--tekst-jak);
font-weight: 500;
font-size: 15px;
white-space: nowrap;
}
.logo-podnazlov {
color: var(--tekst-sporedni);
font-size: 11px;
white-space: nowrap;
}
/* navigacija */
.sidebar-nav {
flex: 1;
overflow-y: auto;
overflow-x: hidden;
padding: 8px 0;
scrollbar-width: none;
}
.sidebar-nav::-webkit-scrollbar {
display: none;
}
.nav-oznaka {
font-size: 10px;
text-transform: uppercase;
letter-spacing: 0.08em;
color: var(--tekst-sporedni);
padding: 12px 16px 4px;
white-space: nowrap;
opacity: 1;
transition: opacity 0.28s;
}
.sidebar.skupljen .nav-oznaka {
opacity: 0;
}
.nav-stavka {
display: flex;
align-items: center;
gap: 12px;
padding: 9px 16px;
cursor: pointer;
color: var(--tekst-sporedni);
white-space: nowrap;
position: relative;
text-decoration: none;
transition: background 0.2s, color 0.2s, transform 0.15s ease;
}
.nav-stavka:hover {
background: var(--pozadina-hover);
color: var(--tekst-jak);
}
.sidebar:not(.skupljen) .nav-stavka:hover {
transform: scale(1.03);
}
.sidebar.skupljen .nav-stavka:hover svg {
transform: scale(1.15);
}
.nav-stavka.aktivan {
background: var(--sb-aktivan);
color: var(--tekst-jak);
}
.nav-stavka.aktivan::before {
content: '';
position: absolute;
left: 0;
top: 4px;
bottom: 4px;
width: 3px;
background: var(--sb-akcent);
border-radius: 0 3px 3px 0;
}
.nav-stavka svg {
flex-shrink: 0;
width: 20px;
height: 20px;
transition: transform 0.15s ease;
}
.nav-stavka span {
font-size: 14px;
opacity: 1;
transition: opacity 0.28s;
}
.sidebar.skupljen .nav-stavka span {
opacity: 0;
pointer-events: none;
}
/* accordion podmeni u sidebaru */
.nav-podmeni {
overflow: hidden;
max-height: 0;
transition: max-height 0.22s ease-out;
}
.nav-podmeni.otvoren {
max-height: 300px;
transition: max-height 0.25s ease-in;
}
/* pri inicijalnom učitavanju sprečavamo animaciju podmenia */
.nav-podmeni.bez-tranzicije {
transition: none !important;
}
/* u skupljenom modu otvoren podmeni dobija vizuelnu oznaku — pozadina + leva akcenat-linija */
.sidebar.skupljen .nav-podmeni.otvoren {
background: var(--sb-aktivan);
border-left: 3px solid var(--sb-akcent);
}
.nav-podstavka {
padding-left: 48px !important;
}
.nav-podstavka span {
font-size: 13px !important;
}
/* u skupljenom modu reset uvlačenja — ikonica se prikazuje na istoj poziciji */
.sidebar.skupljen .nav-podstavka {
padding-left: 16px !important;
}
/* strelica za accordion — sakriva se zajedno sa tekstom u skupljenom modu */
.nav-strelica {
margin-left: auto;
display: flex;
align-items: center;
flex-shrink: 0;
}
.nav-separator {
height: 0.5px;
background: var(--ivica);
margin: 8px 12px;
}
/* tooltip kada je sidebar skupljen */
.nav-tooltip {
position: absolute;
left: 68px;
top: 50%;
transform: translateY(-50%);
background: rgba(0,0,0,0.85);
color: #fff;
font-size: 12px;
padding: 4px 10px;
border-radius: 6px;
white-space: nowrap;
pointer-events: none;
opacity: 0;
transition: opacity 0.15s;
z-index: 100;
}
.sidebar:not(.skupljen) .nav-tooltip {
display: none;
}
/* specifičniji selektor pobjeđuje .sidebar.skupljen .nav-stavka span { opacity:0 } */
.sidebar.skupljen .nav-stavka:hover .nav-tooltip {
opacity: 1;
pointer-events: none;
}
/* dno sidebara */
.sidebar-dno {
padding: 8px 0;
border-top: 0.5px solid var(--ivica);
}
/* glavni sadržaj */
.glavni-sadrzaj {
flex: 1;
display: flex;
flex-direction: column;
overflow: hidden;
}
/* topbar */
.topbar {
height: 56px;
background: var(--kartica);
border-bottom: 0.5px solid var(--ivica);
display: flex;
align-items: center;
padding: 0 20px;
gap: 12px;
flex-shrink: 0;
}
.topbar-naslov {
font-weight: 600;
font-size: 18px;
color: var(--tekst-glavni);
flex: 1;
min-width: 0;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
/* identifikacija firme u topbaru (naziv + logo) — pomera se i može da se skrati */
.topbar-firma { flex-shrink: 0; line-height: 1.2; min-width: 0; }
.topbar-firma .topbar-firma-naziv {
font-weight: 700; font-size: 14px; color: var(--tekst-glavni); letter-spacing: -0.2px;
overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.topbar-firma .topbar-firma-podnaziv {
font-size: 11px; color: var(--tekst-sporedni);
overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.topbar-logo { height: 34px; width: auto; border-radius: 6px; flex-shrink: 0; }
/* sadržaj stranice */
.sadrzaj {
flex: 1;
overflow-y: auto;
padding: 20px;
}
/* kartice */
.kartica {
background: var(--kartica);
border: 0.5px solid var(--ivica);
border-radius: 12px;
padding: 16px;
box-shadow: var(--senka);
transition: box-shadow 0.25s, border-color 0.25s, transform 0.25s, background 0.25s;
}
.kartica:hover {
box-shadow: var(--senka-hover);
border-color: var(--ivica-jaka);
}
/* hover varijante po korisničkoj preferenciji.
Selektor je [data-hover] (ne body[data-hover]) da bi isti CSS
radio i globalno (body) i lokalno na preview wrapperima. */
[data-hover="bez"] .kartica:hover {
box-shadow: var(--senka);
border-color: var(--ivica);
transform: none;
}
[data-hover="podizanje"] .kartica:hover {
box-shadow: var(--senka-hover);
border-color: var(--ivica-jaka);
transform: translateY(-3px);
}
[data-hover="svetlost"] .kartica:hover {
box-shadow: 0 0 0 1.5px var(--sb-akcent), 0 0 20px color-mix(in srgb, var(--sb-akcent) 35%, transparent);
border-color: var(--sb-akcent);
transform: none;
}
[data-hover="zoom"] .kartica:hover {
box-shadow: var(--senka-hover);
border-color: var(--ivica-jaka);
transform: scale(1.02);
}
[data-hover="boja"] .kartica:hover {
box-shadow: var(--senka-hover);
border-color: var(--ivica-jaka);
background: color-mix(in srgb, var(--sb-akcent) 6%, var(--kartica));
transform: none;
}
/* modal za premeštanje artikla — koristi promenljive teme, pa prati svetlu/tamnu;
kad je aktivna slika u pozadini, glass-override u base.html ga čini providnim kao kartice */
.premesti-modal {
border: 0.5px solid var(--ivica);
border-radius: 12px;
padding: 0;
background: var(--pozadina);
color: var(--tekst-glavni);
width: min(90vw, 320px);
/* eksplicitno centriranje — main.css reset gazi UA „margin:auto", pa bez ovoga modal padne u gornji levi ćošak */
margin: auto;
/* dvoslojna senka: meka difuzna + dublja bliža, da modal jače „iskoči" iznad pozadine */
box-shadow: 0 12px 28px rgba(0, 0, 0, 0.35),
0 32px 80px rgba(0, 0, 0, 0.55);
/* polazno stanje + prelaz za fade in/out (transform daje blagi „zoom") */
opacity: 0;
transform: scale(0.96);
transition: opacity 0.32s ease, transform 0.32s ease,
overlay 0.32s ease allow-discrete, display 0.32s ease allow-discrete;
}
.premesti-modal[open] {
opacity: 1;
transform: scale(1);
}
/* početno stanje na samom otvaranju — bez ovoga nema fade in animacije */
@starting-style {
.premesti-modal[open] {
opacity: 0;
transform: scale(0.96);
}
}
/* zatamnjena pozadina iza modala */
.premesti-modal::backdrop {
background: rgba(0, 0, 0, 0);
transition: background 0.32s ease,
overlay 0.32s ease allow-discrete, display 0.32s ease allow-discrete;
}
.premesti-modal[open]::backdrop {
background: rgba(0, 0, 0, 0.72);
}
@starting-style {
.premesti-modal[open]::backdrop {
background: rgba(0, 0, 0, 0);
}
}
/* zaglavlje modala: naslov + dugme za zatvaranje */
.premesti-zaglavlje {
display: flex;
align-items: center;
justify-content: space-between;
padding: 12px 14px;
margin: 0;
border-bottom: 0.5px solid var(--ivica);
}
.premesti-zaglavlje h3 {
margin: 0;
font-size: 15px;
color: var(--tekst-glavni);
}
.premesti-zatvori {
background: none;
border: none;
color: var(--tekst-sporedni);
font-size: 22px;
line-height: 1;
cursor: pointer;
padding: 0 4px;
}
/* spisak kategorija unutar modala */
.premesti-panel {
display: flex;
flex-direction: column;
gap: 2px;
padding: 8px;
margin: 0;
}
.premesti-opcija {
text-align: left;
padding: 9px 12px;
background: none;
border: none;
border-radius: 6px;
color: var(--tekst-glavni);
font-size: 14px;
cursor: pointer;
white-space: nowrap;
}
.premesti-opcija:hover { background: var(--pozadina-hover); }
.premesti-opcija-prazno {
color: var(--tekst-sporedni);
border-top: 0.5px solid var(--ivica);
margin-top: 4px;
padding-top: 11px;
}
/* primarna dugmad — rade na svim temama */
.btn-primarno {
display: inline-flex;
align-items: center;
background: var(--sb-akcent);
color: #fff;
border: none;
border-radius: 8px;
padding: 8px 16px;
font-size: 14px;
font-weight: 500;
cursor: pointer;
text-decoration: none;
white-space: nowrap;
transition: opacity 0.2s;
}
.btn-primarno:hover { opacity: 0.85; }
/* mala primarna dugmad u tabelama */
.btn-primarno-malo {
display: inline-flex;
align-items: center;
background: var(--sb-akcent);
color: #fff;
border: none;
border-radius: 6px;
padding: 4px 10px;
font-size: 12px;
font-weight: 500;
cursor: pointer;
text-decoration: none;
transition: opacity 0.2s;
}
.btn-primarno-malo:hover { opacity: 0.85; }
/* sekundarno dugme (Odustani) */
.btn-sekundarno {
display: inline-flex;
align-items: center;
background: transparent;
color: var(--tekst-sporedni);
border: 0.5px solid var(--ivica);
border-radius: 8px;
padding: 9px 20px;
font-size: 14px;
cursor: pointer;
text-decoration: none;
transition: background 0.2s, color 0.2s;
}
.btn-sekundarno:hover { background: var(--pozadina); color: var(--tekst-glavni); }
/* crveno dugme za brisanje u tabelama */
.btn-obrisi-malo {
display: inline-flex;
align-items: center;
background: #dc2626;
color: #fff;
border: none;
border-radius: 6px;
padding: 4px 10px;
font-size: 12px;
font-weight: 500;
cursor: pointer;
text-decoration: none;
transition: opacity 0.2s;
}
.btn-obrisi-malo:hover { opacity: 0.8; }
/* ghost dugme za brisanje — providna pozadina, crvena ivica i tekst */
.btn-obrisi-ghost {
display: inline-flex;
align-items: center;
background: transparent;
color: #dc2626;
border: 0.5px solid #fca5a5;
border-radius: 6px;
padding: 4px 12px;
font-size: 12px;
cursor: pointer;
text-decoration: none;
white-space: nowrap;
transition: background 0.2s;
}
.btn-obrisi-ghost:hover { background: rgba(220, 38, 38, 0.08); }
/* opasno dugme (Obriši/Deaktiviraj) — pun format, crveno */
.btn-opasno {
display: inline-flex;
align-items: center;
background: #dc2626;
color: #fff;
border: none;
border-radius: 8px;
padding: 8px 16px;
font-size: 14px;
font-weight: 500;
cursor: pointer;
text-decoration: none;
white-space: nowrap;
transition: opacity 0.2s;
}
.btn-opasno:hover { opacity: 0.85; }
/* upozoravajuće dugme (Storno) — pun format, narandžasto */
.btn-upozorenje {
display: inline-flex;
align-items: center;
background: #f97316;
color: #fff;
border: none;
border-radius: 8px;
padding: 8px 16px;
font-size: 14px;
font-weight: 500;
cursor: pointer;
text-decoration: none;
white-space: nowrap;
transition: opacity 0.2s;
}
.btn-upozorenje:hover { opacity: 0.85; }
/* nazad link na formama */
.nazad-link {
display: inline-flex;
/* u .kolona (flex-column) bi se zbog stretch-a rastegao na punu širinu — ostaje kompaktan */
align-self: flex-start;
align-items: center;
gap: 6px;
font-size: 13px;
color: var(--tekst-sporedni);
text-decoration: none;
margin-bottom: 20px;
transition: color 0.2s;
}
.nazad-link:hover { color: var(--tekst-glavni); }
/* hover na redovima tabela — zamena za inline onmouseover/onmouseout */
.red-tabele {
border-bottom: 0.5px solid var(--ivica);
transition: background 0.15s;
}
.red-tabele:hover { background: var(--pozadina); }
/* naslov sekcije unutar forme */
.sekcija-naslov {
font-size: 12px;
font-weight: 500;
color: var(--tekst-sporedni);
text-transform: uppercase;
letter-spacing: 0.05em;
padding-bottom: 8px;
margin-bottom: 12px;
border-bottom: 0.5px solid var(--ivica);
}
/* avatar krug korisnika u topbaru */
.avatar-korisnik {
width: 32px;
height: 32px;
border-radius: 9px;
background: var(--sb-akcent);
display: flex;
align-items: center;
justify-content: center;
font-size: 12px;
font-weight: 500;
color: #fff;
flex-shrink: 0;
}
/* klizač (input[type=range]) — ujednačen izgled na svim brauzerima.
Chromium ne stilizuje nativni slajder kao Firefox niti popunjava deo pre glave,
pa oblik crtamo ručno preko pseudo-elemenata oba motora. */
.klizac {
-webkit-appearance: none;
appearance: none;
width: 100%;
height: 18px; /* visina klik-zone; sama staza je tanja, crta se u pseudo-elementima */
background: transparent;
cursor: pointer;
--popunjeno: 0%; /* postavlja JS; Firefox to ne koristi (ima ::-moz-range-progress) */
}
/* ——— Chromium/Blink: Opera, Chrome, Edge ——— */
.klizac::-webkit-slider-runnable-track {
height: 6px;
border-radius: 999px;
/* plavo do --popunjeno, dalje siva staza — tvrdi prelaz na istom procentu */
background: linear-gradient(to right,
var(--sb-akcent) var(--popunjeno),
var(--pozadina-hover) var(--popunjeno));
}
.klizac::-webkit-slider-thumb {
-webkit-appearance: none;
appearance: none;
width: 16px;
height: 16px;
margin-top: -5px; /* (6px staza 16px glava) / 2 — centrira glavu na stazu */
border-radius: 50%;
background: #b0b6be;
border: 2px solid #fff;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.35);
}
/* ——— Firefox ——— */
.klizac::-moz-range-track {
height: 6px;
border-radius: 999px;
background: var(--pozadina-hover);
}
.klizac::-moz-range-progress {
height: 6px;
border-radius: 999px;
background: var(--sb-akcent);
}
.klizac::-moz-range-thumb {
width: 16px;
height: 16px;
border: 2px solid #fff;
border-radius: 50%;
background: #b0b6be;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.35);
}
/* fokus — suptilan prsten oko glave (bez podrazumevanog outline-a) */
.klizac:focus { outline: none; }
.klizac:focus-visible::-webkit-slider-thumb { box-shadow: 0 0 0 4px rgba(31, 111, 235, 0.25); }
.klizac:focus-visible::-moz-range-thumb { box-shadow: 0 0 0 4px rgba(31, 111, 235, 0.25); }
/* input polja — konzistentna za sve teme */
input[type="text"],
input[type="email"],
input[type="password"],
input[type="number"],
input[type="date"],
select {
height: 38px;
width: 100%;
padding: 8px 12px;
box-sizing: border-box;
line-height: 1.5;
background: var(--kartica) !important;
color: var(--tekst-glavni) !important;
border: 0.5px solid var(--ivica) !important;
border-radius: 8px;
font-size: 14px;
outline: none;
transition: border-color 0.2s;
}
textarea {
height: auto;
width: 100%;
min-height: 80px;
padding: 8px 12px;
box-sizing: border-box;
line-height: 1.5;
resize: vertical;
background: var(--kartica) !important;
color: var(--tekst-glavni) !important;
border: 0.5px solid var(--ivica) !important;
border-radius: 8px;
font-size: 14px;
outline: none;
transition: border-color 0.2s;
}
input[type="text"]:focus,
input[type="email"]:focus,
input[type="password"]:focus,
input[type="number"]:focus,
input[type="date"]:focus,
textarea:focus,
select:focus {
border-color: var(--sb-akcent) !important;
outline: none;
}
select {
width: 100%;
min-width: 0;
}
/* poruka o uspehu — konzistentna za sve teme */
.poruka-uspeh {
background: var(--poruka-uspeh-bg);
border: 0.5px solid var(--poruka-uspeh-boja);
border-radius: 10px;
padding: 12px 16px;
margin-bottom: 20px;
font-size: 14px;
color: var(--poruka-uspeh-boja);
}
.poruka-greska {
background: rgba(207, 87, 87, 0.12);
border: 0.5px solid var(--greska);
border-radius: 10px;
padding: 12px 16px;
margin-bottom: 20px;
font-size: 14px;
color: var(--greska);
}
/* toast obaveštenja (npr. povratna informacija posle upload-a) */
.toast {
position: fixed;
bottom: 24px;
right: 24px;
z-index: 9999;
display: flex;
align-items: center;
gap: 10px;
padding: 12px 18px;
border-radius: 10px;
font-size: 13px;
font-weight: 500;
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.15);
animation: toastIn 0.3s ease forwards;
max-width: 340px;
}
.toast-greska { background: #fef2f2; color: #dc2626; border: 0.5px solid #fca5a5; }
.toast-uspeh { background: #f0fdf4; color: #16a34a; border: 0.5px solid #86efac; }
.toast.nestaje { animation: toastOut 0.3s ease forwards; }
@keyframes toastIn {
from { opacity: 0; transform: translateY(12px); }
to { opacity: 1; transform: translateY(0); }
}
@keyframes toastOut {
from { opacity: 1; transform: translateY(0); }
to { opacity: 0; transform: translateY(12px); }
}
/* ============================================================
Komponente forme i tabela — zamena za ponavljane inline stilove.
Cilj: čitljiviji template, jedno mesto istine za izgled.
============================================================ */
/* labela iznad polja forme */
.polje-labela {
display: block;
font-size: 13px;
color: var(--tekst-sporedni);
margin-bottom: 6px;
}
/* oznaka obaveznog polja (zvezdica) */
.obavezno {
color: var(--greska);
}
/* sitan pomoćni/sporedni tekst (objašnjenja, vrednosti u listama) */
.pomocni-tekst {
font-size: 13px;
color: var(--tekst-sporedni);
}
/* vertikalni raspored polja unutar forme */
.forma-kolona {
display: flex;
flex-direction: column;
gap: 18px;
}
/* layout utili — struktura bez razmaka; gap/margin se daju po instanci */
.kolona {
display: flex;
flex-direction: column;
}
.red-izmedju {
display: flex;
justify-content: space-between;
}
/* grid raspored polja — osnovne (desktop) vrednosti;
responsivni override na uže ekrane je niže u media bloku */
.forma-grid-2 {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 12px;
}
.forma-grid-4 {
display: grid;
grid-template-columns: 1fr 1fr 1fr 1fr;
gap: 12px;
}
/* === tabele === */
.tabela {
width: 100%;
border-collapse: collapse;
}
.tabela thead tr {
border-bottom: 0.5px solid var(--ivica);
}
.tabela th {
padding: 12px 16px;
text-align: left;
font-size: 12px;
font-weight: 500;
color: var(--tekst-jak);
}
.tabela td {
padding: 12px 16px;
}
.tabela .centar {
text-align: center;
}
/* kartica koja sadrži tabelu — bez paddinga, zaobljeni uglovi sečeni */
.kartica-tabela {
padding: 0;
overflow: hidden;
}
/* horizontalni skrol omotač oko tabele na uskim ekranima */
.tabela-skrol {
overflow-x: auto;
}
/* prazno stanje (nema podataka) u tabeli ili listi kartica */
.prazno-stanje {
padding: 32px;
text-align: center;
font-size: 14px;
color: var(--tekst-sporedni);
}
/* ============================================================
Stranica Dozvole (matrica) — stilovi su ovde (a ne u <head> stranice)
jer HTMX navigacija (hx-select="#glavni-sadrzaj") odbacuje <head>,
pa stil iz dodatni-css bloka ne bi važio dok se ne osveži stranica.
main.css ostaje u headu kroz HTMX navigaciju → uvek se primenjuje.
============================================================ */
.dozvole-tabela tbody tr:nth-child(1) { animation-delay: 0.04s; }
.dozvole-tabela tbody tr:nth-child(2) { animation-delay: 0.08s; }
.dozvole-tabela tbody tr:nth-child(3) { animation-delay: 0.12s; }
.dozvole-tabela tbody tr:nth-child(4) { animation-delay: 0.16s; }
.dozvole-tabela tbody tr:nth-child(5) { animation-delay: 0.20s; }
/* zaglavlja modula — providna staklena traka sa akcentnom levom ivicom.
Bez sopstvenog backdrop-filter-a: kartica već zamućuje pozadinu, pa traka
kroz svoju providnost pokazuje tu zamućenu sliku tonirano u akcent.
Providna je, ali nešto manje od kartice, da se jasno ističe kao traka. */
.matrica-modul td {
padding: 9px 16px;
font-size: 11px;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.08em;
color: var(--tekst-jak);
background: color-mix(in srgb, var(--sb-akcent) 26%, transparent);
border-top: 0.5px solid var(--ivica);
border-bottom: 0.5px solid var(--ivica);
border-left: 3px solid var(--sb-akcent);
}
.matrica-checkbox { text-align: center; padding: 8px 16px; }
.matrica-checkbox input[type=checkbox] { width: 16px; height: 16px; cursor: pointer; accent-color: var(--sb-akcent); }
.matrica-checkbox input[type=checkbox]:disabled { cursor: default; opacity: 0.5; }
/* overlay za mobilni — tamni sloj iza sidebara */
.sidebar-overlay {
display: none;
position: fixed;
inset: 0;
background: rgba(0,0,0,0.5);
z-index: 9;
}
.sidebar-overlay.aktivan {
display: block;
}
/* mobilni ekrani */
@media (max-width: 768px) {
/* sidebar — drawer ponašanje */
.sidebar {
position: fixed;
left: 0;
top: 0;
height: 100vh;
z-index: 10;
transform: translateX(-100%);
transition: transform 0.28s cubic-bezier(.4,0,.2,1);
width: 220px !important;
}
.sidebar.otvoren { transform: translateX(0); }
.sidebar.otvoren .logo-zona { opacity: 1; width: 160px; pointer-events: auto; }
.sidebar.otvoren .nav-oznaka { opacity: 1; }
.sidebar.otvoren .nav-stavka span { opacity: 1; pointer-events: auto; }
.nav-tooltip { display: none !important; }
.glavni-sadrzaj { width: 100%; }
/* topbar hamburger */
#hamburger-topbar { display: flex !important; color: var(--tekst-glavni); }
#hamburger-topbar:hover { background: var(--pozadina); }
/* na telefonu sklanjamo identifikaciju firme iz topbara — naziv i logo su
već vidljivi u bočnom meniju, pa naslov stranice dobija ceo prostor */
.topbar-firma, .topbar-logo { display: none; }
.topbar-naslov { font-size: 16px; }
/* teme */
.topbar-teme { display: none; }
.teme-grid { flex-direction: column !important; }
/* forme */
.forma-grid-2 { grid-template-columns: 1fr !important; }
/* magacin traka */
.magacin-traka { flex-direction: column; align-items: stretch; }
.magacin-traka form { flex-direction: column; align-items: stretch; }
.magacin-traka a { text-align: center; }
.magacin-traka form input,
.magacin-traka form select,
.magacin-traka form button,
.magacin-traka form label { width: 100%; justify-content: flex-start; }
}
/* tačkice za teme */
.tema-krug {
width: 20px;
height: 20px;
border-radius: 50%;
display: inline-block;
border: 2px solid transparent;
transition: border-color 0.2s;
}
.tema-krug:hover {
border-color: var(--tekst-sporedni);
}
.tema-krug-aktivan {
border-color: var(--tekst-glavni) !important;
}
/* animacije */
@keyframes fadeInUp {
from { opacity: 0; transform: translateY(10px); }
to { opacity: 1; transform: translateY(0); }
}
@keyframes fadeIn {
from { opacity: 0; }
to { opacity: 1; }
}
@keyframes scaleIn {
from { opacity: 0; transform: scale(0.95); }
to { opacity: 1; transform: scale(1); }
}
@keyframes slideLeft {
from { opacity: 0; transform: translateX(-12px); }
to { opacity: 1; transform: translateX(0); }
}
@keyframes slideDown {
from { opacity: 0; transform: translateY(-10px); }
to { opacity: 1; transform: translateY(0); }
}
@keyframes shake {
0%, 100% { transform: translateX(0); }
20% { transform: translateX(-6px); }
40% { transform: translateX(6px); }
60% { transform: translateX(-4px); }
80% { transform: translateX(4px); }
}
/* animacije flash/inline poruka (keyframes iznad) */
.poruka-animacija { animation: slideDown 0.3s ease forwards; }
.greska-animacija { animation: shake 0.4s ease; }
/* backwards (ne both): drži početni frame tokom stagger-delay-a da nema treperenja,
ali NE zaključava krajnji transform — pa .kartica:hover lift radi i na .animiraj karticama */
.animiraj {
animation: fadeInUp 0.2s ease backwards;
}
/* kartice ne animiramo po defaultu — animacija je samo na redovima tabela */
.kartica.animiraj {
animation: none;
}
/* korisnikova preferencija animacije: body[data-animacija] nadjačava podrazumevano.
Kad korisnik odabere stil, animiraju se i redovi tabela i mobilne kartice. */
[data-animacija="bez"] .animiraj,
[data-animacija="bez"] .tabela tbody tr,
[data-animacija="bez"] .kartica.animiraj { animation: none; }
[data-animacija="fadeInUp"] .animiraj,
[data-animacija="fadeInUp"] .tabela tbody tr,
[data-animacija="fadeInUp"] .kartica.animiraj { animation: fadeInUp 0.2s ease backwards; }
[data-animacija="fadeIn"] .animiraj,
[data-animacija="fadeIn"] .tabela tbody tr,
[data-animacija="fadeIn"] .kartica.animiraj { animation: fadeIn 0.2s ease backwards; }
[data-animacija="scaleIn"] .animiraj,
[data-animacija="scaleIn"] .tabela tbody tr,
[data-animacija="scaleIn"] .kartica.animiraj { animation: scaleIn 0.2s ease backwards; }
[data-animacija="slideLeft"] .animiraj,
[data-animacija="slideLeft"] .tabela tbody tr,
[data-animacija="slideLeft"] .kartica.animiraj { animation: slideLeft 0.2s ease backwards; }
/* Stepenasta (stagger) animacija redova u svim listama — JEDNO mesto za sve tabele.
Animacija se primenjuje direktno na <tr> u .tabela, bez potrebe za .animiraj klasom.
Mora biti u main.css: HTMX navigacija (hx-select) odbacuje <head>, pa
stilovi iz page <style> blokova ne bi važili tokom navigacije. */
.tabela tbody tr {
animation: fadeInUp 0.2s ease backwards;
}
.tabela tbody tr:nth-child(1) { animation-delay: 0.04s; }
.tabela tbody tr:nth-child(2) { animation-delay: 0.08s; }
.tabela tbody tr:nth-child(3) { animation-delay: 0.12s; }
.tabela tbody tr:nth-child(4) { animation-delay: 0.16s; }
.tabela tbody tr:nth-child(5) { animation-delay: 0.20s; }
.tabela tbody tr:nth-child(6) { animation-delay: 0.24s; }
.tabela tbody tr:nth-child(7) { animation-delay: 0.28s; }
.tabela tbody tr:nth-child(8) { animation-delay: 0.32s; }
.tabela tbody tr:nth-child(9) { animation-delay: 0.36s; }
.tabela tbody tr:nth-child(10) { animation-delay: 0.40s; }
/* Stagger mobilnih lista-kartica (parnjak gornjeg za tabele). Pogađa kartice
unutar bilo kog .X-kartice kontejnera; ostali tipovi kartica (detalji/forma/
dashboard) imaju svoj stagger po strani. Menjaš na JEDNOM mestu. */
[class*="-kartice"] > .animiraj:nth-child(1) { animation-delay: 0.04s; }
[class*="-kartice"] > .animiraj:nth-child(2) { animation-delay: 0.10s; }
[class*="-kartice"] > .animiraj:nth-child(3) { animation-delay: 0.16s; }
[class*="-kartice"] > .animiraj:nth-child(4) { animation-delay: 0.22s; }
[class*="-kartice"] > .animiraj:nth-child(5) { animation-delay: 0.28s; }
/* Stagger naslaganih .kartica.animiraj na stranicama podešavanja/profila — JEDNO mesto.
Descendant selektor (razmak, ne >): nth-child se računa po neposrednom roditelju kao i
ranije, a .stranica-stack na wrapperu sprečava da pravilo curi na liste/forme drugih
strana. Mora u main.css jer HTMX navigacija odbacuje <head>. Menjaš na JEDNOM mestu. */
.stranica-stack .animiraj:nth-child(1) { animation-delay: 0.10s; }
.stranica-stack .animiraj:nth-child(2) { animation-delay: 0.16s; }
.stranica-stack .animiraj:nth-child(3) { animation-delay: 0.22s; }
.stranica-stack .animiraj:nth-child(4) { animation-delay: 0.28s; }
.stranica-stack .animiraj:nth-child(5) { animation-delay: 0.34s; }
/* Dashboard stat kartice — delay da ne krenemo pre nego što view-transition završi */
.dash-stat.animiraj:nth-child(1) { animation-delay: 0.08s; }
.dash-stat.animiraj:nth-child(2) { animation-delay: 0.13s; }
.dash-stat.animiraj:nth-child(3) { animation-delay: 0.18s; }
.dash-stat.animiraj:nth-child(4) { animation-delay: 0.23s; }
.dash-stat.animiraj:nth-child(5) { animation-delay: 0.28s; }
/* kartica koja je ujedno i link — zamena za inline text-decoration/display/cursor */
.kartica-link { text-decoration: none; display: block; cursor: pointer; }
/* ikona wrapper na stat karticama dashboarda */
.dash-ikona {
width: 36px; height: 36px; border-radius: 8px;
display: flex; align-items: center; justify-content: center;
margin-bottom: 10px;
transition: filter 0.25s;
}
.dash-ikona-plava { background: #eff2ff; }
.dash-ikona-zelena { background: #f0fdf4; }
.dash-ikona-narandzasta { background: #fff7ed; }
.dash-ikona-crvena { background: #fef2f2; }
.dash-ikona-nebo { background: #f0f9ff; }
/* Bedž statusa servisnog naloga — JEDNO mesto za izgled i boje statusa (lista i detalji).
Mora biti u main.css: HTMX navigacija odbacuje <head>, pa page <style> ne bi važio. */
.status-badge { display: inline-block; padding: 3px 10px; border-radius: 20px; font-size: 12px; font-weight: 500; white-space: nowrap; }
.status-primljeno { background: rgba(148,163,184,0.15); color: #94a3b8; }
.status-dijagnostika { background: rgba(59,130,246,0.15); color: #3b82f6; }
.status-ceka { background: rgba(249,115,22,0.15); color: #f97316; }
.status-popravka { background: rgba(234,179,8,0.15); color: #ca8a04; }
.status-zavrseno { background: rgba(34,197,94,0.15); color: #16a34a; }
.status-preuzeto { background: rgba(21,128,61,0.15); color: #15803d; }
/* responsive prikaz — tabela/kartice za sve liste (mora biti u main.css jer HTMX ne učitava head ponovo) */
.nabavke-kartice { display: none; flex-direction: column; gap: 12px; }
.dobavljaci-kartice { display: none; flex-direction: column; gap: 12px; }
.klijenti-kartice { display: none; flex-direction: column; gap: 12px; }
.magacin-kartice { display: none; flex-direction: column; gap: 12px; }
.servis-kartice { display: none; flex-direction: column; gap: 12px; }
.prodaja-kartice { display: none; flex-direction: column; gap: 12px; }
.pod-kartice { display: none; flex-direction: column; gap: 12px; }
.stavke-kartice { display: none; flex-direction: column; gap: 10px; }
@media (max-width: 768px) {
.nabavke-tabela { display: none; } .nabavke-kartice { display: flex; }
.dobavljaci-tabela { display: none; } .dobavljaci-kartice { display: flex; }
.klijenti-tabela { display: none; } .klijenti-kartice { display: flex; }
.magacin-tabela { display: none; } .magacin-kartice { display: flex; }
.servis-tabela { display: none; } .servis-kartice { display: flex; }
.prodaja-tabela { display: none; } .prodaja-kartice { display: flex; }
.pod-tabela { display: none; } .pod-kartice { display: flex; }
.stavke-tabela-wrapper { display: none; } .stavke-kartice { display: flex; }
.forma-grid-4 { grid-template-columns: 1fr 1fr !important; }
}
/* podešavanja — raspored pozadine */
.app-poz-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 20px; align-items: start; }
@media (max-width: 680px) { .app-poz-grid { grid-template-columns: 1fr; } }
/* gornja traka magacina — responsive */
.magacin-traka {
display: flex;
align-items: center;
gap: 12px;
flex-wrap: wrap;
}
.magacin-traka form {
display: flex;
align-items: center;
gap: 8px;
flex: 1;
min-width: 200px;
flex-wrap: wrap;
}
/* flash toast — jednokratna poruka u gornjem desnom uglu */
@keyframes flashUlaz {
from { opacity: 0; transform: translateX(20px); }
to { opacity: 1; transform: translateX(0); }
}
@keyframes flashIzlaz {
from { opacity: 1; transform: translateX(0); }
to { opacity: 0; transform: translateX(20px); }
}
.flash-toast {
position: fixed;
top: 20px;
right: 20px;
z-index: 9999;
display: flex;
align-items: center;
gap: 10px;
padding: 12px 16px;
border-radius: 10px;
font-size: 14px;
max-width: 380px;
box-shadow: 0 4px 16px rgba(0,0,0,0.12);
animation: flashUlaz 0.3s ease forwards;
}
.flash-toast.flash-izlaz {
animation: flashIzlaz 0.35s ease forwards;
}
.flash-toast.flash-uspeh {
background: #f0fdf4;
color: #15803d;
border: 0.5px solid #bbf7d0;
}
.flash-toast.flash-greska {
background: #fef2f2;
color: #dc2626;
border: 0.5px solid #fecaca;
}
.flash-ikona {
font-weight: 700;
font-size: 15px;
flex-shrink: 0;
}
.flash-tekst {
flex: 1;
line-height: 1.4;
}
.flash-zatvori {
background: none;
border: none;
cursor: pointer;
font-size: 18px;
line-height: 1;
color: inherit;
opacity: 0.6;
padding: 0 0 0 4px;
flex-shrink: 0;
}
.flash-zatvori:hover { opacity: 1; }
@media (max-width: 480px) {
.flash-toast {
top: auto;
bottom: 20px;
right: 12px;
left: 12px;
max-width: none;
}
}
/* dropdown meni mora biti iznad svih stacking context-a koje glass efekt kreira */
#avatar-meni {
z-index: 9999 !important;
position: relative;
}
/* sprečava treperenje pozadine pri navigaciji između stranica (samo browseri koji podržavaju) */
@supports (view-transition-name: none) {
@view-transition {
navigation: auto;
}
}
/* iOS-style toggle switch (.toggl > input[type=checkbox] + .toggl-klizac) */
.toggl { position:relative; display:inline-block; width:44px; height:26px; flex-shrink:0; }
.toggl input { opacity:0; width:0; height:0; position:absolute; }
.toggl-klizac {
position:absolute; inset:0; border-radius:26px; cursor:pointer;
background:var(--ivica); transition:background 0.2s;
}
.toggl-klizac::before {
content:''; position:absolute;
width:20px; height:20px; border-radius:50%;
left:3px; top:3px;
background:#fff; box-shadow:0 1px 3px rgba(0,0,0,0.25);
transition:transform 0.2s;
}
.toggl input:checked + .toggl-klizac { background:var(--sb-akcent); }
.toggl input:checked + .toggl-klizac::before { transform:translateX(18px); }
/* pomoćne klase (ranije iz Tailwind-a, sada lokalno da ne zavisimo od CDN-a) */
.grid { display: grid; }
.gap-3 { gap: 12px; }
.gap-4 { gap: 16px; }
.mb-6 { margin-bottom: 24px; }
/* broj kolona u grid rasporedu — bazne (mobilni-first) vrednosti */
.grid-cols-1 { grid-template-columns: repeat(1, minmax(0, 1fr)); }
.grid-cols-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
/* responsive varijante — primenjuju se od 768px naviše (Tailwind „md") */
@media (min-width: 768px) {
.md\:grid-cols-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.md\:grid-cols-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.md\:grid-cols-5 { grid-template-columns: repeat(5, minmax(0, 1fr)); }
}