/* Pregled, Tenderi, Detalji tendera (R1 track core), and the shared list
   behaviour of every list screen. Tokens only: no hex here. */

/* The filter bar (partials/filters.html), its phone layout and .pill-empty
   are shared: components.css, block "filters". */

/* ---- list region: heading, actions, the moment of a refresh ---- */
.list-head { display: flex; align-items: center; justify-content: space-between; gap: var(--space-3); flex-wrap: wrap; margin-bottom: var(--space-2); }
.list-title { font: 600 15px/22px var(--font-sans); }
.list-count { color: var(--ink-muted); font-weight: 400; font-variant-numeric: tabular-nums; }
.list-actions { display: flex; gap: var(--space-2); flex-wrap: wrap; justify-content: flex-end; }
/* "Excel sadrži prvih N od M redova" under the Excel button of any list
   whose workbook is cut at the cap; the three bars all wrap, so a full-width
   basis drops it onto its own line. Defined once, used by all three. */
.list-cap { flex: 0 0 100%; text-align: right; margin: 4px 0 0; }
/* The moment of a refresh. The region used to be dimmed to opacity 0.55,
   which is the one loading state in the product and it pushed the whole list
   under AA while the reader looked at it: composited over the tokens, body
   text fell 15,70:1 -> 3,66:1, secondary text 5,81:1 -> 2,31:1 and links to
   3,15:1, and what it made unreadable was the PREVIOUS query's rows and the
   previous count, with nothing saying they were stale. Raising the opacity
   does not rescue it either - at 0.85 --ink-muted still measures 4,16:1 on
   --surface-200 and 3,95:1 on --surface-100. So the text keeps its contrast
   and the staleness is marked instead: a 2 px bar along the top of the
   region, and the count - the one number that is about to change - greyed. */
[data-list-region] { position: relative; }
[data-list-region][aria-busy="true"]::before,
[data-list-region][aria-busy="true"]::after { content: ""; position: absolute; top: 0; height: 2px; border-radius: 1px; }
[data-list-region][aria-busy="true"]::before { left: 0; right: 0; background: var(--brand-soft); }
/* left: 0 and not the animation's own start, so that the segment is on the
   page even where prefers-reduced-motion turns the animation off. */
[data-list-region][aria-busy="true"]::after { left: 0; width: 30%; background: var(--brand); animation: list-busy 1.1s linear infinite; }
@keyframes list-busy { from { left: -30%; } to { left: 100%; } }
[data-list-region][aria-busy="true"] .list-count { color: var(--disabled-ink-strong); }
/* What a failed refresh looks like: the earlier rows stay where they are and
   this sits above them. app.js builds it and gives it role="alert". */
.list-retry { display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: var(--space-2); background: var(--danger-soft); color: var(--danger-ink); border-radius: var(--radius-md); padding: 10px 14px; margin-bottom: var(--space-3); font: var(--text-body-small); }

/* ---- a table under its own heading, as one card (Pregled, lots) ---- */
.card-list { background: var(--surface-200); border: 1px solid var(--border); border-radius: var(--radius-md); overflow: hidden; margin-bottom: var(--space-4); }
.card-list-head { display: flex; align-items: center; justify-content: space-between; gap: var(--space-3); padding: 16px 20px; border-bottom: 1px solid var(--border); }
.card-list-head h2 { font: 600 15px/22px var(--font-sans); }
/* "Vidi sve" was 65x18. The 24 px floor is the target; the negative block
   margins give the flex row back the 6 px it would otherwise grow by, so
   the card head keeps its height and the link keeps its place. */
.card-list-more { display: inline-flex; align-items: center; min-height: 24px; margin: -3px 0; font: 600 13px/18px var(--font-sans); white-space: nowrap; }
.card-list .table-wrap { border: 0; border-radius: 0; margin: 0; }
.card-list .empty { border: 0; margin: 0; }
@media (max-width: 719px) {
  /* rows are cards of their own here; the outer card would only nest borders */
  .card-list { background: transparent; border: 0; overflow: visible; }
  .card-list-head { padding: 0 0 var(--space-2); border-bottom: 0; }
  .card-list .empty { border: 1px dashed var(--border); }
}

/* ---- Pregled ---- */
.dash-updated { margin-top: 10px; }
.kpi-linked { position: relative; }
.kpi-linked:hover { border-color: var(--brand); }
.kpi-value a { color: inherit; }
.kpi-value a:hover { text-decoration: none; }
.kpi-value a::after { content: ""; position: absolute; inset: 0; border-radius: var(--radius-md); }

/* ---- Detalji tendera ---- */
.detail-top { margin-bottom: var(--space-5); }
.page-tender .detail-inst { margin-bottom: 0; }
.detail-inst a { color: inherit; }
.detail-head h1 { overflow-wrap: anywhere; }
.meta-card { margin-bottom: var(--space-4); }
.meta-card .meta { margin: 0; }
.meta dt, .meta dd { margin: 0; }
.meta-oblast { display: block; }
.meta-oblast + .meta-oblast { margin-top: 6px; }
/* An oblast label is one word: never break it letter by letter
   (.meta-value carries overflow-wrap: anywhere for long report numbers). */
.meta-oblast .oblast { color: var(--ink); overflow-wrap: normal; }
/* The rail now starts at 1200 px, where the meta grid has 548 px and three
   columns read; the two-column band this rule held open (1024-1199 px, a
   370 px grid) no longer exists. */
.meta-oblast .caption { display: block; margin-left: 14px; }
.meta-sub { display: block; }
.meta-wide { margin-top: var(--space-4); padding-top: var(--space-3); border-top: 1px solid var(--border); }
.supplier-list { list-style: none; padding: 0; margin: 0 0 4px; font: 600 15px/22px var(--font-sans); }
.meta-note { margin-top: var(--space-3); font: var(--text-body-small); color: var(--ink-muted); }
.card-h { font: 600 15px/22px var(--font-sans); margin-bottom: 12px; }
.card-desc { margin-bottom: var(--space-4); }
.detail-desc { overflow-wrap: anywhere; }
.detail-desc p + p { margin-top: var(--space-2); }
.detail-desc .label { font: var(--text-label); }

/* right rail */
label.card-title { display: block; }
.card-track .help { margin: 0 0 12px; font: var(--text-label); font-weight: 400; }
.card-note .textarea { font-size: 13px; line-height: 18px; min-height: 96px; }
.save-btn { margin-top: var(--space-2); }
html.js .save-btn { display: none; }
html.js form.is-failed .save-btn { display: inline-flex; }
.detail-rail .autosave:empty { min-height: 0; margin: 0; }
.track-by { margin-top: 6px; }
/* No nowrap: a lot title that cannot break drove the table's min-content
   width to 579 px, which the rail column could not give it. Wrapping a long
   lot name costs a line; a sideways scroll cost 36 % of the table. */
table.lots td.c-title { min-width: 0; overflow-wrap: anywhere; }
/* Five columns in a 546 px rail-side column: the nowrap headers of
   components.css ("Prihvatljivih", "Raspon ponuda") held the table 16 px
   wider than the space it had. They may wrap; the figures may not. */
table.lots th { white-space: normal; }
table.lots .caption { display: block; }
.similar-list li + li { border-top: 1px solid var(--border); margin-top: 12px; padding-top: 12px; }
.similar-list a { display: block; font: var(--text-body-small); color: var(--ink); overflow-wrap: anywhere; }
.similar-meta { display: flex; align-items: baseline; justify-content: space-between; gap: var(--space-2); margin-top: 4px; font: var(--text-caption); color: var(--ink-muted); }

/* Under 1200 the rail is below the page, so the action the screen is for gets
   a link from under the title; at 1200 and above the card is already there.
   A link, not `order`: paint order is not tab order. */
.detail-jump { display: none; }
@media (max-width: 1199px) {
  .detail-jump { display: block; margin-top: var(--space-2); font: 600 13px/18px var(--font-sans); }
  /* 145x16 on the one screen where this link is the whole point. The
     negative block margins keep the line box at 18 px, so nothing below
     the title moves; only what a thumb can hit changes. */
  .detail-jump a { display: inline-flex; align-items: center; min-height: 24px; margin: -3px 0; }
}

/* ---- Tender list, Brifing layout ---------------------------------------
   The deadline is the status, so red is spent in exactly one place: the pill
   on a call that closes today or tomorrow. Everything else is ink at four
   weights. A screen where every row shouts says nothing, which is what the
   old column of "Ističe" badges did. */

.tn-gutter {
  width: 26px;
  padding-left: 0;
  padding-right: 0;
  text-align: center;
}

.tn-mark {
  font: var(--text-body);
  line-height: 1;
}

.tn-mark-new {
  color: var(--brand);
}

.tn-group-head {
  font: var(--text-label);
  text-transform: uppercase;
  letter-spacing: .06em;
  color: var(--ink-muted);
  text-align: left;
  padding: var(--space-4) var(--space-2) var(--space-1);
  border-bottom: 1px solid var(--border-firm);
}

.tn-group:first-of-type .tn-group-head {
  padding-top: var(--space-2);
}

.tn-group-n {
  margin-left: var(--space-2);
  font-variant-numeric: tabular-nums;
  color: var(--ink-faint);
  letter-spacing: 0;
}

.tn-table .c-title a {
  font: var(--text-title);
  color: var(--ink);
  text-decoration: none;
}

.tn-table .c-title a:hover {
  color: var(--brand);
  text-decoration: underline;
}

/* Institution, city, oblast on one quiet line instead of three columns. */
.tn-meta {
  display: block;
  font: var(--text-body-small);
  color: var(--ink-muted);
  margin-top: 2px;
}

.tn-meta > span + span::before {
  content: " · ";
  color: var(--ink-faint);
}

.tn-cat::before {
  content: ", ";
}

.tn-direct {
  color: var(--ink-faint);
}

.tn-table .c-value {
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  color: var(--ink);
}

/* A derived figure is never dressed as a value: tilde, secondary ink, and
   its provenance underneath. */
.tn-derived {
  color: var(--ink-muted);
}

.tn-vnote {
  display: block;
  font: var(--text-caption);
  color: var(--ink-faint);
  white-space: normal;
  max-width: 22ch;
  margin-left: auto;
}

.tn-table .c-rok {
  white-space: nowrap;
}

.tn-pill {
  display: inline-block;
  font: var(--text-label);
  color: var(--danger);
  background: var(--danger-soft);
  border-radius: var(--radius-pill);
  padding: 1px var(--space-2);
}

.tn-left {
  display: block;
  font: var(--text-body-small);
  color: var(--ink-muted);
}

.tn-u-soon .tn-left {
  color: var(--ink);
  font-weight: 600;
}

.tn-gone,
.tn-done {
  color: var(--ink-faint);
}

.tn-date {
  display: block;
  font: var(--text-caption);
  font-variant-numeric: tabular-nums;
  color: var(--ink-faint);
}

.tn-order {
  margin-top: var(--space-2);
  color: var(--ink-faint);
  max-width: 74ch;
}

@media (max-width: 720px) {
  /* The phone drops the oblast entirely and lets the value wrap: two values
     repeating down a card list is noise, and a figure that fits is not. */
  .tn-oblast {
    display: none;
  }

  .tn-vnote {
    margin-left: 0;
    max-width: none;
  }

  .tn-gutter {
    display: none;
  }
}

/* ---- Pregled, Brifing layout -------------------------------------------
   One paragraph instead of four tiles. A tile says there are nine of
   something and stops; a sentence carries the relation between the numbers,
   and the rows underneath say which nine. */

.dash-brief {
  font: var(--text-prose);
  color: var(--ink);
  max-width: 64ch;
  margin: 0 0 var(--space-5);
}

/* The one authored moment in the product: the app clearing its throat, once.
   The resting state is the visible one, so nothing depends on this running. */
@media (prefers-reduced-motion: no-preference) {
  .dash-brief {
    animation: brief-in var(--dur-brief) var(--ease-brief) both;
  }
}

@keyframes brief-in {
  from {
    opacity: 0;
    transform: translateY(7px);
    filter: blur(1.5px);
  }
  to {
    opacity: 1;
    transform: none;
    filter: none;
  }
}

.dash-section {
  margin-bottom: var(--space-6);
}

.dash-section-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-3);
  flex-wrap: wrap;
  border-bottom: 1px solid var(--border-firm);
  padding-bottom: var(--space-1);
}

.dash-section-head h2 {
  font: var(--text-h2);
  margin: 0;
}

.dash-more {
  font: var(--text-body-small);
  color: var(--brand);
  white-space: nowrap;
}

.dash-section-sub {
  font: var(--text-body-small);
  color: var(--ink-muted);
  margin: var(--space-1) 0 var(--space-2);
}

/* ---- Detalji: traka odluke ---------------------------------------------
   Three numbers, before any of the facts: what it is worth, when it closes,
   how it is being bought. The meta list below is the reference; this is the
   decision. */

.verdict {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--space-3);
  padding: var(--space-3) 0 var(--space-4);
  border-bottom: 1px solid var(--border-firm);
  margin-bottom: var(--space-4);
}

.verdict-cell {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}

.verdict-label {
  font: var(--text-label);
  text-transform: uppercase;
  letter-spacing: .06em;
  color: var(--ink-muted);
}

.verdict-value {
  font: var(--text-money);
  font-variant-numeric: tabular-nums;
  color: var(--ink);
}

/* A procedure name is words, not a figure, so it takes the reading voice and
   is allowed to wrap. */
.verdict-text {
  font: var(--text-body);
  overflow-wrap: anywhere;
}

.verdict-derived {
  color: var(--ink-muted);
}

.verdict-none {
  font: var(--text-body);
  color: var(--ink-faint);
}

.verdict-note {
  font: var(--text-caption);
  color: var(--ink-faint);
}

.verdict-now {
  color: var(--danger);
  font-weight: 600;
}

/* Two columns for the facts below, as the direction asks. */
.meta {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--space-3) var(--space-4);
}

.paid-amount {
  font-variant-numeric: tabular-nums;
  color: var(--ink);
}

.paid-when {
  color: var(--ink-faint);
}

.paid-when::before {
  content: " · ";
}

@media (max-width: 720px) {
  .verdict {
    grid-template-columns: 1fr;
    gap: var(--space-2h);
  }

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

/* "Novo objavljeno": the publication date, and the star that shortlists.
   The star is a real pressed state rather than two icons, so a screen reader
   says it and a keyboard reaches it; the outline version has to stay legible
   on its own, so it is drawn in muted ink, not in a lighter brand tint. */
.tn-pubcol,
.c-pub {
  white-space: nowrap;
}

.tn-pub {
  font-variant-numeric: tabular-nums;
}

.tn-starcol,
.c-star {
  width: 1%;
  text-align: center;
}

.tn-star {
  background: none;
  border: 0;
  padding: var(--space-1);
  cursor: pointer;
  line-height: 1;
  color: var(--ink-muted);
  border-radius: var(--radius-sm);
}

.tn-star .tn-star-glyph {
  font-size: 17px;
  opacity: 0.35;
}

.tn-star:hover .tn-star-glyph {
  opacity: 0.7;
}

.tn-star[aria-pressed="true"] {
  color: var(--warning);
}

.tn-star[aria-pressed="true"] .tn-star-glyph {
  opacity: 1;
}

.tn-star[disabled] {
  cursor: default;
  opacity: 0.5;
}

/* The gutter's second mark, and the buyer's own. Never colour alone: the
   glyph is drawn, the words are in the row for a screen reader, and both
   survive a monochrome print. */
.tn-mark-won {
  color: var(--brand);
  font-weight: 600;
}

.tn-own {
  margin-left: var(--space-1);
  font: var(--text-caption);
  color: var(--brand);
  border: 1px solid currentColor;
  border-radius: var(--radius-pill);
  padding: 0 var(--space-1);
  white-space: nowrap;
}

/* Izmjene objave: a short before/after list, read down the page rather than
   across a table - there are rarely more than a handful, and a table of three
   rows is a table nobody needed. */
.chg-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}

.chg {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--space-2);
  font: var(--text-body-small);
}

.chg-at {
  color: var(--ink-muted);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.chg-what {
  font-weight: 600;
}

.chg-move {
  display: inline-flex;
  align-items: baseline;
  gap: var(--space-1);
  flex-wrap: wrap;
}

.chg-old {
  color: var(--ink-muted);
  text-decoration: line-through;
}

.chg-arrow {
  color: var(--ink-muted);
}

.chg-new {
  font-weight: 600;
}

/* Žalbe i presude. Two kinds on one list, so the kind is a word on the row
   and not a colour: a decision of the review body and a judgment of the court
   are different things to a reader deciding whether to file. */
.res-kind {
  display: block;
  font: var(--text-caption);
  color: var(--ink-muted);
  text-transform: uppercase;
  letter-spacing: 0.03em;
}

.res-kind-presuda {
  color: var(--brand);
  font-weight: 600;
}

.res-number {
  font-weight: 500;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.res-flags,
.res-party {
  display: inline-flex;
  flex-wrap: wrap;
  gap: var(--space-1);
}

.res-flag {
  font: var(--text-caption);
  color: var(--ink-muted);
  border: 1px solid var(--border);
  border-radius: var(--radius-pill);
  padding: 0 var(--space-1);
  white-space: nowrap;
}

.res-party {
  margin-right: var(--space-1);
}

.res-party-un {
  color: var(--ink-muted);
  font-style: italic;
}

.res-table td {
  vertical-align: top;
}

/* "Prikazano 50 od 74": said under the block it applies to, quietly, because
   it is a caveat about the list and not a second subtitle for it. */
.dash-more-note {
  font: var(--text-caption);
  color: var(--ink-muted);
  margin-top: calc(-1 * var(--space-1));
  margin-bottom: var(--space-2);
}

/* The changes band. Red because it is the one thing on the screen that says
   "you may have missed something", and that claim has to be rare enough to
   stay believable - ui.changes_banner draws it only when a tender the reader
   follows has actually moved. A link, not a dialog: the useful action is to
   go and look. */
.chgband {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding: 10px var(--space-4);
  margin-bottom: var(--space-3);
  background: var(--danger-soft);
  color: var(--danger-ink);
  border: 1px solid var(--danger);
  border-radius: var(--radius-md);
  font: var(--text-body-small);
  text-decoration: none;
}

.chgband:hover {
  text-decoration: none;
  background: var(--surface-200);
}

.chgband-dot {
  width: 8px;
  height: 8px;
  flex: 0 0 auto;
  border-radius: var(--radius-pill);
  background: var(--danger);
}

.chgband-text {
  flex: 1 1 auto;
}

.chgband-go {
  font-weight: 600;
  white-space: nowrap;
}

.chg-groups {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}

.chg-note {
  margin-top: var(--space-3);
  color: var(--ink-muted);
}
