/* =========================================================
   Portal za članove — nadovezuje se na ../styles.css
   (boje, .btn, .ffield/.cform, .eyebrow, .h-lead, .ledger* su
   odatle — namerno se ne dupliraju ovde).

   Art direction: "živi godišnji izveštaj" — portal nije
   dashboard nego institucionalni dokument koji klub piše sam
   od sebe dok radi. Otud hijerarhija linija umesto kutija, i
   jedna fleksibilna tipografska porodica (Google Sans Flex) čija
   promenljiva debljina/optički razmer nosi hijerarhiju umesto
   mešanja više fontova.

   ZABRANJENO, potvrđeno u više krugova korisničkog fidbeka —
   ne uvoditi nijedno od ovoga ponovo, ni kao "tiši" alternativni
   tretman:
     - monospace bilo gde
     - VERZAL + razmaknuta slova na labelama
     - numerisane sekcije (01, 02...)
     - KURZIV kao poseban "glas" za labele — pokušano, odbijeno
       rečju "iskrivio" (isto što i "krive forme" kod Fraunces-a
       ranije — nagnuto pismo se čita kao isti AI-tik kao i
       verzal/mono, ne kao rešenje za njega)
   Font je prošao PET rundi (Archivo → IBM Plex Serif+Mono →
   IBM Plex Serif sam → Bodoni Moda → Google Sans Flex, korisnik
   ga je izričito imenovao). Ne menjati opet bez izričitog
   zahteva — vidi [[invklub-art-direction]] za punu istoriju.
   Sekundarni tekst (labele, footnote-ovi, hint-ovi) je prosto
   manji i sivkastiji, uspravan, sentence case. Nema posebnog
   tretmana — to je namerno. Traženje "pametnog sistema" za
   svaku sitnicu je samo po sebi template-tik.
   ========================================================= */

body{
  /* Jedna varijabilna porodica za oba glasa — Google Sans Flex nosi i
     wght (400-700) i opsz (6-144) ose iz jednog fajla, tačno isti pristup
     koji Google koristi u sopstvenim proizvodima umesto uparivanja
     serif+sans. --disp/--sans i dalje postoje kao odvojene promenljive
     (mnogo pravila u ovom fajlu ih već referencira po imenu), ali sad
     pokazuju na istu familiju — hijerarhiju nosi font-weight po pravilu,
     ne različit font. */
  --disp:'Google Sans Flex',system-ui,-apple-system,'Segoe UI',sans-serif;
  --sans:'Google Sans Flex',system-ui,-apple-system,'Segoe UI',sans-serif;
  /* Alias only, for shared classes inherited from ../styles.css that still
     reference var(--mono) — resolves to the plain upright sans, never a
     monospace or an italic. */
  --mono:var(--sans);
  font-family:var(--sans);
  /* Lets the browser pick the opsz instance per rendered size — crisp at
     both the huge .statement__figure numerals and small table text from
     the one variable file. Do NOT set font-variation-settings explicitly
     anywhere in this file: an explicit value overrides the automatic
     font-weight/font-optical-sizing → wght/opsz mapping per spec, which
     would silently freeze every heading at one weight regardless of the
     font-weight declared on it. (This bit us with the old Archivo 'wdth'
     neutralisation — removed for that exact reason.) */
  font-optical-sizing:auto;
  /* Figures line up in columns portal-wide, not only inside .statement. */
  font-variant-numeric:tabular-nums;
}
.portal-app .h-lead,
.portal-app h1,.portal-app h2,.portal-app h3,.portal-app h4{
  letter-spacing:-.01em;
}

.portal-app{
  min-height:100vh;
  display:flex;
  font-size:.95rem;
  line-height:1.55;
  background:var(--paper);
}

/* ---------- Sidebar ---------- */
.sidebar{
  width:252px;flex:none;
  background:var(--navy-900);
  color:var(--powder-soft);
  display:flex;flex-direction:column;justify-content:space-between;
  padding:22px 16px;
  position:sticky;top:0;height:100vh;
}
/* Masthead — rule underneath, the way a title block sits above a
   contents list. */
.sidebar__brand{
  display:flex;align-items:center;gap:10px;padding:2px 4px 18px;margin-bottom:8px;
  border-bottom:1px solid rgba(255,255,255,.14);
}
.sidebar__brand .ik-mark{width:34px;height:34px;flex:none;color:#fff}
.sidebar__brand .ik-mark .arc{stroke:var(--powder)}
.sidebar__brand span{font-family:var(--disp);font-weight:600;font-size:.95rem;line-height:1.2;color:#fff;letter-spacing:-.01em}
.sidebar__brand small{display:block;font-weight:400;font-size:.74rem;color:var(--powder);opacity:.65;margin-top:2px}

/* Nav as a contents page, not app chrome. The rounded active pill + filled
   background + left accent border it used to have is the Stripe/Linear
   signature — the single most template-looking thing on the screen. A
   contents list marks its current entry typographically instead: hairline
   rules between entries, and the active row stated in white with a rule
   under the label. The 01-06 folio numbers are gone with it — numbered
   nav is its own template tic (every Framer/Webflow theme ships it). */
.sidebar__nav{display:flex;flex-direction:column;gap:0}
.sidebar__nav a{
  display:flex;align-items:center;gap:11px;padding:11px 4px;
  color:var(--powder-soft);font-weight:500;font-size:.92rem;
  border-top:1px solid rgba(255,255,255,.07);
  transition:color .15s ease;
}
.sidebar__nav a:first-child{border-top:0}
.sidebar__nav a:hover{color:#fff}
.sidebar__nav a.is-active{color:#fff;font-weight:600}
/* Icons sit at half opacity like the old folio numbers did — full white only
   for the active page, so they read as wayfinding, not decoration. */
.sidebar__nav a svg{flex:none;opacity:.55;transition:opacity .15s ease}
.sidebar__nav a:hover svg{opacity:.85}
.sidebar__nav a.is-active svg{opacity:1}
.sidebar__nav-label{display:inline-block;padding-bottom:2px}
.sidebar__nav a.is-active .sidebar__nav-label{box-shadow:0 1px 0 var(--accent)}

.sidebar__bottom .sidebar__nav{margin-bottom:14px}
.sidebar__user{border-top:1px solid rgba(255,255,255,.14);padding-top:14px}
.sidebar__name{margin:0 0 3px;color:#fff;font-weight:600;font-size:.9rem;padding:0 4px;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.sidebar__role{margin:0 0 12px;padding:0 4px}
.sidebar__role .badge{
  background:none;padding:0;font-size:.82rem;color:var(--powder);opacity:.75;font-weight:400;
}
.sidebar__signout{
  background:none;border:0;color:var(--powder);opacity:.75;
  font-family:var(--sans);font-size:.84rem;font-weight:500;
  cursor:pointer;padding:4px;
}
.sidebar__signout:hover{opacity:1;color:#fff;text-decoration:underline}

/* ---------- Main content ---------- */
.portal-main{flex:1;min-width:0;padding:clamp(24px,3.5vw,44px)}
.portal-head{margin-bottom:26px}
.portal-head .eyebrow{margin-bottom:6px}
.portal-head .h-lead{font-size:clamp(1.5rem,2.4vw,2.05rem);margin:0 0 4px}
.portal-head p.lead-text{margin:0;color:var(--ink-soft);max-width:60ch}
.portal-head-row{display:flex;justify-content:space-between;align-items:flex-end;gap:16px;flex-wrap:wrap;margin-bottom:26px}
.portal-head-row .portal-head{margin-bottom:0}

/* ---------- Buttons ----------
   ../styles.css draws .btn as a full pill (border-radius:999px) with a
   soft coloured glow shadow and a hover lift (translateY) in --accent, a
   bright sky-blue (#1e77c4) that is also, near-verbatim, the default
   "primary" blue of Bootstrap and countless generated templates. Pill +
   glow + lift + that exact blue is a very recognisable generic AI/SaaS
   signature — and it would be the one floating, shadowed, off-palette
   element on a page that is otherwise flat ink-on-paper everywhere else
   (statement, cards, sidebar all sit flush with no shadow, and the only
   large fills anywhere are the navy sidebar/hero rules). Overridden here
   rather than edited in styles.css because that file is shared with the
   club's separate public marketing site, which nobody asked to change.

   Primary is now --navy-900, the same ink the sidebar and every
   institutional rule in .statement already use — a button should look
   like it belongs to this document, not like a CTA borrowed from a
   marketing landing page. Padding/font-size are both down a notch too:
   the old size read as a big marketing "buy now" button, oversized next
   to the restrained scale of everything around it (badges, status dots,
   table text). --r-sm matches the corner radius already used on
   task-card/cal-nav buttons elsewhere in this file.

   No selector scoping needed: portal.css only ever loads on portal pages
   and login.html, so a bare .btn override can't leak into the other site,
   and it correctly reaches buttons inside .modal too (which sits outside
   .portal-app in the DOM, so a scoped .portal-app .btn would have missed
   every button in every form). */
.btn{
  padding:.6em 1.1em;
  border-radius:var(--r-sm);
  font-size:.88rem;
  font-weight:600;
  box-shadow:none;
}
.btn:hover{
  transform:none;
}
.btn--primary{
  background:var(--navy-900);
  box-shadow:none;
}
.btn--primary:hover{
  background:var(--navy-700);
}

/* ---------- Badges ---------- */
.badge{
  display:inline-flex;align-items:center;padding:3px 9px;border-radius:5px;
  font-size:.76rem;font-weight:600;
  background:rgba(255,255,255,.1);color:var(--powder-soft);
}
.badge--light{background:var(--mist);color:var(--navy-800)}
.badge--gain{background:var(--gain-soft);color:var(--gain)}
.badge--warn{background:#fdecea;color:#b3261e}
.badge--neutral{background:var(--line);color:var(--ink-soft)}

/* Status dot — used for repeated status columns (tables, list rows) instead
   of another rounded pill; keeps badges for one-off counts/roles. */
.status-dot{display:inline-flex;align-items:center;gap:7px;font-size:.85rem;font-weight:600;color:var(--ink);white-space:nowrap}
.status-dot::before{content:"";width:7px;height:7px;border-radius:50%;background:var(--ink-soft);flex:none}
.status-dot--gain{color:var(--gain)}
.status-dot--gain::before{background:var(--gain)}
.status-dot--warn{color:#b3261e}
.status-dot--warn::before{background:#b3261e}
.status-dot--accent{color:var(--accent)}
.status-dot--accent::before{background:var(--accent)}
.status-dot--neutral{color:var(--ink-soft)}
.status-dot--neutral::before{background:var(--ink-soft)}

/* ---------- Ledger stat row (reuses .ledger-band/.ledger/.ledger__* look
   from the main site — see styles.css lines ~254-261) ---------- */
.portal-main .ledger-band{margin-bottom:28px;border:1px solid var(--line);border-radius:var(--r-md);padding-inline:20px;background:#fff}
.portal-main .ledger-band--navy{
  background:var(--navy-900);border-color:var(--navy-900);
}
.ledger-band--navy .ledger__num{color:#fff}
.ledger-band--navy .ledger__num .u{color:var(--powder)}
.ledger-band--navy .ledger__item--gain .ledger__num{color:var(--gain-bright)}
.ledger-band--navy .ledger__label{color:var(--powder)}
.portal-main .ledger{padding-block:20px;gap:10px clamp(28px,4vw,64px)}

/* ---------- Cards / panels ---------- */
.panel{background:#fff;border:1px solid var(--line);border-radius:var(--r-md);padding:22px}
.panel + .panel{margin-top:16px}
.panel h2,.panel h3{font-family:var(--disp);font-weight:700;color:var(--ink);margin:0 0 14px;font-size:1.05rem}
.panel__eyebrow{font-size:.85rem;color:var(--accent);margin:0 0 6px;font-weight:500}

/* ../styles.css sets .eyebrow in caps with wide tracking for the marketing
   site. Neutralise it here — the portal keeps that voice nowhere. */
.portal-app .eyebrow,.login-side .eyebrow{
  font-weight:500;text-transform:none;letter-spacing:0;font-size:.9rem;
}

.dash-grid{display:grid;grid-template-columns:1.4fr 1fr;gap:18px;align-items:start}
@media (max-width:920px){.dash-grid{grid-template-columns:1fr}}

/* =========================================================
   Statement / ledger system — the "financial statement, not
   admin dashboard" language. No boxes: hairline dividers,
   mono numbers, one dominant figure per screen. This is the
   default for summary/overview content; .panel is reserved for
   modals and small self-contained groupings (see above).
   ========================================================= */

/* =========================================================
   STATEMENT BLOCK — "živi godišnji izveštaj" art direction.
   The page hero on the dashboard + Finansije.

   Two voices, deliberately. Archivo carries the editorial /
   institutional side (folio line, the one big figure); --mono
   carries the machine / ledger side (labels, the reconciliation
   column). A statement is legible as a statement precisely
   because set text and tabular data speak differently — see the
   --mono note at the top of this file.
   ========================================================= */

.statement{
  display:grid;grid-template-columns:1.25fr .9fr;gap:clamp(26px,5vw,64px);
  padding-block:30px 26px;
  border-top:2px solid var(--navy-900);
  border-bottom:1px solid var(--line);
  margin-bottom:8px;
  /* Every figure in this block is a column figure. */
  font-variant-numeric:tabular-nums;
  font-feature-settings:'tnum' 1;
}
@media (max-width:820px){.statement{grid-template-columns:1fr;gap:24px}}

/* Statement heading — plain words, no folio number. */
.statement__folio{
  font-family:var(--disp);font-size:1.02rem;font-weight:600;
  color:var(--ink);margin:0 0 18px;display:flex;gap:14px;align-items:baseline;
}
.statement__folio span{
  margin-left:auto;font-weight:400;font-size:.88rem;color:var(--ink-soft);
}

.statement__figure{
  font-family:var(--disp);font-weight:600;
  font-size:clamp(2.5rem,5.4vw,4rem);line-height:.94;letter-spacing:-.025em;
  color:var(--ink);display:flex;align-items:baseline;gap:16px;flex-wrap:wrap;
}
.statement__figure.is-negative{color:#b3261e}
.statement__unit{
  font-family:var(--sans);font-size:.92rem;
  font-weight:500;color:var(--ink-soft);
}
.statement__note{margin:16px 0 0;color:var(--ink-soft);font-size:.9rem;max-width:42ch}
.statement__flag{
  display:inline-block;margin-top:16px;font-family:var(--sans);
  font-size:.88rem;font-weight:500;
  color:var(--accent);border-bottom:1px solid currentColor;padding-bottom:2px;
}
.statement__flag:hover{color:var(--navy-900)}

/* Reconciliation column. Accounting rule hierarchy does the work here:
   hairline = row, single heavy rule = subtotal, double rule = bottom line.
   That double rule above the total is the oldest convention in bookkeeping
   and it is what makes the block read as a document instead of a widget. */
.statement__calc{margin:0;align-self:end;font-family:var(--sans);font-size:.9rem}
.calc-row{display:flex;justify-content:space-between;align-items:baseline;gap:16px;padding-block:7px}
.calc-row dt{margin:0;color:var(--ink-soft)}
.calc-row dd{margin:0;color:var(--ink);font-weight:600}
.calc-row--sub{border-top:1px solid var(--ink);margin-top:5px;padding-top:9px}
.calc-row--sub dt{color:var(--ink)}
.calc-row--total{border-top:3px double var(--navy-900);margin-top:5px;padding-top:10px}
.calc-row--total dt{color:var(--ink);font-weight:600}
.calc-row--total dd{font-size:1.02rem;font-weight:700}
.calc-row--aside{margin-top:16px;padding-top:11px;border-top:1px dotted var(--line)}
.calc-row--aside dd{color:var(--gain)}
.calc-row__hint{
  display:block;font-size:.8rem;color:var(--ink-soft);opacity:.85;margin-top:2px;font-weight:400;
}

/* Annual target, demoted. It is a legitimate thing for a sponsorship-funded
   club to track, but it is an aspiration someone typed in — it belongs as a
   footnote under the real position, not as the headline figure. Lives on
   Finansije only; the dashboard drops it entirely. */
.statement__goal{
  margin-top:24px;padding-top:14px;border-top:1px solid var(--line);
  font-family:var(--sans);max-width:36ch;
}
.statement__goal-head{
  display:flex;justify-content:space-between;align-items:baseline;gap:12px;
  font-size:.88rem;color:var(--ink-soft);
}
.statement__goal-head b{color:var(--ink);font-weight:600}
.statement__goal-track{height:2px;background:var(--mist);margin:9px 0 7px}
.statement__goal-track span{display:block;height:100%;background:var(--navy-900)}
.statement__goal-foot{
  display:flex;justify-content:space-between;align-items:baseline;gap:12px;
  font-size:.84rem;color:var(--ink-soft);
}
.statement__goal-foot button{
  background:none;border:0;padding:0;font:inherit;color:var(--accent);
  cursor:pointer;font-weight:500;
}
.statement__goal-foot button:hover{text-decoration:underline}

.statement-section{padding-block:26px}
.statement-section + .statement-section{border-top:1px solid var(--line)}
.statement-section__head{display:flex;justify-content:space-between;align-items:baseline;margin-bottom:14px;gap:12px;flex-wrap:wrap}
.statement-section__head h2{font-family:var(--disp);font-weight:600;font-size:1.14rem;margin:0}
.statement-section__head .count{font-family:var(--sans);color:var(--ink-soft);font-size:.88rem}
.statement-section__eyebrow{font-size:.86rem;color:var(--accent);margin:0 0 4px;font-weight:500}

.statement-columns{display:grid;grid-template-columns:1fr 1fr;gap:40px}
@media (max-width:820px){.statement-columns{grid-template-columns:1fr}}

.ledger-rows{display:flex;flex-direction:column}
.ledger-row{
  display:flex;justify-content:space-between;align-items:center;gap:16px;
  padding-block:14px;border-top:1px solid var(--line);
}
.ledger-row:first-child{border-top:none}
a.ledger-row{color:inherit}
a.ledger-row:hover .ledger-row__name{color:var(--accent)}
.ledger-row__name{font-weight:700;color:var(--ink);font-size:.98rem;display:block;transition:color .15s ease}
.ledger-row__meta{color:var(--ink-soft);font-size:.82rem}
.ledger-row__value{text-align:right;font-family:var(--sans);flex:none}
.ledger-row__pct{font-weight:700;color:var(--ink);display:block}
.ledger-row__sub{color:var(--ink-soft);font-size:.78rem}
.ledger-row__bar{width:110px;height:3px;background:var(--mist);margin-top:6px}
.ledger-row__bar span{display:block;height:100%;background:var(--gain)}

/* Compact 2-column breakdown rows (sector composition, partner list on
   dashboard) — quieter than .ledger-row since it's secondary content. */
.mini-rows{display:flex;flex-direction:column}
.mini-row{display:flex;align-items:center;gap:14px;padding-block:10px;border-top:1px solid var(--line);font-size:.88rem}
.mini-row:first-child{border-top:none}
.mini-row__name{flex:none;width:140px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--ink)}
.mini-row__name--icon{display:flex;align-items:center;gap:6px}
.mini-row__name--icon svg{flex:none;width:15px;height:15px;color:var(--accent)}
.mini-row__name--icon span{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0}
.mini-row__bar{flex:1;height:3px;background:var(--mist)}
.mini-row__bar span{display:block;height:100%;background:var(--accent)}
.mini-row__count{font-family:var(--sans);font-weight:700;width:22px;text-align:right;flex:none}
.mini-row--split{justify-content:space-between}

/* ---------- Bar chart (sektor breakdown) ---------- */
.barchart{display:flex;flex-direction:column;gap:11px}
.barchart__row{display:grid;grid-template-columns:120px 1fr 30px;align-items:center;gap:10px;font-size:.85rem}
.barchart__label{color:var(--ink-soft);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.barchart__track{display:block;background:var(--mist);height:6px;overflow:hidden}
.barchart__fill{display:block;background:var(--accent);height:100%}
.barchart__count{font-family:var(--sans);color:var(--ink);font-weight:600;text-align:right}

/* ---------- Progress bar ---------- */
.progress{background:var(--mist);height:5px;overflow:hidden}
.progress__fill{background:var(--gain);height:100%;transition:width .3s ease}

/* ---------- List rows (upcoming deadlines, partner breakdown) ---------- */
.row-list{display:flex;flex-direction:column;gap:2px}
.row-item{
  display:flex;justify-content:space-between;align-items:center;gap:12px;
  padding:12px 2px;border-bottom:1px solid var(--line);
}
.row-item:last-child{border-bottom:none}
.row-item__title{font-weight:600;color:var(--ink);font-size:.92rem}
.row-item__meta{font-size:.78rem;color:var(--ink-soft);font-family:var(--sans)}
.row-item__delete{
  background:none;border:0;color:var(--ink-soft);opacity:.6;cursor:pointer;
  font-size:1.1rem;line-height:1;padding:2px;flex:none;
}
.row-item__delete:hover{opacity:1;color:#b3261e}

/* ---------- Tables ---------- */
.table-wrap{overflow-x:auto;border:1px solid var(--line);border-radius:var(--r-md);background:#fff}
table.dtable{width:100%;border-collapse:collapse;font-size:.88rem}
table.dtable th{
  text-align:left;padding:11px 16px;background:var(--mist);color:var(--ink-soft);
  font-weight:600;font-size:.8rem;
  white-space:nowrap;
}
table.dtable td{padding:12px 16px;border-top:1px solid var(--line);vertical-align:middle}
table.dtable tbody tr:hover{background:var(--paper)}
table.dtable td.num{text-align:right}

/* ---------- Filters bar ---------- */
.filters{display:flex;flex-wrap:wrap;gap:10px;margin-bottom:18px}
.filters input[type="text"],.filters input[type="search"],.filters select{
  border:1.5px solid var(--line);border-radius:var(--r-sm);padding:9px 12px;
  font:inherit;color:var(--ink);background:#fff;
}
.filters input:focus,.filters select:focus{outline:none;border-color:var(--accent)}

/* ---------- Tags (skills / interests) ---------- */
.tag-list{display:flex;flex-wrap:wrap;gap:6px}
.tag-pill{
  display:inline-flex;align-items:center;gap:6px;padding:4px 10px;border-radius:999px;
  background:var(--mist);color:var(--navy-800);font-size:.78rem;font-weight:600;
}
.tag-pill--interest{background:#eef0fb;color:#3f4ba0}
.tag-pill button{background:none;border:0;color:inherit;opacity:.6;cursor:pointer;font-size:.9em;line-height:1;padding:0}
.tag-pill button:hover{opacity:1}
.tag-picker{display:flex;flex-wrap:wrap;gap:6px;margin-top:8px}
.tag-picker__option{
  border:1.5px solid var(--line);background:#fff;border-radius:999px;padding:4px 12px;
  font-size:.78rem;font-weight:600;color:var(--ink-soft);cursor:pointer;
}
.tag-picker__option.is-selected{border-color:var(--accent);background:var(--accent);color:#fff}
.tag-picker__option:disabled{cursor:default;opacity:.7}

/* ---------- Form fields ----------
   Portal-wide input style: label above (mono, uppercase — same voice as
   .eyebrow/.panel__eyebrow elsewhere), field itself is an underline, not a
   filled rounded box. Ties forms into the same hairline-divider language as
   the ledger rows instead of importing the marketing site's boxed .cform
   join-form look wholesale. One pattern for input/select/textarea — no
   floating-label mechanic, so there's no risk of the old select-overlay bug
   recurring on a future field. */
.field-label{display:flex;flex-direction:column;gap:6px;margin-bottom:18px}
.field-label > span{
  font-family:var(--sans);font-size:.86rem;
  color:var(--ink-soft);font-weight:500;
}
.field-label select,.field-label input,.field-label textarea{
  border:0;border-bottom:1.5px solid var(--line);border-radius:0;
  padding:6px 2px 9px;font:inherit;font-size:.95rem;color:var(--ink);
  background:transparent;width:100%;transition:border-color .15s ease;
}
.field-label textarea{resize:vertical;min-height:76px;padding-top:8px}
.field-label select{
  appearance:none;cursor:pointer;padding-right:20px;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%2348657c' stroke-width='2'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
  background-repeat:no-repeat;background-position:right 2px center;background-size:14px;
}
.field-label select:focus,.field-label input:focus,.field-label textarea:focus{
  outline:none;border-bottom-color:var(--accent);
}
.field-label select:disabled,.field-label input:disabled,.field-label textarea:disabled{
  color:var(--ink-soft);border-bottom-style:dotted;
}

/* ---------- Kanban-ish task list ---------- */
.task-columns{display:grid;grid-template-columns:repeat(3,1fr);gap:14px}
@media (max-width:760px){.task-columns{grid-template-columns:1fr}}
.task-col h4{margin:0 0 10px;font-size:.8rem;color:var(--ink-soft);font-weight:600}
.task-card{
  background:#fff;border:1px solid var(--line);border-radius:var(--r-sm);
  padding:12px 14px;margin-bottom:10px;
}
.task-card__title{font-weight:600;font-size:.88rem;color:var(--ink);margin:0 0 6px}
.task-card__meta{font-size:.76rem;color:var(--ink-soft);display:flex;justify-content:space-between;align-items:center;gap:8px}
.task-card select{font-size:.76rem;border:1px solid var(--line);border-radius:6px;padding:4px 6px;background:#fff;width:100%}

.member-chip{
  display:inline-flex;align-items:center;gap:6px;background:var(--mist);color:var(--navy-800);
  border-radius:999px;padding:4px 10px 4px 4px;font-size:.78rem;font-weight:600;
}
.member-chip__avatar{
  width:20px;height:20px;border-radius:50%;background:var(--accent);color:#fff;
  display:flex;align-items:center;justify-content:center;font-size:.66rem;font-weight:700;flex:none;
}
.partner-chip{
  display:inline-flex;align-items:center;gap:6px;background:var(--gain-soft);color:var(--gain);
  border-radius:999px;padding:5px 12px;font-size:.78rem;font-weight:600;
}

/* ---------- Label:value line — a lighter dt/dd pattern than .calc-row for
   use inside cards, no accounting rules. ---------- */
.kv-row{display:flex;justify-content:space-between;gap:10px;font-size:.85rem;padding:2px 0}
.kv-row dt{margin:0;color:var(--ink-soft)}
.kv-row dd{margin:0;color:var(--ink);font-weight:600;text-align:right}

/* ---------- Member boxes (Baza članova) — fourth iteration, chosen by the
   user from a side-by-side against a flat hairline-row list.

   History worth keeping, because each step was rejected for a *different*
   reason and it's easy to re-introduce an old fault: (1) a full-width
   table — every member forced into one row shape, "nepregledno"; (2) big
   rounded cards with pastel avatar circles and pill badges — the default
   "user card" of every UI kit (Notion/Linear/shadcn/Figma community),
   generic regardless of colour, and mostly empty once grouping moved the
   sector name up to the heading; (3) flat hairline rows — solved density
   but, inside a .portal-main that has no max-width, put ~1500px between a
   person and their own label and read as an undifferentiated bold field.

   This version keeps the *containment* of (2) — one member = one bounded
   object the eye can separate without effort — while stripping what made
   it generic: radius drops 14px -> 6px, padding 16px -> 9px/11px, no
   avatar, no pills, one bold weight per box. Small boxes also use the
   page width honestly: a six-person sector fills several columns instead
   of running as one thin ragged column down a 1900px screen. ---------- */
.member-boxes{
  display:grid;grid-template-columns:repeat(auto-fill,minmax(210px,1fr));
  gap:7px;align-items:start;margin-top:10px;
}
.member-box{
  background:#fff;border:1px solid var(--line);border-radius:6px;
  padding:9px 11px;cursor:pointer;
  display:flex;flex-direction:column;gap:2px;
  transition:border-color .15s ease,background .15s ease;
}
.member-box:hover{border-color:var(--accent);background:var(--paper)}
/* 600, not 700: the section heading above is already 700 at nearly the
   same size — two bold weights that close together gave the eye nothing
   to rank, which is what made the page read as "sve je boldovano".
   Heading leads (700), name follows (600), everything else is light.
   Wraps rather than ellipsizing — truncating a person's name is the one
   place in this app where the cut is never acceptable. */
.member-box__name{font-weight:600;color:var(--ink);font-size:.9rem;line-height:1.25;overflow-wrap:break-word}
.member-box__meta{
  display:flex;align-items:baseline;gap:8px;flex-wrap:wrap;
  font-size:.79rem;color:var(--ink-soft);
}
/* Scoped override, NOT an edit to .status-dot itself — that base class is
   shared with Partneri/Projekti/Finansije, where 600 is correct because it
   carries a whole column. Here it's a trailing footnote after a name. */
.member-box .status-dot{font-weight:400;font-size:.79rem}
.member-box .status-dot::before{width:5px;height:5px}

/* Members grouped by sector (directory reads by section instead of a
   shuffled list) — a heading + hairline rule, not a boxed .panel: the
   boxes below already carry their own borders, so wrapping the whole
   group in another bordered container would nest one box inside another
   for no reason. The sector icon sits here, once per section, instead of
   being repeated on every member in it.

   Capped measure, following .notes-sheet's existing precedent: .portal-main
   has no max-width, so on a wide monitor the heading's rule ran past
   1700px with two words under it. The cap also keeps the box grid to a
   sane 3-4 columns instead of smearing six people across a 1900px row. */
.member-section{max-width:74ch}
.member-section + .member-section{margin-top:30px}
.member-section__head{
  display:flex;justify-content:space-between;align-items:center;gap:12px;
  margin-bottom:2px;padding-bottom:9px;border-bottom:1px solid var(--line);
}
.member-section__head h3{
  margin:0;display:flex;align-items:center;gap:9px;
  font-family:var(--disp);font-weight:700;font-size:1.05rem;color:var(--ink);
}
.member-section__head h3 svg{flex:none;width:21px;height:21px;color:var(--accent)}
.member-section__count{font-size:.85rem;color:var(--ink-soft);font-variant-numeric:tabular-nums}

/* ---------- Partner cards (Partneri) — same "cards over a wide table"
   reasoning as members, but partners carry more heterogeneous data
   (pipeline stage, contact cadence, money), so the card is denser and
   grouped into hairline-divided blocks rather than one flat list. ---------- */
.partner-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(290px,1fr));gap:16px}
.partner-card{
  background:#fff;border:1px solid var(--line);border-radius:var(--r-md);
  padding:18px;cursor:pointer;transition:border-color .15s ease;
}
.partner-card:hover{border-color:var(--accent)}
.partner-card__name{font-weight:700;color:var(--ink);font-size:1rem;margin:0}

/* Pipeline — reuses the .progress bar's segmented-fill language rather than
   inventing a new "CRM stepper" widget, so it reads as part of this system
   instead of an imported component. Neuspešno is a dead end, not a
   position on the forward pipeline (Lead → Kontaktiran → Pregovori →
   Partner), so it renders as a separate warn state instead of a 5th
   segment — a relationship that failed didn't "complete more steps" than
   one that's merely earlier in negotiation. */
.partner-pipeline{margin:12px 0 2px}
.partner-pipeline__track{display:flex;gap:3px}
.partner-pipeline__seg{flex:1;height:4px;border-radius:2px;background:var(--mist)}
.partner-pipeline__seg.is-filled{background:var(--accent)}
.partner-pipeline__stage{margin-top:7px;font-size:.82rem;font-weight:600;color:var(--accent)}
.partner-pipeline--lost .partner-pipeline__stage{color:#b3261e}

.partner-card__block{margin-top:13px;padding-top:12px;border-top:1px solid var(--line)}
.partner-card__stats{display:flex;gap:22px}
.partner-card__stat b{display:block;font-family:var(--disp);font-size:1.25rem;font-weight:600;color:var(--ink);line-height:1.1}
.partner-card__stat span{font-size:.76rem;color:var(--ink-soft)}
.partner-card__label{font-size:.78rem;color:var(--ink-soft);margin:0}
.partner-card__foot{margin-top:12px;font-size:.76rem;color:var(--ink-soft)}

/* ---------- Documents (Dokumenti, admin-only) ---------- */
.doc-group + .doc-group{margin-top:16px}
.doc-group__head{display:flex;justify-content:space-between;align-items:center;gap:12px;margin-bottom:2px}
.doc-group__head h3{margin:0}
/* align-items:flex-start, not center — .doc-row__meta wraps to two lines on
   narrow screens (extension badge + size + uploader + date is long), and
   centering against that variable height drifted the icon down to the
   middle of the whole row instead of sitting next to the filename. */
.doc-row{display:flex;align-items:flex-start;gap:12px;padding:11px 2px;border-top:1px solid var(--line)}
.doc-row:first-child{border-top:none}
.doc-row__icon{flex:none;color:var(--accent);margin-top:2px}
.doc-row__body{flex:1;min-width:0}
.doc-row__name{font-weight:600;color:var(--ink);font-size:.9rem;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.doc-row__meta{font-size:.78rem;color:var(--ink-soft);margin-top:3px;display:flex;align-items:center;flex-wrap:wrap;row-gap:4px}
.doc-row__ext{
  font-family:var(--sans);font-size:.66rem;font-weight:700;color:var(--ink-soft);
  background:var(--mist);border-radius:4px;padding:2px 5px;margin-right:6px;
}
.doc-row__actions{display:flex;gap:2px;flex:none;margin-top:1px}
.doc-row__actions button{
  background:none;border:0;color:var(--ink-soft);cursor:pointer;padding:6px;
  border-radius:6px;display:flex;transition:background .15s ease,color .15s ease;
}
.doc-row__actions button:hover{background:var(--mist);color:var(--accent)}
.doc-row__actions button.is-danger:hover{background:#fdecea;color:#b3261e}

/* ../styles.css sets .back-link in caps with tracking — reset it here. */
.portal-main .back-link{
  display:inline-block;margin-bottom:16px;color:var(--accent);
  font-family:var(--sans);font-weight:500;font-size:.9rem;
  text-transform:none;letter-spacing:0;
}
.back-link:hover{text-decoration:underline}

.detail-meta-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(140px,1fr));gap:16px;margin:16px 0 4px}
.detail-meta-item{border-top:2px solid var(--line);padding-top:8px}
.detail-meta-item__label{display:block;font-size:.78rem;color:var(--ink-soft);margin-bottom:3px}
.detail-meta-item__value{font-weight:700;color:var(--ink);font-family:var(--disp)}

/* ---------- Beleške (shared notes — everyone reads & writes) ----------
   View mode reads like a printed memo: comfortable measure (68ch caps line
   length), generous line-height, paragraphs from blank-line-separated
   blocks — not a raw dump of a textarea. Edit mode is a single plain
   textarea, no markdown/rich-text — "moze da se kuca tekst" was the whole
   ask, and a shared document anyone can touch is exactly the wrong place
   to add syntax someone has to learn. One shared row, last save wins,
   same as club_settings.annual_goal — no conflict UI. */
.notes-sheet{max-width:68ch}
.notes-sheet__head{display:flex;justify-content:space-between;align-items:center;gap:16px;margin-bottom:22px}
.notes-sheet__head .statement__folio{margin-bottom:0;flex:1;min-width:0}
.notes-edit-btn{
  flex:none;width:34px;height:34px;border-radius:var(--r-sm);
  border:1.5px solid var(--line);background:#fff;color:var(--ink-soft);
  display:flex;align-items:center;justify-content:center;cursor:pointer;
  transition:border-color .15s ease,color .15s ease;
}
.notes-edit-btn svg{width:16px;height:16px}
.notes-edit-btn:hover{border-color:var(--accent);color:var(--accent)}
.notes-sheet__body{font-size:1.05rem;line-height:1.75;color:var(--ink)}
.notes-sheet__body p{margin:0 0 1.2em}
.notes-sheet__body p:last-child{margin-bottom:0}
.notes-textarea{
  display:block;width:100%;min-height:380px;
  border:1.5px solid var(--line);border-radius:var(--r-md);
  padding:18px 20px;font:inherit;font-size:1rem;line-height:1.7;color:var(--ink);
  resize:vertical;transition:border-color .15s ease;
}
.notes-textarea:focus{outline:none;border-color:var(--accent)}

/* ---------- Modal ---------- */
.modal-backdrop{
  position:fixed;inset:0;background:rgba(8,36,59,.55);
  display:flex;align-items:flex-start;justify-content:center;
  padding:40px 20px;overflow-y:auto;z-index:100;
}
.modal-backdrop[hidden]{display:none}
.modal{
  background:#fff;border-radius:var(--r-lg);padding:clamp(22px,3vw,32px);
  max-width:600px;width:100%;box-shadow:var(--shadow);
}
.modal__head{display:flex;justify-content:space-between;align-items:flex-start;margin-bottom:18px;gap:12px}
.modal__head h3{font-family:var(--disp);font-weight:700;font-size:1.3rem}
.modal__close{background:none;border:0;font-size:1.3rem;line-height:1;color:var(--ink-soft);cursor:pointer;padding:4px}
.modal__actions{display:flex;gap:10px;margin-top:18px;flex-wrap:wrap}

/* ---------- Misc ---------- */
.text-muted{color:var(--ink-soft)}
.empty-state{padding:36px;text-align:center;color:var(--ink-soft)}
.btn--sm{padding:.55em 1.1em;font-size:.85rem}
.head-actions{display:flex;gap:8px;flex-wrap:wrap;align-items:center}
/* Destructive action: quiet at rest (it sits next to an everyday Edit
   button and shouldn't shout on every page view), unmistakably dangerous
   once the pointer is on it. Red is meaning here, not decoration.
   NOT scoped under .portal-app — .modal is rendered outside it, so a
   scoped rule silently missed the confirm button in the delete dialog,
   which is the one place the colour matters most. */
.btn--danger{
  background:#fff;border:1.5px solid var(--line);color:#b3261e;box-shadow:none;
}
.btn--danger:hover{background:#b3261e;border-color:#b3261e;color:#fff}
.field-grid{display:grid;grid-template-columns:1fr 1fr;gap:14px}
@media (max-width:520px){.field-grid{grid-template-columns:1fr}}
.readonly-field{padding:9px 0;color:var(--ink-soft);font-size:.9rem}

/* ---------- Calendar ----------
   Scoped to this page only: .dash-grid's default 1.4fr/1fr is right for
   the dashboard, but here it left the month grid at ~58% of the width, so
   every chip truncated to "Poče…" while the day-detail panel sat mostly
   empty. The grid is the page; the detail panel is a sidebar to it. */
[data-page="kalendar"] .dash-grid{grid-template-columns:2.5fr 1fr}
@media (max-width:1100px){[data-page="kalendar"] .dash-grid{grid-template-columns:1fr}}
.cal-head{display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;gap:8px 12px;margin-bottom:18px}
.cal-head__title{font-family:var(--disp);font-weight:700;font-size:1.3rem;color:var(--ink);text-align:center;min-width:11ch}
.cal-nav{display:flex;align-items:center;gap:4px}
.cal-nav--center{gap:14px}
.cal-nav button{
  border:1.5px solid var(--line);background:#fff;border-radius:var(--r-sm);
  width:34px;height:34px;font-size:1rem;cursor:pointer;color:var(--ink);
}
.cal-nav button:hover{border-color:var(--accent);color:var(--accent)}
/* The month is built as six independent week grids, not one 42-cell grid.
   That is what lets a range become a single bar spanning several columns
   (grid-column: <day> / span <n>) carrying its own name, instead of an
   anonymous 4px line repeated per cell plus a chip truncated to "Poče…".
   minmax(0,1fr), never a bare 1fr: `1fr` is minmax(auto,1fr) and `auto`
   will not shrink below min-content, so a single nowrap label used to drag
   one weekday column out to 336px while the rest collapsed to ~53px. */
.cal-grid{border:1px solid var(--line);border-radius:var(--r-md);overflow:hidden;background:#fff}
.cal-weekdays{display:grid;grid-template-columns:repeat(7,minmax(0,1fr));background:var(--mist)}
.cal-weekday{
  color:var(--ink-soft);font-weight:600;font-size:.78rem;text-align:center;padding:8px 4px;
  border-right:1px solid var(--line);
}
.cal-weekday:last-child{border-right:none}
/* Row 1 holds the date numbers; every further row is created only when a
   bar actually occupies it, so a week with nothing in it collapses to its
   minimum instead of reserving 96px per cell the way the old fixed-height
   cells did. */
.cal-week{
  display:grid;grid-template-columns:repeat(7,minmax(0,1fr));
  grid-template-rows:24px;grid-auto-rows:19px;
  row-gap:3px;padding-bottom:6px;min-height:58px;
  border-top:1px solid var(--line);
}
.cal-day{
  grid-row:1 / -1;padding:4px 6px;cursor:pointer;min-width:0;
  border-right:1px solid var(--line);
}
.cal-day:nth-child(7){border-right:none}
.cal-day:hover{background:var(--paper)}
.cal-day.is-outside{background:var(--paper)}
.cal-day.is-selected{background:var(--mist)}
.cal-day__num{font-size:.8rem;color:var(--ink);font-weight:600}
.cal-day.is-outside .cal-day__num{color:var(--ink-soft)}
.cal-day.is-today .cal-day__num{
  background:var(--accent);color:#fff;border-radius:50%;
  width:21px;height:21px;display:inline-flex;align-items:center;justify-content:center;
}

/* ---------- Calendar entries ----------
   A range used to tint its whole day cell. That could not survive two
   ranges overlapping: the fills stacked into a muddy third colour and you
   could not tell which range was which, or even how many there were. Each
   range is now one labelled bar in its own colour, so overlaps read as
   parallel named lines.

   Palette taken from the club logo's own bar-chart mark (blue, teal,
   muted red, violet) plus the periwinkle of its arcs and the navy of the
   wordmark, each darkened enough to carry white text at .7rem (all
   measured >=4.5:1). These six are identity colours — they carry no status
   meaning and must not be reused for gain/warn anywhere else. SPAN_COLORS
   in kalendar.js must equal the number of --c* rules here. */
.cal-ev{
  position:relative;z-index:1;align-self:center;
  height:19px;line-height:19px;padding:0 7px;
  font-size:.7rem;font-weight:500;color:#fff;background:var(--span-c);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
  text-decoration:none;display:block;cursor:pointer;
}
.cal-ev:hover{filter:brightness(1.08)}
/* Only the real ends are capped and inset. A segment continuing past the
   week edge stays flush so it reads as the same bar resuming on the next
   row rather than as a new one. */
.cal-ev.is-start{border-top-left-radius:4px;border-bottom-left-radius:4px;margin-left:3px}
.cal-ev.is-end{border-top-right-radius:4px;border-bottom-right-radius:4px;margin-right:3px}
.cal-ev--c0{--span-c:#1a6fb8}
.cal-ev--c1{--span-c:#2f7d72}
.cal-ev--c2{--span-c:#b0475a}
.cal-ev--c3{--span-c:#6f5f9c}
.cal-ev--c4{--span-c:#4a6d92}
.cal-ev--c5{--span-c:#0c3350}
/* Single-day items keep type colours — a task, a payment and a one-day
   deadline are different kinds of thing, unlike ranges which need to be
   told apart from each other. */
.cal-ev--task{--span-c:#1a6fb8}
.cal-ev--project{--span-c:#0f7a52}
.cal-ev--payment{--span-c:#7a4f00}
.cal-ev--event{--span-c:#a5231c}

.cal-when{font-size:.78rem;color:var(--ink-soft);white-space:nowrap;flex:none}
.cal-when.is-running{color:var(--gain);font-weight:600}

/* ---------- Mobile sidebar collapse ---------- */
@media (max-width:820px){
  .portal-app{flex-direction:column}
  .sidebar{
    width:100%;height:auto;position:sticky;top:0;z-index:40;
    flex-direction:row;align-items:center;padding:10px 16px;
  }
  /* Grid, not flex-wrap: the masthead and sign-out take row 1, both navs
     share row 2. Squeezing everything onto one row left the nav ~127px —
     barely one and a half entries, with the current page usually scrolled
     out of sight. minmax(0,1fr) is what lets the nav column actually shrink
     so its own overflow-x engages instead of pushing the row wider than the
     screen; a plain 1fr has a min-content floor and would not. */
  .sidebar{
    display:grid;grid-template-columns:minmax(0,1fr) auto;
    grid-template-areas:"brand user" "nav kal";
    align-items:center;gap:6px 12px;
  }
  .sidebar__top,.sidebar__bottom{display:contents}
  .sidebar__brand{grid-area:brand;margin-bottom:0;padding-bottom:0;border-bottom:0}
  .sidebar__user{grid-area:user;justify-self:end;border-top:0;padding-top:0;display:flex;align-items:center;gap:10px}
  .sidebar__nav{flex-direction:row;overflow-x:auto;margin-bottom:0}
  .sidebar__nav::-webkit-scrollbar{height:0}
  .sidebar__top .sidebar__nav{grid-area:nav;min-width:0}
  .sidebar__bottom .sidebar__nav{grid-area:kal;margin-bottom:0}
  /* The contents-page rules only read vertically — laid out in a row they
     would draw a line over each item instead of between them. */
  .sidebar__nav a{
    display:flex;align-items:center;gap:6px;
    border-top:0;padding:7px 10px;white-space:nowrap;
  }
  .sidebar__nav a:first-child{padding-left:0}
  .sidebar__nav a svg{width:16px;height:16px}
  .sidebar__name,.sidebar__role{display:none}
}

/* ---------- Print (Finansije "Odštampaj izveštaj") ---------- */
@media print{
  .sidebar,.filters,#newTransactionBtn,#exportCsvBtn,#printBtn,
  #editGoalBtn,.dash-grid,#pendingList,.modal-backdrop{display:none !important}
  .portal-main{padding:0}
  .panel{border:none;padding:0}
  table.dtable th{background:#fff;border-bottom:2px solid var(--ink)}
}
