/* ASNET layout — container, header/nav (client area + public), footer.
 *
 * Navigation is mobile-first and intentionally has no Bootstrap
 * navbar-expand-* dependency: base/default rules ARE the mobile hamburger
 * layout, and the single `@media (min-width: 992px)` block below switches
 * to the inline desktop nav. That makes <=991px unambiguously mobile/tablet
 * and >=992px (992 included) unambiguously desktop, with no dead zone -
 * this is what section 12/36 of the brief requires and what the previous
 * candidate's `navbar-expand-md`/`navbar-expand-lg` swap failed to do.
 */

/* Content-rail parity with asnet-web/dev.asnet.rs (canonical source - see
   final report). Same width/gutter model as its own .container:
   `width: min(calc(100% - 40px), var(--container))`, no separate
   padding-inline gutter, 28px total (14px/side) under 600px, no gutter
   step at 768px. --asnet-container itself (1180px) is unchanged - only
   HOW the rail reaches that cap changes. max-width is kept alongside
   width even though min() already caps it, purely as a defensive
   belt-and-suspenders for any browser context that fails to parse min() -
   removing it would save one line but isn't the "safe, minimal" side of
   that trade-off. */
.asnet-container {
  width: min(calc(100% - 40px), var(--asnet-container));
  max-width: var(--asnet-container);
  margin-inline: auto;
  padding-inline: 0;
}
@media (max-width: 600px) {
  .asnet-container {
    width: min(calc(100% - 28px), var(--asnet-container));
  }
}

/* ---------------------------------------------------------------------
   Client-area header
--------------------------------------------------------------------- */
.asnet-header {
  position: sticky;
  top: 0;
  z-index: 50;
  background: #09111bc7;
  -webkit-backdrop-filter: blur(16px);
  backdrop-filter: blur(16px);
  color: var(--asnet-text-on-dark);
  border-bottom: 1px solid var(--asnet-border-on-dark-soft);
}

.asnet-header__bar {
  display: flex;
  align-items: center;
  gap: var(--asnet-space-md);
  min-height: var(--asnet-header-height);
}

.asnet-brand { display: inline-flex; align-items: center; gap: 8px; flex-shrink: 0; }
.asnet-brand__logo { height: 30px; width: auto; display: block; }
.asnet-brand__name { font-weight: 800; font-size: var(--asnet-fs-md); color: #fff; }

.asnet-nav--desktop { display: none; }

.asnet-header__actions {
  display: flex;
  align-items: center;
  gap: var(--asnet-space-xs);
  margin-left: auto;
}

/* "Back to asnet.rs" control (item 4 of this pass): a plain low-contrast
   text link before, now composed from the existing .asnet-btn system
   instead of a one-off style, so it reads as a deliberate control and
   looks like the SAME control everywhere it appears - .asnet-btn--ghost on
   the two permanently-dark surfaces (client header, mobile-nav drawer),
   .asnet-btn--outline on the permanently-light public header - rather than
   three different bespoke looks for one function. This class now only adds
   the parts .asnet-btn doesn't already cover: no-wrap + icon sizing. */
.asnet-back-link { white-space: nowrap; }
.asnet-back-link .asnet-icon { width: 15px; height: 15px; }

.asnet-icon-btn {
  border: 1px solid var(--asnet-border-on-dark);
  border-radius: var(--asnet-radius-sm);
  background: transparent;
  color: #fff;
  cursor: pointer;
}
.asnet-icon-btn {
  width: 36px;
  height: 36px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.asnet-icon-btn:hover { background: #ffffff14; }
.asnet-theme-toggler .asnet-icon { width: 16px; height: 16px; }

/* Language picker (button + listbox, replaces a native <select> that
   rendered unreliably cross-browser). Reuses the same surface/border/text
   tokens as .asnet-account__menu below so light/dark mode and z-index stay
   consistent with the rest of the header's popovers. */
.asnet-lang-picker { position: relative; }
.asnet-lang-picker__trigger {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  height: 36px;
  padding: 0 10px;
  border: 1px solid var(--asnet-border-on-dark);
  border-radius: var(--asnet-radius-sm);
  background: transparent;
  color: #fff;
  font-size: var(--asnet-fs-sm);
  font-weight: 600;
  cursor: pointer;
}
.asnet-lang-picker__trigger:hover { background: #ffffff14; }
.asnet-lang-picker__trigger-flag {
  display: block;
  width: 22px;
  height: 15px;
  border-radius: 2px;
  box-shadow: 0 0 0 1px #0000001f;
  object-fit: cover;
}
.asnet-lang-picker__trigger .asnet-icon { transition: transform var(--asnet-transition-fast) var(--asnet-ease-out); }
.asnet-lang-picker.is-open .asnet-lang-picker__trigger .asnet-icon { transform: rotate(180deg); }

.asnet-lang-picker__menu {
  position: absolute;
  top: calc(100% + 8px);
  left: 0;
  width: 238px;
  max-width: calc(100vw - 28px);
  box-sizing: border-box;
  margin: 0;
  padding: 6px;
  list-style: none;
  background: var(--asnet-surface-elevated);
  border: 1px solid var(--asnet-border);
  border-radius: var(--asnet-radius-md);
  box-shadow: var(--asnet-shadow-lifted);
  z-index: 60;
}
.asnet-lang-picker__menu[hidden] { display: none; }

.asnet-header__actions .asnet-lang-picker__menu,
.asnet-public-bar__actions .asnet-lang-picker__menu {
  right: 0;
  left: auto;
}

.asnet-lang-picker__option {
  display: grid;
  grid-template-columns: 22px minmax(0, 1fr) auto 14px;
  align-items: center;
  gap: 10px;
  padding: 8px 10px;
  border-radius: var(--asnet-radius-sm);
  color: var(--asnet-text);
  font-size: var(--asnet-fs-sm);
  font-weight: 500;
  cursor: pointer;
}
.asnet-lang-picker__option:hover,
.asnet-lang-picker__option.is-active { background: var(--asnet-surface-muted); }
.asnet-lang-picker__option.is-selected { font-weight: 700; color: var(--asnet-primary); }
.asnet-lang-picker__option-flag {
  display: block;
  width: 22px;
  height: 15px;
  border-radius: 2px;
  box-shadow: 0 0 0 1px #0000001f;
  object-fit: cover;
}
.asnet-lang-picker__option-code {
  flex-shrink: 0;
  font-size: 11px;
  font-weight: 700;
  line-height: 1;
  letter-spacing: .03em;
  white-space: nowrap;
  color: var(--asnet-text-muted);
}
.asnet-lang-picker__option.is-selected .asnet-lang-picker__option-code { color: var(--asnet-primary); }
.asnet-lang-picker__option-name { min-width: 0; }
.asnet-lang-picker__check { color: var(--asnet-primary); text-align: center; }

/* Mobile nav panel instance: full-width row like the buttons around it,
   instead of the compact header trigger. */
.asnet-mobile-nav__actions .asnet-lang-picker { width: 100%; }
.asnet-mobile-nav__actions .asnet-lang-picker__trigger {
  width: 100%;
  height: 46px;
  justify-content: space-between;
  padding: 0 16px;
}
.asnet-mobile-nav__actions .asnet-lang-picker__menu {
  right: 0;
  left: 0;
  width: auto;
  max-width: none;
}

/* Account dropdown (logged-in) */
.asnet-account { position: relative; }
.asnet-account__trigger {
  display: flex;
  align-items: center;
  gap: 8px;
  border: 1px solid var(--asnet-border-on-dark);
  border-radius: var(--asnet-radius-full);
  background: transparent;
  color: #fff;
  padding: 4px 12px 4px 4px;
  cursor: pointer;
}
.asnet-account__trigger:hover { background: #ffffff14; }
.asnet-account__avatar { border-radius: 50%; overflow: hidden; display: inline-flex; }
.asnet-account__name {
  font-size: var(--asnet-fs-sm);
  font-weight: 600;
  max-width: 140px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.asnet-account__menu {
  position: absolute;
  top: calc(100% + 8px);
  right: 0;
  min-width: 190px;
  background: var(--asnet-surface-elevated);
  border: 1px solid var(--asnet-border);
  border-radius: var(--asnet-radius-md);
  box-shadow: var(--asnet-shadow-lifted);
  padding: 6px;
  display: none;
  z-index: 60;
}
.asnet-account.is-open .asnet-account__menu { display: block; }
.asnet-account__menu a {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 9px 10px;
  border-radius: var(--asnet-radius-sm);
  color: var(--asnet-text);
  font-size: var(--asnet-fs-sm);
  font-weight: 500;
}
.asnet-account__menu a:hover { background: var(--asnet-surface-muted); }

/* Domeni mega-menu: same [data-asnet-dropdown] trigger/panel primitive as
   .asnet-account above (position:relative wrapper, absolutely positioned
   panel, .is-open toggles visibility - see nav.js initDropdowns()), styled
   as a 2x2 tile grid instead of a plain link list. The trigger reuses
   .asnet-nav__link's own look (color/size/weight already come from that
   class) and is a real <button> (not <a>, it opens a panel rather than
   navigating), so native button chrome is reset here. Right-anchored
   (not centered) because this is the last/rightmost item in the fixed-width
   NAV track, right next to the ACTIONS zone - a centered panel could push
   past the header's right edge; anchoring right and growing left keeps it
   inside the rail at every supported width. */
.asnet-domain-menu { position: relative; }
.asnet-domain-menu__trigger {
  background: none;
  border: none;
  padding: 0;
  font: inherit;
  cursor: pointer;
}
/* The chevron must stay visible at every width (it's the dropdown's own
   open/close indicator, not a decorative nav-icon), so it needs its own
   display override here: the base .asnet-nav__link .asnet-icon rule
   hides all nav-link icons unscoped, and only the mobile-panel context
   re-enables them generally (see .asnet-mobile-nav__links .asnet-nav__link
   .asnet-icon below) - desktop never would otherwise. */
.asnet-domain-menu__trigger .asnet-icon:last-child {
  display: inline-flex;
  width: 14px;
  height: 14px;
  /* No-op on desktop (the trigger is a shrink-wrapped grid cell with no
     spare width to push into); on the mobile 100%-wide trigger below,
     this is what keeps the chevron pinned to the far right while the
     globe icon + label stay grouped together at the left, without
     needing a 3-way justify-content:space-between that would also shove
     the globe icon away from its own label. */
  margin-left: auto;
  transition: transform var(--asnet-transition-fast) var(--asnet-ease-out);
}
.asnet-domain-menu.is-open .asnet-domain-menu__trigger .asnet-icon:last-child { transform: rotate(180deg); }

.asnet-domain-menu__panel {
  position: absolute;
  top: calc(100% + 8px);
  right: 0;
  width: 480px;
  max-width: calc(100vw - 28px);
  box-sizing: border-box;
  background: var(--asnet-surface-elevated);
  border: 1px solid var(--asnet-border);
  border-radius: var(--asnet-radius-md);
  box-shadow: var(--asnet-shadow-lifted);
  padding: 8px;
  display: none;
  grid-template-columns: 1fr 1fr;
  gap: 4px;
  z-index: 60;
}
.asnet-domain-menu.is-open .asnet-domain-menu__panel { display: grid; }

.asnet-domain-menu__tile {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 10px;
  border-radius: var(--asnet-radius-sm);
  color: inherit;
}
a.asnet-domain-menu__tile:hover { background: var(--asnet-surface-muted); }
.asnet-domain-menu__tile.is-disabled { cursor: default; }
.asnet-domain-menu__tile-icon { flex-shrink: 0; color: var(--asnet-primary); margin-top: 1px; }
.asnet-domain-menu__tile-icon .asnet-icon { width: 18px; height: 18px; }
.asnet-domain-menu__tile.is-disabled .asnet-domain-menu__tile-icon { color: var(--asnet-text-muted); }
.asnet-domain-menu__tile-body { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.asnet-domain-menu__tile-title {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 6px;
  font-size: var(--asnet-fs-sm);
  font-weight: 700;
  color: var(--asnet-ink);
}
.asnet-domain-menu__tile.is-disabled .asnet-domain-menu__tile-title { color: var(--asnet-text-muted); }
.asnet-domain-menu__tile-desc { font-size: var(--asnet-fs-xs); color: var(--asnet-text-muted); }

@media (max-width: 991.98px) {
  .asnet-domain-menu__trigger {
    display: flex;
    align-items: center;
    width: 100%;
    padding: var(--asnet-space-sm) var(--asnet-space-2xs);
    border-bottom: 1px solid var(--asnet-border-on-dark-soft);
    color: var(--asnet-text-on-dark-muted);
    font-size: var(--asnet-fs-md);
  }
  /* Globe icon: no rule needed here to show it - the existing general
     .asnet-mobile-nav__links .asnet-nav__link .asnet-icon rule already
     makes every mobile nav-link icon visible, and this trigger keeps the
     .asnet-nav__link class. Only the chevron needed its own always-visible
     override above, since it isn't a plain nav link elsewhere. */
  .asnet-domain-menu.is-open .asnet-domain-menu__trigger { border-bottom-color: transparent; }

  /* Same panel, rendered as a plain stacked expandable subsection instead
     of a floating popover - no absolute positioning, no shadow/border of
     its own, just the two tiles stacked full-width under the trigger. */
  .asnet-domain-menu__panel {
    position: static;
    width: auto;
    max-width: none;
    grid-template-columns: 1fr;
    background: transparent;
    border: none;
    box-shadow: none;
    padding: 4px 0 var(--asnet-space-xs);
    border-bottom: 1px solid var(--asnet-border-on-dark-soft);
  }
  .asnet-domain-menu__tile-title,
  .asnet-domain-menu__tile-icon { color: var(--asnet-text-on-dark); }
  .asnet-domain-menu__tile-desc { color: var(--asnet-text-on-dark-muted); }
  .asnet-domain-menu__tile.is-disabled .asnet-domain-menu__tile-title,
  .asnet-domain-menu__tile.is-disabled .asnet-domain-menu__tile-icon,
  .asnet-domain-menu__tile.is-disabled .asnet-domain-menu__tile-desc { color: var(--asnet-text-on-dark-muted); }
  a.asnet-domain-menu__tile:hover { background: #ffffff14; }
}

.asnet-header__auth { display: flex; align-items: center; gap: 8px; }

/* Hamburger — mobile/tablet only */
.asnet-nav-toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  border: 1px solid var(--asnet-border-on-dark);
  border-radius: var(--asnet-radius-sm);
  background: transparent;
  color: #fff;
  cursor: pointer;
  flex-shrink: 0;
}
.asnet-nav-toggle__close { display: none; }
.asnet-nav-toggle[aria-expanded="true"] .asnet-nav-toggle__open { display: none; }
.asnet-nav-toggle[aria-expanded="true"] .asnet-nav-toggle__close { display: block; }

/* Mobile nav panel */
.asnet-mobile-nav {
  position: fixed;
  inset: var(--asnet-header-height) 0 0 0;
  z-index: 40;
  background: var(--asnet-surface-inverse);
  color: var(--asnet-text-on-dark);
  display: flex;
  flex-direction: column;
  overflow-y: auto;
  padding: var(--asnet-space-md) var(--asnet-space-sm);
  opacity: 0;
  transform: translateY(-6px);
  transition: opacity var(--asnet-transition-base) var(--asnet-ease-out),
              transform var(--asnet-transition-base) var(--asnet-ease-out);
}
.asnet-mobile-nav[hidden] { display: none; }
.asnet-mobile-nav.is-open { opacity: 1; transform: translateY(0); }

.asnet-mobile-nav__links { display: flex; flex-direction: column; }
.asnet-mobile-nav__links .asnet-nav__link {
  padding: var(--asnet-space-sm) var(--asnet-space-2xs);
  border-bottom: 1px solid var(--asnet-border-on-dark-soft);
  font-size: var(--asnet-fs-md);
}
.asnet-mobile-nav__links .asnet-nav__link .asnet-icon { display: inline-flex; }

.asnet-mobile-nav__actions {
  display: flex;
  flex-direction: column;
  gap: var(--asnet-space-xs);
  margin-top: var(--asnet-space-md);
  padding-top: var(--asnet-space-md);
  border-top: 1px solid var(--asnet-border-on-dark-soft);
}
/* Nav links — shared by desktop nav and mobile panel (same partial_menu
   include, different container) */
.asnet-nav__link {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  color: var(--asnet-text-on-dark-muted);
  font-size: var(--asnet-fs-sm);
  font-weight: 600;
}
.asnet-nav__link:hover,
.asnet-nav__link.is-active { color: #fff; }
.asnet-nav__link .asnet-icon { display: none; }

@media (max-width: 991.98px) {
  .asnet-header__back,
  .asnet-header__actions .asnet-lang-picker,
  .asnet-account,
  .asnet-header__auth { display: none; }
}

/*
  Canonical cross-system header grid (locked contract with asnet-web/
  dev.asnet.rs - see final report). .asnet-header__bar IS .asnet-container
  (combined classes on one element), so its own width already comes from
  the rail-parity fix (`width: min(calc(100% - 40px), 1180px)`) - this grid
  only describes how that width gets divided into LOGO | NAV | ACTIONS.
  Fixed-px tracks + a fixed column-gap, no `auto`/`1fr`/margin-left:auto/
  content-dependent positioning for these three zones, exactly as required:
  logo 120 + gap 32 + nav 516 + gap 32 + actions 480 = 1180 total, matching
  the rail's own cap exactly once the viewport reaches it (>=1220px; the
  992-1279.98px compact band below uses its own smaller locked numbers).
*/
@media (min-width: 992px) {
  .asnet-nav-toggle,
  .asnet-mobile-nav { display: none !important; }

  .asnet-header__bar {
    display: grid;
    grid-template-columns: 120px 516px 480px;
    column-gap: 32px;
  }

  /* DOMAIN-01C: six natural-width, single-line labels (five original items
     plus "Domeni") now share the same fixed 516px NAV track - still a
     locked-contract fixed width, deliberately NOT widened (see the header
     grid comment above). The five-item version measured real combined
     label width across all seven locales as comfortably below the track
     width; adding a short sixth label ("Domeni"/"Domains"/... - all under
     10 characters in every shipped locale) consumes some of that slack.
     The font-size step-down below (--asnet-fs-sm -> --asnet-fs-xs, 14px ->
     13px) is a deliberate safety margin on top of that, reusing the exact
     token this same nav already ships at the narrower 446px compact
     breakpoint with five items - i.e. a size already proven to fit five
     labels in less space, now used here with six in more space. This
     could not be pixel-verified in a real browser from this workspace (no
     Docker/browser access); a visual check across all seven locales at
     both desktop breakpoints is recommended before/after deploy. */
  .asnet-nav--desktop {
    display: grid;
    grid-template-columns: repeat(6, max-content);
    justify-content: space-between;
    column-gap: 0;
    min-width: 0;
  }
  /* line-height:normal (not the inherited body{line-height:1.55}, which
     computed to the reported ~20.15px @13px / ~21.7px @14px mismatch
     against public's `normal`) - scoped to .asnet-nav--desktop .asnet-nav__link
     specifically, NOT the base .asnet-nav__link class, so
     .asnet-mobile-nav__links .asnet-nav__link (a separate selector at
     equal specificity) is completely unaffected and keeps inheriting
     1.55 as before - no shared-rule conflict to report, the desktop and
     mobile instances were already distinctly selectable. Weight,
     letter-spacing, color and active-state are untouched. Font-size is the
     one DOMAIN-01C addition on top of that (see the six-item comment
     above). */
  .asnet-nav--desktop .asnet-nav__link {
    justify-content: center;
    white-space: nowrap;
    line-height: normal;
    font-size: var(--asnet-fs-xs);
  }

  .asnet-header__actions {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: var(--asnet-space-xs);
    width: 480px;
  }
  /* justify-content:flex-end (not margin-left:auto on the zone itself -
     that prohibition was about positioning the three TOP-LEVEL zones,
     this is internal alignment within the already-fixed 480px zone) keeps
     the control cluster flush against the zone's own right edge - and so
     the rail's right edge - in the normal case where natural content is
     narrower than 480px. flex-shrink:0 on back-link/lang-picker/theme
     means only .asnet-account (default flex-shrink:1, left un-set below)
     ever compresses if natural content did exceed 480px - it can't pull
     width from the other three controls, and NAV is a separate grid track
     entirely so it was never reachable regardless (item 4's "ne dozvoli
     da sadržaj Account-a utiče na NAV track"). min-width:0 lets Account
     shrink below its own natural width if that ever happens, which is
     what lets .asnet-account__name's existing max-width/ellipsis (below)
     actually engage under real pressure instead of just overflowing. */
  .asnet-header__actions > .asnet-lang-picker,
  .asnet-header__actions > .asnet-theme-toggler,
  .asnet-header__actions > .asnet-back-link { flex: 0 0 auto; }
  .asnet-header__actions > .asnet-account,
  .asnet-header__actions > .asnet-header__auth { min-width: 0; }

  /*
    Canonical action-control grammar (item 5): one shared height (40px)
    and vertical-centering across Language/Theme/asnet.rs/Account. Border
    (1px solid var(--asnet-border-on-dark)) and border-radius
    (var(--asnet-radius-sm), already 8px in tokens.css - confirmed, not
    changed) were already identical across these three before this pass;
    only height/width previously diverged (36/36/38px). Selectors here are
    intentionally 2+ classes deep (.asnet-header__actions ancestor) so
    they reliably outrank .asnet-btn/.asnet-btn--sm's own min-height/width
    regardless of layout.css vs components.css load order - the exact
    cascade failure mode flagged for the public-site follow-up (item 5's
    "pre-existing cascade problem... 46px").
  */
  .asnet-header__actions .asnet-lang-picker__trigger { height: 40px; }
  .asnet-header__actions .asnet-icon-btn { width: 40px; height: 40px; }
  .asnet-header__actions .asnet-back-link { height: 40px; }
  .asnet-header__actions .asnet-account__trigger { height: 40px; box-sizing: border-box; }

  /* Avatar/chevron are fixed-size visual elements inside the trigger's own
     internal flex row (avatar, name, chevron) - protected from ever being
     compressed themselves; .asnet-account__name's PRE-EXISTING
     max-width:140px + overflow:hidden + text-overflow:ellipsis +
     white-space:nowrap (unchanged, not touched by this pass) already caps
     the trigger's own natural width deterministically - no flex:1/stretch
     needed on the name or the trigger for the "never exceeds 480px"
     guarantee; that ceiling was already correct and independent of any
     text-width estimate. */
  .asnet-account__avatar,
  .asnet-account__trigger > .asnet-icon { flex-shrink: 0; }
}

/* Compact desktop header: right above the 992px switch the container hasn't
   reached its 1180px cap yet - unlike full desktop (>=1280px, fixed
   120/516/480 grid, .asnet-container already exactly 1180px there so a
   fixed grid sum matches it exactly), .asnet-container in THIS band ranges
   937px (at exactly 992px, once scrollbar-gutter:stable's reserved
   scrollbar-width is accounted for - a real Chromium measurement, not the
   min(calc(100% - 40px),1180px) formula's own nominal 952px) up to 1180px
   (from ~1220px on) - a fixed-px middle track can't track that. Fixed
   outer edges (LOGO 104px, ACTIONS 355px) with a FLEXIBLE middle grid
   track - minmax(446px, 1fr) - resolves this: the track grows to consume
   whatever the container's variable width leaves over, so LOGO stays
   pinned to the rail's left edge and ACTIONS stays pinned to the rail's
   right edge at every width in this band, not just near 992px. Column-gap
   is 16px (not 18px): 104 + 16 + 446 + 16 + 355 = 937px, the exact
   Chromium-measured minimum at 992px - the previous 18px gap (941px
   minimum) left a 4px deficit against that real figure. The NAV element
   itself is NOT stretched to that grown track width, though - it keeps an
   explicit width:446px (with the same natural-width internal grid) and is
   justify-self:center within the (possibly wider) middle track, so NAV's
   own rendered width stays fixed regardless of viewport; only its centering
   offset changes. No margin-left:auto anywhere - the
   flexible track does the alignment work via ordinary grid sizing, not
   margin pushing. */
@media (min-width: 992px) and (max-width: 1279.98px) {
  .asnet-header__bar {
    grid-template-columns: 104px minmax(446px, 1fr) 355px;
    column-gap: 16px;
  }

  /* Logo 104x26px: unchanged from before this pass (26px height x its
     4:1 intrinsic ratio = 104px width - already matched the canonical
     compact logo cell exactly, confirmed, not re-derived). */
  .asnet-brand__logo { height: 26px; }

  /* Same content-sized six-item grammar as full desktop (see DOMAIN-01C
     comment above), distributed across the unchanged 446px compact NAV
     track - the tightest of the two desktop bands. --asnet-fs-xs (13px,
     what five items already used here) is the full-desktop six-item size
     now, so a sixth item in this narrower track needs to go below the
     smallest existing font-size token; there isn't one, hence the literal
     12px rather than a token. Same "could not be pixel-verified without a
     browser" caveat as above applies here too, more so given the tighter
     track. */
  .asnet-nav--desktop {
    width: 446px;
    justify-self: center;
    grid-template-columns: repeat(6, max-content);
    justify-content: space-between;
    column-gap: 0;
  }
  .asnet-nav--desktop .asnet-nav__link { font-size: 12px; }

  .asnet-header__actions { gap: 6px; width: 355px; }

  .asnet-header__actions .asnet-back-link { padding: 8px; height: 34px; }
  .asnet-header__back span { display: none; }

  .asnet-header__actions .asnet-lang-picker__trigger { height: 34px; padding: 0 6px; }

  .asnet-header__actions .asnet-icon-btn { width: 34px; height: 34px; }

  .asnet-header__actions .asnet-account__trigger {
    height: 34px;
    /* Vertical padding only, reduced from the full-desktop 4px/4px to
       2px/2px: the existing 28px avatar (avatar_size, set right where the
       account trigger markup calls `avatar()` in layout_default.html.twig -
       not changed here) plus the original 4px+4px padding needs 36px of
       content-box height, which doesn't fit inside a 34px box
       (border-box: 34 - 2px border = 32px available). 2px+2px fits it
       exactly (2+28+2=32). Horizontal padding (4px/12px) is unchanged. */
    padding-top: 2px;
    padding-bottom: 2px;
  }
  .asnet-account__name {
    /* Reduced from the full-desktop 140px, not the same value reused:
       estimated compact budget is ~141px (355 minus the other three
       compact controls' estimated combined width) - kept at 130px for
       the same estimation-safety-margin reasoning as the 140px full-
       desktop figure. Never widens the 355px track itself. */
    max-width: 130px;
  }

  .asnet-header__auth { gap: 6px; }
  .asnet-header__auth .asnet-btn--sm { padding: 0 8px; }
}

/* ---------------------------------------------------------------------
   Guest/public header + footer (login, signup, reset, status pages)
--------------------------------------------------------------------- */
/* Header geometry parity with the client shell (item 2 of this pass): same
   --asnet-header-height (72px) and same 30px logo scale as .asnet-header/
   .asnet-brand__logo above, so login/signup reads as the same ASNET
   product even though this surface stays permanently light. Only the
   background/border stay public-specific. */
.asnet-public-bar { border-bottom: 1px solid var(--asnet-border); background: var(--asnet-surface); }
.asnet-public-bar__row { display: flex; align-items: center; justify-content: space-between; min-height: var(--asnet-header-height); gap: var(--asnet-space-sm); }
.asnet-public-bar__actions { display: flex; align-items: center; gap: var(--asnet-space-xs); flex-shrink: 0; }

/* .asnet-icon-btn / .asnet-lang-picker__trigger default to the client
   header's dark-surface colors (see layout.css above); this permanently
   light surface needs its own light-surface variant, same idea as
   .asnet-btn--outline vs .asnet-btn--ghost for the back-link. */
.asnet-public-bar .asnet-icon-btn,
.asnet-public-bar .asnet-lang-picker__trigger {
  border-color: var(--asnet-border-strong);
  color: var(--asnet-text);
}
.asnet-public-bar .asnet-icon-btn:hover,
.asnet-public-bar .asnet-lang-picker__trigger:hover {
  background: var(--asnet-surface-muted);
}

/* This header has no mobile-nav drawer/collapse (unlike the client
   header), so on narrow screens the back-link drops its text label
   instead of disappearing - same "icon-only" compaction concept as the
   client header's 992-1279.98px band, just triggered by a plain
   small-screen breakpoint here since there's no desktop/mobile nav switch
   on this shell at all. */
@media (max-width: 480px) {
  .asnet-public-bar__row { gap: var(--asnet-space-2xs); }
  .asnet-public-bar__actions { gap: 6px; }
  .asnet-public-bar .asnet-back-link { padding: 0 10px; }
  .asnet-public-bar .asnet-back-link span { display: none; }
}

.asnet-public-main {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--asnet-space-xl) var(--asnet-space-sm);
}

body.asnet-public { display: flex; flex-direction: column; min-height: 100vh; }

/* Same sticky-to-bottom shell for the authenticated/client layout
   (layout_default.html.twig) as the public one above: header/main/footer
   are direct body children in both layouts, so flex-column + min-height on
   body plus flex:1 on the growing middle element (.asnet-main below) is
   enough - no position:fixed, no hardcoded content height. On short pages
   .asnet-main absorbs the leftover viewport height and the footer lands at
   the bottom; on long pages .asnet-main just grows past the viewport and
   the footer follows the content as normal. */
body.asnet-app { display: flex; flex-direction: column; min-height: 100vh; }

/* Same vertical padding as .asnet-footer below (item 3 of this pass): the
   client footer already uses --asnet-space-lg, this one used the smaller
   --asnet-space-md, so with no optional bank-info block on either surface
   the two footers previously differed by 32px of perceived height for no
   content reason. No fixed height on either - both stay content-driven,
   sticky-to-bottom via body.asnet-public/body.asnet-app + flex, unchanged. */
.asnet-public-footer { border-top: 1px solid var(--asnet-border); padding: var(--asnet-space-lg) 0; }
.asnet-public-footer__row {
  display: flex;
  flex-wrap: wrap;
  gap: var(--asnet-space-sm);
  align-items: center;
  justify-content: space-between;
  font-size: var(--asnet-fs-sm);
  color: var(--asnet-text-muted);
}
.asnet-public-footer nav { display: flex; gap: var(--asnet-space-md); flex-wrap: wrap; }
.asnet-public-footer a { color: var(--asnet-text-muted); }
.asnet-public-footer a:hover { color: var(--asnet-primary); }

/* ---------------------------------------------------------------------
   Content area, breadcrumb, footer (client area)
--------------------------------------------------------------------- */
.asnet-main { flex: 1 0 auto; padding-block: var(--asnet-space-lg) var(--asnet-space-xl); }

/*
  Root cause of the reported stray bullet / inconsistent spacing on
  Privatnost and Uslovi korišćenja: FOSSBilling's own (unoverridden, out of
  scope to touch - see compose.override.yaml's comment on Page's
  about-us/tos/privacy-policy) mod_page_tos.html.twig and
  mod_page_privacy-policy.html.twig override this file's `breadcrumb` block
  with stock Bootstrap-shaped markup:

      <li class="breadcrumb-item active" aria-current="page">Terms</li>

  - a bare <li>, not the <a>/<span class="asnet-breadcrumb__current"> this
  theme's own pages use. Two real bugs followed from that mismatch:

  1. Stray bullet: an <li> keeps `display: list-item` (and its default
     `list-style-type: disc` marker) from the UA stylesheet even with no
     <ul>/<ol> ancestor - browsers still generate the marker box. Nothing
     in this file previously reset list-style on children of
     .asnet-breadcrumb, so that lone <li> rendered its own bullet exactly
     where the review screenshots show one.
  2. Missing/inconsistent separator: the "/" separator was only ever added
     via `.asnet-breadcrumb a::after`, so it only ever appeared after an
     <a>. A trailing <li> (or any non-<a> current-item element) got no
     separator at all - "no clean relationship to the previous item", per
     the report.

  Fixed at the container level so this is a real ASNET-breadcrumb-wide
  fix, not a per-page workaround: list-style is reset on any list-item
  child regardless of source template, and the separator is generated for
  ANY non-first child via :not(:first-child)::before instead of only
  a::after - so it's identical whether the current item is this theme's
  own <span class="asnet-breadcrumb__current"> (Panel, Contact Us, ...) or
  a stock module's <li class="breadcrumb-item active"> (Privatnost, Uslovi
  korišćenja). .breadcrumb-item.active's color/weight (compat.css) already
  matched .asnet-breadcrumb__current, so no color change was needed there.
*/
.asnet-breadcrumb {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 0;
  font-size: var(--asnet-fs-sm);
  color: var(--asnet-text-muted);
  margin-bottom: var(--asnet-space-md);
  padding: 0;
  list-style: none;
}
.asnet-breadcrumb li { list-style: none; }
.asnet-breadcrumb a { color: var(--asnet-text-muted); text-decoration: none; }
.asnet-breadcrumb a:hover { color: var(--asnet-primary); }
.asnet-breadcrumb > :not(:first-child) { margin-left: 8px; }
.asnet-breadcrumb > :not(:first-child)::before {
  content: "/";
  margin-right: 8px;
  color: var(--asnet-border-strong);
}
.asnet-breadcrumb__current,
.asnet-breadcrumb .breadcrumb-item.active { color: var(--asnet-text); font-weight: 600; }

.asnet-footer {
  background: var(--asnet-surface-inverse);
  color: var(--asnet-text-on-dark-muted);
  border-top: 1px solid var(--asnet-border-on-dark-soft);
  padding: var(--asnet-space-lg) 0;
  margin-top: var(--asnet-space-xl);
}
.asnet-footer__row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--asnet-space-sm);
  font-size: var(--asnet-fs-sm);
}
.asnet-footer__links { display: flex; flex-wrap: wrap; gap: var(--asnet-space-sm) var(--asnet-space-md); margin: 0; padding: 0; list-style: none; }
.asnet-footer__links a { color: var(--asnet-text-on-dark-muted); }
.asnet-footer__links a:hover { color: #fff; }

/* Footer brand block: logo discreetly above the copyright line, left side
   of the footer row (item 2 of this pass). Reuses partial_company_logo.html.twig
   (dark_logo_url - the light-on-dark official variant - since the footer
   background is always the dark navy surface regardless of site theme, same
   as the header), just with its own compact sizing instead of the header's
   .asnet-brand/.asnet-brand__logo rules. */
.asnet-footer__brand { display: flex; flex-direction: row; align-items: center; gap: 11px; }
.asnet-footer__brand-link { display: inline-flex; align-items: center; }
.asnet-footer__logo { height: 25px; width: auto; display: block; }
.asnet-footer__signature { font-size: var(--asnet-fs-sm); opacity: 0.85; }
.asnet-footer__bank-info { margin-top: var(--asnet-space-sm); font-size: var(--asnet-fs-xs); }

.asnet-to-top {
  position: fixed;
  right: var(--asnet-space-md);
  bottom: var(--asnet-space-md);
  width: 44px;
  height: 44px;
  border-radius: 50%;
  background: var(--asnet-primary);
  color: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: var(--asnet-shadow-lifted);
  z-index: 45;
}
.asnet-to-top:hover { background: var(--asnet-primary-strong); }
.asnet-to-top .asnet-icon { transform: rotate(180deg); }

.asnet-toast-container {
  position: fixed;
  right: var(--asnet-space-md);
  bottom: var(--asnet-space-md);
  z-index: 1070;
  display: flex;
  flex-direction: column;
  gap: 8px;
  max-width: min(360px, calc(100vw - 2 * var(--asnet-space-md)));
}

/* Toast markup created by assets/js/messages.js (this theme's own
   FOSSBilling.message implementation - see that file for why one is
   needed at all). */
.asnet-toast {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: var(--asnet-space-sm);
  border-radius: var(--asnet-radius-sm);
  border: 1px solid;
  background: var(--asnet-surface-elevated);
  box-shadow: var(--asnet-shadow-lifted);
  font-size: var(--asnet-fs-sm);
  opacity: 0;
  transform: translateY(8px);
  transition: opacity var(--asnet-transition-base) var(--asnet-ease-out),
              transform var(--asnet-transition-base) var(--asnet-ease-out);
}
.asnet-toast.is-visible { opacity: 1; transform: translateY(0); }
.asnet-toast__icon { flex-shrink: 0; margin-top: 1px; }
.asnet-toast__text { flex: 1; margin: 0; color: var(--asnet-text); }
.asnet-toast__close {
  flex-shrink: 0;
  width: 22px;
  height: 22px;
  display: flex;
  align-items: center;
  justify-content: center;
  border: none;
  background: transparent;
  color: var(--asnet-text-muted);
  cursor: pointer;
  border-radius: 4px;
}
.asnet-toast__close:hover { background: var(--asnet-surface-muted); color: var(--asnet-text); }
.asnet-toast--info { border-color: var(--asnet-info-border); }
.asnet-toast--info .asnet-toast__icon { color: var(--asnet-info); }
.asnet-toast--success { border-color: var(--asnet-success-border); }
.asnet-toast--success .asnet-toast__icon { color: var(--asnet-success); }
.asnet-toast--warning { border-color: var(--asnet-warning-border); }
.asnet-toast--warning .asnet-toast__icon { color: var(--asnet-warning); }
.asnet-toast--danger { border-color: var(--asnet-danger-border); }
.asnet-toast--danger .asnet-toast__icon { color: var(--asnet-danger); }
