/* ============================================================
   CUPS market 2.0 — theme override
   Sets the KI Admin theme to the blue ".nature" swatch.
   Keep this file linked LAST in <head>, after style.css.
   ============================================================ */

.app-wrapper {
  --primary: 19, 62, 135;
  --secondary: 24, 59, 78;
  /* Must match header.header-main's own height (style.css: height:65px,
     hardcoded there too — the vendor defines no variable for it). Used
     by the sidebar logo area below so its bottom edge lines up with the
     header's, in every sidebar layout. */
  --header-height: 65px;
}

/* style.css force-capitalizes every word in .main-title and in the dashboard
   sidebar's nav links (text-transform: capitalize) — fine for English
   titles/labels, wrong for Slovenian sentence case ("Podrobnosti o izdelku"
   should not become "Podrobnosti O Izdelku"; "Vprašanja in odgovori" should
   not become "Vprašanja In Odgovori"). We always write this text in correct
   Slovenian case ourselves, so just stop the theme from re-casing it. */
.main-title,
nav .app-nav .main-nav > li:not(.menu-title) > a {
  text-transform: none;
}

/* Sidebar active-link highlight (nav-active-highlight branch) — server-side
   marking (core.templatetags.nav_tags' {% nav_active %} tag, base.html/
   cups/base_cups.html) adds .active to the current page's <li>. The
   vendor's own li.active rule (style.css ~L12208) only ever fires INSIDE a
   nested submenu <ul> — our sidebar is flat (every item is li.no-sub, no
   submenus), so without this a top-level active item rendered identically
   to every other one. Deliberately understated: a light primary-tinted
   pill + primary text/icon (the icon recolors for free via inherited
   `color` — see the sidebar-icons rule below for why that still holds
   now that the icons are Phosphor `<i>` glyphs, not the svg this comment
   originally described), not the vendor's bold white-on-primary
   a[aria-expanded=true] treatment a few rules up — that one means "this
   submenu toggle is open", a different state from "this is the current
   page". li.no-sub in the selector keeps this from ever touching a nested
   submenu li.active (which has no .no-sub class, so it still gets only the
   vendor's own treatment). */
nav .app-nav .main-nav > li.no-sub.active > a {
  background-color: rgba(var(--primary), 0.1);
  color: rgba(var(--primary), 1);
}

/* Sidebar icons (sidebar-icons branch) — REPLACES the sidebar's old
   sprite-based <svg><use xlink:href="{% static %}..."></use></svg> icons,
   which silently rendered nothing anywhere (expanded, collapsed rail,
   mobile): Django's `static` template tag percent-encodes the whole
   string it's given, including a `#` meant as an SVG fragment identifier
   — {% static 'assets/svg/_sprite.svg#home' %} rendered as
   ".../_sprite.svg%23home", which the browser resolves as a request for a
   literal file of that name (which doesn't exist), not as
   "_sprite.svg" + fragment "#home". Confirmed by editing one <use>'s
   href live in the browser to the correct unencoded '#' and watching the
   icon appear. Separately, the sprite has no "people" icon at all
   (needed for "Zaposleni"), so even a path fix couldn't have covered
   every item. Switched to Phosphor duotone instead — already loaded on
   every page (templates/_phosphor_css.html, vendored CSS) and already the icon
   set this exact sidebar's own profile dropdown uses (ph-duotone
   ph-user-circle etc., a few lines up in the markup) — template markup
   is now a plain `<i class="ph-duotone ph-...">`, covering every
   sidebar concept precisely with no fragile path/fragment plumbing at
   all.

   font-size in REM (not em, and not the vendor svg rule's own unit
   choice, which doesn't apply to a font icon anyway) keeps the icon's
   rendered size independent of the link's own font-size — needed
   because the vendor's own collapsed-rail rule (style.css:
   `nav.semi-nav .main-nav li a{font-size:0}`) hides the label text
   exactly that way, and an em-sized icon would shrink to nothing right
   along with it. Mirrors the vendor's own three-tier svg sizing
   (expanded / collapsed-not-hovered / collapsed-and-hovered) exactly,
   just retargeted at `i` — same three selectors, same values, so the
   collapsed rail's hover-to-reveal-labels transition behaves identically
   to how it already did for every other icon on the page before this
   branch. Color is never set here: a duotone icon's two glyph layers
   (the vendored phosphor-duotone.css's own :before/:after rules, one at
   opacity:0.2, one at full opacity) both derive purely from the
   inherited `color`, the same way the old svg's `stroke="currentColor"`
   did, so the active-pill rule above recolors the icon for free with no
   extra selector needed. */
nav .app-nav .main-nav > li:not(.menu-title) > a i {
  font-size: 1.375rem;
  margin-right: 0.3rem;
}
.app-wrapper .semi-nav .app-nav .main-nav > li:not(.menu-title) > a i {
  margin: 0 auto;
}
.app-wrapper .semi-nav:hover .app-nav .main-nav > li a i {
  margin-right: 0.25rem;
  margin-left: 0;
}

/* templates/_messages.html (included from base.html) renders the inline-
   alerts wrapper directly in base.html's own body, not inside a <main> (each
   page extending base.html supplies its own) — so unlike normal page
   content, it doesn't automatically get the clearance that style.css's
   `main { padding-top: 4rem }` rule gives everything else below the fixed
   header (`header.header-main { position: fixed; height: 65px }`;
   .app-content's own padding-top of 45px alone is 20px short). Reuses that
   same 4rem, rather than inventing a new offset, so a message isn't hidden
   behind the header. base.html passes this class in via
   alerts_wrapper_class; cups/base_cups.html doesn't (its <main> already
   clears the header on its own). */
.app-messages {
  padding-top: 4rem;
  /* style.css narrows and centers <main> itself
     (`main { width: calc(100% - 62px); margin: 0 auto }`) so page content
     sits inset from .app-content's edges. .app-messages is a sibling of
     <main>, not inside it, so without this it stays full-width and reads
     wider than the content below it. Reuses main's own formula so the two
     line up exactly, rather than guessing a matching inset. */
  width: calc(100% - 62px);
  margin-left: auto;
  margin-right: auto;
}

/* When a message IS showing, the page's own <main> (a sibling of
   .app-messages — both are direct children of .app-content's inner wrapper)
   no longer needs its own 4rem of header-clearing padding-top: the message
   above it already cleared the header. Left as-is, both paddings stack,
   leaving an oversized gap between the message and the page's title. Cut
   main's padding-top down to a normal small gap in that case only — pages
   with no message keep the full 4rem clearance untouched. */
.app-messages ~ main {
  padding-top: 1.5rem;
}

/* Toasts (templates/_messages.html) float in the top-right corner, but
   Bootstrap's own `top-0` would place them flush against the viewport top —
   overlapping header.header-main (position: fixed, height: 65px) instead of
   sitting below it. Clear the header, plus a little breathing room, rather
   than pinning to the very top of the page. */
.app-toast-container {
  top: 70px;
}

/* Widen the toast itself (Bootstrap's own --bs-toast-max-width, default
   350px) — at the default width, even a short Slovenian message plus the
   close button wrapped to two lines, making the box tall enough to reach
   the content below the header on some pages. A bit more width keeps
   typical messages on one line, so the toast stays short — max-width:100%
   (already set by Bootstrap) still shrinks it to fit on narrow viewports
   regardless. Targets `.app-toast-container .toast` specifically (not just
   `.app-toast-container`) because Bootstrap's own `.toast` rule redeclares
   --bs-toast-max-width directly on itself — an ancestor override alone
   loses to that same-element redeclaration, so this needs the extra class
   in the selector to out-rank it. */
.app-toast-container .toast {
  --bs-toast-max-width: 420px;
}

/* templates/core/product_detail.html's breadcrumb: the active (last) crumb
   holds the product name, already hard-capped server-side to 50 chars
   (|truncatechars:50) — this adds CSS ellipsis on top so it also never
   visually wraps the breadcrumb line at any width, with a shorter cap on
   narrow/mobile viewports where even 50 chars can be too wide for one
   line. Scoped to `.product-breadcrumb` (added only on that one template),
   NOT the bare `.app-line-breadcrumbs` the theme also uses elsewhere (e.g.
   company_detail.html's own breadcrumb) — so this can't affect any other
   page's breadcrumb. */
.product-breadcrumb li.active a {
  display: inline-block;
  max-width: 320px;
  overflow: hidden;
  text-overflow: ellipsis;
  vertical-align: bottom;
  white-space: nowrap;
}

@media (max-width: 575.98px) {
  .product-breadcrumb li.active a {
    max-width: 160px;
  }
}

/* templates/core/_storefront_topbar.html — the slim member-only bar that
   REPLACES the storefront's own plain public navbar for a logged-in
   member (company_list.html/company_detail.html/product_detail.html).
   Deliberately reuses header.header-main's own fixed/height/background/
   box-shadow (style.css) for the "same as the dashboard topbar" look and
   the sticky-on-scroll behaviour — this override just drops the sidebar
   reservation, since there's no sidebar on these pages. Higher specificity
   (two classes) beats the bare `header.header-main` rule's padding-left. */
.storefront-header.header-main {
  padding-left: 1.5rem;
}

/* header.header-main is position:fixed (style.css) and occupies no space
   in normal flow — without this, page content would start underneath it.
   Applied to body (not a shared wrapper element, since these are 3
   independent standalone pages with no single common container) only
   when the member bar is actually rendered — see the has-storefront-header
   class each page's own <body> tag adds conditionally. The extra 1rem
   (beyond the header's own 65px) is just breathing room so the page's
   first section doesn't sit flush against the bar. */
body.has-storefront-header {
  padding-top: calc(65px + 1rem);
}

/* ============================================================
   CUPS market branding (step A3) — the real logo/favicon, sized by
   height since the source PNG's aspect ratio (~9:1) differs from the
   old KI Admin placeholder the theme's own width-based rules assumed.
   ============================================================ */

/* Storefront topbar and every standalone storefront/auth page's own
   plain navbar — all on light backgrounds, all the full wordmark. (The
   sidebar's own logo is NOT sized via this class — see the dedicated
   sidebar rules further down; the sidebar has a vendor width rule to
   contend with that these contexts don't.) */
.cups-logo {
  width: auto;
  height: 32px;
}

/* Storefront topbar's narrowest-width brand mark (Part 5,
   templates/core/_storefront_topbar.html) — swaps in for .cups-logo
   below the sm breakpoint so the wordmark doesn't compete with the
   icon-only nav buttons for space at ~375px. Square source image, sized
   to match .cups-logo's own height for visual parity. */
.cups-logo-icon {
  width: 32px;
  height: 32px;
}

/* Landing hero navbar + the entrance-page brand showcase panel — more
   prominent placements, a bit larger than the sidebar/header default.
   !important for the same reason as .cups-logo above — entrance.html's
   panel has its own competing `.signup-content span img{width:200px}`
   vendor rule. */
.cups-logo-lg {
  width: auto !important;
  height: 44px !important;
}

/* Entrance pages (login/signup, allauth/layouts/entrance.html): the
   white brand panel's curve comes from the box's `background-size:
   cover` image, so it moves LEFT as the box gets taller (the teacher
   signup form) or narrower (lg container). Measured worst case at the
   logo's height: ~278px from the box's left edge (teacher signup, 960px
   container), ~375px (1140px), ~479px (1320px). The logo is therefore
   left-aligned instead of centred and steps down per breakpoint so its
   right edge stays well clear of the curve (~9:1 aspect ratio kept). */
.image-content-box .signup-content img.cups-logo-lg {
  /* !important: the vendor's centring `margin: auto` rule wins otherwise. */
  margin-left: 0 !important;
  margin-right: 0 !important;
  height: 20px !important;
}
@media screen and (min-width: 1200px) {
  .image-content-box .signup-content img.cups-logo-lg {
    height: 28px !important;
  }
}
@media screen and (min-width: 1400px) {
  .image-content-box .signup-content img.cups-logo-lg {
    height: 36px !important;
  }
}

@media screen and (max-width: 991px) {
  /* Beats style.css's `.landing-wrapper .landing-navbar .logo img
     {width:160px !important}` mobile rule — needs !important too since
     specificity is otherwise equal and source order alone wouldn't be
     enough to rely on here. */
  .landing-wrapper .landing-navbar .logo img.cups-logo-lg {
    width: auto !important;
    height: 32px;
  }
}

/* style.css's `.landing-wrapper .landing-navbar .logo img
   {filter:brightness(1000)}` force-whitened the old color-only
   placeholder for use on the blue hero. cups-market-logo-white.png is
   already white, so that filter is no longer needed — worse, left on,
   it can fatten anti-aliased edge pixels into a faint halo. Overridden
   here rather than edited in style.css itself (vendor file; custom.css
   is the only override point per CLAUDE.md). */
.landing-wrapper .landing-navbar .logo img {
  filter: none;
}

/* Sidebar logo area (base.html / cups/base_cups.html) — the theme's own
   single <img>, unchanged; only its src/alt point at our asset.

   ALIGNMENT (step A3.3, §0): style.css never gives `.app-logo .logo` an
   explicit height — its rendered height just falls out of `padding:1rem`
   plus whatever the image's own height happens to be, which is why it
   drifted from header.header-main's fixed 65px (confirmed in real Chrome:
   the old ~20px-tall wordmark left it ~7px SHORTER than the header; the
   32px collapsed icon left it ~5px TALLER). Also, `.logo` is
   `display:inline-block` (Bootstrap's `.d-inline-block`, itself
   `!important`) sitting in normal flow next to text-sized content, which
   leaves a ~6.5px baseline/line-height gap below it regardless of its own
   height — confirmed by toggling `display` alone: switching only to
   `flex` (`.logo`'s own box height unchanged) did NOT close that gap,
   but `display:flex` DOES remove it (flex takes the box out of the
   inline/baseline formatting context entirely) — so both are needed
   together. `height: var(--header-height)` (defined above, alongside
   this file's other shared theme values) plus `align-items:center` give
   a single, explicit, always-correct box: nav-profile's border-top (the
   line that reads as "the logo area's bottom border") now lands exactly
   on header.header-main's own bottom edge in every sidebar layout —
   expanded, the >=1200px collapsed rail, and the 768-1199px auto rail
   (verified in real Chrome, all three, both shells; ±0px in each). */
nav .app-logo .logo {
  display: flex !important;
  align-items: center;
  height: var(--header-height);
}

/* Expanded wordmark: width:100% (beats style.css's own `nav .app-logo
   .logo img{width:180px}` on the identical selector — no !important
   needed, same specificity, this file loads after style.css) fills the
   logo box's full available width, with height:auto preserving the
   image's aspect ratio exactly (never distorts, never overflows — a
   percentage width can only ever shrink to fit). Renders close to the
   original KI-Admin logo's ~29px height (real-Chrome reference,
   `de21b1c` in a worktree) without hardcoding a height that would fight
   the aspect ratio if the logo box's width ever changes. */
nav .app-logo .logo img {
  width: 100%;
  height: auto;
}

/* Narrow rail: style.css's `.semi-nav:not(.horizontal-sidebar):not(:hover)
   .app-logo .logo{width:61px;overflow:hidden}` clips this same image to
   its leftmost 61px — the vendor's own wordmark has its icon mark at the
   LEFT edge, so that crop reveals it "for free"; ours has the cart icon
   at the RIGHT edge, so the same crop shows "CU" instead (confirmed in
   real Chrome at both the >=1200px manually-collapsed rail and the
   768-1199px rail script.js's own resize() applies automatically — both
   clip the same way). Swap the rendered image via `content:url()`
   instead of adding a second <img> — same element, same layout, just a
   different picture. 36px (up from an earlier 32px, itself accidentally
   clamped down to 29px by the old max-width:100% rule) roughly matches
   the original theme's own visible rail icon size (~29-45px, measured
   in the same worktree reference — the vendor never shrinks its image
   for the rail, just crops it, so "visible icon size" there is the
   image's full rendered height plus whatever crop-window width shows).
   justify-content:center centers the icon in the rail horizontally,
   replacing the wordmark's left-alignment; the container's own padding
   (style.css's `padding:1rem`) is zeroed on all sides so the full 61px
   width and the shared height are both available for centering a 36px
   icon comfortably (kept, it would only leave 33px of vertical room —
   too tight for 36px). !important on width/height: style.css's
   `nav.semi-nav .app-logo .logo img{width:180px!important}` (both its
   768-1199px and <768px variants) outranks a plain declaration here. */
/* min-width:768px scopes this to the desktop/tablet icon rail only. Below
   768px, `.semi-nav` also means "mobile drawer open" (script.js's
   header-toggle click handler reuses the same class — see §4/step A3.3's
   own note on this) — without this gate, an open drawer with the mouse
   away from <nav> was ALSO matching `:not(:hover)` and getting this same
   icon-only treatment, even though style.css's own <768px rule
   (`nav.semi-nav .app-logo .logo img{width:180px!important}`) already
   shows the full wordmark there by design. Gating this rule lets that
   vendor rule through unmodified at mobile widths. */
@media (min-width: 768px) {
  .semi-nav:not(.horizontal-sidebar):not(:hover) .app-logo .logo {
    justify-content: center;
    padding: 0;
  }
  .semi-nav:not(.horizontal-sidebar):not(:hover) .app-logo .logo img {
    content: url("../images/cups/cups-market-icon.c1c79ee53b3c.png");
    width: 36px !important;
    height: 36px !important;
  }
}

/* accounts/_school_picker.html's new-school block (dark signup panel,
   ?role=teacher) — every .form-control there already renders translucent
   (rgba(255,255,255,0.4), style.css's own .app-form .form-control, so it
   blends with the panel/box tint behind it), but .form-select (the
   "Regija" dropdown) has no equivalent override anywhere and falls back
   to a plain opaque white box — the one visibly inconsistent field in the
   block. Matches the same translucency, scoped to .app-form so it can
   never affect a select outside the entrance/signup panels (e.g.
   accounts/company_form.html's own school-region select, a plain card on
   base.html, needs no such treatment — confirmed it doesn't use the
   .app-form class at all). */
.app-form .form-select {
  background-color: rgba(255, 255, 255, 0.4);
}

/* Landing-page footer badge (a white circle on the dark footer) — was
   sized only by the old icon file's intrinsic 48x48px (no explicit
   desktop rule existed); cups-market-icon.png's native 512x512 needs an
   explicit size here or it overflows the badge. style.css's own mobile
   override (`.landing-footer .container .footer-section-logo img
   {width:32px}`) is more specific and still wins at that breakpoint. */
.footer-section-logo img {
  width: 48px;
  height: 48px;
}

/* Sidebar "Pregled" section heading (base.html, Part F) — a thin
   separator above it, matching style.css's own nav-profile border
   (`nav .app-logo .nav-profile{border-top:1px solid rgba(var(--primary),
   0.2)}`) exactly, so it reads as the same visual language as the border
   around the sidebar user-profile block rather than a new line style. */
.menu-title-separated {
  border-top: 1px solid rgba(var(--primary), 0.2);
  padding-top: 0.5rem;
}

/* Sidebar actionable-count badges (base.html, Part H; repositioned step 1,
   final overnight-ui fixes). base.html now renders TWO copies of each
   badge/dot — one inside .sidebar-badge-wrap (around the <i>), one inside
   a new .sidebar-label-wrap (around the link's own text) — and this file
   picks which one shows via the badge-on-icon/badge-on-label modifier
   classes, using the EXACT SAME rail-state selector the app-logo image
   swap above already uses (including its min-width:768px gate, so a
   <768px open mobile drawer — also `.semi-nav`, script.js's own
   header-toggle reuse — is never treated as "icon-only" the way the
   >=768px collapsed rail is).

   Default (expanded sidebar, OR a <768px open mobile drawer, where the
   label is always full-size): label-anchored copy shows, icon-anchored
   copy stays hidden — no media query needed, this IS the unconditional
   default. Icon-anchored copy shows instead ONLY inside the >=768px
   rail's collapsed-AND-NOT-hovered state (both the manual >=1200px
   toggle and the automatic 768-1199px rail script.js's resize()
   applies) — the vendor's own `nav.semi-nav .main-nav li a{font-size:0}`
   rule is what hides the label text in exactly that same state, so
   syncing to the identical selector keeps the two in lockstep with no
   separate breakpoint logic of our own to maintain. Hovering the
   collapsed rail (`.semi-nav:hover`) falls straight back to the default
   (unconditional) rules, no extra selector needed for that direction. */
.sidebar-badge-wrap {
  position: relative;
  display: inline-block;
}
.sidebar-label-wrap {
  position: relative;
  display: inline-block;
}
.sidebar-badge {
  position: absolute;
  min-width: 15px;
  height: 15px;
  padding: 0 3px;
  border-radius: 999px;
  background-color: #dc3545;
  color: #fff;
  font-size: 0.625rem;
  line-height: 15px;
  text-align: center;
}
.sidebar-dot {
  position: absolute;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background-color: #198754;
}
.sidebar-badge.badge-on-icon {
  top: -6px;
  right: -8px;
}
.sidebar-dot.badge-on-icon {
  top: -2px;
  right: -4px;
}
.sidebar-badge.badge-on-label {
  top: -8px;
  right: -12px;
}
.sidebar-dot.badge-on-label {
  top: -2px;
  right: -8px;
}
.badge-on-icon {
  display: none;
}
@media (min-width: 768px) {
  .semi-nav:not(.horizontal-sidebar):not(:hover) .badge-on-icon {
    display: inline-block;
  }
  .semi-nav:not(.horizontal-sidebar):not(:hover) .badge-on-label {
    display: none;
  }
}

/* Public "open now" indicator (landing/Vsa podjetja cards + storefront
   hero, Part I, overnight-ui) — reuses the same green dot colour as
   .sidebar-dot above, unrelated component. .company-teaser-card gets
   position:relative here (the vendor .card rule doesn't set one) so the
   corner dot positions against the card, not the page. */
.company-teaser-card {
  position: relative;
}
.open-now-dot {
  position: absolute;
  top: 10px;
  right: 10px;
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background-color: #198754;
  animation: open-now-pulse 2s ease-in-out infinite;
}
.open-now-dot-inline {
  position: static;
  display: inline-block;
  width: 8px;
  height: 8px;
  margin-right: 0.25rem;
  vertical-align: middle;
}
@keyframes open-now-pulse {
  0%, 100% {
    box-shadow: 0 0 0 0 rgba(25, 135, 84, 0.6);
  }
  50% {
    box-shadow: 0 0 0 6px rgba(25, 135, 84, 0);
  }
}
@media (prefers-reduced-motion: reduce) {
  .open-now-dot {
    animation: none;
  }
}
/* Storefront hero pill — dark, semi-opaque so it stays legible over both
   the plain light background (no cover) and an arbitrary cover photo
   (has-cover), rather than switching treatment between the two. */
.open-now-pill {
  position: absolute;
  top: 12px;
  right: 12px;
  display: inline-flex;
  align-items: center;
  padding: 0.25rem 0.75rem;
  border-radius: 999px;
  background-color: rgba(0, 0, 0, 0.55);
  color: #fff;
  font-size: 0.8125rem;
  line-height: 1.2;
}

/* Storefront hero "Trgovina"/"O nas" view-switch (Part 5,
   templates/core/_company_header.html; pill background/container
   dropped batch-3 Part 1e — just two separate buttons with a small gap
   now). inline-flex (not block) so text-center on the hero's own column
   centers it exactly like every other element there. The template
   picks different button-style tokens depending on whether a cover
   image is set (company.cover_image): with one, the hero already gets
   its own dark overlay (has-cover, see company_detail.html/
   product_detail.html's page-scoped CSS), so btn-light/btn-outline-
   light stay legible directly against it; without one the hero is plain
   light, so btn-primary/btn-outline-primary are used instead — the
   vendor's own dark-on-light `.btn-light`/`.btn-outline-light` text
   would otherwise read as washed-out grey there. */
.hero-view-switch {
  display: inline-flex;
  gap: 0.5rem;
}

/* btn-light's dark-on-light text (style.css's own unconditional
   `.btn-light, .btn-outline-light { color: rgba(var(--dark),1) !important }`
   rule, further down that file) is exactly right for the ACTIVE button —
   its background is light, so dark text reads fine. But that same
   vendor rule also forces the INACTIVE (btn-outline-light) button's text
   dark, and its background is transparent — against the has-cover dark
   overlay that leaves near-black text on a dark photo, invisible
   (confirmed in a real browser over a dark cover photo). Higher
   specificity beats that vendor rule without editing the vendor file:
   light text at rest (transparent bg, matches the dark overlay), back
   to the vendor's own dark text on :hover (its background does turn
   light then, per that same style.css rule, a few lines above the
   !important one). Only ever applied with a cover image set (see the
   template) — without one, the buttons use btn-primary/btn-outline-
   primary instead, which need no such fix. */
.hero-view-switch .btn-outline-light {
  color: rgba(var(--light), 1) !important;
}
.hero-view-switch .btn-outline-light:hover {
  color: rgba(var(--dark), 1) !important;
}

/* "O nas" gallery grid (Part 5, core/_company_presentation.html) — the
   theme's own .imagebox/.caption-content hover-caption markup
   (_theme_reference's gallery.html) assumes a masonry-style layout with
   images at their natural size; this app's grid is uniform instead, so
   a fixed aspect-ratio box (same 4:3 the old single-column gallery used)
   plus object-fit:cover keeps every thumbnail the same size regardless
   of the source photo's own dimensions. */
.company-gallery-grid .imagebox {
  aspect-ratio: 4 / 3;
  overflow: hidden;
  border-radius: var(--app-border-radius);
}
.company-gallery-grid .imagebox img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* "Oglej si kot" banner (batch-2 Part C) — fixed to the BOTTOM of the
   viewport, deliberately not the top: this app's header/sidebar are
   themselves position:fixed at the top on every shell AND on several
   standalone public pages (landing's navbar, the storefront topbar), each
   already tuned to an exact height/z-index — a normal-flow element
   inserted before them (tried first) gets silently painted OVER by those
   fixed elements instead of pushing them down, since position:fixed
   ignores preceding normal-flow content entirely (confirmed live: the
   banner rendered in the HTML — this app's own tests assert
   `assertContains(resp, "Ogleduješ si kot")` — but was visually hidden
   behind the header). Anchoring to the BOTTOM instead needs no coordination
   with any of that top-anchored fixed chrome at all — it can only ever
   overlap the very bottom edge of a page's own content/footer, never a
   clickable header/sidebar control. */
.impersonation-banner {
  position: fixed;
  bottom: 0;
  left: 0;
  right: 0;
  z-index: 2000;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 1rem;
  flex-wrap: wrap;
  padding: 0.5rem 1rem;
  background-color: #ffc107;
  color: #212529;
  font-size: 0.875rem;
  text-align: center;
  box-shadow: 0 -2px 8px rgba(0, 0, 0, 0.15);
}
.impersonation-banner form {
  margin: 0;
}
/* "Deluj kot" (act-as, batch-3 Part 4) — a visibly different, more
   alarming colour than the read-only banner above, so a CUPS admin can
   never mistake "writes are going out under someone else's name" for the
   ordinary read-only view. Same layout, just danger red instead of the
   read-only banner's warning yellow. */
.impersonation-banner-acting {
  background-color: #dc3545;
  color: #fff;
}

/* "Zamrzni poslovanje" banner (pre-deploy Part 7, templates/
   _freeze_banner.html) — same bottom-anchored fixed bar as the
   impersonation banner above (same reasoning: never fights the fixed
   top header), in a cool info blue. When the impersonation banner is
   ALSO showing (it is rendered first, as a preceding sibling), this one
   sits just above it instead of on top of it. Hidden when printing so
   a printed report never carries it. */
.freeze-banner {
  position: fixed;
  bottom: 0;
  left: 0;
  right: 0;
  z-index: 1999;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  flex-wrap: wrap;
  padding: 0.5rem 1rem;
  background-color: #0aa2c0;
  color: #fff;
  font-size: 0.875rem;
  text-align: center;
  box-shadow: 0 -2px 8px rgba(0, 0, 0, 0.15);
}
.freeze-banner a {
  color: #fff;
  text-decoration: underline;
}
.impersonation-banner ~ .freeze-banner {
  bottom: 3rem;
}
@media print {
  .freeze-banner {
    display: none !important;
  }
}

/* Sanitized rich text (batch-2, extended batch-3 Part 5) — the ONE scoped
   class for anywhere core.richtext.sanitize_body_html()'d HTML is either
   edited (Trumbowyg's contenteditable area — static/assets/vendor/
   trumbowyg, class added via JS on 'tbwinit' in templates/core/
   company_profile.html and templates/cups/announcement_edit.html, since
   Trumbowyg builds that markup at runtime, not something a template can
   put a class on directly) or rendered (templates/core/
   _company_presentation.html's "O nas" body, templates/support/
   _announcements.html's announcement cards). Only ever needs to cover
   p/br/strong/em/ul/ol/li/h3/a — core/richtext.py's own strict allowlist
   is the complete set of tags that can ever reach here.

   The theme's global reset (style.css: `ul { list-style-type: none;
   padding-left: 0; }`) is what made bullets vanish on both the editor and
   the published page — restoring padding alone (the previous, narrower
   `.company-presentation-text` version of this rule) was never enough,
   since `list-style-type` stayed `none`. `li { display: list-item }` is
   reasserted too, belt-and-suspenders, in case any ancestor ever resets
   display on list items. Likewise links needed an explicit color: the
   theme's reset makes them visually identical to surrounding text. */
.rich-text p {
  margin-bottom: 1rem;
}
.rich-text ul,
.rich-text ol {
  padding-left: 1.5rem;
  margin-bottom: 1rem;
}
.rich-text ul {
  list-style-type: disc;
}
.rich-text ol {
  list-style-type: decimal;
}
.rich-text li {
  display: list-item;
}
.rich-text h3 {
  font-size: 1.25rem;
  font-weight: 600;
  margin-top: 1.5rem;
  margin-bottom: 0.75rem;
}
.rich-text a {
  color: rgb(var(--primary));
  text-decoration: underline;
}
.rich-text > *:last-child {
  margin-bottom: 0;
}

/* Achievement badge grid (batch-2, templates/core/_achievement_badges.html)
   — earned badges in full primary colour, unearned ones greyed out/
   desaturated so the earned/unearned difference reads instantly without
   relying on colour alone (each badge's own hint/date text underneath
   already carries the same information for a colourblind or
   screen-reader viewer). */
.achievement-badge {
  border: 1px solid rgba(var(--primary), 0.15);
}
.achievement-badge-earned {
  background-color: rgba(var(--primary), 0.08);
  color: rgb(var(--primary));
}
.achievement-badge-earned i {
  color: rgb(var(--primary));
}
.achievement-badge-locked {
  background-color: #f5f5f5;
  color: #adb5bd;
  filter: grayscale(1);
  opacity: 0.75;
}

/* "Letni povzetek" (batch-2, templates/core/annual_summary.html) — print
   support. The vendored theme (style.css) already hides header/nav/
   footer globally in @media print; this just additionally hides this
   page's own on-screen-only controls (.no-print, e.g. the "Natisni"
   button) so the printed/PDF output is exactly the report content. */
@media print {
  .no-print {
    display: none !important;
  }
}

/* "Letno poročilo" (pre-deploy Part 7, templates/cups/annual_report.html)
   — same print technique as above; additionally hides the DataTables
   search/info chrome so the printed company table is just the table. */
@media print {
  .annual-report .dataTables_filter,
  .annual-report .dataTables_length,
  .annual-report .dataTables_info,
  .annual-report .dataTables_paginate {
    display: none !important;
  }
  .annual-report .card {
    break-inside: avoid;
  }
}

/* Header notification-bell badge (batch-3 Part 1c) — the vendor's
   `.badge.badge-notification` (style.css) is a full Bootstrap pill badge,
   much bigger than the small circular sidebar count badges (.sidebar-
   badge, above). Scoped to `.header-notification` only so the header
   CART badge (`.header-cart .js-cart-badge`, same badge-notification
   class) keeps the vendor's own larger size unchanged — this is a bell-
   only visual match, not a global badge-notification resize. Same
   specificity as the vendor rule (two classes); custom.css is linked
   after style.css in every shell, so this wins on the tie without
   needing !important. */
.header-notification .badge-notification {
  min-width: 15px;
  height: 15px;
  padding: 0 3px;
  font-size: 0.625rem;
  line-height: 15px;
}

/* Page-loader overlay text (batch-3 Part 1d) — base.html/cups/
   base_cups.html both render the vendor's `.loader_24` spinner
   unchanged; its "Loading..." text comes from style.css's own
   `.loader_24::before { content: "Loading..."; ... }` rule, so the text
   is overridden here (same selector/specificity, later in the cascade)
   rather than touching that vendor file or the loader's markup/
   behaviour. */
.loader_24::before {
  content: "Nalaganje …";
}

/* Invoice line table (batch-3 Part 7d, templates/core/invoice_detail.html)
   — clear horizontal row borders plus a header bottom border. The table
   there intentionally uses no vendor `.table` class (its own "table-sm
   align-middle w-100" markup, unchanged by this part), so there is
   nothing to override — this just adds the borders directly, scoped to
   this one table only. Borders print fine as-is (no @media print rule
   needed): the only print-specific behaviour on this page is .no-print
   above, which already hides the on-screen-only controls.
   Applied to td/th, not tr: under the default "separate" border model
   (no border-collapse:collapse set anywhere on this table or its
   ancestors), browsers don't render a border set directly on a <tr> at
   all — only on its cells — so border-bottom on tbody tr would have
   silently had no visible effect. */
.invoice-lines-table thead th {
  border-bottom: 2px solid rgba(var(--dark), 0.4);
}
.invoice-lines-table tbody td {
  border-bottom: 1px solid rgba(var(--dark), 0.15);
}

/* "Si dijak?" note on /za-ucitelje/ (pre-deploy Part 1,
   templates/accounts/teacher_info.html) — .alert-primary is a SOLID
   primary background with white text here (style.css), so the default
   .alert-link colour was barely legible on it. Scoped to this one link
   only: white, bold, underlined so it still reads as a link, with a
   visible hover/focus state. Never a global link-colour change. */
.teacher-info-student-note .teacher-info-student-note-link {
  color: #fff;
  font-weight: 700;
  text-decoration: underline;
  text-underline-offset: 3px;
  text-decoration-thickness: 1px;
}
.teacher-info-student-note .teacher-info-student-note-link:hover,
.teacher-info-student-note .teacher-info-student-note-link:focus-visible {
  color: #e8f7ec;
  text-decoration-thickness: 2px;
}
.teacher-info-student-note .teacher-info-student-note-link:focus-visible {
  outline: 2px solid #fff;
  outline-offset: 2px;
  border-radius: 2px;
}

/* CUPS "Zahtevki" status cards (pre-deploy Part 2) — the whole ticket card
   is a link that filters the table; the currently selected one gets an
   inset outline so the active filter is visible at a glance. */
.support-status-card {
  text-decoration: none;
}
.support-status-card .ticket-card {
  transition: transform .15s ease, box-shadow .15s ease;
}
.support-status-card:hover .ticket-card,
.support-status-card:focus-visible .ticket-card {
  transform: translateY(-2px);
}
.support-status-card.active .ticket-card {
  box-shadow: inset 0 0 0 3px rgba(255, 255, 255, .75);
}

/* "Obvestila" page (templates/support/announcement_list.html) — expired
   announcements stay listed but visually recede behind the "Poteklo" badge. */
.announcement-expired strong,
.announcement-expired .rich-text {
  opacity: 0.65;
}

/* Landing-page announcements (templates/core/landing.html #obvestila). */
.landing-announcement .rich-text {
  font-size: 0.95rem;
}

/* CUPS metric tables — "Aktivnost podjetij" (cups/company_overview.html)
   and "Letno poročilo" (cups/annual_report.html), both built from
   cups/_metric_head_cells.html + _metric_row_cells.html (pre-deploy Part
   11). Every cell stays on one line, plus at most one smaller muted detail
   line (the existing `.f-s-11.d-block` spans), so a row is never taller
   than two lines; the surrounding .table-responsive scrolls sideways
   instead. Screen only — the printed "Letno poročilo" may still wrap to
   fit the page width. */
@media screen {
  .metric-table th,
  .metric-table td {
    white-space: nowrap;
  }
  .metric-table td .f-s-11.d-block {
    line-height: 1.2;
  }
}

/* Small shared footer on the standalone public pages (templates/
   _public_footer.html, pre-launch Part 3) — those pages have no shell
   footer of their own; this just carries the "Politika zasebnosti" link. */
.public-footer {
  padding: 1.25rem 0;
  margin-top: 2rem;
  border-top: 1px solid rgba(var(--secondary), 0.15);
  text-align: center;
  font-size: 0.875rem;
  color: rgba(var(--secondary), 1);
}
.public-footer a {
  color: rgb(var(--primary));
  text-decoration: underline;
}

/* Thin horizontal lines between table rows (pre-launch Part 5) — ONE shared
   class, put on the <table> itself: `<table class="... table-row-lines">`.
   A 1px bottom border on every body cell in the theme's own light border
   colour (--border_color, which style.css redefines for the dark theme).
   Works on a plain Bootstrap .table AND on a DataTable inside
   .app-datatable-default, whose own rule draws a dashed top border on each
   cell (and DataTables' own .display/.row-border styles a grey one) — the
   second/third selectors out-rank those so only this single solid line
   remains. A line after the last row is fine. */
table.table-row-lines > tbody > tr > td,
table.dataTable.table-row-lines > tbody > tr > td,
.app-datatable-default .dataTables_wrapper table.table-row-lines > tbody > tr > td {
  border-top: 0;
  border-bottom: 1px solid var(--border_color);
}
/* Modifier `.table-row-lines-plain` (pre-launch Part 6, "Poraba prostora"):
   same lines, but every row on the card's own background — no grey
   striping/hover tint (DataTables' .display odd rows, .table-hover) — so
   the grey empty track of a progress bar inside a cell stays distinct.
   --bs-card-bg is set on the enclosing .card (white in light mode, the
   dark card colour in the dark theme); --bs-body-bg is the fallback. */
table.table-row-lines.table-row-lines-plain > tbody > tr,
table.table-row-lines.table-row-lines-plain > tbody > tr > td,
.app-datatable-default .dataTables_wrapper table.dataTable.table-row-lines.table-row-lines-plain > tbody > tr,
.app-datatable-default .dataTables_wrapper table.dataTable.table-row-lines.table-row-lines-plain > tbody > tr > td {
  background-color: var(--bs-card-bg, var(--bs-body-bg));
  box-shadow: none;
  --bs-table-accent-bg: transparent;
}

/* Fixed-width action slots on the CUPS queue tables (Učitelji / Šole /
   Podjetja, pre-launch Part 5): every row renders the SAME number of slots
   (an empty one where that row's status has no such action), each sized
   for the longest label ("Na čakanje"), so the same action — "Zavrni",
   "Več" — lines up vertically down the column regardless of each row's
   status. The button fills its slot. */
.queue-action-slot {
  flex: 0 0 auto;
  width: 5.75rem;
}
.queue-action-slot form,
.queue-action-slot .btn {
  width: 100%;
}
/* Tighter horizontal padding than the theme's btn-sm (20px) so
   "Na čakanje" fits the slot and the queue tables fit at ~1170px. */
.queue-action-slot .btn {
  padding-left: .5rem;
  padding-right: .5rem;
}
/* Long school-name badges in the queue tables may wrap instead of
   widening the table (status badges stay on one line). */
.badge.badge-wrap {
  white-space: normal;
}

/* CUPS "Nadzorna plošča" — "Odprte zadeve" 2x2 grid cells (pre-launch
   Part 7). Each cell fills its equal-width grid column (h-100 on the
   link), so the second column's left edges align; a zero cell stays in
   place, muted. */
.dashboard-open-item {
    padding: .75rem 1rem;
    border: 1px solid var(--border_color);
    border-radius: var(--app-border-radius);
    background-color: rgba(var(--primary), .06);
    color: rgba(var(--dark), 1);
    transition: background-color .15s ease-in-out;
}
.dashboard-open-item:hover,
.dashboard-open-item:focus-visible {
    background-color: rgba(var(--primary), .12);
    color: rgba(var(--dark), 1);
}
.dashboard-open-item__count {
    min-width: 2.25rem;
    font-size: .875rem;
}
.dashboard-open-item--zero {
    background-color: transparent;
}
.dashboard-open-item--zero .dashboard-open-item__label {
    color: var(--bs-secondary-color);
}
.dashboard-open-item--zero:hover,
.dashboard-open-item--zero:focus-visible {
    background-color: rgba(var(--secondary), .06);
}

/* CUPS dashboard KPI cards (pre-launch Part 7): symmetric vertical
   padding so the value no longer sits on the card's bottom edge, and —
   in the six-across col-xl-2 layout only, where a column is ~130px with
   the sidebar open — a value font that scales down so "1.709,17 €"
   stays on one line (text-nowrap on the value). */
.cups-kpi .card-body {
    padding: 1.25rem 1.25rem;
}
.cups-kpi__value {
    line-height: 1.2;
}
@media (min-width: 1200px) {
    .cups-kpi .card-body {
        padding-left: 1rem;
        padding-right: 1rem;
    }
    .cups-kpi__value {
        font-size: clamp(1rem, .25rem + 1.05vw, 1.5rem);
    }
}

/* Landing "Poglej si vsa podjetja in njihove trgovine" (pre-launch Part 8):
   the theme's btn-warning (yellow, --warning 249,193,35) as the page's
   prominent CTA. Dark text for contrast (text-dark on the element too),
   a darker yellow on hover/active (the theme forces its own flat yellow
   on hover/focus with !important, hence !important here), a visible
   focus ring for keyboard users, and a small arrow nudge on hover. */
.landing-all-companies-btn {
  color: #1f1f1f !important;
  font-weight: 600;
  box-shadow: 0 6px 16px rgba(249, 193, 35, 0.35);
  transition: background-color 0.15s ease, border-color 0.15s ease, box-shadow 0.15s ease;
}
.landing-all-companies-btn:hover,
.landing-all-companies-btn:active {
  background-color: #e0a80a !important;
  border-color: #e0a80a !important;
  color: #1f1f1f !important;
  box-shadow: 0 8px 20px rgba(224, 168, 10, 0.4);
}
.landing-all-companies-btn:focus-visible {
  outline: 3px solid #7a5a00;
  outline-offset: 3px;
  box-shadow: 0 0 0 0.25rem rgba(249, 193, 35, 0.45);
}
.landing-all-companies-btn .ph-arrow-right {
  display: inline-block;
  vertical-align: -0.125em;
  transition: transform 0.15s ease;
}
.landing-all-companies-btn:hover .ph-arrow-right,
.landing-all-companies-btn:focus-visible .ph-arrow-right {
  transform: translateX(4px);
}
@media (prefers-reduced-motion: reduce) {
  .landing-all-companies-btn,
  .landing-all-companies-btn .ph-arrow-right {
    transition: none;
  }
}

/* Landing hero background image (pre-launch Part 8, CUPS-configurable on
   /cups/nastavitve/). The section gets the photo inline; a dark shade of
   the landing's brand green (--primary on the public pages is the theme's
   15, 98, 106 — this is ~half of it) is laid over it at the configured
   opacity (--landing-hero-overlay-opacity, set inline as e.g. "0.70") so
   the white heading stays readable. .landing-section is already
   position:relative + z-index:1 (style.css), i.e. its own stacking
   context, so the z-index:-1 overlay sits above the section's own
   background but below its content. */
.landing-section.landing-hero-image {
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
}
.landing-section.landing-hero-image::before {
  content: "";
  position: absolute;
  inset: 0;
  background-color: rgb(7, 49, 53);
  opacity: var(--landing-hero-overlay-opacity, 0.7);
  z-index: -1;
  pointer-events: none;
}
/* The navbar is transparent at the top of the page (style.css; the theme
   only colours it on scroll via landing.js' .landing-navbar-active), which
   over the plain hero reads as the brand green. Over a photo it must stay
   that same green, so give it the solid colour up front. */
.landing-wrapper.landing-has-hero-image .landing-navbar {
  background-color: rgba(var(--primary), 1);
}

/* Settings-page preview of the landing hero (cups/platform_settings.html). */
.landing-hero-preview {
  position: relative;
  height: 140px;
  border-radius: 10px;
  overflow: hidden;
  background-size: cover;
  background-position: center;
}
.landing-hero-preview::before {
  content: "";
  position: absolute;
  inset: 0;
  background-color: rgb(7, 49, 53);
  opacity: var(--landing-hero-overlay-opacity, 0.7);
}
.landing-hero-preview__text {
  position: relative;
  color: #fff;
  font-weight: 600;
}
