/*
 * copied from demo/assets @2026-07-04; demo remains the design source until P3 ports pages
 * Source: demo/assets/stellacris.css (verbatim copy, spec .build/specs/p2-platform.md §6).
 * Do not hand-edit divergently from the demo file - port changes back to demo/assets/stellacris.css
 * first, then re-copy, so the two never drift silently.
 */

/* ============================================================================
   stellacris.css  --  Stellacris shared design system + chrome
   Single source of truth linked by every demo page (admin / user / discovery).
   Harvested + merged from the canonical inline <style> blocks of:
     admin/researcher-detail.html, admin/01-home.html, admin/07-projects.html,
     user/01-home.html, user/05-my-outputs.html, discovery/01-home.html
   Plain CSS, no @import, ASCII comments only.
   Section index:
     (1)  Page scrollbar
     (2)  :root tokens
     (3)  Base / reset / typography
     (4)  Admin + user app shell (.app / .side / .side-nav)
     (5)  Topbar (.topbar / .tb-*)
     (6)  Buttons (.btn family)
     (7)  Badges (.b-badge)
     (8)  Tables (.dtbl / .tbl / pagination)
     (9)  Detail components (record header / tabs / fields / cards / match)
     (10) Dashboard + list components (KPI / sections / filters / health / pager)
     (11) User widget cards + claim tabs
     (12) Discovery horizontal nav (.nav-acc) + discovery page surfaces
     (13) Accessibility: focus-visible + reduced-motion guard
   ============================================================================ */


/* ============================================================================
   (1) PAGE SCROLLBAR  (design manual s31)
   stable gutter = no content shift on appear/disappear; fallback for old
   browsers; modal scroll lock; token-coloured thumb at native 14px width
   (NOT the forbidden 6px shrink anti-pattern).
   ============================================================================ */
html{scrollbar-gutter:stable;scrollbar-color:var(--border) var(--bg-alt)}
@supports not (scrollbar-gutter:stable){html{overflow-y:scroll}}
body.modal-open,body.nav-drawer-open{overflow:hidden}
::-webkit-scrollbar{width:14px;height:14px}
::-webkit-scrollbar-track{background:var(--bg-alt)}
::-webkit-scrollbar-thumb{background:var(--border);border-radius:7px;border:3px solid var(--bg-alt)}
::-webkit-scrollbar-thumb:hover{background:#cbd5e1}
::-webkit-scrollbar-corner{background:var(--bg-alt)}


/* ============================================================================
   (2) :ROOT TOKENS
   Full token set used across every layer + Bootstrap 5.3 --bs-* overrides.
   --page-inset: admin/app-shell baseline (clamp 1rem..1.5rem). User & discovery
   pages widen this + centre via .container-xxl rules below.
   --side-w: left sidebar width (admin pages reference the token; user pages
   used a literal 240px -- unified to the token here).
   ============================================================================ */
:root{
  --primary:#0f172a;
  /* accent darkened 2026-07-07 to #2563eb (blue-600) so link text + white-on-accent
     buttons clear WCAG 2.1 AA 4.5:1 on white (was #3b82f6 ~3.68:1). knowledge/31 §8 P1. */
  --accent:#2563eb;
  --text:#1e293b;
  --text-muted:#64748b;
  --border:#e2e8f0;
  --bg:#ffffff;
  --bg-alt:#f8fafc;
  /* Element surface tint (table headers, row/menu/card hover) - a 4th,
     independently editable brand color (Branding::DEFAULT_TINT / settings
     "Farba podfarbenia") so shaded elements never blend into the page
     background. Overridden per-tenant by Branding::headStyle() when set. */
  --tint:#e9edf2;
  --success:#22c55e;
  --danger:#ef4444;
  --warning:#f59e0b;
  --hero-from:#0a0e1a;
  --hero-to:#1a1f35;
  --page-inset:clamp(1rem,2vw,1.5rem);
  --side-w:240px;
  --rail-w:56px;
  /* Bootstrap 5.3 overrides */
  --bs-primary:#0f172a;
  --bs-primary-rgb:15,23,42;
  --bs-link-color:#2563eb;
  --bs-link-hover-color:#1d4ed8;
  --bs-border-color:#e2e8f0;
  --bs-border-radius:2px;
  --bs-border-radius-sm:2px;
  --bs-border-radius-lg:2px;
  --bs-border-radius-xl:2px;
  --bs-border-radius-pill:2px;
  --bs-btn-border-radius:2px;
  --bs-btn-font-weight:600;
  --bs-body-font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif;
  --bs-body-color:#1e293b;
  --bs-body-bg:#ffffff;
}
@media (min-width:1900px){:root{--page-inset:2rem}}


/* ============================================================================
   (3) BASE / RESET / TYPOGRAPHY
   ============================================================================ */
*{box-sizing:border-box}
body{margin:0;line-height:1.6;color:var(--text);background:var(--bg-alt);font-size:.95rem;-webkit-font-smoothing:antialiased}
h1,h2,h3,h4,h5,h6{font-weight:600;color:var(--primary);letter-spacing:-.01em}
a{color:var(--accent);text-decoration:none}
a:hover{text-decoration:underline;text-underline-offset:3px}
/* Inline prose links (axe: link-in-text-block, SC 1.4.1 - a link cannot rely
   on color alone to stand out from its surrounding text; --accent measures
   well under 3:1 against both --text and --text-muted, spec
   u2-wcag-formal-audit.md). Scoped to the specific "hint sentence with a
   trailing link" pattern (admin/settings institution note, admin/gdpr audit
   link, discovery cookie banner) rather than underlining every <a> site-wide
   (nav/card/button links intentionally stay underline-free - not a redesign). */
.u-link{text-decoration:underline;text-underline-offset:2px}
.rounded,.rounded-1,.rounded-2,.rounded-3,.rounded-pill,.rounded-circle{border-radius:2px!important}
.text-muted{color:var(--text-muted)!important}
.mono{font-family:Monaco,'Courier New',monospace;font-variant-numeric:tabular-nums}


/* ============================================================================
   (4) ADMIN + USER APP SHELL  (.app grid / .side / .side-nav)
   The left sidebar scrolls when long but its OWN scrollbar is hidden
   (scrollbar-width:none + ::-webkit-scrollbar display:none) while keeping
   overflow-y:auto. .side-footer / .side-user intentionally omitted -- that
   block is being removed from the product.
   ============================================================================ */
.app{display:grid;grid-template-columns:var(--side-w) 1fr;min-height:100vh;transition:grid-template-columns .18s}

/* Collapsible navigation (2026-07-07). A single state on <html data-nav> drives
   the sidebar everywhere - set flash-free by an inline <head> script and toggled
   by the brand burger (.side-collapse, data-side-toggle) through assets/facets.js:
     full = desktop labelled sidebar (default at >=992px)
     rail = icons-only column that STAYS on the page (default <992px, or when the
            user collapses on desktop - persisted in localStorage 'nav-collapsed')
     open = mobile overlay - the full labelled sidebar slides over the content
   The rail LOOK is written once (keyed on [data-nav="rail"]); full/open simply
   reuse the default labelled .side-* rules, so no per-property "restore". */
html[data-nav="rail"] .app{grid-template-columns:var(--rail-w) 1fr}
html[data-nav="rail"] .side-head{justify-content:center;padding-top:.8rem}
html[data-nav="rail"] .side-head .side-brand{display:none}
html[data-nav="rail"] .side-collapse{margin-right:0}
html[data-nav="rail"] .side-context,
html[data-nav="rail"] .side-section{display:none}
html[data-nav="rail"] .side-nav a{justify-content:center;gap:0;font-size:0;padding:.8rem 0;border-left-width:0;position:relative}
html[data-nav="rail"] .side-nav a i{font-size:1.05rem;width:auto}
html[data-nav="rail"] .side-nav a .b{position:absolute;top:.15rem;right:.35rem;margin:0;font-size:.5rem;padding:0 .18rem;line-height:1.4;border:0}
@media (max-width:991.98px){
  /* Mobile (2026-07-07 fix): the sidebar is an OFF-CANVAS drawer, not a
     persistent rail. A position:fixed .side is removed from grid flow, so a
     reserved rail column left the ONLY remaining in-flow grid item (.content)
     auto-placed into that narrow track - the whole page collapsed behind the
     rail. Now the grid is a single column (content full width) and the topbar
     burger (.tb-burger) slides the full labelled sidebar in as an overlay with
     a backdrop. `html[data-nav] .app` matches the (0,2,1) specificity of the
     desktop rail rule so it wins here by source order; `.app .side` outranks the
     base `.side{position:sticky}` declared later. */
  html[data-nav] .app{grid-template-columns:1fr}
  /* 100dvh (not 100vh) so the fixed off-canvas height excludes the mobile
     browser's bottom URL bar; padding-bottom (safe-area + 2rem) gives the last
     nav item scroll clearance so it can be reached ABOVE the URL bar even where
     dvh is unsupported (user 2026-07-11: "posledna polozka v menu nikdy nejde
     nascrolovat ... pod systemovym priestorom na url"). */
  .app .side{position:fixed;left:0;top:0;height:100vh;height:100dvh;padding-bottom:calc(env(safe-area-inset-bottom,0px) + 2rem);z-index:200;width:min(264px,84vw);transform:translateX(-100%);transition:transform .18s;overflow-x:hidden}
  html[data-nav="open"] .app .side{transform:translateX(0);box-shadow:2px 0 12px rgba(15,23,42,.15)}
}
.side{background:#fff;color:var(--text);border-right:1px solid var(--border);display:flex;flex-direction:column;position:sticky;top:0;height:100vh;overflow-y:auto;scrollbar-width:none;padding-bottom:calc(1.5rem + env(safe-area-inset-bottom,0px))}
.side::-webkit-scrollbar{display:none}
.side-brand{padding:1rem 1.25rem;display:flex;align-items:center;gap:.6rem;border-bottom:1px solid var(--border);color:var(--primary);text-decoration:none}
.side-brand:hover{color:var(--primary);text-decoration:none}
.side-brand strong{font-weight:800;font-size:1.05rem;letter-spacing:-.3px;color:var(--primary)}
.side-brand .tag{display:inline-block;font-size:.6rem;font-weight:700;letter-spacing:.1em;text-transform:uppercase;color:var(--accent);margin-left:.4rem;padding:.1rem .35rem;background:rgba(59,130,246,.1);border-radius:2px}
/* Sidebar header row: brand link + collapse burger (nav toggle, visible at
   EVERY width - the user can collapse the desktop sidebar to the rail at will).
   The burger sits next to the wordmark when expanded and is the only visible
   control in the rail. */
.side-head{display:flex;align-items:center;border-bottom:1px solid var(--border)}
.side-head .side-brand{flex:1;border-bottom:0}
.side-collapse{display:inline-flex;flex-shrink:0;background:transparent;border:0;padding:.5rem .7rem;margin-right:.35rem;color:var(--text-muted);font-size:1.05rem;line-height:1;cursor:pointer}
.side-collapse:hover{color:var(--primary)}
.side-context{padding:.75rem 1.25rem;border-bottom:1px solid var(--border)}
.side-context .lbl{font-size:.6rem;letter-spacing:.1em;text-transform:uppercase;color:var(--text-muted);font-weight:700;margin-bottom:.15rem}
/* View/role pill above the institution name (2026-07-07): moved out of the
   brand row so the wordmark stands alone; uses the accent token pair, 2px
   radius - same language as the old .side-brand .tag. */
.side-role{display:inline-block;font-size:.58rem;font-weight:700;letter-spacing:.09em;text-transform:uppercase;color:var(--accent);background:rgba(var(--accent-rgb),.1);padding:.13rem .45rem;border-radius:2px;margin-bottom:.4rem}
.side-context .name{font-size:.88rem;color:var(--primary);font-weight:600}
.side-section{padding:.85rem 1.25rem .35rem;font-size:.6rem;letter-spacing:.1em;text-transform:uppercase;color:var(--text-muted);font-weight:700}
.side-nav{display:flex;flex-direction:column}
.side-nav a{padding:.55rem 1.25rem;font-size:.875rem;color:var(--text);text-decoration:none;display:flex;align-items:center;gap:.7rem;border-left:3px solid transparent;transition:.12s}
.side-nav a:hover,.side-nav a:focus-visible{background:var(--tint);color:var(--primary);text-decoration:none}
.side-nav a.active{background:rgba(59,130,246,.08);border-left-color:var(--accent);color:var(--primary);font-weight:600}
.side-nav a i{width:18px;text-align:center;font-size:.92rem;color:var(--text-muted);transition:color .12s}
.side-nav a:hover i,.side-nav a:focus-visible i{color:var(--primary)}
.side-nav a.active i{color:var(--accent)}
.side-nav a .b{margin-left:auto;font-family:Monaco,monospace;font-size:.7rem;background:var(--bg-alt);color:var(--text-muted);padding:.05rem .35rem;border-radius:2px;font-weight:700;border:1px solid var(--border)}
.content{display:flex;flex-direction:column;min-width:0}


/* ============================================================================
   (5) TOPBAR  (.topbar / .tb-*)
   ============================================================================ */
.topbar{display:flex;align-items:center;gap:1rem;padding:0 var(--page-inset);background:#fff;border-bottom:1px solid var(--border);height:56px;position:sticky;top:0;z-index:100}
/* min-width:0 is what makes the shrink work: a flex item defaults to
   min-width:auto, so a nowrap heading refuses to go below its full text width
   and pushes the whole page into a horizontal scroll. A long record title
   (project/output name in $pageTitle) did exactly that between 992 and 1440px
   - the rule below used to live ONLY in the <=991.98px media query, so the
   desktop range was unprotected (user report 2026-07-31). Truncation with an
   ellipsis is correct at every width; the full title is always visible in the
   record header inside <main>. */
.topbar h1{font-size:1.05rem;margin:0;font-weight:700;white-space:nowrap;flex:1 1 0;min-width:0;overflow:hidden;text-overflow:ellipsis}
.tb-crumb{display:flex;align-items:center;gap:.5rem;font-size:.85rem;color:var(--text-muted);white-space:nowrap}
.tb-crumb a{color:var(--text-muted);font-weight:600}
.tb-crumb a:hover{color:var(--primary)}
.tb-crumb .sep{color:var(--border)}
.tb-crumb .here{color:var(--primary);font-weight:600}
.tb-search{position:relative;flex:1;max-width:420px}
.tb-search input{width:100%;height:36px;padding:0 .75rem 0 2.1rem;border:1px solid var(--border);border-radius:2px;background:var(--bg-alt);font-size:.85rem;font-family:inherit;outline:0}
.tb-search input:focus{background:#fff;border-color:var(--primary)}
.tb-search i{position:absolute;left:.7rem;top:50%;transform:translateY(-50%);color:var(--text-muted);font-size:.82rem}
.tb-right{margin-left:auto;display:flex;align-items:center;gap:.5rem}
.tb-add{background:var(--accent);border:1px solid var(--accent);color:#fff;font-weight:600;font-size:.85rem;padding:.45rem .9rem;border-radius:2px;display:inline-flex;align-items:center;gap:.4rem;text-decoration:none}
.tb-add:hover{background:#2563eb;color:#fff;text-decoration:none}
.tb-role{display:inline-flex;align-items:center;gap:.45rem;font-size:.82rem;font-weight:600;color:var(--text);background:#fff;border:1px solid var(--border);border-radius:2px;padding:.4rem .7rem;cursor:pointer}
.tb-role i{color:var(--text-muted);font-size:.65rem}
.tb-ico{display:inline-flex;align-items:center;justify-content:center;background:transparent;border:0;padding:.45rem;color:var(--text-muted);cursor:pointer;font-size:1rem;position:relative;text-decoration:none}
.tb-ico:hover{color:var(--primary)}
.tb-pip{position:absolute;top:.3rem;right:.28rem;width:6px;height:6px;background:var(--danger);border-radius:50%}
/* Pending-update indicator in the topbar (2026-07-07): accent icon + small
   coloured count badge; shown only when /admin/update has pending work. */
.tb-update{color:var(--accent)}
.tb-update:hover{color:var(--link-hover)}
/* BOTTOM-right, not the conventional top-right: fa-arrow-rotate-right carries
   its arrowhead in the TOP-RIGHT corner, and a badge there covered it exactly,
   leaving a plain broken circle that no longer read as "refresh" (user report
   2026-08-16). Measured against three alternatives at 6x zoom: bottom-right
   keeps the arrowhead fully legible and only clips the arc's tail; bottom-LEFT
   also frees the arrowhead but sits visually detached from the glyph; pushing
   it further out of the top-right corner clears the arrowhead but collides
   with the neighbouring topbar control. */
.tb-updot{position:absolute;bottom:-1px;right:-3px;min-width:15px;height:15px;padding:0 3px;border-radius:8px;background:#b91c1c;color:#fff;font-size:.6rem;font-weight:700;line-height:15px;text-align:center;box-shadow:0 0 0 2px #fff}
.tb-acct{display:inline-flex;align-items:center;gap:.45rem;border-left:1px solid var(--border);padding-left:.7rem;margin-left:.2rem;color:var(--text);text-decoration:none}
.tb-acct:hover{color:var(--primary);text-decoration:none}
.tb-acct .av{width:30px;height:30px;background:var(--bg-alt);border:1px solid var(--border);border-radius:2px;display:inline-flex;align-items:center;justify-content:center;font-size:.7rem;font-weight:700;color:var(--primary)}

/* --- TOPBAR kebab (mobile) -------------------------------------------------
   The secondary topbar controls (accessibility, language, open-discovery,
   account, logout) are wrapped in <details class="tb-kebab"> in all three app
   shells (admin/layout, shell/admin, user/layout). Two mutually-exclusive
   breakpoints keep one set of markup doing both jobs (user 2026-07-11):
     - Desktop (>=992px): the whole thing is display:contents so the controls
       become direct flex children of .tb-right - pixel-identical to before,
       and the kebab summary is hidden.
     - Mobile (<992px): display:contents is dropped; the summary shows as an
       icon button and the panel becomes an absolutely-positioned dropdown that
       only renders when the <details> is open. No-JS still works (native
       disclosure); nav-dropdowns.js only refines outside-click / Escape close.
   The kebab marker triangle is suppressed on the summary. */
.tb-kebab-btn{list-style:none;cursor:pointer;align-items:center;justify-content:center;padding:.45rem;color:var(--text-muted);font-size:1.05rem;border-radius:2px}
.tb-kebab-btn::-webkit-details-marker{display:none}
.tb-kebab-btn:hover{color:var(--primary)}
@media (min-width:992px){
  .tb-kebab{display:contents}
  .tb-kebab-btn{display:none}
  .tb-kebab-panel{display:contents}
  /* Chrome 128+ hides a CLOSED <details>'s content via the ::details-content
     pseudo (content-visibility:hidden), which display:contents does NOT
     override - so the desktop topbar utilities (a11y, language, discovery,
     account, logout) vanished on newer engines. Neutralise the pseudo so the
     inline desktop layout shows regardless of open state (nav-dropdowns.js
     additionally forces `open` on desktop for engines without this pseudo). */
  .tb-kebab::details-content{display:contents;content-visibility:visible}
}
/* Kebab item text labels: hidden by default (desktop topbar = icon-only), shown
   only inside the mobile dropdown panel below. */
.kebab-label{display:none}
@media (max-width:991.98px){
  .tb-kebab{position:relative;display:inline-flex}
  .tb-kebab-btn{display:inline-flex}
  .tb-kebab-panel{display:none}
  .tb-kebab[open] .tb-kebab-panel{display:flex;flex-direction:column;align-items:stretch;gap:.15rem;position:absolute;right:0;top:calc(100% + 8px);min-width:210px;background:#fff;border:1px solid var(--border);border-radius:2px;box-shadow:0 8px 24px rgba(15,23,42,.16);padding:.35rem .35rem calc(.6rem + env(safe-area-inset-bottom, 0px));z-index:300}
  /* Normalise the wrapped controls into a clean stacked list inside the panel:
     every row identical - NO inherited framed-button chrome (the a11y + langsw
     summaries carry a 32px border/background box on desktop, which read as a
     design bug inside the stacked panel; user 2026-07-12), uniform height,
     text color and one aligned icon column. */
  .tb-kebab-panel>*{width:100%}
  .tb-kebab-panel .a11y-menu>summary,.tb-kebab-panel .langsw>summary,.tb-kebab-panel .tb-ico,.tb-kebab-panel .tb-acct{display:flex;align-items:center;width:100%;justify-content:flex-start;padding:.55rem .6rem;border:0;background:transparent;height:auto;min-width:0;margin:0;border-radius:2px;font-size:.9rem;color:var(--text)}
  .tb-kebab-panel .a11y-menu>summary i,.tb-kebab-panel .langsw>summary i,.tb-kebab-panel .tb-ico i{width:1.2rem;text-align:center;font-size:1rem;color:var(--text-muted);flex-shrink:0}
  .tb-kebab-panel .tb-acct{padding-left:.6rem;border-left:0}
  .tb-kebab-panel .a11y-menu>summary:hover,.tb-kebab-panel .langsw>summary:hover,.tb-kebab-panel .tb-ico:hover,.tb-kebab-panel .tb-acct:hover{background:var(--tint);color:var(--text)}
  .tb-kebab-panel .a11y-menu[open]>summary{background:var(--tint);border:0;color:var(--text)}
  .tb-kebab-panel .langsw[open]>summary{background:var(--tint);border:0;color:var(--text)}
  /* Account menu inside the mobile kebab: the chip becomes a full-width row
     like its neighbours, and its panel drops inline instead of floating -
     an absolutely-positioned submenu inside an already-absolute kebab panel
     would hang off the screen edge on a phone. */
  .tb-kebab-panel .acctmenu{display:block;width:100%}
  .tb-kebab-panel .acctmenu>summary{width:100%}
  .tb-kebab-panel .acct-menu{position:static;min-width:0;border:0;box-shadow:none;padding:.1rem 0 .2rem .9rem;background:transparent}
  .tb-kebab-panel .acctmenu[open]>summary{background:var(--tint);color:var(--text)}
  /* logout form: make its button a full-width row like the others. */
  .tb-kebab-panel form[action="/logout"]{width:100%}
  .tb-kebab-panel form[action="/logout"] .tb-ico{width:100%;justify-content:flex-start;padding:.5rem .55rem}
  /* Icon-only controls get a readable text label INSIDE the dropdown so a new
     user can tell what each item does; the desktop topbar stays icon-only
     (.kebab-label is display:none there). */
  .tb-kebab-panel .kebab-label{display:inline;font-size:.9rem;color:inherit}
  .tb-kebab-panel .a11y-menu>summary,.tb-kebab-panel .langsw>summary,.tb-kebab-panel .tb-ico,.tb-kebab-panel .tb-acct,.tb-kebab-panel form[action="/logout"] .tb-ico{gap:.6rem}
}


/* ============================================================================
   (6) BUTTONS  (.btn family)
   Canonical chrome button (admin baseline padding). Dark / outline use the
   dominant inverted-hover pattern (dashboard, list, user, discovery pages).
   ============================================================================ */
.btn{border-radius:2px;font-weight:600;transition:.18s;padding:.5rem 1.1rem;font-size:.875rem;border:1px solid transparent;display:inline-flex;align-items:center;gap:.4rem;justify-content:center;line-height:1.2;font-family:inherit;cursor:pointer;text-decoration:none;white-space:nowrap}
.btn:hover{text-decoration:none}
/* Action-only forms (a submit .btn + hidden fields / an optional hint <p>, no
   visible input) become a shrink-to-content flex column instead of a block:
   this removes the block line-box "strut" that offset the wrapped button from
   a sibling bare .btn in the same row (user 2026-07-06: "tlacidla su vychylene
   a nie su riadne vedla seba"). ROOT FIX (2026-07-07, user "tato chyba sa
   vsade opakuje ... tlacidla stale nie su v jednej linii"): make such a lone-
   button CSRF form display:contents so it has NO box of its own - the button
   becomes a direct child of whatever container the form sits in (a flex button
   row -> aligns as a flex item; a plain block -> flows inline-block naturally).
   This replaces the earlier per-spot `style="display:contents"` patches (which
   only fixed the one header they were on) and the previous flex-column-form
   approach (as a flex item the form still carried intrinsic width/margin and
   spaced rows unevenly). Forms with real fields (visible input / select /
   textarea / .fg / .mf-fields) are excluded and keep their normal block box;
   forms with TWO+ buttons (.wfbar Submit + Validate) are excluded via
   :not(:has(> .btn ~ .btn)) - they lay their buttons out themselves.

   W39 part D - OPT-OUT `.form-self-placed`: display:contents removes the form's
   box, which also makes its own `position:absolute` inert. A form that PLACES
   ITSELF (absolute/grid/flex coordinates) therefore silently collapsed into
   normal flow and its button dropped BELOW the content it was supposed to sit
   beside - the reported "krizky na odstranenie pod textom a nie vedla neho" on
   the project status roadmap (.rm-delete). Any self-positioning lone-button form
   must carry `.form-self-placed` so this rule skips it. A named opt-out, not a
   per-spot exception list: the next such form inherits the fix instead of
   rediscovering the bug. */
form:has(> .btn):not(.form-self-placed):not(:has(> .btn ~ .btn)):not(:has(input:not([type="hidden"]))):not(:has(select)):not(:has(textarea)):not(:has(.fg)):not(:has(.mf-fields)){display:contents}
/* UNIVERSAL button-row alignment (2026-07-08 - user "tlacidlo spustit stale nie
   je v jednej rovine ... univerzalne to oprav, opakujuca chyba a antipattern").
   The :has() rule above (CSS :has() ships only from 2023 - Chrome 105 / Firefox
   121 / Safari 15.4) is IGNORED WHOLESALE on older/other engines, so any bare
   single-button <form> stays a block element and its button drops off the row -
   the exact recurring stagger. This container-scoped rule needs NO :has(): every
   direct-child <form> of a known button-row container is made layout-transparent
   so its button becomes a flex sibling of the other buttons/links and sits on
   the SAME line. display:contents is supported everywhere since 2018 (Chrome 65
   / Firefox 37 / Safari 11.1). 2-button forms (.wfbar) are fine too - both
   buttons simply flow as siblings. This is the durable universal fix; the
   per-page inline `style="display:contents"` patches are now redundant. */
.actions > form,
.rec-header .actions > form,
.wfbar > form,
.btn-row > form,
.toolbar > form,
.dbar > form,
.danger-row > form{display:inline-flex;align-items:center;gap:.4rem;margin:0}
/* inline-flex (not display:contents) so a form carrying a <select> + button
   (e.g. .lifecycle-switch: state dropdown + "Zmenit stav") ALSO aligns on the
   row - display:contents promoted only bare buttons and left select-forms
   baseline-misaligned (user 2026-07-08 "nie je to zarovnane ... malo to byt
   univerzalne opravene"). As an inline-flex flex-item of the align-items:center
   row, the whole form sits centered and its own contents are centered too;
   respects intentional inline-flex forms instead of overriding them. */
.btn-sm{padding:.35rem .75rem;font-size:.8rem}
.btn-dark{background:var(--primary);border-color:var(--primary);color:#fff}
.btn-dark:hover{background:#fff;color:var(--primary);border-color:var(--primary)}
.btn-outline-dark{background:#fff;border-color:var(--border);color:var(--text)}
.btn-outline-dark:hover{background:var(--primary);border-color:var(--primary);color:#fff}
.btn-danger-soft{background:#fff;border-color:rgba(239,68,68,.4);color:#b91c1c}
.btn-danger-soft:hover{background:#b91c1c;border-color:#b91c1c;color:#fff}
.btn-ghost{background:transparent;color:var(--text-muted)}
/* Discovery hero light button (on dark background) */
.btn-light-brand{background:#fff;border-color:#fff;color:var(--primary)}
.btn-light-brand:hover{background:transparent;color:#fff;border-color:#fff}


/* ============================================================================
   (7) BADGES  (.b-badge)
   ============================================================================ */
.b-badge{display:inline-block;padding:.2rem .55rem;font-size:.68rem;font-weight:700;text-transform:uppercase;letter-spacing:.05em;border-radius:2px;line-height:1.5}
.b-badge.dark{background:var(--primary);color:#fff}
.b-badge.muted{background:var(--bg-alt);color:var(--primary);border:1px solid var(--border)}
.b-badge.accent{background:rgba(59,130,246,.1);color:var(--accent)}
/* alpha .06 not .12/.12 (knowledge/31 sec 8 gap, axe: SERIOUS color-contrast,
   spec u2-wcag-formal-audit.md) - .idline/.rec-header have no own background,
   so these badges often sit directly on --bg-alt (#f8fafc) rather than a
   white card; text on the OLD tint measured 4.35:1 (ok) / 4.40:1 (warn)
   there, just under the 4.5:1 AA text threshold. Lighter tint clears both
   (~4.57-4.58:1) without touching --success/--warn or the badge text colors. */
.b-badge.ok{background:rgba(34,197,94,.06);color:#15803d}
.b-badge.warn{background:rgba(245,158,11,.06);color:#b45309}
.b-badge.danger{background:rgba(239,68,68,.12);color:#b91c1c}
.b-badge.info{background:#dbeafe;color:#1d4ed8}
.b-badge.purple{background:#f3e8ff;color:#7e22ce}


/* ============================================================================
   (8) TABLES  (.dtbl admin / .tbl user-discovery / pagination)
   ============================================================================ */
/* --- .dtbl (admin detail + list) --- */
.dtbl{width:100%;border-collapse:collapse;font-size:.86rem;background:#fff}
.dtbl thead th{text-align:left;font-size:.66rem;text-transform:uppercase;letter-spacing:.06em;color:var(--accent);font-weight:700;padding:.6rem 1rem;border-bottom:2px solid var(--accent);background:var(--tint);white-space:nowrap}
.dtbl tbody td{padding:.7rem 1rem;border-bottom:1px solid var(--border);vertical-align:middle;color:var(--text)}
.dtbl tbody tr:last-child td{border-bottom:0}
.dtbl tbody tr:hover{background:var(--tint)}
.dtbl a{font-weight:600}
.dtbl .num{font-family:Monaco,monospace;font-variant-numeric:tabular-nums}
.dtbl td.num,.dtbl th.num{text-align:right}
.dtbl .code{font-family:Monaco,monospace;font-size:.8rem;color:var(--primary);font-weight:600;white-space:nowrap}
.dtbl .ttl{color:var(--primary);font-weight:600;line-height:1.35;display:block}
.dtbl .acr{font-size:.72rem;color:var(--text-muted);font-family:Monaco,monospace}
.dtbl .sub{font-size:.76rem;color:var(--text-muted)}
.dtbl .amt{font-family:Monaco,monospace;font-variant-numeric:tabular-nums;white-space:nowrap;color:var(--primary);font-weight:600}
.dtbl .row-actions{display:flex;gap:.25rem;justify-content:flex-end;white-space:nowrap}
.dtbl-wrap{background:#fff;border:1px solid var(--border);border-radius:2px;overflow-x:auto;-webkit-overflow-scrolling:touch}
.tbl-foot{padding:.8rem 1rem;font-size:.84rem}
.add-link{display:inline-flex;align-items:center;gap:.4rem;font-size:.8rem;font-weight:600;color:var(--accent);margin-top:1rem}
.icon-btn{display:inline-flex;align-items:center;justify-content:center;width:28px;height:28px;border:1px solid var(--border);background:#fff;border-radius:2px;color:var(--text-muted);cursor:pointer;font-size:.78rem;text-decoration:none;transition:.12s}
.icon-btn:hover{background:var(--primary);border-color:var(--primary);color:#fff;text-decoration:none}
.icon-btn.warn{color:#b45309;border-color:rgba(245,158,11,.35)}
.icon-btn.warn:hover{background:#b45309;border-color:#b45309;color:#fff}
.btn-ok{background:#15803d;border-color:#15803d;color:#fff}
.btn-ok:hover{background:#16a34a;border-color:#16a34a;color:#fff}

/* --- .tbl (user + discovery) --- */
.tbl{width:100%;border-collapse:separate;border-spacing:0;overflow:hidden;font-size:.88rem;background:#fff}
.tbl th,.tbl td{padding:.85rem 1rem;text-align:left;vertical-align:middle;border-bottom:1px solid var(--border)}
.tbl thead th{background:var(--bg-alt);font-size:.68rem;letter-spacing:.07em;text-transform:uppercase;color:var(--text-muted);font-weight:700}
.tbl tbody tr:last-child td{border-bottom:0}
.tbl tbody tr:hover td{background:#fafbfc}
.tbl .num{font-family:Monaco,monospace;font-size:.82rem}
.tbl .title-cell{font-weight:600;color:var(--primary)}
.tbl .title-cell a{color:var(--primary)}
.tbl .title-cell a:hover{color:var(--accent)}
.tbl .title-sub{font-weight:400;font-size:.78rem;color:var(--text-muted);margin-top:.2rem}
.tbl .actions{display:flex;gap:.3rem;justify-content:flex-end}

/* --- pagination: list .pager / .pg-btn (admin) + Bootstrap .pagination (user) --- */
.pager{display:flex;align-items:center;justify-content:space-between;gap:1rem;margin-top:1rem;flex-wrap:wrap}
.pager .info{font-size:.8rem;color:var(--text-muted)}
.pager .ctrls{display:flex;gap:.3rem}
.pg-btn{min-width:32px;height:32px;display:inline-flex;align-items:center;justify-content:center;border:1px solid var(--border);background:#fff;border-radius:2px;color:var(--text);font-size:.82rem;cursor:pointer;text-decoration:none;padding:0 .5rem}
.pg-btn:hover{border-color:#94a3b8;text-decoration:none}
.pg-btn.active{background:var(--primary);border-color:var(--primary);color:#fff;font-weight:700}
.pg-btn.disabled{opacity:.45;pointer-events:none}
.pagination{display:inline-flex;gap:0;border:1px solid var(--border);border-radius:2px;overflow:hidden;margin:0}
.pagination .page-item .page-link{padding:.5rem .8rem;font-size:.875rem;color:var(--text);background:#fff;border:0;border-right:1px solid var(--border);border-radius:0}
.pagination .page-item:last-child .page-link{border-right:0}
.pagination .page-item.active .page-link{background:var(--primary);color:#fff}
.pagination .page-item.disabled .page-link{color:var(--text-muted);background:var(--bg-alt)}


/* ============================================================================
   (9) DETAIL COMPONENTS  (record header / tabs / fields / aside cards / match)
   ============================================================================ */
.main{padding:1.5rem var(--page-inset) 3rem}

/* Record header -- identity once */
/* flex-wrap belongs on the BASE rule, not only in the <=991.98px branch: the
   action row is flex-shrink:0 (buttons must not be squashed), so on a page with
   many actions it keeps its full max-content width - 843px on
   /admin/integrations/crepc - and with nowrap it simply pushed the page into a
   horizontal scroll once the content column got narrower than that (measured at
   1024px: doc 1231 vs viewport 1024). Wrapping costs nothing at wide widths
   because there is room to stay on one line; it only engages when the row would
   otherwise overflow. Same drift as .topbar h1, found by the same sweep
   (2026-07-31). */
.rec-header{display:flex;flex-wrap:wrap;align-items:flex-start;gap:1.25rem;margin-bottom:1.25rem}
.rec-header .av-lg{width:88px;height:88px;border-radius:2px;background:var(--primary);color:#fff;display:flex;align-items:center;justify-content:center;font-size:2rem;font-weight:700;flex-shrink:0}
.rec-header .meta{flex:1;min-width:0}
/* h2 here on purpose (WCAG audit-lite p8-hardening.md sec C1): the admin/user
   layout topbar already renders the page's single <h1> (= this same record
   title/name via pageTitle); this record-header heading is a visual repeat of
   that identity inside the content area, so it must sit one level below the
   page h1, not duplicate it. Selector still matches historical h1 markup too,
   in case a page has not been converted. */
.rec-header h1,.rec-header h2{font-size:1.5rem;font-weight:700;margin:0;line-height:1.2}
.rec-header .affil{font-size:.9rem;color:var(--text-muted);margin-top:.3rem}
.rec-header .idline{display:flex;gap:.85rem;flex-wrap:wrap;align-items:center;margin-top:.6rem;font-size:.82rem}
.rec-header .idline a{font-weight:600}
.rec-header .idline .dot{color:var(--border)}
/* max-width:100% is what lets the inner flex-wrap actually engage. flex-shrink:0
   is deliberate (buttons must not be squashed into unreadable slivers), but it
   also means the row's used width is its max-content width - 843px on the CREPC
   page - even after .rec-header wrapped it onto a line of its own. Clamping to
   the container is what forces the BUTTONS to wrap instead of the page. */
.rec-header .actions{display:flex;gap:.5rem;flex-shrink:0;max-width:100%;flex-wrap:wrap;justify-content:flex-end;align-items:center}
.rec-metrics{display:flex;gap:1.75rem;font-size:.85rem;color:var(--text-muted);padding:.7rem 1rem;background:#fff;border:1px solid var(--border);border-radius:2px;margin-bottom:1rem}
.rec-metrics b{color:var(--primary);font-family:Monaco,monospace;font-weight:700;font-size:1rem;margin-right:.3rem}

/* Tabs (Pure / WoS style) */
/* Record-tab bar sticky offset. Admin/user layer: sits directly under the
   sticky .topbar (56px default; user 2026-07-08 "navbar sa lepi ale bar sa
   nelepi"). Discovery layer: the top nav (.nav-acc) is NOT sticky (user
   2026-07-09), so the tab bar sticks to the viewport top (0px) instead.
   Covers .rec-tabs (admin) AND .record-tabs (discovery, demo lineage).
   z-index 90 keeps it above content. */
:root{--tabs-sticky-top:56px}
body.layer-discovery{--tabs-sticky-top:0px}
.rec-tabs{display:flex;gap:.25rem;border-bottom:1px solid var(--border);margin-bottom:0;overflow-x:auto;padding:.35rem .25rem 0;position:sticky;top:var(--tabs-sticky-top);z-index:90;background:var(--bg-alt)}
.rec-tabs button{background:var(--bg-alt);border:1px solid var(--border);border-bottom:0;border-radius:2px 2px 0 0;padding:.6rem 1.1rem;font-size:.875rem;font-weight:600;color:var(--text-muted);cursor:pointer;font-family:inherit;margin-bottom:0;white-space:nowrap;position:relative;top:1px}
.rec-tabs button:hover{color:var(--primary);background:#fff}
.rec-tabs button.active{color:var(--primary);background:#fff;font-weight:700;box-shadow:inset 0 2px 0 var(--accent)}
.rec-tabs button .n{font-family:Monaco,monospace;font-size:.72rem;color:#fff;background:var(--primary);border-radius:2px;padding:.08rem .4rem;margin-left:.45rem;font-weight:700;display:inline-block;min-width:1.4em;text-align:center}
.tab-panel{display:none}
.rec-tabs+.tab-panel,.tab-panel~.tab-panel{background:#fff;border:1px solid var(--border);border-top:0;border-radius:0 0 2px 2px;padding:1.25rem;margin-bottom:1.5rem}
.tab-panel.active{display:block}

/* Two column detail layout */
.cols{display:grid;grid-template-columns:1fr 340px;gap:1.5rem;align-items:start;margin-bottom:1.75rem}
@media (max-width:1099.98px){.cols{grid-template-columns:1fr}}
/* Two-column variant where the RIGHT cell is a document, not an aside.
   The base .cols is "content + 340px aside", which is right for admin detail
   pages and wrong for the CV builder: there the right cell holds the CV
   preview (a page that wants ~820px, see CvController DOC_CSS) while the left
   cell is a stack of collapsed section rows that needs far less. At 1730px the
   old split gave the document 340px and the row list 1600px of empty space
   (user 2026-09-03). Collapses at the same breakpoint as .cols. */
.cols.cols-2{grid-template-columns:minmax(340px,440px) minmax(0,1fr)}
@media (max-width:1099.98px){.cols.cols-2{grid-template-columns:1fr}}
/* Grid tracks floor at min-content (min-width:auto); once .cols collapses to a
   single column a wide cell child (a detail form/card) otherwise held the track
   wider than the viewport (user 2026-07-11 responsive pass, detail pages).
   min-width:0 lets the 1fr cell shrink so its content wraps/clips instead. */
.cols>*{min-width:0}

/* Block + block title */
.block{margin-bottom:1.75rem}
.block:last-child{margin-bottom:0}
/* A .block right after a <form> (e.g. the Expertise block below the profile
   form on the researcher detail): the form's own last .block has its
   margin-bottom zeroed by :last-child, so restore the gap here (user
   2026-07-06: "sekcie by mali mat rozostup"). */
form + .block{margin-top:1.75rem}
.block-title{font-size:.7rem;font-weight:700;letter-spacing:.09em;text-transform:uppercase;color:var(--text-muted);margin:0 0 .9rem;padding-bottom:.5rem;border-bottom:1px solid var(--border)}

/* Editable field grid */
.fg{display:grid;grid-template-columns:1fr 1fr;gap:1rem 1.25rem}
@media (max-width:575.98px){.fg{grid-template-columns:1fr}}
.f{display:flex;flex-direction:column;gap:.3rem;min-width:0}
/* Grid tracks + flex items floor at min-content (min-width:auto); a wide field -
   a <select> with a long option, a <textarea>'s cols intrinsic width - pushed
   the .fg track / .f item past a narrow viewport (user 2026-07-11 responsive
   pass). min-width:0 + the control rule below let fields shrink and wrap. */
.fg>*{min-width:0}
.f.full{grid-column:1 / -1}
.f label{font-size:.78rem;font-weight:600;color:var(--text)}
/* Read-only key/value display (knowledge/31 sec 8 gap #3, axe: "label" rule -
   <label> is form-control-only semantics; a display-only fact next to a
   .ro value, or a free-standing stat line, is not one). Same look as .f
   label (copy, not a shared selector, so a future .f label restyle does not
   silently reach these too). */
.f .f-label{font-size:.78rem;font-weight:600;color:var(--text)}
.f input,.f select,.f textarea{width:100%;min-width:0;max-width:100%;box-sizing:border-box;border:1px solid var(--border);border-radius:2px;padding:.45rem .65rem;font-size:.85rem;font-family:inherit;background:#fff;color:var(--text);outline:0}
.f input:focus,.f select:focus,.f textarea:focus{border-color:var(--primary);box-shadow:0 0 0 2px rgba(15,23,42,.08)}
.f textarea{resize:vertical;min-height:80px;line-height:1.5}
/* Multi-value slot field (W40, templates/admin/_form.php 'multiselect'): a
   bounded scrollable checkbox group. The VERTICAL inner scroll is deliberate -
   a 94-term scheme must not stretch the form; horizontal overflow stays
   impossible (min-width:0 inherited from .fg>*, labels wrap). legend mirrors
   .f label (copy, not shared selector - same rationale as .f-label above). */
.ms-fieldset{border:0;padding:0;margin:0;min-width:0}
.ms-fieldset legend{font-size:.78rem;font-weight:600;color:var(--text);padding:0;margin-bottom:.3rem}
.ms-list{max-height:220px;overflow-y:auto;border:1px solid var(--border);border-radius:2px;background:#fff;padding:.3rem .65rem}
/* .f-scoped selectors on purpose: the generic `.f label` (600 weight) and
   `.f input` (full-width bordered box) rules are MORE specific than a bare
   .ms-opt and would win - an option row must read as a value, not a label,
   and a native checkbox must not inherit a text-input's border and padding. */
.f .ms-opt{display:flex;align-items:baseline;gap:.5rem;padding:.2rem 0;font-size:.85rem;color:var(--text);cursor:pointer;font-weight:400}
.f .ms-opt input{flex-shrink:0;width:auto;border:0;padding:0;box-shadow:none}
.f .ms-opt span{min-width:0;overflow-wrap:anywhere}

/* File drop zone (assets/filedrop.js wraps every <input type=file>). The native
   input is stretched transparently over the zone so the browser's own click +
   drag-drop do the work; this is only the visual shell. */
.filedrop{position:relative;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:.3rem;min-height:96px;padding:1rem;border:1.5px dashed var(--border);border-radius:2px;background:var(--bg-alt);text-align:center;cursor:pointer;transition:border-color .15s,background .15s}
.filedrop:hover{border-color:var(--accent)}
.filedrop.dragover{border-color:var(--accent);background:rgba(var(--accent-rgb),.06)}
.filedrop:focus-within{border-color:var(--primary);box-shadow:0 0 0 2px rgba(15,23,42,.08)}
.filedrop input[type=file]{position:absolute;inset:0;width:100%;height:100%;padding:0;margin:0;border:0;opacity:0;cursor:pointer}
.filedrop-icon{font-size:1.35rem;color:var(--text-muted);transition:color .15s}
.filedrop:hover .filedrop-icon,.filedrop.dragover .filedrop-icon{color:var(--accent)}
.filedrop-prompt{font-size:.85rem;color:var(--text-muted)}
.filedrop-file{font-size:.82rem;font-weight:600;color:var(--primary);word-break:break-all}
.filedrop.has-file{border-style:solid;background:#fff}
.filedrop.has-file .filedrop-prompt{display:none}
.filedrop.has-file .filedrop-icon{color:#15803d}

/* Toggle switch - boxed so it never reads as (or crowds) a text/date input
   (user 2026-07-06: "toggle sa pletu s inputmi"). Rendered full-width via
   .toggle-cell in admin/_form. */
.toggle-row{display:flex;align-items:center;gap:.7rem;padding:.65rem .85rem;border:1px solid var(--border);border-radius:2px;background:var(--bg-alt)}
.toggle-row span{font-size:.85rem;color:var(--text);font-weight:600}
.toggle-cell small{display:block;margin-top:.4rem}
.switch{position:relative;width:38px;height:20px;flex-shrink:0}
.switch input{opacity:0;width:0;height:0}
.switch .sl{position:absolute;inset:0;background:var(--border);border-radius:20px;transition:.2s;cursor:pointer}
.switch .sl:before{content:"";position:absolute;width:14px;height:14px;left:3px;top:3px;background:#fff;border-radius:50%;transition:.2s}
.switch input:checked + .sl{background:var(--accent)}
.switch input:checked + .sl:before{transform:translateX(18px)}

/* Chips */
.chips{display:flex;flex-wrap:wrap;gap:.4rem}
.chip{display:inline-flex;align-items:center;gap:.4rem;font-size:.78rem;background:var(--bg-alt);border:1px solid var(--border);border-radius:2px;padding:.25rem .55rem;color:var(--primary)}
.chip .rm{color:var(--text-muted);cursor:pointer;font-size:.7rem}
.chip .rm:hover{color:#b91c1c}
.chip-add{display:inline-flex;align-items:center;gap:.35rem;font-size:.78rem;background:#fff;border:1px dashed var(--border);border-radius:2px;padding:.25rem .55rem;color:var(--text-muted);cursor:pointer}
.chip-add:hover{border-color:var(--accent);color:var(--accent)}

/* Aside cards */
.card-x{background:#fff;border:1px solid var(--border);border-radius:2px;margin-bottom:1.25rem}
.card-x h3{font-size:.7rem;font-weight:700;letter-spacing:.08em;text-transform:uppercase;color:var(--text-muted);margin:0;padding:.8rem 1rem;border-bottom:1px solid var(--border)}
.card-x .bd{padding:.5rem 1rem}

/* Identifier rows */
.id-row{display:flex;align-items:center;gap:.7rem;padding:.6rem 0;border-bottom:1px solid var(--border)}
.id-row:last-child{border-bottom:0}
.id-row .ico{width:30px;height:30px;background:var(--bg-alt);border:1px solid var(--border);border-radius:2px;display:flex;align-items:center;justify-content:center;color:var(--text-muted);flex-shrink:0;font-size:.82rem}
.id-row .bd2{flex:1;min-width:0}
.id-row .bd2 .lbl{font-size:.72rem;color:var(--text-muted)}
.id-row .bd2 .val{font-size:.84rem;color:var(--primary);font-weight:600}
.id-row .bd2 .val.mono{font-size:.8rem;font-weight:500}

/* Affiliation rows */
.affil-row{padding:.7rem 0;border-bottom:1px solid var(--border)}
.affil-row:last-child{border-bottom:0}
.affil-row .org{font-size:.85rem;font-weight:600;color:var(--primary)}
.affil-row .pos{font-size:.78rem;color:var(--text-muted);margin-top:.1rem}
.affil-row .per{font-size:.76rem;color:var(--text-muted);font-family:Monaco,monospace;margin-top:.15rem}

/* Mini list (record meta) */
.ml{font-size:.82rem}
.ml .mi{display:flex;justify-content:space-between;gap:1rem;padding:.45rem 0;border-bottom:1px solid var(--border)}
.ml .mi:last-child{border-bottom:0}
/* Both cells need the guard, not just the value one. The 2026-07-11 fix below
   covered .v because permalinks land there, but the attachments card puts the
   uploaded FILE NAME in .k - and an upload is named by whoever uploaded it, so
   "Zaverecna_sprava_projektu_APVV_2024_konsolidovana_verzia_final.pdf" is one
   unbreakable run (underscores offer no break opportunity). Measured overflowing
   the page at BOTH 375px and 1366px before this (2026-07-31). */
.ml .mi .k{color:var(--text-muted);min-width:0;overflow-wrap:anywhere}
/* min-width:0 lets the flex value cell shrink, overflow-wrap breaks long
   unbreakable strings (URIs/permalinks) so they wrap instead of overflowing
   the screen (user 2026-07-11). */
.ml .mi .v{color:var(--primary);font-weight:600;text-align:right;min-width:0;overflow-wrap:anywhere}
/* Neutral, default-collapsed disclosure for the destructive record-removal
   action (replaces the old red "danger zone" heading + warning triangle). */
.dz>summary{list-style:none;cursor:pointer;display:flex;align-items:center;gap:.5rem;font-weight:600;color:var(--text);font-size:.92rem}
.dz>summary::-webkit-details-marker{display:none}
.dz>summary:hover{color:var(--primary)}
.dz>summary .dz-chev{margin-left:auto;font-size:.72rem;color:var(--text-muted);transition:transform .15s ease}
.dz[open]>summary .dz-chev{transform:rotate(180deg)}
.dz>summary:focus-visible{outline:2px solid var(--accent);outline-offset:2px;border-radius:2px}
/* W39 part C: per-row correction disclosure in the project team table. Follows
   the .dz neutral-disclosure convention above (no alarm styling, no marker
   triangle, visible focus ring) and is the ONLY control that opens the row's
   edit form, so it must work with scripts off. App-only component - the demo
   layer has no production team table, so this block deliberately lives in the
   app copy of stellacris.css only. The row spans all 8 columns and carries no
   cell borders of its own so it reads as a continuation of the member row above
   it, not as a separate record. */
.dtbl .tm-edit-tr>.tm-edit-cell{padding:0 .75rem .6rem;border-top:0;background:var(--bg-alt)}
.tm-edit>summary{list-style:none;cursor:pointer;display:inline-flex;align-items:center;gap:.4rem;font-size:.78rem;font-weight:600;color:var(--text-muted);padding:.35rem 0}
.tm-edit>summary::-webkit-details-marker{display:none}
.tm-edit>summary::before{content:"";display:inline-block;width:0;height:0;border-left:4px solid currentColor;border-top:3.5px solid transparent;border-bottom:3.5px solid transparent;transition:transform .15s ease}
.tm-edit[open]>summary::before{transform:rotate(90deg)}
.tm-edit>summary:hover{color:var(--accent)}
.tm-edit>summary:focus-visible{outline:2px solid var(--accent);outline-offset:2px;border-radius:2px}
.tm-edit[open]>summary{color:var(--primary)}
.tm-edit .mini-form{padding-bottom:.35rem}

/* Dashboard effective-permissions panel: default-collapsed disclosure, expand
   on click (user 2026-07-11) - admin + user dashboards. */
.dash-perms>summary{list-style:none;cursor:pointer;display:flex;align-items:center;gap:.5rem}
.dash-perms>summary::-webkit-details-marker{display:none}
.dash-perms>summary .dash-chev{margin-left:auto;color:var(--text-muted);font-size:.8rem;transition:transform .15s ease}
.dash-perms[open]>summary .dash-chev{transform:rotate(180deg)}
.dash-perms>summary:hover .dash-chev{color:var(--primary)}
.dash-perms>summary:focus-visible{outline:2px solid var(--accent);outline-offset:2px;border-radius:2px}
.aside-card.dash-perms>summary>span:first-child{font-size:.95rem;font-weight:700}

/* Match candidate */
.match{display:flex;gap:.85rem;align-items:center;background:var(--bg-alt);border:1px solid var(--border);border-radius:2px;padding:.85rem 1rem;margin-top:1rem}
.match .ico{color:#b45309;font-size:1rem}
.match .bd{flex:1;min-width:0}
.match .bd strong{font-size:.85rem;color:var(--primary)}
.match .bd small{display:block;font-size:.76rem;color:var(--text-muted)}
.match .act{display:flex;gap:.4rem;flex-shrink:0}


/* ============================================================================
   (10) DASHBOARD + LIST COMPONENTS
   KPI strip / section heads / health strip / cards grid / csec / approvals /
   activity / canonical-stats / filter bar + filter chips / filter row
   ============================================================================ */
/* Section heads */
/* View tabs (shared 2026-08-16): one strip per entity/pane. Styles BOTH
   <button> (JS pane switching, /admin/integrations) and <a> (server-side tabs
   that carry facets/sort/page/export in the query string, /admin/consortium) -
   the two mechanisms look identical to the user and must not diverge. */
.view-tabs{display:flex;gap:0;border-bottom:1px solid var(--border);margin-bottom:1.5rem;overflow-x:auto;scrollbar-width:none}
.view-tabs::-webkit-scrollbar{display:none}
.view-tabs button,.view-tabs>a{padding:.75rem 1rem;font-size:.9rem;font-weight:600;color:var(--text-muted);background:transparent;border:0;border-bottom:2px solid transparent;white-space:nowrap;cursor:pointer;font-family:inherit;display:inline-flex;align-items:center;gap:.45rem;text-decoration:none}
.view-tabs button:hover,.view-tabs>a:hover{color:var(--primary);text-decoration:none}
.view-tabs button.active,.view-tabs>a.active{color:var(--primary);border-bottom-color:var(--primary)}
.view-tabs button .n,.view-tabs>a .n{font-family:Monaco,monospace;font-size:.78rem;color:var(--text-muted)}
.section-head{display:flex;align-items:flex-end;justify-content:space-between;gap:1rem;margin-bottom:1rem;flex-wrap:wrap}
/* Page-level contextual help (W42, knowledge/15 convention 28 - the WordPress
   Help-tab analogue): default-collapsed "?" whose panel carries the text that
   used to be a lead paragraph (A17 notation). <details>-based like tb-kebab -
   no JS, touch-friendly. Field-level constraints use .tooltip-acc below. */
.page-help{position:relative;display:inline-flex}
.page-help>summary{list-style:none;cursor:pointer;display:inline-flex;align-items:center;justify-content:center;width:28px;height:28px;border:1px solid var(--border);border-radius:2px;background:#fff;color:var(--text-muted);font-size:.92rem}
.page-help>summary::-webkit-details-marker{display:none}
.page-help>summary:hover{color:var(--primary);border-color:#94a3b8}
.page-help>summary:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
.page-help[open]>summary{color:var(--primary);background:var(--bg-alt)}
.page-help-panel{position:absolute;right:0;top:calc(100% + 8px);width:min(340px,80vw);background:#fff;border:1px solid var(--border);border-radius:2px;box-shadow:0 8px 24px rgba(15,23,42,.16);padding:.7rem .85rem;font-size:.85rem;line-height:1.5;color:var(--text);z-index:300}
/* Field-level constraint tooltip - the design manual's .tooltip-acc component
   ported to the app (W42): an info affordance next to a field label whose
   data-tooltip shows on hover AND keyboard focus. Wrap allowed (the manual's
   nowrap variant fits only two words); width bounded so it cannot push the
   page (knowledge/12 no-horizontal-overflow rule). */
.tooltip-acc{position:relative;display:inline-flex;align-items:center;justify-content:center;color:var(--text-muted);cursor:help;font-size:.8rem}
.tooltip-acc::after{content:attr(data-tooltip);position:absolute;bottom:calc(100% + 6px);left:50%;transform:translateX(-50%);background:var(--primary);color:#fff;padding:.4rem .6rem;border-radius:2px;font-size:.78rem;font-weight:500;line-height:1.4;width:max-content;max-width:min(280px,72vw);opacity:0;pointer-events:none;transition:.15s;z-index:300}
.tooltip-acc:hover::after,.tooltip-acc:focus-visible::after{opacity:1}
.tooltip-acc:focus-visible{outline:2px solid var(--accent);outline-offset:2px;border-radius:2px}
.section-head:not(:first-child){margin-top:2rem}
.section-title{font-size:.7rem;font-weight:700;letter-spacing:.09em;text-transform:uppercase;color:var(--text-muted);margin:0}
.section-title .count{font-family:Monaco,monospace;font-size:.7rem;font-weight:500;color:var(--text-muted);margin-left:.4rem}

/* KPI strip */
.kpi-strip{display:grid;grid-template-columns:repeat(auto-fit,minmax(170px,1fr));gap:.75rem;margin-bottom:1.5rem}
.kpi-card{background:#fff;border:1px solid var(--border);border-radius:2px;padding:1rem 1.15rem}
.kpi-val{font-size:1.55rem;font-weight:700;color:var(--primary);font-family:Monaco,monospace;letter-spacing:-.02em;line-height:1.1}
.kpi-lbl{font-size:.7rem;color:var(--text-muted);text-transform:uppercase;letter-spacing:.06em;font-weight:600;margin-top:.25rem}
.kpi-trend{font-size:.72rem;margin-top:.4rem;display:flex;align-items:center;gap:.3rem;color:#15803d}
.kpi-trend.neu{color:var(--text-muted)}
.kpi-trend.warn{color:#b45309}

/* Reporting overview - pure-CSS horizontal bar charts (no JS/canvas) */
.rep-charts{display:grid;grid-template-columns:1fr 1fr;gap:1rem;align-items:start;margin-bottom:1.25rem}
@media (max-width:767.98px){.rep-charts{grid-template-columns:1fr}}
.rep-chart{display:flex;flex-direction:column;gap:.5rem}
.rep-bar{display:grid;grid-template-columns:6.5rem 1fr auto;align-items:center;gap:.6rem;font-size:.82rem}
.rep-bar-label{color:var(--text);font-weight:600;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.rep-bar-track{background:var(--bg-alt);border:1px solid var(--border);border-radius:2px;height:1.1rem;overflow:hidden}
.rep-bar-fill{height:100%;background:var(--accent);min-width:2px}
.rep-bar-count{font-family:Monaco,monospace;font-weight:700;color:var(--primary);font-size:.8rem;text-align:right;min-width:2.4rem}
.rep-report-card{text-decoration:none;color:inherit;display:block;transition:border-color .12s,box-shadow .12s}
.rep-report-card:hover{border-color:var(--accent);box-shadow:0 1px 6px rgba(0,0,0,.06)}
.rep-report-card h3 i{color:var(--accent);margin-right:.35rem}
.rep-report-go{display:inline-flex;align-items:center;gap:.35rem;margin-top:.75rem;font-size:.82rem;font-weight:600;color:var(--accent)}

/* Health strip */
.health-strip{display:grid;grid-template-columns:repeat(auto-fit,minmax(220px,1fr));gap:.75rem;margin-bottom:1.5rem}
.health-cell{background:#fff;border:1px solid var(--border);border-radius:2px;padding:.85rem 1rem;display:flex;align-items:center;gap:.85rem}
.health-cell.ok{border-left:3px solid var(--success)}
.health-cell.warn{border-left:3px solid var(--warning)}
.health-cell.danger{border-left:3px solid var(--danger)}
.health-cell .dot{width:10px;height:10px;border-radius:50%;flex-shrink:0;animation:pulse 2s infinite}
.health-cell.ok .dot{background:var(--success)}
.health-cell.warn .dot{background:var(--warning)}
.health-cell.danger .dot{background:var(--danger)}
.health-cell .body{flex:1;min-width:0}
.health-cell strong{display:block;font-size:.88rem;color:var(--primary);font-weight:600}
.health-cell small{font-size:.78rem;color:var(--text-muted)}

/* Cards grid */
.grid-2{display:grid;grid-template-columns:1fr 1fr;gap:1.25rem}
@media (max-width:1199.98px){.grid-2{grid-template-columns:1fr}}

/* Content section card (.csec) */
.csec{background:#fff;border:1px solid var(--border);border-radius:2px;overflow:hidden}
.csec-head{padding:.85rem 1.25rem;border-bottom:1px solid var(--border);display:flex;align-items:center;justify-content:space-between;gap:.5rem;flex-wrap:wrap}
.csec-head h2{font-size:.72rem;font-weight:700;letter-spacing:.09em;text-transform:uppercase;color:var(--text-muted);margin:0}

/* Pending approvals */
.approval-row{display:flex;align-items:center;gap:.85rem;padding:.85rem 1.25rem;border-bottom:1px solid var(--border)}
.approval-row:last-child{border-bottom:0}
.approval-row .ico{width:34px;height:34px;background:var(--bg-alt);border:1px solid var(--border);border-radius:2px;display:flex;align-items:center;justify-content:center;color:var(--text-muted)}
.approval-row .body{flex:1;min-width:0}
.approval-row .body strong{display:block;font-size:.92rem;color:var(--primary);font-weight:600;line-height:1.35}
.approval-row .body small{font-size:.78rem;color:var(--text-muted)}
.approval-row .actions{display:flex;gap:.3rem}

/* Activity rows */
.act-row{display:flex;align-items:flex-start;gap:.85rem;padding:.7rem 1.25rem;border-bottom:1px solid var(--border);font-size:.875rem}
.act-row:last-child{border-bottom:0}
.act-row .ico{width:28px;height:28px;background:var(--bg-alt);border:1px solid var(--border);border-radius:2px;display:flex;align-items:center;justify-content:center;font-size:.78rem;color:var(--text-muted);flex-shrink:0}
.act-row .ico.add{background:rgba(34,197,94,.1);border-color:rgba(34,197,94,.3);color:#15803d}
.act-row .ico.edit{background:rgba(59,130,246,.08);border-color:rgba(59,130,246,.3);color:var(--accent)}
.act-row .ico.warn{background:rgba(245,158,11,.1);border-color:rgba(245,158,11,.3);color:#b45309}
.act-row .body{flex:1;min-width:0}
.act-row .body strong{color:var(--primary);font-weight:600}
.act-row .time{font-size:.75rem;color:var(--text-muted);font-family:Monaco,monospace;white-space:nowrap;flex-shrink:0}

/* Canonical data stats cards */
.cat-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(220px,1fr));gap:.75rem}
.cat-card{background:#fff;border:1px solid var(--border);border-radius:2px;padding:1rem 1.15rem;text-decoration:none;color:inherit;display:flex;align-items:center;gap:1rem;transition:.15s}
.cat-card:hover{border-color:#94a3b8;color:inherit;text-decoration:none;transform:translateY(-2px);box-shadow:0 4px 12px rgba(15,23,42,.04)}
.cat-card .ico{width:42px;height:42px;background:var(--bg-alt);border:1px solid var(--border);border-radius:2px;display:flex;align-items:center;justify-content:center;color:var(--primary);font-size:1.1rem;flex-shrink:0}
.cat-card .body{flex:1;min-width:0}
.cat-card .lbl{font-size:.72rem;color:var(--text-muted);text-transform:uppercase;letter-spacing:.05em;font-weight:600}
.cat-card .val{font-size:1.3rem;font-weight:700;color:var(--primary);font-family:Monaco,monospace;display:block;line-height:1.1;margin-top:.15rem}
.cat-card .sub{font-size:.78rem;color:var(--text-muted);margin-top:.25rem}
/* Admin "Sprava" landing cards reuse .cat-card but lead with a full title
   (not the uppercase .lbl kicker + numeric .val the dashboard uses). */
.cat-card .adm-title{font-size:.95rem;font-weight:700;color:var(--primary);display:flex;align-items:center;gap:.4rem}
.cat-card .adm-title .b{font-family:Monaco,monospace;font-size:.7rem;background:#b91c1c;color:#fff;padding:.05rem .35rem;border-radius:8px;font-weight:700}

/* List page: filter row (boxed select group) */
.filter-row{display:flex;align-items:flex-end;gap:.75rem;flex-wrap:wrap;margin-bottom:1.1rem;background:#fff;border:1px solid var(--border);border-radius:2px;padding:.9rem 1rem}
.filter-field{display:flex;flex-direction:column;gap:.25rem;min-width:150px}
.filter-field .flbl{font-size:.62rem;letter-spacing:.08em;text-transform:uppercase;color:var(--text-muted);font-weight:700}
.filter-field select,.filter-field input{height:34px;border:1px solid var(--border);border-radius:2px;background:var(--bg-alt);font-size:.85rem;font-family:inherit;padding:0 .6rem;color:var(--text);outline:0}
.filter-field select:focus,.filter-field input:focus{border-color:var(--accent);background:#fff}
.filter-actions{margin-left:auto;display:flex;gap:.4rem;align-items:flex-end}
/* Call lifecycle state switcher (rec-header actions): select of allowed target states + confirm button */
.lifecycle-switch{display:inline-flex;gap:.4rem;align-items:center;margin:0}
.lifecycle-switch select{border:1px solid var(--border);border-radius:2px;padding:.4rem .6rem;font-size:.85rem;font-family:inherit;background:#fff;color:var(--text);outline:0}
.lifecycle-switch select:focus{border-color:var(--accent)}

/* User page: filter bar (inline chip group) */
.filter-bar{display:flex;align-items:center;gap:.5rem;flex-wrap:wrap;margin-bottom:1.25rem}
.filter-bar .label{font-size:.7rem;font-weight:700;letter-spacing:.08em;text-transform:uppercase;color:var(--text-muted)}
.fchip{display:inline-flex;align-items:center;gap:.4rem;padding:.35rem .75rem;background:#fff;border:1px solid var(--border);border-radius:2px;font-size:.85rem;color:var(--text);cursor:pointer;font-family:inherit}
.fchip:hover{border-color:var(--primary);color:var(--primary)}
.fchip.active{background:var(--primary);border-color:var(--primary);color:#fff}
.form-select-sm{height:36px;padding:0 2rem 0 .75rem;border:1px solid var(--border);border-radius:2px;font-size:.85rem;background:#fff;color:var(--text);font-family:inherit;font-weight:500}

/* Shared keyframe (health dot + discovery hero pulse) */
@keyframes pulse{0%,100%{opacity:1}50%{opacity:.45}}


/* ============================================================================
   (11) USER VIEW: wider layout + widget cards + claim tabs
   User & discovery pages widen --page-inset and centre content via the
   Bootstrap .container-xxl. Keeps the app-shell baseline inset by default.
   ============================================================================ */
@media (min-width:1200px){.container-xxl{max-width:1680px}}

/* User page surfaces (page head / body / compliance / footer) */
.page-head{padding:2rem var(--page-inset) 1.5rem;background:#fff;border-bottom:1px solid var(--border)}
.page-head-inner{display:flex;align-items:flex-start;justify-content:space-between;gap:2rem;flex-wrap:wrap}
.page-head h1{font-size:clamp(1.4rem,2.8vw,1.85rem);font-weight:700;color:var(--primary);letter-spacing:-.025em;margin:0 0 .35rem}
.page-head p{margin:0;color:var(--text-muted);font-size:.95rem;max-width:65ch}
.page-head-row{display:flex;justify-content:space-between;align-items:center;flex-wrap:wrap;gap:1rem}
.greet-eyebrow{display:inline-flex;align-items:center;gap:.45rem;font-size:.72rem;font-weight:700;letter-spacing:.06em;text-transform:uppercase;color:var(--accent);margin-bottom:.6rem}
.crumbs{display:flex;align-items:center;gap:.4rem;font-size:.72rem;color:var(--text-muted);margin-bottom:.7rem;text-transform:uppercase;letter-spacing:.08em;font-weight:700}
.crumbs a{color:var(--text-muted)}
.crumbs i{font-size:.6rem;color:#cbd5e1}
.page-body{padding:2rem var(--page-inset) 4rem}

/* Compliance ring */
.compliance-card{background:var(--bg-alt);border:1px solid var(--border);border-radius:2px;padding:1rem 1.25rem;display:flex;align-items:center;gap:1rem;min-width:300px}
.ring-wrap{position:relative;width:64px;height:64px;flex-shrink:0}
.ring-svg{width:64px;height:64px;transform:rotate(-90deg)}
.ring-bg{fill:none;stroke:var(--border);stroke-width:8}
.ring-fg{fill:none;stroke:var(--success);stroke-width:8;transition:stroke-dashoffset .4s}
.ring-fg.warn{stroke:var(--warning)}
.ring-fg.danger{stroke:var(--danger)}
.ring-val{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;font-size:1rem;font-weight:700;color:var(--primary);font-family:Monaco,monospace}
.compliance-card .body strong{display:block;font-size:.92rem;color:var(--primary);margin-bottom:.15rem}
.compliance-card .body span{font-size:.8rem;color:var(--text-muted)}

/* Two-col dashboard grid (user) */
.dx-grid{display:grid;grid-template-columns:1fr 340px;gap:2rem;align-items:start}
@media (max-width:920px){.dx-grid{grid-template-columns:1fr}}
/* min-width:0 so the collapsed single column can shrink below its content's
   min-content instead of pushing the dashboard past a narrow viewport (user
   2026-07-11 responsive pass, /user + /admin dashboards). */
.dx-grid>*{min-width:0}

/* Action-required cards */
.act-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(310px,1fr));gap:1rem}
.act-card{background:#fff;border:1px solid var(--border);border-radius:2px;padding:1.25rem;display:flex;flex-direction:column;gap:.85rem;transition:.15s}
.act-card:hover{border-color:#94a3b8;box-shadow:0 4px 12px rgba(15,23,42,.04)}
.act-card.urgent{border-left:3px solid var(--danger)}
.act-card.warn{border-left:3px solid var(--warning)}
.act-card.info{border-left:3px solid var(--accent)}
.act-card .head{display:flex;align-items:center;justify-content:space-between;gap:.5rem}
.act-card .title{font-size:.98rem;font-weight:700;color:var(--primary);line-height:1.4;margin:0}
.act-card .meta{font-size:.78rem;color:var(--text-muted);display:flex;align-items:center;gap:.4rem;flex-wrap:wrap}
.act-card .body{font-size:.88rem;color:var(--text);flex:1;line-height:1.6;margin:0}
.act-card .foot{display:flex;align-items:center;justify-content:space-between;gap:.5rem;padding-top:.85rem;border-top:1px solid var(--border)}
.act-card .due{font-size:.78rem;color:var(--text-muted);font-family:Monaco,monospace}
.act-card.urgent .due{color:#b91c1c;font-weight:700}

/* Progress bar */
.progress-acc{height:6px;background:var(--bg-alt);border:1px solid var(--border);border-radius:2px;overflow:hidden}
.progress-acc .fill{height:100%;background:var(--accent)}
.progress-acc .fill.ok{background:var(--success)}
.progress-acc .fill.warn{background:var(--warning)}
.progress-acc .fill.danger{background:var(--danger)}

/* Aside cards (user dashboard right column) */
.aside-card{background:#fff;border:1px solid var(--border);border-radius:2px;padding:1.25rem}
.aside-card + .aside-card{margin-top:1rem}
/* h3 not h4 (axe/DOM-audit: heading level skip h2->h4 on /user/dashboard,
   SC 1.3.1 - the greeting/section titles above these aside cards are h2, so
   h4 skipped a level; tag promoted, selector follows, visual unchanged). */
.aside-card h3{font-size:.72rem;font-weight:700;letter-spacing:.09em;text-transform:uppercase;color:var(--text-muted);margin:0 0 .85rem}
.aside-item{display:flex;align-items:flex-start;gap:.6rem;padding:.5rem 0;border-bottom:1px dashed var(--border);font-size:.875rem}
.aside-item:last-child{border-bottom:0}
.aside-item i{color:var(--text-muted);font-size:.78rem;margin-top:.3rem;flex-shrink:0}
.aside-item .body{flex:1;min-width:0}
.aside-item .body strong{color:var(--primary);font-weight:600;display:block}
.aside-item .body small{font-size:.78rem;color:var(--text-muted)}

/* Quick actions */
.quick-grid{display:grid;grid-template-columns:1fr 1fr;gap:.5rem}
.quick-btn{display:flex;align-items:center;gap:.6rem;padding:.75rem .85rem;background:#fff;border:1px solid var(--border);border-radius:2px;color:var(--text);font-size:.875rem;font-weight:600;text-align:left;transition:.15s;text-decoration:none}
.quick-btn:hover{border-color:var(--primary);color:var(--primary);background:var(--bg-alt);text-decoration:none}
.quick-btn i{color:var(--text-muted);font-size:.95rem;width:18px;text-align:center}
.quick-btn:hover i{color:var(--accent)}

/* Persistent-ID badges (my-outputs) */
.id-badge{display:inline-flex;align-items:center;gap:.45rem;padding:.35rem .7rem;background:var(--bg-alt);border:1px solid var(--border);border-radius:2px;font-size:.82rem;font-weight:600;color:var(--text);font-family:Monaco,monospace}
.id-badge .id-mark{display:inline-flex;align-items:center;justify-content:center;width:16px;height:16px;background:#e9711c;color:#fff;border-radius:2px;font-size:.62rem;font-weight:800;font-family:-apple-system,sans-serif}

/* Claim-state tabs (Moje / Cakajuce / Nie moje -- Symplectic pattern) */
.tabs-line{display:flex;gap:0;border-bottom:1px solid var(--border);margin-bottom:1.5rem;overflow-x:auto;scrollbar-width:none}
.tabs-line::-webkit-scrollbar{display:none}
.tabs-line a{padding:.75rem 1rem;font-size:.9rem;font-weight:600;color:var(--text-muted);text-decoration:none;border-bottom:2px solid transparent;white-space:nowrap}
.tabs-line a.active{color:var(--primary);border-bottom-color:var(--primary)}
.tabs-line .count{margin-left:.35rem;font-family:Monaco,monospace;font-size:.78rem;color:var(--text-muted)}

/* Claim panes + claim accept/reject buttons */
.pane{display:none}
.pane.active{display:block}
.claim-btn{display:inline-flex;align-items:center;justify-content:center;width:32px;height:32px;border-radius:2px;border:1px solid var(--border);background:#fff;cursor:pointer;font-size:.9rem;transition:.15s}
.claim-btn.yes{color:#15803d}
.claim-btn.yes:hover{background:rgba(34,197,94,.12);border-color:#15803d}
.claim-btn.no{color:#b91c1c}
.claim-btn.no:hover{background:rgba(239,68,68,.1);border-color:var(--danger)}

/* App-shell footer strip (user inner pages) */
.foot{background:#fff;padding:1.5rem var(--page-inset);border-top:1px solid var(--border);font-size:.85rem;color:var(--text-muted)}
.foot-inner{display:flex;align-items:center;gap:1rem;flex-wrap:wrap}
.foot-inner .sep{color:#cbd5e1}


/* ============================================================================
   (12) DISCOVERY HORIZONTAL NAV (.nav-acc) + discovery page surfaces
   Public discovery layer uses a top horizontal nav instead of a sidebar.
   ============================================================================ */
.nav-acc{display:flex;align-items:center;gap:1.75rem;padding:1.15rem var(--page-inset);background:#fff;border-bottom:1px solid var(--border);min-height:72px}
.nav-brand{display:flex;align-items:center;gap:.6rem;font-weight:800;font-size:1.05rem;color:var(--primary);letter-spacing:-.3px;flex-shrink:1;min-width:0;overflow:hidden;white-space:nowrap;text-overflow:ellipsis;text-decoration:none}
.nav-brand:hover{text-decoration:none;color:var(--primary)}
.nav-divider{width:1px;height:22px;background:var(--border);flex-shrink:0}
.nav-context{display:flex;flex-direction:column;line-height:1.15;flex-shrink:0}
.nav-context .label{font-size:.68rem;letter-spacing:.1em;text-transform:uppercase;color:var(--text-muted);font-weight:700}
.nav-context .name{font-size:.92rem;color:var(--primary);font-weight:600}
.nav-search-top{flex:1 1 280px;max-width:560px;position:relative}
.nav-search-top input{width:100%;height:36px;padding:0 .75rem 0 2.1rem;border:1px solid var(--border);border-radius:2px;background:var(--bg-alt);font-size:.875rem;color:var(--text);font-family:inherit;outline:0}
.nav-search-top-ico{position:absolute;left:.7rem;top:50%;transform:translateY(-50%);color:var(--text-muted);font-size:.82rem}
/* flex-shrink:1 + min-width:0 (was flex-shrink:0) so this container can shrink
   below its content width - THEN its clientWidth == the real space left after
   a (possibly long) brand, which is exactly the budget nav-overflow.js measures
   to decide how many links collapse into "Viac". With flex-shrink:0 it grew to
   fit every link, the JS saw infinite room, nothing collapsed, and a long
   institution name pushed the row into a horizontal scroll (user 2026-07-10). */
.nav-actions{display:flex;align-items:center;gap:.65rem;margin-left:auto;flex-shrink:1;min-width:0}
.nav-link{padding:.45rem .8rem;font-size:.875rem;color:var(--text-muted);font-weight:500;text-decoration:none;transition:.15s;white-space:nowrap}
.nav-link:hover{color:var(--primary);text-decoration:none}
.nav-link.active{color:var(--primary);font-weight:700}
.nav-icon-btn{display:inline-flex;align-items:center;justify-content:center;background:transparent;border:0;padding:.5rem;color:var(--text-muted);font-size:1rem;cursor:pointer;transition:.15s;position:relative}
.nav-icon-btn:hover{color:var(--primary)}
.nav-pip{position:absolute;top:.35rem;right:.32rem;width:6px;height:6px;background:var(--accent);border-radius:50%}
.nav-burger{display:none;background:transparent;border:0;padding:.5rem;color:var(--text);font-size:1.1rem}
.nav-user{display:inline-flex;align-items:center;gap:.5rem;padding:.25rem .25rem .25rem .7rem;border:1px solid var(--border);border-radius:2px;font-size:.875rem;font-weight:500;color:var(--text);text-decoration:none}
.nav-user:hover{border-color:#94a3b8;text-decoration:none;color:var(--text)}
.avatar{width:26px;height:26px;display:inline-flex;align-items:center;justify-content:center;background:var(--primary);color:#fff;border-radius:2px;font-size:.7rem;font-weight:700}
@media (max-width:1199.98px){.nav-search-top{display:none}}
@media (max-width:991.98px){
  .nav-actions .nav-link{display:none}
  /* Below 992px the utilities collapse into the burger menu (they overflow the
     bar otherwise); the open burger reveals them as labeled rows (user
     2026-07-12). */
  .nav-actions>.a11y-menu,.nav-actions>.langsw,.nav-actions>a.btn,.nav-actions>.nav-divider{display:none}
  .nav-burger{display:inline-flex}
}

/* Athena affordance (discovery) */
.athena-ring{display:inline-block;width:14px;height:14px;border:2px solid var(--accent);border-radius:50%;background:transparent;vertical-align:middle}
.demo-dark .athena-ring,.on-dark .athena-ring{border-color:#fff}
.icon-athena-plate{width:44px;height:44px;display:inline-flex;align-items:center;justify-content:center;background:var(--bg-alt);border:1px solid var(--border);border-radius:2px}

/* Clean card */
.card-clean{background:#fff;border:1px solid var(--border);border-radius:2px;padding:1.5rem;transition:border-color .15s, box-shadow .15s}
.card-clean:hover{border-color:#94a3b8}
.card-clean.hoverable{cursor:pointer}
.card-clean.hoverable:hover{box-shadow:0 4px 16px rgba(15,23,42,.06);transform:translateY(-2px)}

/* Dark hero (discovery s16) */
.hero{position:relative;overflow:hidden;background:linear-gradient(135deg,var(--hero-from) 0%,var(--hero-to) 100%);color:#fff;padding:5rem var(--page-inset);border-top:1px solid rgba(255,255,255,.12);border-bottom:1px solid rgba(255,255,255,.12)}
.hero::before,.hero::after{content:"";position:absolute;pointer-events:none;border-radius:50%;background:radial-gradient(circle,rgba(59,130,246,.18) 0%,transparent 70%);width:680px;height:680px;top:-220px;right:-120px;animation:hero-pulse 8s ease-in-out infinite}
.hero::after{background:radial-gradient(circle,rgba(139,92,246,.12) 0%,transparent 70%);width:460px;height:460px;top:auto;bottom:-160px;right:auto;left:-100px;animation:hero-pulse 10s ease-in-out infinite reverse}
@keyframes hero-pulse{0%,100%{opacity:.65}50%{opacity:1}}
.hero-inner{position:relative;z-index:1}
.hero-eyebrow{display:inline-flex;align-items:center;gap:.5rem;padding:.4rem .85rem;background:rgba(255,255,255,.07);border:1px solid rgba(255,255,255,.18);border-radius:2px;font-size:.72rem;font-weight:700;letter-spacing:.06em;text-transform:uppercase;color:rgba(255,255,255,.85);margin-bottom:1.25rem}
.hero h1{font-size:clamp(1.85rem, 4.5vw, 3.2rem);font-weight:700;letter-spacing:-.02em;line-height:1.15;margin:0 0 1rem;color:#fff}
.hero h1 .accent{color:#60a5fa}
.hero .lead{font-size:1.1rem;color:rgba(255,255,255,.78);max-width:60ch;margin:0 0 2.25rem;line-height:1.6}
.hero-search{background:rgba(255,255,255,.06);border:1px solid rgba(255,255,255,.18);border-radius:2px;padding:.5rem;display:flex;align-items:center;gap:.5rem;max-width:760px;margin-bottom:1rem}
.hero-search input{flex:1;height:48px;padding:0 .25rem 0 1rem;background:transparent;border:0;outline:0;color:#fff;font-size:1rem;font-family:inherit}
.hero-search input::placeholder{color:rgba(255,255,255,.55)}
.hero-search .btn{flex-shrink:0;height:48px;padding:0 1.5rem}
.hero-search-hints{display:flex;gap:.5rem;flex-wrap:wrap;max-width:760px;margin-bottom:2.75rem}
.hero-search-hint{display:inline-flex;align-items:center;gap:.35rem;padding:.3rem .65rem;background:rgba(255,255,255,.05);border:1px solid rgba(255,255,255,.12);border-radius:2px;font-size:.78rem;color:rgba(255,255,255,.75);cursor:pointer;transition:.15s;text-decoration:none}
.hero-search-hint:hover{color:#fff;background:rgba(255,255,255,.1);text-decoration:none}

/* KPI tile (dark hero) */
.kpi-tile{background:rgba(255,255,255,.05);border:1px solid rgba(255,255,255,.12);border-radius:2px;padding:1.5rem 1.25rem;height:100%;display:flex;flex-direction:column}
.kpi-tile .kpi-value{display:block;font-size:1.85rem;font-weight:700;letter-spacing:-.02em;color:#fff;line-height:1.1;margin-bottom:.25rem}
.kpi-tile .kpi-label{display:block;font-size:.78rem;color:rgba(255,255,255,.65);text-transform:uppercase;letter-spacing:.05em;font-weight:600}
.kpi-tile .kpi-trend{font-size:.78rem;margin-top:.5rem;color:#4ade80;display:flex;align-items:center;gap:.35rem}
.kpi-tile .kpi-trend.neu{color:rgba(255,255,255,.5)}

/* Sections (discovery) */
.section{padding:6rem var(--page-inset)}
.section-alt{background:var(--bg-alt)}
.section-tight{padding:4rem var(--page-inset)}
@media (max-width:767.98px){.section,.section-tight{padding:4rem var(--page-inset)}}
.section-head.with-link{display:flex;align-items:flex-end;justify-content:space-between;gap:2rem;flex-wrap:wrap}
.section-eyebrow{display:inline-block;font-size:.72rem;font-weight:700;letter-spacing:.08em;text-transform:uppercase;color:var(--accent);margin-bottom:.85rem}
.section-h2{font-size:clamp(1.5rem, 3vw, 1.85rem);font-weight:600;color:var(--primary);margin:0 0 .65rem;letter-spacing:-.015em}
.section-lead{font-size:1.05rem;color:var(--text-muted);max-width:65ch;margin:0}
.section-more{font-size:.875rem;color:var(--accent);font-weight:600;white-space:nowrap}
.section-more:hover{text-decoration:underline}

/* Project card (discovery) */
.proj-card{background:#fff;border:1px solid var(--border);border-radius:2px;padding:1.5rem;height:100%;display:flex;flex-direction:column;transition:border-color .15s, box-shadow .15s;text-decoration:none;color:inherit;position:relative}
.proj-card:hover{border-color:#94a3b8;box-shadow:0 4px 16px rgba(15,23,42,.06);background:var(--tint);text-decoration:none;color:inherit}
.proj-card .badges{display:flex;gap:.35rem;flex-wrap:wrap;margin-bottom:.75rem;min-height:1.5rem}
.proj-card .title{font-size:1.05rem;font-weight:700;color:var(--primary)!important;line-height:1.4;letter-spacing:-.01em;margin:0 0 .4rem;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;min-height:2.94rem}
.proj-card .code{font-family:Monaco,monospace;font-size:.78rem;color:var(--text-muted);margin-bottom:1rem;display:flex;flex-wrap:wrap;gap:.25rem .5rem;align-items:baseline}
.proj-card .code .sep{color:#cbd5e1}
.proj-card .desc{font-size:.88rem;color:var(--text);line-height:1.6;margin-bottom:1.25rem;display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;overflow:hidden;flex:1}
.proj-card .meta{display:grid;grid-template-columns:1fr 1fr;gap:.4rem .85rem;font-size:.82rem;color:var(--text-muted);padding-top:.9rem;border-top:1px solid var(--border);margin:0}
.proj-card .meta .m-row{display:flex;align-items:center;gap:.45rem;min-width:0;margin:0}
.proj-card .meta i{width:12px;color:var(--text-muted);font-size:.78rem;text-align:center;flex-shrink:0}
.proj-card .meta strong{color:var(--primary);font-weight:600}
.proj-card .meta .m-row.full{grid-column:1 / -1}
.proj-card .meta .m-row span{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.proj-card .meta .m-row.full span{white-space:normal}
.proj-card.closed{border-left:3px solid #94a3b8}
.proj-card.rejected{border-left:3px solid var(--danger)}

/* Generic initials avatar (discovery researcher rows/profile/team members) */
.avatar-box{background:var(--bg-alt);border:1px solid var(--border);border-radius:2px;display:flex;align-items:center;justify-content:center;font-weight:700;color:var(--text-muted);letter-spacing:-.02em;overflow:hidden;flex-shrink:0}
.avatar-box.sm{width:44px;height:44px;font-size:.85rem}
.avatar-box.md{width:56px;height:56px;font-size:1.1rem}
.avatar-box.lg{width:120px;height:120px;font-size:2.2rem}

/* Stat blocks (discovery researcher/project stat strips) */
.stat-block{background:#fff;border:1px solid var(--border);border-radius:2px;padding:1rem 1.25rem}
.stat-block .lbl{font-size:.68rem;text-transform:uppercase;letter-spacing:.07em;color:var(--text-muted);font-weight:700;margin-bottom:.25rem}
.stat-block .val{font-size:1.45rem;font-weight:700;color:var(--primary);font-family:Monaco,monospace;letter-spacing:-.02em;line-height:1.1}

/* Output row (discovery project/researcher/output listings) */
.out-row{display:flex;align-items:flex-start;gap:1rem;padding:1rem 0;border-bottom:1px solid var(--border)}
.out-row:last-child{border-bottom:0}
.out-body{flex:1;min-width:0}
.out-title{font-size:.95rem;font-weight:600;color:var(--primary);line-height:1.45;margin:0 0 .3rem;text-decoration:none;display:block}
.out-title:hover{color:var(--accent)}
.out-meta{font-size:.82rem;color:var(--text-muted);display:flex;flex-wrap:wrap;gap:.4rem .6rem;align-items:center}
.out-meta .sep{color:#cbd5e1}
.out-meta .doi{font-family:Monaco,monospace}
.out-actions{flex-shrink:0;display:flex;gap:.35rem;align-items:flex-start}

/* Project row (discovery researcher profile "Projekty" list) */
.p-row{display:flex;flex-direction:column;padding:1rem 0;border-bottom:1px solid var(--border);text-decoration:none;color:inherit;gap:.35rem}
.p-row:last-child{border-bottom:0}
.p-row .head{display:flex;flex-wrap:wrap;gap:.4rem;align-items:center}
.p-row .title{font-size:1rem;font-weight:700;color:var(--primary);line-height:1.4;margin:0}
.p-row:hover .title{color:var(--accent)}
.p-row .code{font-family:Monaco,monospace;font-size:.78rem;color:var(--text-muted)}
.p-row .meta{font-size:.85rem;color:var(--text-muted);display:flex;flex-wrap:wrap;gap:.35rem .65rem;align-items:center}

/* Browse cards (entry points) */
.browse-card{display:flex;flex-direction:column;justify-content:space-between;background:#fff;border:1px solid var(--border);border-radius:2px;padding:1.75rem;height:100%;text-decoration:none;color:inherit;transition:.18s}
.browse-card:hover{border-color:var(--primary);transform:translateY(-2px);box-shadow:0 8px 24px rgba(15,23,42,.06);text-decoration:none;color:inherit}
.browse-card .icon{width:48px;height:48px;display:inline-flex;align-items:center;justify-content:center;background:var(--primary);color:#fff;border-radius:2px;font-size:1.2rem;margin-bottom:1.25rem}
.browse-card h3{font-size:1.15rem;font-weight:700;letter-spacing:-.01em;margin:0 0 .35rem}
.browse-card p{font-size:.92rem;color:var(--text-muted);margin:0 0 1.25rem;line-height:1.55}
.browse-card .browse-chips{display:flex;flex-wrap:wrap;gap:.3rem;margin-bottom:1rem}
.browse-card .browse-chips span,.browse-card .browse-chips a{font-size:.72rem;font-weight:600;color:var(--text-muted);padding:.2rem .5rem;background:var(--bg-alt);border:1px solid var(--border);border-radius:2px;text-decoration:none}.browse-card .browse-chips a:hover{color:var(--primary);border-color:var(--primary)}
.browse-card .cta{font-size:.875rem;color:var(--accent);font-weight:600;display:inline-flex;align-items:center;gap:.35rem}

/* Researcher row (discovery) */
.person-row{display:flex;align-items:center;gap:1rem;padding:1rem 0;border-bottom:1px solid var(--border);text-decoration:none;color:inherit;transition:.12s}
.person-row:last-child{border-bottom:0}
.person-row:hover{background:var(--bg-alt);text-decoration:none;color:inherit}
.person-avatar{width:42px;height:42px;display:inline-flex;align-items:center;justify-content:center;background:var(--primary);color:#fff;border-radius:2px;font-size:.85rem;font-weight:700;flex-shrink:0}
.person-body{flex:1;min-width:0}
.person-name{font-size:.95rem;font-weight:700;color:var(--primary);margin:0;line-height:1.3}
.person-row:hover .person-name{color:var(--accent)}
.person-aff{font-size:.82rem;color:var(--text-muted)}
.person-stats{display:flex;gap:1.25rem;font-size:.78rem;color:var(--text-muted);flex-shrink:0}
.person-stats strong{display:block;font-size:1.05rem;color:var(--primary);font-weight:700;font-family:Monaco,monospace}

/* Recent activity row (discovery) */
.activity-row{display:flex;align-items:flex-start;gap:.85rem;padding:.85rem 0;border-bottom:1px solid var(--border)}
.activity-row:last-child{border-bottom:0}
.activity-icon{width:32px;height:32px;display:inline-flex;align-items:center;justify-content:center;background:var(--bg-alt);border:1px solid var(--border);border-radius:2px;font-size:.85rem;color:var(--text-muted);flex-shrink:0}
.activity-icon.add{background:rgba(34,197,94,.1);border-color:rgba(34,197,94,.3);color:#15803d}
.activity-icon.update{background:rgba(59,130,246,.08);border-color:rgba(59,130,246,.3);color:var(--accent)}
.activity-body{flex:1;min-width:0;font-size:.9rem}
.activity-body strong{color:var(--primary);font-weight:600}
.activity-body a{color:var(--primary);font-weight:500;text-decoration:none}
.activity-body a:hover{color:var(--accent);text-decoration:underline}
.activity-time{font-size:.78rem;color:var(--text-muted);font-family:Monaco,monospace;flex-shrink:0;text-align:right;white-space:nowrap}

/* Discovery footer (multi-column) */
.foot-grid{display:grid;grid-template-columns:2fr 1fr 1fr 1fr;gap:2.5rem}
@media (max-width:767.98px){.foot-grid{grid-template-columns:1fr 1fr;gap:2rem}}
@media (max-width:480px){.foot-grid{grid-template-columns:1fr}}
.foot h5{font-size:.72rem;font-weight:700;letter-spacing:.1em;text-transform:uppercase;color:var(--text-muted);margin:0 0 1rem}
.foot ul{list-style:none;padding:0;margin:0}
.foot ul li{margin-bottom:.5rem}
.foot ul a{color:var(--text);font-size:.92rem;text-decoration:none}
.foot ul a:hover{color:var(--accent);text-decoration:none}
.foot .brand{font-weight:800;font-size:1.05rem;color:var(--primary);display:flex;align-items:center;gap:.6rem;margin-bottom:1rem}
.foot .tagline{font-size:.92rem;color:var(--text-muted);margin-bottom:1.25rem;max-width:30ch;line-height:1.6}
.foot-bottom{margin-top:3rem;padding-top:1.5rem;border-top:1px solid var(--border);display:flex;align-items:center;gap:1rem;font-size:.82rem;color:var(--text-muted);flex-wrap:wrap}
.foot-bottom .sep{color:#cbd5e1}
.dot{display:inline-block;width:8px;height:8px;border-radius:999px;background:var(--success)}


/* ============================================================================
   (13) ACCESSIBILITY
   Keyboard focus ring + reduced-motion guard for hero pulse / health dot /
   hover transforms.
   ============================================================================ */
:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{animation-duration:.001ms!important;animation-iteration-count:1!important;transition-duration:.001ms!important;scroll-behavior:auto!important}
  .hero::before,.hero::after{animation:none}
  .health-cell .dot{animation:none}
}

/* ===== Faceted filter (OPAC / discovery style) — shared, driven by assets/facets.js ===== */
.fl-layout{display:grid;grid-template-columns:264px 1fr;gap:1.25rem;align-items:start}
@media (max-width:991.98px){.fl-layout{grid-template-columns:1fr}}
.fl-layout>*{min-width:0}
.facet-col{display:flex;flex-direction:column}
.facet-group{border:1px solid var(--border);border-radius:2px;background:#fff;margin-bottom:.75rem;overflow:hidden}
.facet-head{padding:.7rem 1rem;background:var(--bg-alt);font-size:.66rem;letter-spacing:.1em;text-transform:uppercase;font-weight:700;color:var(--text-muted);display:flex;align-items:center;justify-content:space-between}
.facet-list{display:flex;flex-direction:column}
.facet-list a,.facet-list label{display:flex;align-items:center;gap:.55rem;padding:.4rem 1rem;color:var(--text);font-size:.85rem;border-left:2px solid transparent;transition:background .12s,border-color .12s;line-height:1.4;cursor:pointer;margin:0;text-decoration:none}
.facet-list a:hover,.facet-list label:hover{background:var(--bg-alt);border-left-color:var(--accent);text-decoration:none;color:var(--text)}
.facet-list a.active,.facet-list label.checked{background:var(--bg-alt);border-left-color:var(--primary);color:var(--primary);font-weight:600}
.facet-list label input[type=checkbox]{accent-color:var(--primary);width:14px;height:14px;flex-shrink:0;cursor:pointer;margin:0}
.facet-list .name{flex:1;min-width:0}
.facet-list .count{margin-left:auto;font-family:Monaco,monospace;font-size:.76rem;color:var(--text-muted);font-weight:500;flex-shrink:0}
.facet-list .more-link{padding:.4rem 1rem;font-size:.8rem;color:var(--accent);font-weight:500;background:transparent;border:0;text-align:left;cursor:pointer;font-family:inherit;display:block;width:100%}
.facet-list .more-link:hover{background:var(--bg-alt)}
.facet-scroll{max-height:236px;overflow-y:auto}
.facet-scroll::-webkit-scrollbar{width:6px}
.facet-scroll::-webkit-scrollbar-thumb{background:#cbd5e1;border-radius:2px}
.facet-search{padding:.5rem 1rem;border-bottom:1px solid var(--border)}
.facet-search input{width:100%;height:30px;padding:0 .55rem;border:1px solid var(--border);border-radius:2px;font-size:.8rem;font-family:inherit;outline:0}
.facet-search input:focus{border-color:var(--primary)}
.facets-reset{display:block;width:100%;text-align:left;padding:.55rem 0;font-size:.82rem;font-weight:600;color:var(--accent);background:transparent;border:0;cursor:pointer;font-family:inherit}
.results-toolbar{display:flex;align-items:center;gap:1rem;margin-bottom:1rem;flex-wrap:wrap;background:#fff;border:1px solid var(--border);border-radius:2px;padding:.65rem .9rem}/* 2026-07-05 (user rule 'kazdy input v bielej sekcii'): list search+filter toolbar is a white card */
.results-count{font-size:.9rem;color:var(--text-muted)}
/* List filter (label + <select> of long option labels): let the select shrink
   and truncate instead of forcing the label past a narrow viewport (user
   2026-07-11 responsive pass, /admin/schemes + /admin/output-types). */
.lt-filter{min-width:0;max-width:100%}
.lt-filter select{min-width:0;max-width:100%}
.results-count strong{color:var(--primary);font-weight:700}
/* Unified facet-page layout (user 2026-07-06 "zjednotime dizajn pre kazdu
   stranku kde su facety"): one full-width .list-toolbar above BOTH the facet
   aside and the table. The GET form uses display:contents so its search box +
   facet checkboxes join this grid while the table stays OUTSIDE the form. */
.facet-page{display:grid;grid-template-columns:250px minmax(0,1fr);gap:1rem 1.5rem;align-items:start}
.facet-form{display:contents}
.facet-page .list-toolbar{grid-column:1 / -1;display:flex;align-items:center;gap:.75rem;flex-wrap:wrap;background:#fff;border:1px solid var(--border);border-radius:2px;padding:.6rem .85rem}
.facet-page .list-toolbar .facet-bar{flex:0 1 340px;max-width:none;margin:0}
.facet-page .list-toolbar .results-count{margin-left:auto;font-size:.82rem;white-space:nowrap}
.facet-page .list-toolbar .lt-perpage{display:inline-flex;align-items:center;gap:.4rem;font-size:.78rem;color:var(--text-muted);margin:0}
.facet-page .list-toolbar .lt-perpage select{border:1px solid var(--border);border-radius:2px;padding:.3rem .45rem;font-size:.8rem;background:#fff;color:var(--text)}
.facet-page .facet-aside{grid-column:1;min-width:0}
.facet-page .facet-table{grid-column:2;min-width:0}
@media(max-width:900px){.facet-page{grid-template-columns:1fr}.facet-page .list-toolbar,.facet-page .facet-aside,.facet-page .facet-table{grid-column:1}}
/* min-width:0 so the group can shrink below its content, and max-width:100% so
   it never exceeds the toolbar even once flex-wrap has put it on its own line.
   The sort control inside carries a variable-length label ("Zoradit podla:
   Najnovsie pridane"), and without these the toolbar ran off the right edge of
   a 375px screen - and because nothing here scrolls, the search button and the
   sort control were simply CUT OFF and unreachable, not merely off-screen
   (2026-07-31). */
.results-toolbar .right{margin-left:auto;display:flex;align-items:center;gap:.6rem;min-width:0;max-width:100%;flex-wrap:wrap}
.results-toolbar .right .dropdown{min-width:0}
.results-toolbar .right .dropdown-toggle{max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.facet-bar{position:relative;flex:1;max-width:440px}
.facet-bar input{width:100%;height:36px;padding:0 .75rem 0 2.1rem;border:1px solid var(--border);border-radius:2px;background:var(--bg-alt);font-size:.85rem;font-family:inherit;outline:0}
.facet-bar input:focus{background:#fff;border-color:var(--primary)}
.facet-bar i{position:absolute;left:.7rem;top:50%;transform:translateY(-50%);color:var(--text-muted);font-size:.82rem}
.active-filters{display:flex;align-items:center;gap:.5rem;flex-wrap:wrap;margin-bottom:1rem}
.active-filters .label{font-size:.66rem;font-weight:700;letter-spacing:.08em;text-transform:uppercase;color:var(--text-muted)}
.active-filters .fchip i{cursor:pointer;margin-left:.25rem}
.fchip-clear{color:var(--accent);font-size:.82rem;font-weight:600;text-decoration:none;cursor:pointer;margin-left:.3rem}

/* ===== Consolidated page classes (folded into shared system — fixes orphan/undefined classes) ===== */
/* read-only field value (shown instead of an input on detail records) */
.ro{display:block;font-size:.88rem;color:var(--primary);font-weight:500;padding:.2rem 0;line-height:1.5}
/* table cell helpers (list rows) */
.t-title{font-weight:600;color:var(--primary)}
.t-title:hover{color:var(--accent)}
.t-sub{font-size:.78rem;color:var(--text-muted);margin-top:.15rem}
.t-venue{color:var(--text)}
.t-authors{font-size:.82rem;color:var(--text-muted)}
.t-doi{font-family:Monaco,monospace;font-size:.78rem;color:var(--accent)}
.name-cell{display:flex;align-items:center;gap:.6rem;min-width:0}
.nm{font-weight:600;color:var(--primary)}
.cb{width:1%;text-align:center;white-space:nowrap}
/* section-card parts */
.csec-title{font-size:.72rem;font-weight:700;letter-spacing:.09em;text-transform:uppercase;color:var(--text-muted);margin:0}
.csec-body{padding:1.25rem}
/* table wrapper + pagers */
.tbl-wrap{background:#fff;border:1px solid var(--border);border-radius:2px;overflow-x:auto;-webkit-overflow-scrolling:touch}
.pages{display:flex;gap:.4rem;align-items:center;justify-content:flex-end;margin-top:1rem;font-size:.85rem;color:var(--text-muted)}
.list-pager{display:flex;align-items:center;justify-content:space-between;gap:1rem;margin-top:1rem;font-size:.85rem;color:var(--text-muted)}
/* ORCID + identifiers */
.orcid{color:var(--text-muted);font-family:Monaco,monospace;font-size:.82rem}
.orcid-ico{color:#a6ce39}
.id-badges{display:flex;gap:.4rem;flex-wrap:wrap;align-items:center}
.src{color:var(--text-muted)}
.scheme{color:var(--text-muted);font-size:.82rem}
.x{color:var(--text-muted);cursor:pointer}
.x:hover{color:#b91c1c}
/* button variants */
.btn-success-outline{background:#fff;border-color:rgba(34,197,94,.45);color:#15803d}
.btn-success-outline:hover{background:#15803d;border-color:#15803d;color:#fff}
.btn-danger-outline{background:#fff;border-color:rgba(239,68,68,.45);color:#b91c1c}
.btn-danger-outline:hover{background:#b91c1c;border-color:#b91c1c;color:#fff}
/* candidate (claim) rows */
.cand-claim{color:#15803d}
.cand-dismiss{color:var(--text-muted)}
/* row state tints */
.duplicate{background:rgba(245,158,11,.06)}
.pending{background:rgba(59,130,246,.05)}


/* ============================================================================
   (14) SHARED ADDITIONS 2026-07 — mockup refresh
   Sortable table headers (driven by assets/facets.js th[data-sort]),
   responsive admin chrome (burger + backdrop for the off-canvas .side),
   whitelabel discovery hero (tenant background image), permission matrix
   (hybrid RBAC + ABAC direct grants with validity), connector meta rows.
   ============================================================================ */

/* --- sortable column headers (.th-sort is added by facets.js) --- */
.th-sort{cursor:pointer;user-select:none;position:relative;padding-right:1.7rem!important}
.th-sort::before,.th-sort::after{content:"";position:absolute;right:.75rem;border-left:4px solid transparent;border-right:4px solid transparent;opacity:.3}
.th-sort::before{top:calc(50% - 7px);border-bottom:5px solid currentColor}
.th-sort::after{top:calc(50% + 2px);border-top:5px solid currentColor}
.th-sort:hover::before,.th-sort:hover::after{opacity:.65}
.th-sort.asc::before{opacity:1}
.th-sort.asc::after{opacity:.15}
.th-sort.desc::after{opacity:1}
.th-sort.desc::before{opacity:.15}
.th-sort:focus-visible{outline:2px solid var(--accent);outline-offset:-2px}

/* --- responsive admin/user chrome: topbar burger + sidebar backdrop --- */
.tb-burger{display:none;align-items:center;background:transparent;border:0;padding:.4rem .5rem;color:var(--text);font-size:1.1rem;cursor:pointer;margin-left:-.35rem}
.tb-burger:hover{color:var(--primary)}
/* Mobile: show the topbar burger so the off-canvas sidebar (data-nav="open")
   can be opened. This override MUST stay AFTER the base display:none above -
   equal-specificity single-class rules resolve by source order, so a base
   display:none placed later would re-hide it (the 2026-07-07 regression). */
@media (max-width:991.98px){.tb-burger{display:inline-flex}}
/* Topbar burger retired 2026-07-07: the icon-rail brand burger (.side-collapse)
   is now the sole menu toggle below 992px, so this stays hidden at every width. */
.side-backdrop{display:none;position:fixed;inset:0;background:rgba(15,23,42,.45);z-index:150}
.side-backdrop.show{display:block}
@media (max-width:991.98px){
  .topbar{flex-wrap:wrap;height:auto;min-height:56px;padding-top:.4rem;padding-bottom:.4rem;row-gap:.4rem}
  /* .topbar h1 shrink/truncate used to be redeclared here. It now lives on the
     base rule because the desktop range needed it too - see the comment there;
     keeping a second copy is how the two ranges drifted apart in the first
     place. The wrap-specific reasoning that justified it: below 992px .topbar
     is flex-wrap:wrap, and a wrap container breaks lines on an item's
     HYPOTHETICAL size, so flex-basis MUST stay 0 - with basis:auto a long
     title's basis is the full text width and the h1 wrapped onto its own line
     (user 2026-07-12: burger/title/kebab stacked in 3 rows). */
  .tb-search{order:10;flex-basis:100%;max-width:none}
  /* The topbar wraps to a variable height below 992px, so a fixed 56px sticky
     offset for the record tabs would overlap it - keep the tabs static here. */
  .rec-tabs,.record-tabs{position:static;top:auto}
  .rec-header{flex-wrap:wrap}
  .rec-header .actions{width:100%;justify-content:flex-start}
  .rec-metrics{flex-wrap:wrap;gap:.9rem 1.5rem}
}

/* --- whitelabel discovery hero: institution background image ---
   Usage: <section class="hero has-image" style="--hero-img:url('...')">
   Image is set per institution in Admin -> Nastavenia -> Vzhľad; a dark scrim
   keeps text WCAG-readable over any image; decorative orbs are disabled. */
.hero.has-image{background-image:linear-gradient(rgba(10,14,26,.72),rgba(10,14,26,.78)),var(--hero-img);background-size:cover;background-position:center}
.hero.has-image::before,.hero.has-image::after{display:none}

/* --- permission matrix (hybrid RBAC roles + ABAC direct grants) ---
   Used by admin/user-detail.html and admin/roles.html. One .perm-group per
   permission domain; .perm-item rows carry a checkbox, code, description and
   optional validity (valid_from / valid_until) + origin badge (.perm-src). --- */
.perm-group{background:#fff;border:1px solid var(--border);border-radius:2px;margin-bottom:.85rem;overflow:hidden}
.perm-group-head{display:flex;align-items:center;gap:.6rem;padding:.65rem 1rem;background:var(--bg-alt);border-bottom:1px solid var(--border);font-size:.72rem;font-weight:700;letter-spacing:.08em;text-transform:uppercase;color:var(--text-muted)}
.perm-group-head input[type=checkbox]{accent-color:var(--primary);width:14px;height:14px;margin:0}
.perm-group-head .n{margin-left:auto;font-family:Monaco,monospace;font-weight:500}
.perm-list{display:grid;grid-template-columns:1fr 1fr}
@media (max-width:1199.98px){.perm-list{grid-template-columns:1fr}}
.perm-item{display:flex;align-items:flex-start;gap:.6rem;padding:.6rem 1rem;border-bottom:1px solid var(--border);border-right:1px solid var(--border);font-size:.85rem}
.perm-item:nth-child(2n){border-right:0}
.perm-item input[type=checkbox]{accent-color:var(--primary);width:14px;height:14px;margin-top:.2rem;flex-shrink:0}
.perm-item .bd{flex:1;min-width:0}
.perm-item .perm-code{display:block;font-family:Monaco,monospace;font-size:.78rem;font-weight:600;color:var(--primary)}
.perm-item .perm-desc{display:block;font-size:.78rem;color:var(--text-muted);margin-top:.1rem}
.perm-item.granted{background:rgba(59,130,246,.04)}
.perm-src{display:inline-block;font-size:.64rem;font-weight:700;text-transform:uppercase;letter-spacing:.05em;padding:.1rem .4rem;border-radius:2px;margin-top:.3rem}
.perm-src.role{background:var(--bg-alt);color:var(--text-muted);border:1px solid var(--border)}
.perm-src.direct{background:rgba(59,130,246,.1);color:var(--accent)}
/* alpha .06 not .12 (axe: SERIOUS color-contrast, spec u2-wcag-formal-audit.md
   - same near-miss class as .b-badge.warn above). */
.perm-src.expiring{background:rgba(245,158,11,.06);color:#b45309}
.perm-validity{display:flex;align-items:center;gap:.45rem;margin-top:.4rem;font-size:.76rem;color:var(--text-muted);flex-wrap:wrap}
.perm-validity input[type=date]{height:28px;border:1px solid var(--border);border-radius:2px;font-size:.76rem;font-family:inherit;padding:0 .4rem;color:var(--text);background:#fff}

/* --- connector registry meta (admin/integrations + connector detail) --- */
.conn-meta{display:flex;gap:1rem 1.75rem;flex-wrap:wrap;font-size:.8rem;color:var(--text-muted);padding:.6rem 0}
.conn-meta .k{font-weight:600;color:var(--text)}
.conn-meta .mono{font-size:.78rem}
.conn-ver{display:inline-flex;align-items:center;gap:.35rem;font-family:Monaco,monospace;font-size:.76rem;font-weight:700;background:var(--bg-alt);border:1px solid var(--border);border-radius:2px;padding:.15rem .45rem;color:var(--primary)}
/* Import-candidate review (2026-07-07): per-author person picker + record
   institution on /admin/integrations/candidate/{id}. */
.cand-author{border:1px solid var(--border);border-radius:2px;background:#fff;padding:.7rem .85rem;margin-bottom:.6rem}
.cand-author-head{display:flex;align-items:center;gap:.5rem;flex-wrap:wrap;margin-bottom:.15rem}
.cand-author-head strong{font-size:.9rem;color:var(--primary)}
.cand-author-affil{font-size:.78rem;color:var(--text-muted);margin:.1rem 0 .5rem}
.cand-author label,.cand-block label{display:block;font-size:.72rem;font-weight:700;letter-spacing:.02em;text-transform:uppercase;color:var(--text-muted);margin-bottom:.25rem}
.cand-author .cbx,.cand-block .cbx{max-width:520px}
.cand-block{margin-top:.25rem}
.cand-hint{display:block;margin-top:.35rem;font-size:.76rem}
.cand-actions{display:flex;gap:.5rem;margin:1.1rem 0 .3rem}
.cand-reject{margin:0}
.cand-note{font-size:.8rem;margin-top:.6rem}

/* --- canonical validation pipeline (.vsteps) ---
   Replaces the four bespoke per-page implementations (.wflow/.vstate/.valpill/.stage).
   <div class="vsteps"><span class="vstep done">Harvestované</span><span class="vstep current">Na kontrole</span><span class="vstep">Validované</span></div> */
.vsteps{display:flex;align-items:center;gap:.35rem;flex-wrap:wrap;margin-bottom:1.25rem}
.wfbar{display:flex;align-items:center;gap:.9rem;flex-wrap:wrap;background:#fff;border:1px solid var(--border);border-radius:2px;padding:.55rem .9rem;margin-bottom:1rem}
.wfbar .wf-label{font-size:.68rem;font-weight:700;letter-spacing:.08em;text-transform:uppercase;color:var(--text-muted);white-space:nowrap}
.wfbar .vsteps{margin-bottom:0}
.wfbar form{margin-left:auto}
@media (max-width:768px){.wfbar form{margin-left:0}}
.xlink-bar{display:flex;align-items:center;gap:.75rem;flex-wrap:wrap;background:#fff;border:1px solid var(--border);border-left:3px solid var(--accent);border-radius:2px;padding:.5rem .9rem;margin-bottom:1rem;font-size:.82rem}
.xlink-bar.none{border-left-color:var(--border)}
.xlink-bar .t{font-weight:700;color:var(--primary);white-space:nowrap}
.xlink-bar .d{color:var(--text-muted);flex:1;min-width:0}
.xlink-bar .btn{margin-left:auto}
.vstep{display:inline-flex;align-items:center;gap:.4rem;font-size:.78rem;font-weight:600;color:var(--text-muted);background:#fff;border:1px solid var(--border);border-radius:2px;padding:.35rem .7rem;position:relative}
.vstep::before{content:"";width:8px;height:8px;border-radius:50%;background:var(--border);flex-shrink:0}
.vstep.done{color:#15803d;border-color:rgba(34,197,94,.35)}
.vstep.done::before{background:var(--success)}
.vstep.current{color:var(--primary);border-color:var(--accent);background:rgba(59,130,246,.05)}
.vstep.current::before{background:var(--accent)}
.vstep + .vstep{margin-left:.6rem}
.vstep + .vstep::after{content:"";position:absolute;left:-.75rem;top:50%;width:.55rem;height:1px;background:var(--border)}

/* --- stat line (compact per-list KPI strip; promoted from inline duplicates) ---
   <div class="stat-line"><div class="cell"><span class="val">312</span><span class="lbl">Celkom</span></div>…</div> */
.stat-line{display:flex;flex-wrap:wrap;gap:.5rem;margin-bottom:1.1rem}
.stat-line .cell{background:#fff;border:1px solid var(--border);border-radius:2px;padding:.55rem .95rem;display:flex;flex-direction:column;min-width:110px}
.stat-line .val{font-family:Monaco,monospace;font-size:1.05rem;font-weight:700;color:var(--primary);line-height:1.2}
.stat-line .lbl{font-size:.66rem;text-transform:uppercase;letter-spacing:.06em;color:var(--text-muted);font-weight:700;margin-top:.1rem}
.stat-line .cell.warn .val{color:#b45309}
.stat-line .cell.danger .val{color:#b91c1c}

/* --- bulk action bar (canonical; replaces per-page .bulk-bar/.bulkbar) --- */
.bulk-bar{display:flex;align-items:center;gap:.75rem;background:#fff;border:1px solid var(--border);border-radius:2px;padding:.55rem .9rem;margin-bottom:.9rem;font-size:.85rem;flex-wrap:wrap}
.bulk-bar .cnt{font-weight:700;color:var(--primary);font-family:Monaco,monospace}
.bulk-bar .spacer{margin-left:auto}

/* --- harvest confidence bar (validation queue, outputs) --- */
.conf{display:flex;align-items:center;gap:.5rem;min-width:110px}
.conf-bar{flex:1;height:6px;background:var(--bg-alt);border:1px solid var(--border);border-radius:2px;overflow:hidden}
.conf-bar .fill{height:100%;background:var(--success)}
.conf-bar .fill.mid{background:var(--warning)}
.conf-bar .fill.lo{background:var(--danger)}
.conf .n{font-family:Monaco,monospace;font-size:.76rem;color:var(--text-muted);font-weight:600}

/* --- SDG goal chip (P9 W6, module m11-sdg): admin /admin/sdg mapping table
   cell + small discovery output/project detail chips (spec sec B.2). Added
   directly here rather than round-tripped through demo/assets/stellacris.css
   first (that file's own header comment says port-then-copy) because this
   pass's task instructions excluded touching demo/ - the source markup/
   colour values are ported verbatim from demo/admin/sdg.html's own
   page-unique ".sdg-pill" rule, this is a documented, deliberate gap to
   reconcile in a future demo-sync pass (Princip 21 cyclic sync). --- */
.sdg-pill{display:inline-flex;align-items:center;justify-content:center;min-width:22px;height:20px;padding:0 .3rem;border-radius:2px;color:#fff;font-family:Monaco,monospace;font-size:.7rem;font-weight:700;margin-right:.2rem;margin-bottom:.15rem}

/* --- audit before/after diff spans --- */
.chg{font-size:.82rem;line-height:1.6}
.chg .before{background:rgba(239,68,68,.08);color:#b91c1c;padding:.05rem .35rem;border-radius:2px;text-decoration:line-through;text-decoration-thickness:1px}
/* alpha .06 not .1 (axe: SERIOUS color-contrast, spec u2-wcag-formal-audit.md
   - same near-miss class as .b-badge.ok above). */
.chg .after{background:rgba(34,197,94,.06);color:#15803d;padding:.05rem .35rem;border-radius:2px;font-weight:600}
.chg .arr{color:var(--text-muted);margin:0 .3rem}

/* --- audit action-type pills --- */
/* .create/.state alpha .06 not .12 (axe: SERIOUS color-contrast, spec
   u2-wcag-formal-audit.md - same near-miss class as .b-badge.ok/.warn). */
.act-pill{display:inline-block;padding:.16rem .5rem;font-size:.68rem;font-weight:700;border-radius:2px;white-space:nowrap}
.act-pill.create{background:rgba(34,197,94,.06);color:#15803d}
.act-pill.edit{background:rgba(59,130,246,.1);color:#1d4ed8}
.act-pill.validate{background:rgba(15,23,42,.08);color:var(--primary)}
.act-pill.sync{background:#f3e8ff;color:#7e22ce}
.act-pill.state{background:rgba(245,158,11,.06);color:#b45309}
.act-pill.role{background:#dbeafe;color:#1d4ed8}
.act-pill.merge{background:var(--bg-alt);color:var(--text);border:1px solid var(--border)}

/* --- file upload row (branding logo, discovery hero image, attachments) --- */
.upload-row{display:flex;align-items:center;gap:.85rem;padding:.75rem 0;border-bottom:1px solid var(--border)}
.upload-row:last-child{border-bottom:0}
.upload-row .ico{width:38px;height:38px;background:var(--bg-alt);border:1px solid var(--border);border-radius:2px;display:flex;align-items:center;justify-content:center;color:var(--text-muted);flex-shrink:0}
.upload-row .bd{flex:1;min-width:0}
.upload-row .bd strong{display:block;font-size:.86rem;color:var(--primary);font-weight:600}
.upload-row .bd small{font-size:.76rem;color:var(--text-muted)}
.upload-row .acts{display:flex;gap:.35rem;flex-shrink:0}
.upload-preview{border:1px solid var(--border);border-radius:2px;overflow:hidden;margin-top:.6rem;max-width:520px}
.upload-preview img,.upload-preview .ph{display:block;width:100%;height:120px;object-fit:cover}
.upload-preview .ph{background:linear-gradient(135deg,var(--hero-from),var(--hero-to));display:flex;align-items:center;justify-content:center;color:rgba(255,255,255,.7);font-size:.8rem}

/* --- danger-zone action card (settings advanced) --- */
.danger-card{display:flex;align-items:center;gap:1rem;padding:1rem 1.15rem;background:#fff;border:1px solid var(--border);border-radius:2px;margin-bottom:.75rem;flex-wrap:wrap}
.danger-card.destructive{border-color:rgba(239,68,68,.45)}
.danger-card .bd{flex:1;min-width:220px}
.danger-card .bd strong{display:block;font-size:.9rem;color:var(--primary)}
.danger-card .bd small{font-size:.78rem;color:var(--text-muted)}

/* ---- product wordmark 2026-07-04 --------------------------------------- */
/* Text-only "Stella"+"cris" wordmark (bold + regular weight pair), no icon.
   Sizing/color are inherited from the surrounding context (.side-brand,
   .nav-brand, footer text) - this rule only fixes the internal weight
   contrast between the two halves of the word. */
.logo-mark{display:inline-flex;align-items:baseline}
.logo-mark .lc{font-weight:400;letter-spacing:0}
/* Discreet product-credit line in the Discovery footer (white-label
   principle: client identity is the prominent .foot-inner text, the
   Stellacris wordmark is pushed right + shrunk + kept in the ambient muted
   footer color instead of --primary). */
.foot-credit{margin-left:auto;font-size:.78rem}

/* ===== Discovery footer: two rows + accessibility bar ====================
   (2026-07-09, spec .build/specs/p9-discovery-footer-accessibility.md). Top row
   .foot-nav = institution + nav sitemap; bottom row .foot-meta = content (c)
   institution + legal (left) and .a11y-bar + software (c) Stellacris credit
   (right). Dual attribution per the on-prem standard. */
.foot-nav{display:flex;align-items:center;gap:.4rem 1rem;flex-wrap:wrap}
.foot-nav .foot-org{color:var(--primary);font-weight:700}
.foot-nav a{color:var(--text-muted);text-decoration:none}
.foot-nav a:hover{color:var(--accent)}
.foot-nav .sep{color:#cbd5e1}
.foot-meta{display:flex;align-items:center;justify-content:space-between;gap:.6rem 1.25rem;flex-wrap:wrap;margin-top:1rem;padding-top:.85rem;border-top:1px solid var(--border);font-size:.8rem}
.foot-meta-legal,.foot-meta-tools{display:flex;align-items:center;gap:.35rem .7rem;flex-wrap:wrap}
.foot-meta-legal .sep{color:#cbd5e1}
.foot-meta-legal a{color:var(--text-muted);text-decoration:none}
.foot-meta-legal a:hover{color:var(--accent)}
.foot-copy,.foot-copy-sw{white-space:nowrap}
.foot-meta .foot-credit{margin-left:0;font-size:.78rem;display:inline-flex;align-items:center;gap:.25rem}
@media (max-width:767.98px){.foot-meta{justify-content:flex-start}.foot-meta-tools{width:100%}}

/* Accessibility controls. Native <button>s; toggles carry aria-pressed;
   a11y.js applies instantly, no-JS posts /a11y. Live in a <details> menu in
   the discovery nav next to the language picker (.a11y-menu below, user
   2026-07-09; relocated from the footer). */
.a11y-bar{display:inline-flex;align-items:center;gap:.3rem;flex-wrap:wrap}
.a11y-bar .a11y-label{color:var(--text-muted);font-size:.76rem;margin-right:.15rem;display:inline-flex;align-items:center;gap:.3rem}
.a11y-ctl{margin:0;display:inline-flex}
.a11y-btn{font-family:inherit;font-size:.78rem;font-weight:600;line-height:1;display:inline-flex;align-items:center;gap:.3rem;padding:.32rem .5rem;border:1px solid var(--border);border-radius:2px;background:#fff;color:var(--text);cursor:pointer}
.a11y-btn:hover{border-color:var(--accent);color:var(--accent)}
.a11y-font{min-width:2rem;justify-content:center}
.a11y-toggle[aria-pressed="true"],.a11y-toggle.is-on{background:var(--accent);border-color:var(--accent);color:#fff}
.a11y-toggle[aria-pressed="true"]:hover,.a11y-toggle.is-on:hover{color:#fff}
/* Accessibility <details> menu in the discovery nav (icon trigger + dropdown
   panel that stacks the .a11y-bar controls vertically). */
.a11y-menu{position:relative;display:inline-flex}
/* Framed icon trigger, matching the language switch + login (public-www
   .a11y-toggle pattern, user 2026-07-09). Shared 32px height below. */
.a11y-menu-btn{list-style:none;cursor:pointer;display:inline-flex;align-items:center;justify-content:center;height:32px;min-width:32px;padding:0 .5rem;border:1px solid var(--border);border-radius:2px;background:#fff;color:var(--text-muted);font-size:1.05rem}
.a11y-menu-btn::-webkit-details-marker{display:none}
.a11y-menu-btn::marker{content:""}
.a11y-menu-btn:hover{border-color:var(--text-muted);color:var(--text)}
.a11y-menu[open] .a11y-menu-btn{border-color:var(--accent);color:var(--accent)}
.a11y-menu-btn:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
/* Utility controls (lang select, a11y trigger, login) share one height so the
   nav row aligns (user 2026-07-09). */
.nav-actions>.btn-sm{height:32px;display:inline-flex;align-items:center;padding-top:0;padding-bottom:0}
/* Dropdown panel: uppercase label eyebrow; A-/A+ sit side by side (nth-child
   2&3 = the two .a11y-font forms of _a11y-bar.php), contrast/reading/reset are
   full width. */
.a11y-menu-panel{position:absolute;top:calc(100% + .45rem);right:0;min-width:224px;background:#fff;border:1px solid var(--border);border-radius:3px;box-shadow:0 10px 28px rgba(15,23,42,.12);padding:.7rem .7rem calc(.9rem + env(safe-area-inset-bottom, 0px));z-index:1000}
.a11y-menu-panel .a11y-bar{display:flex;flex-wrap:wrap;gap:.4rem}
.a11y-menu-panel .a11y-label{flex-basis:100%;margin:0 0 .1rem;font-size:.68rem;font-weight:700;letter-spacing:.06em;text-transform:uppercase}
.a11y-menu-panel .a11y-ctl{flex:1 1 100%;display:flex}
.a11y-menu-panel .a11y-ctl:nth-child(2),.a11y-menu-panel .a11y-ctl:nth-child(3){flex:1 1 calc(50% - .2rem)}
.a11y-menu-panel .a11y-btn{width:100%;justify-content:flex-start;padding:.45rem .6rem}
.a11y-menu-panel .a11y-font{justify-content:center;font-weight:700}
.a11y-menu-panel .a11y-reset{color:var(--text-muted)}
/* Language switch: <details> dropdown (globe + code) mirroring public-www
   .langsw, on discovery tokens (2px radius, 32px height to match the row). */
/* ACCOUNT dropdown (templates/_account-menu.php). The summary reuses .tb-acct
   so the chip is pixel-identical to the plain link it replaced; only the caret
   and the panel are new. Panel styling is shared with .langsw-menu below -
   one dropdown look, defined once (knowledge/12). */
.acctmenu{position:relative;display:inline-flex}
.acctmenu>summary{list-style:none;cursor:pointer}
.acctmenu>summary::-webkit-details-marker{display:none}
.acctmenu>summary::marker{content:""}
.acctmenu>summary:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
.acctmenu>summary .nm{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;min-width:0}
.acctmenu>summary .av img{width:100%;height:100%;object-fit:cover;border-radius:2px}
.acct-caret{font-size:.62rem;color:var(--text-muted);flex-shrink:0}
.acctmenu[open]>summary,.acctmenu[open]>summary .acct-caret{color:var(--primary)}
.acct-menu{position:absolute;top:calc(100% + .4rem);right:0;min-width:210px;list-style:none;margin:0;padding:.3rem .3rem calc(.35rem + env(safe-area-inset-bottom, 0px));background:#fff;border:1px solid var(--border);border-radius:3px;box-shadow:0 10px 28px rgba(15,23,42,.12);z-index:1000}
.acct-menu a,.acct-menu button{display:flex;align-items:center;gap:.55rem;width:100%;padding:.45rem .6rem;border:0;border-radius:2px;background:transparent;color:var(--text);font-size:.85rem;font-weight:500;text-align:left;text-decoration:none;cursor:pointer;font-family:inherit}
.acct-menu a i,.acct-menu button i{width:1rem;text-align:center;color:var(--text-muted);font-size:.85rem;flex-shrink:0}
.acct-menu a:hover,.acct-menu button:hover{background:var(--bg-alt);color:var(--text);text-decoration:none}
.acct-menu form{margin:0}
.acct-sep{border-top:1px solid var(--border);margin-top:.3rem;padding-top:.3rem}

.langsw{position:relative;display:inline-flex}
.langsw>summary{list-style:none;cursor:pointer;display:inline-flex;align-items:center;gap:.35rem;height:32px;padding:0 .6rem;border:1px solid var(--border);border-radius:2px;background:#fff;color:var(--text-muted);font-size:.82rem;font-weight:600;user-select:none}
.langsw>summary::-webkit-details-marker{display:none}
.langsw>summary::marker{content:""}
.langsw>summary i{color:var(--text-muted);font-size:.85rem}
.langsw>summary:hover{border-color:var(--text-muted);color:var(--text)}
.langsw[open]>summary{border-color:var(--accent);color:var(--accent)}
.langsw>summary:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
.langsw-menu{position:absolute;top:calc(100% + .4rem);right:0;min-width:160px;list-style:none;margin:0;padding:.3rem .3rem calc(.55rem + env(safe-area-inset-bottom, 0px));background:#fff;border:1px solid var(--border);border-radius:3px;box-shadow:0 10px 28px rgba(15,23,42,.12);z-index:1000}
.langsw-menu a{display:block;padding:.45rem .6rem;border-radius:2px;color:var(--text);font-size:.85rem;font-weight:500;text-decoration:none}
.langsw-menu a:hover{background:var(--bg-alt);text-decoration:none}
.langsw-menu a[aria-current="true"]{color:var(--accent);font-weight:700}
/* Mobile: a right-anchored dropdown panel can be wider than the space left of
   its trigger and get clipped off-screen (user 2026-07-09). In the top-bar
   layers pin it as a full-width sheet just below the bar instead. Scoped to
   those layers (the bar sits at the viewport top) - other contexts keep the
   absolute drop. */
@media (max-width:640px){
  :is(body.layer-discovery,body.layer-admin,body.layer-user) .a11y-menu-panel,
  :is(body.layer-discovery,body.layer-admin,body.layer-user) .langsw-menu{position:fixed;left:.75rem;right:.75rem;top:3.9rem;min-width:0;max-width:none}
  body.layer-discovery .a11y-menu-panel,body.layer-discovery .langsw-menu{top:5.1rem}
}

/* Font-size steps - the type system is rem-based, so scaling the root font-size
   scales all discovery text + spacing. The attribute is only ever set in
   discovery (server + a11y.js), so these never fire in admin/user. */
html[data-a11y-font="1"]{font-size:112.5%}
html[data-a11y-font="2"]{font-size:125%}
html[data-a11y-font="3"]{font-size:137.5%}

/* High contrast (discovery + admin + user layers, user 2026-07-09): override
   key tokens on the body, underline links, thicker focus. Targets high ratios
   (dark text/navy accent on white). */
html[data-a11y-contrast="high"] :is(body.layer-discovery,body.layer-admin,body.layer-user){--text:#000;--text-muted:#1f2937;--border:#334155;--accent:#0b3d91;--accent-rgb:11,61,145;--bg:#fff;--bg-alt:#fff}
html[data-a11y-contrast="high"] :is(body.layer-discovery,body.layer-admin,body.layer-user) a{text-decoration:underline}
html[data-a11y-contrast="high"] :is(body.layer-discovery,body.layer-admin,body.layer-user) .sep{color:#475569}
html[data-a11y-contrast="high"] :is(body.layer-discovery,body.layer-admin,body.layer-user) :focus-visible{outline-width:3px}

/* Readability (discovery + admin + user layers): looser line/letter/word
   spacing + underlined links (CSS-only, no webfont - asset governance). */
html[data-a11y-reading="on"] :is(body.layer-discovery,body.layer-admin,body.layer-user){line-height:1.9;letter-spacing:.02em;word-spacing:.05em}
html[data-a11y-reading="on"] :is(body.layer-discovery,body.layer-admin,body.layer-user) a{text-decoration:underline}

/* ---- P9 W3: user project-edit keyword chips + danger zone + budget mirror
   (mockup demo/user/03-project-edit.html) - shared so any future tabbed
   detail page (admin or user) can reuse the same components. ---- */
.kw-wrap{display:flex;flex-wrap:wrap;gap:.4rem;align-items:center}
.kw{display:inline-flex;align-items:center;gap:.4rem;padding:.3rem .65rem;background:var(--bg-alt);border:1px solid var(--border);border-radius:2px;font-size:.82rem;color:var(--text)}
.kw button{background:transparent;border:0;color:var(--text-muted);cursor:pointer;font-size:.7rem;padding:0;line-height:1}
.kw button:hover{color:#b91c1c}
.danger-row{display:flex;align-items:center;justify-content:space-between;gap:1rem;padding:1rem;border:1px solid var(--border);border-radius:2px;flex-wrap:wrap}
.danger-row.crit{border-color:rgba(239,68,68,.3);background:rgba(239,68,68,.03)}
.bkpi-strip{display:grid;grid-template-columns:repeat(3,1fr);gap:1rem;margin-bottom:1.25rem}
@media (max-width:720px){.bkpi-strip{grid-template-columns:1fr}}
.bkpi{background:#fff;border:1px solid var(--border);border-radius:2px;padding:1rem 1.25rem}
.bkpi.accent{border-left:3px solid var(--accent)}
.bkpi.ok{border-left:3px solid var(--success)}
.bkpi-l{font-size:.68rem;text-transform:uppercase;letter-spacing:.06em;color:var(--text-muted);font-weight:700;margin-bottom:.3rem}
.bkpi-v{font-size:1.4rem;font-weight:700;color:var(--primary);font-family:Monaco,monospace;letter-spacing:-.02em;line-height:1.1}
.bkpi-v.accent{color:var(--accent)}
.bkpi-v.ok{color:#15803d}

/* W9 discovery visual parity */
/* ---- .search-bar / .search-inner (discovery list-page + /search hero) ---
   Ported verbatim from every demo/discovery/{02-results,06-researchers,
   07-outputs,08-grants,09-materials}.html <style> block (byte-identical
   page-unique CSS repeated in all five mockup files - never promoted to
   demo/assets/stellacris.css there). Production's templates/discovery/
   {projects,researchers,outputs,calls}/list.php + search.php ALL emit this
   exact `<header class="search-bar">...<div class="search-inner">` markup
   already (shared across 5 templates), but until this pass no CSS for it
   existed anywhere in this app copy - the hero rendered as a completely
   unstyled <input>/<button>, which is the dominant cause of the "looks
   broken/bare" report on every discovery list page. Centralised HERE
   (once, shared) rather than duplicated as five identical $pageCss blocks,
   since the markup itself is already identically shared across those five
   templates. Not ported back to demo/assets/stellacris.css in this pass
   (task scope: demo/ is not to be edited) - a future demo-sync pass should
   fold the same rule out of the five per-page <style> blocks into
   demo/assets/stellacris.css so both copies host it identically. */
.search-bar{background:var(--bg-alt);padding:1.5rem var(--page-inset);border-bottom:1px solid var(--border)}
.search-inner{background:#fff;border:1px solid var(--border);border-radius:2px;padding:.5rem;display:flex;align-items:center;gap:.5rem}
.search-inner:focus-within{border-color:var(--primary);box-shadow:0 0 0 3px rgba(15,23,42,.06)}
.search-inner input{flex:1;height:44px;padding:0 .25rem 0 .85rem;background:transparent;border:0;outline:0;font-size:1rem;font-family:inherit;color:var(--text)}

/* W8 combobox */
/* ---- Searchable entity <select> component (spec .build/specs/
   p9-w8-searchable-selects.md, checklist
   .build/parity/app-searchable-selects.md) - markup built by
   app/public/assets/combobox.js. Sizing/spacing matches the plain <select>
   inputs used all over admin/user mini-forms (.4rem .6rem padding,
   .82rem font-size, 1px border, 2px radius) so a converted field sits
   flush with any sibling untouched field in the same row. */
.cbx{position:relative;display:inline-block;width:100%}
/* Standard sr-only clip-rect technique (NOT display:none): the real
   <select> must stay "a candidate for constraint validation" per the HTML5
   spec so the pre-existing `required` attribute keeps being enforced by the
   browser with no separate JS re-implementation. */
.cbx-native{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}
.cbx-control{position:relative;display:flex;align-items:center}
.cbx-input{width:100%;border:1px solid var(--border);border-radius:2px;padding:.45rem 1.8rem .45rem .65rem;font-size:.85rem;font-family:inherit;color:var(--text);background:#fff}
.cbx-input:focus{outline:0;border-color:var(--primary);box-shadow:0 0 0 2px rgba(15,23,42,.08)}
.cbx-input:disabled{background:var(--bg-alt);color:var(--text-muted)}
.cbx-clear{position:absolute;right:.35rem;top:50%;transform:translateY(-50%);border:0;background:transparent;color:var(--text-muted);font-size:1rem;line-height:1;cursor:pointer;padding:.1rem .3rem}
.cbx-clear:hover{color:#b91c1c}
.cbx-menu{position:absolute;z-index:40;top:calc(100% + 2px);left:0;right:0;max-height:260px;overflow-y:auto;background:#fff;border:1px solid var(--border);border-radius:2px;box-shadow:0 6px 18px rgba(15,23,42,.12);margin:0;padding:.25rem;list-style:none}
.cbx-item{display:flex;align-items:baseline;justify-content:space-between;gap:.6rem;padding:.4rem .55rem;border-radius:2px;font-size:.82rem;color:var(--text);cursor:pointer}
.cbx-item:hover,.cbx-item.active{background:var(--bg-alt)}
.cbx-item-label{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* Bootstrap dropdown (discovery sort menu _sort-links.php etc.): active item
   follows the branded --primary, not Bootstrap's default #0d6efd blue (user
   2026-07-07 "roletka podfarbena aktivnej polozky nie je podla farby
   primarnej"). Loaded after bootstrap.min.css so same-specificity wins. */
.dropdown-item.active,.dropdown-item:active{background-color:var(--primary);color:#fff}
/* Cookie consent banner (2026-07-08; 2026-07-09 reshaped to a contained,
   bottom-anchored card ~content-column width instead of an edge-to-edge bar -
   border all round, 2px radius per design manual, no rounded corners). */
.cookie-banner{position:fixed;left:0;right:0;bottom:1rem;z-index:2000;width:min(1680px,calc(100% - 2*var(--page-inset)));margin:0 auto;background:#fff;border:1px solid var(--border);border-radius:2px;box-shadow:0 6px 24px rgba(15,23,42,.14);padding:.9rem 1.15rem;display:flex;align-items:center;justify-content:space-between;gap:1rem;flex-wrap:wrap}
.cookie-banner-text{margin:0;font-size:.84rem;color:var(--text);max-width:78ch}
.cookie-banner-actions{display:flex;gap:.5rem;align-items:center;flex-shrink:0}
@media (max-width:575.98px){.cookie-banner{bottom:0;width:100%;border-radius:0;border-left:0;border-right:0;border-bottom:0;flex-direction:column;align-items:stretch}.cookie-banner-actions{justify-content:flex-end}}
/* Analytics dashboard charts (2026-07-08) - dependency-free, branded palette
   (var(--accent)), fixed heights so nothing grows unbounded. */
.chart-bars{display:flex;align-items:flex-end;gap:2px;height:150px;padding-top:.5rem;border-bottom:1px solid var(--border)}
.chart-bar{flex:1 1 0;min-width:1px;background:var(--accent);border-radius:2px 2px 0 0;align-self:flex-end}
.chart-axis{display:flex;justify-content:space-between;font-size:.72rem;color:var(--text-muted);margin-top:.35rem}
.chart-donut-wrap{display:flex;gap:1.25rem;align-items:center;flex-wrap:wrap}
.chart-donut{width:150px;height:150px;flex-shrink:0}
.chart-legend{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:.4rem;font-size:.82rem;min-width:150px;flex:1}
.chart-legend-item{display:flex;align-items:center;gap:.5rem}
.chart-legend-dot{width:12px;height:12px;border-radius:2px;background:var(--accent);flex-shrink:0}
.chart-legend-label{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.chart-legend-val{color:var(--text-muted);font-variant-numeric:tabular-nums;flex-shrink:0}
.chart-hbars{display:flex;flex-direction:column;gap:.5rem}
.chart-hbar-row{display:grid;grid-template-columns:minmax(90px,200px) 1fr auto;gap:.6rem;align-items:center;font-size:.82rem}
.chart-hbar-label{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--text)}
.chart-hbar-track{background:var(--bg-alt);border:1px solid var(--border);border-radius:2px;height:.85rem;overflow:hidden}
.chart-hbar-fill{height:100%;background:var(--accent);border-radius:2px 0 0 2px;min-width:2px}
.chart-hbar-val{font-weight:700;font-variant-numeric:tabular-nums;color:var(--text)}
/* Settings sub-navigation (2026-07-07, parity with demo/admin/06-settings.html
   - user "stranka nastavenia potrebuju menu tak ako je v demo"): sticky left
   menu of anchor links to each settings section. */
.set-grid{display:grid;grid-template-columns:240px 1fr;gap:1.5rem}
/* Grid tracks default to a min-width:auto floor = the item's min-content, which
   below 992px (single column) let a wide child push the whole track - and with
   it the sticky .set-nav - past the viewport (user 2026-07-11 "stranka
   nastavenia ma scrolbar do stran"). min-width:0 lets the 1fr track shrink to
   the container so inner content wraps instead of overflowing. */
.set-grid>*{min-width:0}
.set-nav{background:#fff;border:1px solid var(--border);border-radius:2px;overflow:hidden;align-self:start;position:sticky;top:70px}
.set-nav a{display:flex;align-items:center;gap:.65rem;padding:.7rem 1rem;font-size:.88rem;color:var(--text);text-decoration:none;border-bottom:1px solid var(--border);border-left:3px solid transparent;transition:.12s}
.set-nav a:last-child{border-bottom:0}
.set-nav a:hover{background:var(--bg-alt);text-decoration:none}
.set-nav a.active{background:var(--bg-alt);border-left-color:var(--primary);color:var(--primary);font-weight:700}
.set-nav a i{color:var(--text-muted);width:18px;text-align:center;font-size:.92rem}
.set-nav a.active i{color:var(--primary)}
@media (max-width:991.98px){.set-grid{grid-template-columns:1fr}.set-nav{position:static}}
.cbx-item-hint{flex-shrink:0;font-size:.72rem;color:var(--text-muted)}
.cbx-empty{padding:.5rem .55rem;font-size:.8rem;color:var(--text-muted);text-align:center}
.search-inner .btn{height:44px;padding:0 1.4rem}

/* W11 id-fetch */
/* ---- Fetch-by-identifier button + inline feedback (spec .build/specs/
   p9-w11-connectors-idfetch.md sec 0/1, checklist
   .build/parity/connectors-idfetch.md) - markup rendered by
   templates/admin/_form.php's 'idfetch' field key or hand-placed next to a
   read-only identifier row; behavior in app/public/assets/idfetch.js.
   The wrap keeps the input + button on one row; the message (injected by
   the JS after the button) wraps onto its own full-width line. */
.idfetch-wrap{display:flex;gap:.4rem;align-items:stretch;flex-wrap:wrap}
.idfetch-wrap input{flex:1;min-width:0}
.idfetch-msg{flex-basis:100%;font-size:.78rem;line-height:1.45;margin-top:.15rem}
.idfetch-msg.ok{color:#15803d}
.idfetch-msg.err{color:#b45309}

/* Main-loop fix 2026-07-05 (user report: save button glued to the next
   section heading). Primary submit buttons that END a main edit form get
   breathing room before whatever follows; grids separate from following
   content. Card mini-forms use .btn-outline-dark, so they are unaffected.

   2026-07-08 universal fix: apply ONLY to real EDIT forms, NOT to single-button
   POST forms (flattened to display:contents, see the `form:has(> .btn)...` rule
   above) and NOT to horizontal action bars; a bottom margin in a flex row offsets
   the primary button upward under align-items:center -> the misalignment seen
   across every action bar.

   2026-07-09 correction: "has a visible field" is the WRONG signal - a flex
   action bar can carry a field too (the queue row's note input, the
   .lifecycle-switch state <select>), and those matched form:has(input)/has(select)
   and broke exactly like before. The reliable signal for a STACKED edit form is
   the Core\Form field-group grid (.fg) or a mini-form field block (.mf-fields);
   raw input/select/textarea direct children are action bars in this codebase, so
   they no longer trigger the margin. */
form:has(.fg) > .btn.btn-dark:last-child,
form:has(.mf-fields) > .btn.btn-dark:last-child{margin-bottom:1.75rem}
.tab-panel > .cols{margin-bottom:.75rem}

/* P11: discovery nav overflow ("Viac" dropdown - assets/nav-overflow.js) */
.nav-more{position:relative;display:inline-flex}
.nav-more-btn{background:none;border:0;cursor:pointer;font-family:inherit;white-space:nowrap}
.nav-more-menu{position:absolute;top:calc(100% + .35rem);right:0;min-width:200px;background:#fff;border:1px solid var(--border);border-radius:2px;box-shadow:0 8px 24px rgba(15,23,42,.1);padding:.35rem 0 calc(.6rem + env(safe-area-inset-bottom, 0px));z-index:1000;display:flex;flex-direction:column}
.nav-more-menu .nav-link{padding:.5rem 1rem;display:block;width:100%;text-align:left}
/* P11: list/grid view toggle (discovery researchers) */
.view-toggle{display:inline-flex;border:1px solid var(--border);border-radius:2px;overflow:hidden;vertical-align:middle}
.view-toggle a{display:inline-flex;align-items:center;justify-content:center;width:34px;height:30px;color:var(--text-muted);background:#fff;font-size:.85rem}
.view-toggle a.active{background:var(--primary);color:#fff}
.view-toggle a:hover{text-decoration:none}
/* P11: researchers grid view (Pure-style 3/2/1 column cards) */
.res-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:1rem}
@media (max-width:991px){.res-grid{grid-template-columns:repeat(2,1fr)}}
@media (max-width:575px){.res-grid{grid-template-columns:1fr}}

/* P11.x sticky footer: on sparse pages the footer must still sit at the
   bottom of the viewport (user report 2026-07-05). Scoped via :has() to the
   discovery chrome only (admin/user shells have their own .app grid). */
body:has(> footer.foot){display:flex;flex-direction:column;min-height:100vh}
body:has(> footer.foot) footer.foot{margin-top:auto}
/* P11.x mobile nav: burger toggles the collapsed links as a full-width panel */
.nav-acc.mobile-open{flex-wrap:wrap}
.nav-acc.mobile-open .nav-actions{flex-basis:100%;flex-direction:column;align-items:stretch}
.nav-acc.mobile-open .nav-actions .nav-link{display:flex;padding:.65rem .25rem;border-top:1px solid var(--border)}
/* Utilities revealed as full-width labeled rows inside the open burger menu. */
.nav-acc.mobile-open .nav-actions>.a11y-menu,
.nav-acc.mobile-open .nav-actions>.langsw{display:block;border-top:1px solid var(--border)}
.nav-acc.mobile-open .nav-actions>.a11y-menu>summary,
.nav-acc.mobile-open .nav-actions>.langsw>summary{display:flex;align-items:center;gap:.55rem;width:100%;padding:.65rem .25rem;justify-content:flex-start;border:0;background:transparent;min-width:0}
.nav-acc.mobile-open .nav-actions>a.btn{display:inline-flex;margin:.7rem .25rem 0}
.nav-util-label{display:none}
.nav-acc.mobile-open .nav-util-label{display:inline}
/* The vertical divider is a desktop-only separator between the nav links and
   the lang/login actions; in the stacked mobile menu it renders as a stray
   line after the last item (user 2026-07-08) - drop it there. */
.nav-acc.mobile-open .nav-divider{display:none}

/* P11.x: rec-tabs - overflow-x:auto forces overflow-y to 'auto' too, and the
   -1px button margin then yields a phantom vertical scrollbar (user report). */
.rec-tabs{overflow-y:hidden}
/* P11.x: queue row note input had no sizing - keep the actions row compact */
.q-note{width:120px;flex:0 0 auto;border:1px solid var(--border);border-radius:2px;padding:.35rem .5rem;font-size:.78rem;font-family:inherit}

/* P11.x global (user 2026-07-05: "kazdy input alebo skupina inputov musi
   byt v sekcii podfarbenej na bielo"): .block sections render as white
   cards app-wide - grouping is visible, forms stop floating on the page
   background. */
.block{background:#fff;border:1px solid var(--border);border-radius:2px;padding:1.15rem 1.35rem}

/* --- W18 SDG suggested chip (spec .build/specs/p9-w18-sdg-per-record.md
   sec 4, module m11-sdg): OpenAlex suggestion awaiting referent review on
   the record SDG card - visually distinct from a confirmed .chip (dashed
   border, white bg). App-only for now, same documented demo-sync gap as
   .sdg-pill above (no demo edit in W18 - Princip 21 follow-up). --- */
.chip.sdg-sug{background:#fff;border-style:dashed}
.chip.sdg-sug .sdg-ok:hover{opacity:.7}

/* --- P9 W20 central registries (knowledge/25 §3): globe marker on rows
   managed by the central Stellacris registry (source='central'). Rendered
   by Core\View::sourceGlobe() in lists/details; muted + slightly smaller
   than the surrounding text so it reads as provenance, not decoration. --- */
.globe-src{color:var(--text-muted);font-size:.82em;margin-left:.15rem}

/* Effective-permissions list (admin user detail) - ported from the mockup's
   page-inline styles (demo/admin/user-detail.html), which were never copied
   into the app CSS: the grid rendered with no row layout and origin badges
   wrapped at random heights (user report 2026-07-05). */
.eff-list{display:flex;flex-direction:column;gap:.6rem}
.eff-row{display:flex;align-items:center;flex-wrap:wrap;gap:.4rem .6rem;font-size:.84rem;color:var(--text)}
.eff-row>i{color:#15803d;font-size:.78rem;flex-shrink:0}
.eff-row .perm-src{margin-left:auto}

/* wfbar tidy-up (user 2026-07-05 "toto je rozhadzane"): buttons share the
   pills' exact height/typography so the strip reads as ONE aligned row;
   the action form centers its children and never stretches them. */
.wfbar form{display:flex;align-items:center;gap:.5rem;flex-wrap:wrap}
.wfbar .btn{display:inline-flex;align-items:center;gap:.4rem;padding:.35rem .7rem;font-size:.78rem;line-height:1.2}

/* Grant card (mockup demo/discovery/08-grants.html, promoted to shared 2026-07-06) */
.g-card{background:#fff;border:1px solid var(--border);border-radius:2px;padding:1.5rem;margin-bottom:.75rem;display:grid;grid-template-columns:130px 1fr auto;gap:1.5rem;align-items:start;transition:border-color .15s, box-shadow .15s}
.g-card:hover{border-color:#94a3b8;box-shadow:0 4px 12px rgba(15,23,42,.04)}
.g-card.urgent{border-left:3px solid var(--danger)}
.g-card.soon{border-left:3px solid var(--warning)}
.g-card.closed{border-left:3px solid #94a3b8}
.g-deadline{text-align:center;padding:.85rem .5rem;background:var(--bg-alt);border:1px solid var(--border);border-radius:2px;display:flex;flex-direction:column;gap:.25rem}
.g-deadline .day{font-family:Monaco,monospace;font-size:1.45rem;font-weight:700;color:var(--primary);line-height:1;letter-spacing:-.02em}
.g-deadline .month{font-size:.75rem;font-weight:700;color:var(--text-muted);text-transform:uppercase;letter-spacing:.08em}
.g-deadline .year{font-family:Monaco,monospace;font-size:.78rem;color:var(--text-muted)}
.g-deadline .countdown{font-size:.7rem;font-weight:700;text-transform:uppercase;letter-spacing:.05em;margin-top:.2rem;padding-top:.4rem;border-top:1px solid var(--border)}
.g-deadline .countdown.urgent{color:#b91c1c}
.g-deadline .countdown.soon{color:var(--warning)}
.g-deadline .countdown.ok{color:#15803d}
.g-body{min-width:0}
.g-head{display:flex;flex-wrap:wrap;gap:.4rem;margin-bottom:.55rem;align-items:center}
.g-title{font-size:1.08rem;font-weight:700;color:var(--primary);line-height:1.4;margin:0 0 .25rem}
.g-title a{color:inherit;text-decoration:none}
.g-card:hover .g-title a{color:var(--accent)}
.g-sub{font-family:Monaco,monospace;font-size:.82rem;color:var(--text-muted);margin:0 0 .85rem}
.g-desc{font-size:.92rem;color:var(--text);margin:0 0 .85rem;line-height:1.6}
.g-meta{display:flex;flex-wrap:wrap;gap:.55rem 1rem;font-size:.82rem;color:var(--text-muted)}
.g-meta .item{display:inline-flex;align-items:center;gap:.4rem}
.g-meta strong{color:var(--primary);font-weight:600}
.g-actions{display:flex;flex-direction:column;gap:.4rem;justify-content:flex-start;min-width:160px}
.g-actions .btn{padding:.45rem .75rem;font-size:.82rem;white-space:nowrap}
@media (max-width:767.98px){
  .g-card{grid-template-columns:90px 1fr;gap:1rem}
  .g-deadline{padding:.5rem}
  .g-deadline .day{font-size:1.15rem}
  .g-actions{grid-column:1/-1;flex-direction:row;flex-wrap:wrap;min-width:0}
  .g-actions .btn{flex:1}
}

/* Result card (mockup demo/discovery/02-results.html, promoted 2026-07-06) */
.result-item{display:block;background:#fff;border:1px solid var(--border);border-radius:2px;padding:1.5rem;margin-bottom:.75rem;transition:border-color .15s, box-shadow .15s;text-decoration:none;color:inherit}
.result-item:hover{border-color:#94a3b8;box-shadow:0 4px 12px rgba(15,23,42,.04);text-decoration:none;color:inherit}
.result-head{display:flex;gap:.4rem;flex-wrap:wrap;margin-bottom:.65rem;align-items:center}
.result-head .code{font-family:Monaco,monospace;font-size:.78rem;color:var(--text-muted);margin-left:.25rem}
.result-title{font-size:1.15rem;font-weight:700;color:var(--primary);line-height:1.4;letter-spacing:-.015em;margin:0 0 .35rem}
.result-item:hover .result-title{color:var(--accent)}
.result-meta{display:flex;flex-wrap:wrap;gap:.35rem .85rem;font-size:.85rem;color:var(--text-muted);margin-bottom:.65rem}
.result-meta strong{color:var(--text);font-weight:600}
.result-snippet{font-size:.92rem;color:var(--text);line-height:1.65;margin:0;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
.result-footer{display:flex;align-items:center;gap:1rem;margin-top:.85rem;padding-top:.85rem;border-top:1px solid var(--border);font-size:.82rem;color:var(--text-muted);flex-wrap:wrap}
.result-footer .stat{display:inline-flex;align-items:center;gap:.4rem}
.result-footer .stat strong{color:var(--primary);font-weight:700}
/* Researcher row card (mockup demo/discovery/06-researchers.html, promoted 2026-07-06) */
.r-card{display:grid;grid-template-columns:80px 1fr auto;gap:1.25rem;background:#fff;border:1px solid var(--border);border-radius:2px;padding:1.25rem 1.5rem;margin-bottom:.75rem;text-decoration:none;color:inherit;transition:border-color .15s, box-shadow .15s}
.r-card:hover{border-color:#94a3b8;box-shadow:0 4px 12px rgba(15,23,42,.04);background:var(--tint);text-decoration:none;color:inherit}
.r-photo{width:80px;height:80px;background:var(--bg-alt);border:1px solid var(--border);border-radius:2px;display:flex;align-items:center;justify-content:center;font-size:1.4rem;font-weight:700;color:var(--text-muted);letter-spacing:-.02em;flex-shrink:0;overflow:hidden}
.r-photo img{width:100%;height:100%;object-fit:cover}
.r-body{min-width:0}
.r-name{font-size:1.05rem;font-weight:700;color:var(--primary);line-height:1.35;margin:0 0 .15rem}
.r-name a{color:inherit;text-decoration:none}
.r-card:hover .r-name a{color:var(--accent)}
.r-title-line{font-size:.8rem;color:var(--text-muted);margin:0 0 .35rem;line-height:1.4}
.r-aff{font-size:.85rem;color:var(--text-muted);margin:0 0 .65rem;line-height:1.5}
.r-aff strong{color:var(--text);font-weight:600}
.r-keywords{display:flex;flex-wrap:wrap;gap:.3rem;margin-bottom:.65rem}
.r-kw{display:inline-flex;padding:.2rem .55rem;background:var(--bg-alt);border:1px solid var(--border);border-radius:2px;font-size:.74rem;color:var(--text)}
.r-stats{display:flex;gap:1.5rem;font-size:.82rem;color:var(--text-muted);align-items:center;flex-wrap:wrap}
.r-stats .stat strong{color:var(--primary);font-weight:700;font-family:Monaco,monospace;font-size:.95rem;display:block;line-height:1.1}
.r-actions{display:flex;flex-direction:column;gap:.4rem;justify-content:center;align-items:stretch;min-width:130px}
.r-actions .btn{padding:.45rem .75rem;font-size:.8rem;white-space:nowrap}
@media (max-width:767.98px){
  .r-card{grid-template-columns:60px 1fr}
  .r-photo{width:60px;height:60px;font-size:1.1rem}
  .r-actions{grid-column:1/-1;flex-direction:row;min-width:0}
  .r-actions .btn{flex:1}
}
/* hero (dark) kpi-trend readability (2026-07-06) */
.kpi-tile .kpi-trend{color:#4ade80}.kpi-tile .kpi-trend.neu{color:rgba(255,255,255,.55)}

/* Researcher profile head (mockup demo/discovery/04-researcher.html, promoted 2026-07-06) */
.profile-grid{display:grid;grid-template-columns:160px 1fr auto;gap:2rem;align-items:start}
.profile-photo{width:160px;height:160px;background:#fff;border:1px solid var(--border);border-radius:2px;overflow:hidden;display:flex;align-items:center;justify-content:center;font-size:3rem;font-weight:700;color:var(--text-muted);letter-spacing:-.02em}
.profile-photo img{width:100%;height:100%;object-fit:cover}
.profile-body{min-width:0}
.profile-name{font-size:clamp(1.5rem, 3vw, 2.1rem);font-weight:700;color:var(--primary);letter-spacing:-.025em;line-height:1.2;margin:0 0 .55rem}
.profile-aff{font-size:1rem;color:var(--text);margin:0 0 1.25rem;line-height:1.6}
.profile-aff strong{font-weight:600}
.profile-tags{display:flex;flex-wrap:wrap;gap:.35rem}
.profile-tag{display:inline-flex;padding:.25rem .6rem;background:#fff;border:1px solid var(--border);border-radius:2px;font-size:.78rem;color:var(--text)}
.profile-actions{display:flex;flex-direction:column;gap:.5rem;min-width:200px}
.profile-actions .btn{justify-content:flex-start}
.profile-id{font-family:Monaco,monospace;font-size:.78rem;color:var(--text-muted);margin-top:.85rem;padding-top:.85rem;border-top:1px solid var(--border);display:flex;align-items:center;gap:.4rem;word-break:break-all}
.stats-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(140px,1fr));gap:1rem}
.stat-cell{padding:.5rem 1rem;border-left:1px solid var(--border)}
.stat-cell:first-child{border-left:0}
.stat-val{font-size:1.65rem;font-weight:700;color:var(--primary);font-family:Monaco,monospace;line-height:1.1;letter-spacing:-.02em}
.stat-lbl{font-size:.72rem;color:var(--text-muted);text-transform:uppercase;letter-spacing:.06em;font-weight:600;margin-top:.3rem}
@media (max-width:767.98px){
  .profile-grid{grid-template-columns:120px 1fr;gap:1.5rem}
  .profile-photo{width:120px;height:120px;font-size:2.2rem}
  .profile-actions{grid-column:1/-1;flex-direction:row;flex-wrap:wrap;margin-top:1rem}
  .stat-cell{border-left:0;border-top:1px solid var(--border);padding-top:1rem}
  .stat-cell:first-child{border-top:0;padding-top:.5rem}
}

/* ===== P9 W21: shared admin mini-form component (templates/admin/_mini-form.php,
   spec .build/specs/p9-w21-ui-skeleton.md, knowledge/15 sec 23) - the ONLY
   sanctioned styling for mini-add forms. Sizing intentionally matches the
   historical hand-rolled inputs (.4rem .6rem padding, .82rem font, 1px border,
   2px radius) so migrated forms are pixel-equivalent. Layouts: stack (aside
   cards - fields full width, half fields pair up) and mf-row (full-width
   blocks - one wrapping row, labels above inputs, submit aligned to the
   input baseline). mf-sep = divider when the form is appended under a list
   inside the same card. .af-msg is the inline slot asyncform.js writes into
   (pre-rendered empty so it never jumps layout; :empty hides it). ===== */
.mini-form{display:flex;flex-direction:column;gap:.55rem;margin:0;min-width:0;width:100%}
.mini-form.mf-sep{margin-top:.75rem;border-top:1px solid var(--border);padding-top:.75rem}
.mini-form .mf-title{font-size:.78rem;font-weight:700}
.mini-form .mf-fields{display:flex;flex-wrap:wrap;gap:.5rem .6rem}
.mini-form .mf-f{display:flex;flex-direction:column;gap:.2rem;min-width:0;flex:1 1 100%}
.mini-form .mf-f.mf-half{flex:1 1 calc(50% - .3rem)}
.mini-form.mf-row .mf-fields{gap:.6rem .75rem;align-items:flex-end}
.mini-form.mf-row .mf-f{flex:1 1 180px}
.mini-form.mf-row .mf-f.mf-grow-2{flex-grow:2}
.mini-form.mf-row .mf-f.mf-grow-3{flex-grow:3}
.mini-form.mf-row .mf-f.mf-check{flex:0 1 auto;padding-bottom:.45rem}
.mini-form .mf-f label{font-size:.75rem;font-weight:600;margin:0}
.mini-form .mf-f.mf-check label{display:flex;align-items:center;gap:.4rem;font-size:.78rem;font-weight:600}
.mini-form .mf-f input:not([type=checkbox]):not([type=file]),.mini-form .mf-f select,.mini-form .mf-f textarea{border:1px solid var(--border);border-radius:2px;padding:.4rem .6rem;font-size:.82rem;font-family:inherit;color:var(--text);background:#fff;width:100%}
.mini-form .mf-f input[type=file]{font-size:.8rem}
.mini-form .af-msg{font-size:.8rem;margin:0}
.mini-form .af-msg:empty{display:none}
.mini-form > .mf-submit{align-self:flex-start}
.mini-form.mf-row .mf-fields .mf-submit-cell{flex:0 0 auto;display:flex;flex-direction:column;gap:.2rem}

/* Record section nav (mockup demo/discovery/04-researcher.html, promoted 2026-07-06) */
/* Discovery record-tab bar stays sticky, but the top nav (.nav-acc) is no
   longer sticky (user 2026-07-09) - so this bar pins to the viewport top
   (--tabs-sticky-top = 0px on body.layer-discovery) once the nav has scrolled
   away, with no empty band above it. z-index 90 sits above content. */
.record-tabs{background:#fff;border-bottom:1px solid var(--border);position:sticky;top:var(--tabs-sticky-top);z-index:90}
.record-tabs-inner{display:flex;padding:0 var(--page-inset);overflow-x:auto;scrollbar-width:none}
.record-tabs-inner::-webkit-scrollbar{display:none}
.record-tabs-inner a{padding:.85rem 1.1rem;font-size:.9rem;font-weight:600;color:var(--text-muted);text-decoration:none;border-bottom:2px solid transparent;display:inline-flex;align-items:center;gap:.4rem;white-space:nowrap;transition:.15s}
.record-tabs-inner a:hover{color:var(--primary);text-decoration:none}
.record-tabs-inner a.active{color:var(--primary);border-bottom-color:var(--primary)}
.tab-count{display:inline-flex;align-items:center;justify-content:center;min-width:20px;height:18px;padding:0 .35rem;background:var(--bg-alt);border:1px solid var(--border);border-radius:2px;font-family:Monaco,monospace;font-size:.65rem;font-weight:700;color:var(--text-muted)}

/* Project status roadmap (P9 W23, mockup demo/discovery/03-item.html "Priebeh stavu projektu" - page-inline .tl promoted to shared component; green dot = past state, blue dot = current) */
.roadmap{list-style:none;margin:0;padding:.25rem 0}
.roadmap li{position:relative;padding:0 0 1.1rem 1.5rem;border-left:2px solid var(--border)}
.roadmap li:last-child{border-left-color:transparent;padding-bottom:0}
.roadmap li::before{content:"";position:absolute;left:-6px;top:.2rem;width:10px;height:10px;border-radius:50%;background:var(--border)}
.roadmap li.rm-done::before{background:var(--success)}
.roadmap li.rm-current::before{background:var(--accent);box-shadow:0 0 0 3px rgba(59,130,246,.18)}
.roadmap .rm-date{font-family:Monaco,monospace;font-size:.72rem;color:var(--text-muted)}
.roadmap .rm-state{font-weight:700;color:var(--primary);font-size:.9rem;margin:.1rem 0}
.roadmap .rm-note{font-size:.82rem;color:var(--text-muted)}
.roadmap .rm-delete{position:absolute;top:0;right:0;margin:0}
/* submit buttons breathe below the form grid (2026-07-06) */
.fg ~ .btn,.fg + .btn{margin-top:.85rem}

/* Uniform card heights (user 2026-07-06: "tieto stvorce maju mat jednotnu
   vysku"): stat/KPI cards fill their grid cell / Bootstrap column, so a
   wrapped label in one card no longer leaves its siblings shorter. */
.kpi-card,.stat-block{height:100%;display:flex;flex-direction:column;justify-content:center}

/* P9 W24: OA indicator icon on output rows (View::oaIcon/oaBadge, spec
   .build/specs/p9-w24-oa-indicator.md - open/embargoed/closed; unknown
   renders nothing). Colors match the .b-badge ok/warn text colors. */
.oa-ind{font-size:.85em}
.oa-ind.open{color:#15803d}
.oa-ind.embargoed{color:#b45309}
.oa-ind.closed{color:var(--text-muted)}
.b-badge .oa-ind{color:inherit;font-size:.9em}

/* ============================================================================
   P9 W26: WHITELABEL COLOR TOKENS
   (spec .build/specs/p9-w26-whitelabel-branding.md)
   Default-identical re-declarations of the historical hardcoded accent tints
   using the new --accent-rgb / --accent-light / --link-hover tokens, so the
   per-tenant Core\Branding::headStyle() :root override (emitted in every
   layout head) drives EVERY primary/accent-derived surface. At the default
   token values each rule below computes the exact color it overrides
   (cascade wins by file order, same specificity). Neutral slate shadows
   (rgba(15,23,42,.x)) and the secondary violet hero blob (.hero::after)
   intentionally stay fixed. .color-pick = settings color swatch+hex pair.
   ============================================================================ */
:root{--accent-rgb:37,99,235;--accent-light:#60a5fa;--link-hover:#1d4ed8}
/* alpha .08 not .1 - same 4.48:1-on-white gap as .b-badge.accent above
   (axe: SERIOUS color-contrast, spec u2-wcag-formal-audit.md); .side is a
   plain white sidebar so this is the pure-white case. */
.side-brand .tag{background:rgba(var(--accent-rgb),.08)}
.side-nav a.active{background:rgba(var(--accent-rgb),.08)}
/* alpha .06 not .1/.08 - knowledge/31 sec 8 gap: text=var(--accent) on the .1
   tint measured ~4.48:1 on white (axe: SERIOUS color-contrast, spec
   u2-wcag-formal-audit.md); .08 fixed the white case (~4.65:1) but this
   badge often sits on --bg-alt (record header .idline, no own background)
   where .08 still only reaches 4.44:1 - .06 clears BOTH backdrops
   (~4.56 on bg-alt / ~4.79 on white) without changing the --accent token
   other surfaces rely on. */
.b-badge.accent{background:rgba(var(--accent-rgb),.06)}
.act-row .ico.edit{background:rgba(var(--accent-rgb),.08);border-color:rgba(var(--accent-rgb),.3)}
.hero::before{background:radial-gradient(circle,rgba(var(--accent-rgb),.18) 0%,transparent 70%)}
.hero h1 .accent{color:var(--accent-light)}
.activity-icon.update{background:rgba(var(--accent-rgb),.08);border-color:rgba(var(--accent-rgb),.3)}
.pending{background:rgba(var(--accent-rgb),.05)}
.perm-item.granted{background:rgba(var(--accent-rgb),.04)}
/* alpha .06 not .1/.08 - .08 still measured 4.39:1 on --bg-alt in the live
   sweep (axe: SERIOUS color-contrast, spec u2-wcag-formal-audit.md) - same
   root cause and fix as .b-badge.accent above. */
.perm-src.direct{background:rgba(var(--accent-rgb),.06)}
.vstep.current{background:rgba(var(--accent-rgb),.05)}
.act-pill.edit{background:rgba(var(--accent-rgb),.1);color:var(--link-hover)}
.roadmap li.rm-current::before{box-shadow:0 0 0 3px rgba(var(--accent-rgb),.18)}
.color-pick{display:flex;gap:.5rem;align-items:center}
.color-pick input[type=color]{width:40px;height:40px;border:1px solid var(--border);border-radius:2px;cursor:pointer;background:#fff;padding:.15rem;flex-shrink:0}
.color-pick input[type=text]{flex:1;min-width:0}

/* app-only: discovery record-tabs zarovnane s .page-head containerom (mockup 03-item
   variant: nav nesie page-inset, vnutri centrovany .container-xxl px-0, inner bez
   vlastneho insetu). Bez toho zalozky sedia na lavej hrane viewportu, obsah v strede. */
.record-tabs{padding:0 var(--page-inset)}
.record-tabs>.container-xxl>.record-tabs-inner{padding:0}

/* avatar pencil-edit (user 2026-07-06, knowledge/15 sec 24): pencil overlay on a
   managed photo/logo; semi-transparent, opaque on hover/focus. The pencil anchors
   the EXISTING manage card (media-edit.js collapses it and toggles on click;
   no-JS fallback = visible card + anchor jump). */
.avatar-edit{position:relative;display:inline-block}
.avatar-edit .avatar-edit-btn{position:absolute;right:.3rem;bottom:.3rem;width:28px;height:28px;display:flex;align-items:center;justify-content:center;background:rgba(15,23,42,.6);color:#fff;border-radius:2px;font-size:.72rem;opacity:.45;transition:opacity .15s;text-decoration:none}
.avatar-edit:hover .avatar-edit-btn,.avatar-edit .avatar-edit-btn:hover,.avatar-edit .avatar-edit-btn:focus-visible{opacity:1;color:#fff;text-decoration:none}
.avatar-edit .avatar-remove{position:absolute;right:.3rem;top:.3rem;line-height:0}
.avatar-edit .avatar-remove-btn{width:28px;height:28px;display:flex;align-items:center;justify-content:center;background:rgba(180,35,24,.72);color:#fff;border:0;border-radius:2px;font-size:.72rem;opacity:.45;transition:opacity .15s;cursor:pointer;padding:0}
.avatar-edit:hover .avatar-remove-btn,.avatar-edit .avatar-remove-btn:hover,.avatar-edit .avatar-remove-btn:focus-visible{opacity:1;color:#fff}
.media-msg{font-size:.78rem;margin:.4rem 0 0}
.media-panel-hidden{display:none}
/* Storage usage (Settings > Uloziste) - iPhone-style segmented bar + legend */
.storage-bar{display:flex;height:16px;border-radius:8px;overflow:hidden;background:var(--bg-alt);border:1px solid var(--border);gap:2px}
.storage-seg{min-width:4px;height:100%}
.storage-empty{flex:1}
.storage-legend{display:flex;flex-wrap:wrap;gap:.5rem 1.4rem;margin-top:.85rem}
.storage-leg{display:flex;align-items:center;gap:.4rem;font-size:.82rem}
.storage-leg .storage-dot{width:10px;height:10px;border-radius:2px;flex-shrink:0}
.storage-leg i{color:var(--text-muted);width:1rem;text-align:center}
.storage-leg-sz{color:var(--text-muted);font-variant-numeric:tabular-nums}
.storage-total{display:flex;flex-wrap:wrap;gap:.4rem 1.4rem;margin-top:.9rem;padding-top:.7rem;border-top:1px solid var(--border);font-size:.85rem}

/* P9 W30 (2026-07-06): record-detail header components promoted from the
   demo/discovery/output-detail.html page-local <style> into the shared sheet
   (mockup values verbatim). Root cause of the "buttons not right-aligned"
   user report: .record-toolbar/.right (and .page-badges/.page-title/...)
   were used by production discovery detail templates with NO definition
   anywhere. Also used bare by projects/researchers/organisations details -
   they inherit the mockup styling too (intended). */
.page-badges{display:flex;flex-wrap:wrap;gap:.3rem;margin-bottom:.85rem}
.page-title{font-size:clamp(1.3rem,2.8vw,1.8rem);font-weight:700;color:var(--primary);letter-spacing:-.02em;line-height:1.3;margin:0 0 .5rem}
.out-authors-line{font-size:.95rem;color:var(--text);margin:0 0 .35rem}
.out-authors-line a{color:var(--text);font-weight:600}
.out-authors-line a:hover{color:var(--accent)}
.out-venue-line{font-size:.85rem;color:var(--text-muted);display:flex;flex-wrap:wrap;gap:.35rem .65rem;align-items:center;margin:0 0 1.25rem}
.out-venue-line .sep{color:#cbd5e1}
.out-venue-line a{color:var(--text-muted);text-decoration:none;font-family:Monaco,monospace;font-size:.82rem}
.out-venue-line a:hover{color:var(--accent);text-decoration:underline}
.record-toolbar{display:flex;flex-wrap:wrap;gap:.5rem;align-items:center;padding:1rem 0 0;border-top:1px solid var(--border);margin-top:.25rem}
.record-toolbar .right{margin-left:auto;display:flex;gap:.5rem}
.annot{font-size:1rem;line-height:1.75;color:var(--text);margin:0}
.rel-row{display:flex;align-items:center;justify-content:space-between;gap:1rem;padding:.75rem 0;border-bottom:1px solid var(--border)}
.rel-row:last-child{border-bottom:0}
.rel-row .k{font-size:.82rem;color:var(--text-muted)}
.rel-row .v a{color:var(--primary);font-weight:600;text-decoration:none}
.rel-row .v a:hover{color:var(--accent)}
/* background alpha .06 not .08 (axe: SERIOUS color-contrast, spec
   u2-wcag-formal-audit.md - 4.496:1 on --bg-alt, just under 4.5:1). */
.oa-path{display:flex;align-items:center;gap:.5rem;padding:.6rem .85rem;background:rgba(34,197,94,.06);border:1px solid rgba(34,197,94,.25);border-radius:2px;color:#15803d;font-size:.85rem;font-weight:600;margin-bottom:.9rem}
.oa-path i{font-size:.95rem}
.oa-path.warn{background:rgba(245,158,11,.08);border-color:rgba(245,158,11,.25);color:#b45309}
.permalink-box{display:flex;align-items:center;gap:.5rem;padding:.6rem .75rem;background:var(--bg-alt);border:1px solid var(--border);border-radius:2px;font-family:Monaco,monospace;font-size:.78rem;color:var(--text-muted);word-break:break-all}
.permalink-url{flex:1 1 auto;min-width:0;word-break:break-all}
.permalink-copy{flex:0 0 auto;background:none;border:0;padding:.2rem .4rem;margin:-.2rem -.25rem;color:var(--text-muted);cursor:pointer;border-radius:2px;line-height:1;font-size:.85rem}
.permalink-copy:hover{background:var(--border);color:var(--primary)}
.permalink-copy:focus-visible{outline:2px solid var(--accent);outline-offset:1px}
.permalink-copy.copied{color:var(--accent)}
/* W30: generated-citation copy block (Citovat payoff, karta Citacie) */
.cite-box{padding:.6rem .75rem;background:var(--bg-alt);border:1px solid var(--border);border-radius:2px;font-size:.82rem;color:var(--text);line-height:1.6;margin-bottom:.75rem}

/* ============================================================================
   App-only class registrations (2026-07-07 audit follow-up). Used in
   app/templates but previously carried ONLY by inline style="" attributes or as
   behavioural JS hooks, so the class name had no rule in the shared stylesheet
   (knowledge/12 governance). Registered here as the canonical definition; where
   an element also has an inline style="" the inline still wins, so these add no
   visual change - they remove the orphan and give a future dev a real class to
   lean on if the inline attribute is dropped.
   ============================================================================ */
.auth-panel{display:block}
.eff-cell{text-align:right}
.eff-row-total,.eff-col-total,.eff-grand-total{font-variant-numeric:tabular-nums}
.eff-grand-total{border-left:1px solid var(--border)}
.lt-csv{white-space:nowrap}
.sel-bar{display:block;height:6px;width:100%;max-width:120px;background:var(--bg-alt);border:1px solid var(--border);border-radius:2px;overflow:hidden;margin-top:.3rem}
.legend{display:flex;align-items:center;gap:1.25rem;flex-wrap:wrap;font-size:.78rem;color:var(--text-muted);margin-top:.85rem}
.oa-compliance{margin-top:1.1rem;border-top:1px solid var(--border);padding-top:.9rem}
.stats-strip{background:#fff;border-bottom:1px solid var(--border);padding:1.5rem var(--page-inset)}
.dl{font-size:.75rem;color:var(--text-muted)}

/* ============================================================
   m19-evaluation: Hodnotenie vyskumnych aktivit (mockup 2026-07-12)
   Zero-dep SVG chart komponenty (dataviz specs, FLAT): hranate bary
   <=24px, flat ring gauges (butt caps), 1px solid recesivna mriezka,
   text v text-tokenoch (nikdy vo farbe serie), hover cez SVG <title>.
   ============================================================ */
.viz-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:1.25rem;margin-bottom:1.5rem}
@media(max-width:1100px){.viz-grid{grid-template-columns:1fr}}
.viz-grid>*{min-width:0}
.viz-body{padding:1rem 1.25rem 0}
.viz-svg{display:block;width:100%;height:auto}
.viz-svg .vx-grid{stroke:#eef2f7;stroke-width:1;shape-rendering:crispEdges}
.viz-svg .vx-axis{stroke:var(--border);stroke-width:1;shape-rendering:crispEdges}
.viz-svg text{font-family:inherit}
.viz-svg .vx-tick{fill:var(--text-muted);font-size:10px}
.viz-svg .vx-lab{fill:var(--text);font-size:10px;font-weight:600}
.viz-legend{display:flex;flex-wrap:wrap;gap:.35rem 1rem;padding:.65rem 1.25rem .9rem;font-size:.78rem;color:var(--text-muted)}
.viz-key{display:inline-flex;align-items:center;gap:.4rem}
.viz-key .sw{width:10px;height:10px;border-radius:2px;flex-shrink:0}
.viz-filters{display:flex;align-items:center;gap:.6rem;flex-wrap:wrap;margin-bottom:1.25rem}
.viz-filters .f-item{display:flex;align-items:center;gap:.4rem;font-size:.8rem;color:var(--text-muted);min-width:0}
/* A <select> sizes itself to its WIDEST option, and the unit filter is populated
   from organisation_unit names, which are unbounded. width:auto alone let it
   grow past a phone viewport (measured 745px against 375px, 2026-07-31).
   All three declarations are load-bearing, in this order of discovery:
     max-width:100%  clamps it to .f-item                    (745 -> 401px)
     min-width:0     on .f-item, so the row itself can shrink
     min-width:0     on the select, because it is ALSO a flex item and its own
                     default min-width:auto floored it at its min-content width,
                     which is what kept the last 26px of overflow (401 -> 360px). */
.viz-filters select{width:auto;max-width:100%;min-width:0}
.spark-svg{display:block;width:100%;max-width:170px;height:38px}
.spark-svg .ln{fill:none;stroke:var(--accent);stroke-width:2;stroke-linecap:round;stroke-linejoin:round}
.spark-svg .dot{fill:var(--accent);stroke:#fff;stroke-width:2}
/* flat ring gauges (0-100 miery a percentily; track = svetlejsi krok tej istej hue, butt caps = flat) */
.gauge-strip{display:grid;grid-template-columns:repeat(auto-fit,minmax(180px,1fr));gap:.75rem;margin-bottom:1.5rem}
.gauge{display:flex;flex-direction:column;align-items:center;text-align:center;gap:.1rem;min-width:0}
.gauge-strip>.gauge{background:#fff;border:1px solid var(--border);border-radius:2px;padding:1.1rem 1rem}
.gauge-row{display:flex;flex-wrap:wrap;gap:1.25rem;align-items:flex-end;justify-content:space-around}
.gauge-wrap{position:relative;width:96px;height:96px}
.gauge-wrap.lg{width:148px;height:148px}
.gauge-svg{display:block;width:100%;height:100%}
.g-bg{fill:none;stroke:#dbeafe;stroke-width:10}
.g-fg{fill:none;stroke:var(--accent);stroke-width:10}
.gauge-val{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;font-family:Monaco,monospace;font-variant-numeric:tabular-nums;font-weight:700;color:var(--primary);font-size:1.02rem}
.gauge-wrap.lg .gauge-val{font-size:1.65rem}
.gauge-lbl{font-size:.7rem;color:var(--text-muted);text-transform:uppercase;letter-spacing:.06em;font-weight:600;margin-top:.55rem}
.gauge-sub{font-size:.74rem;color:var(--text-muted)}
.gauge-mini{width:18px;height:18px;flex-shrink:0;display:inline-block}
.gauge-mini .g-bg,.gauge-mini .g-fg{stroke-width:16}
.idx-cell{display:inline-flex;align-items:center;gap:.45rem}

/* ---------------------------------------------------------------------------
   Tagify skin (2026-08-17) - keyword fields as pills, assets/tags.js +
   assets/vendor/tagify/. App-only block (no demo counterpart yet): the vendor
   stylesheet ships its own rounded, blue-grey look, this maps it onto our
   tokens so a tag is the same object as a .chip elsewhere (2px radius,
   --bg-alt fill, --border outline, --primary text).
   --------------------------------------------------------------------------- */
.f .tagify{--tags-border-color:var(--border);--tags-hover-border-color:var(--border);--tags-focus-border-color:var(--primary);--tag-bg:var(--bg-alt);--tag-hover:var(--bg-alt);--tag-text-color:var(--primary);--tag-remove-bg:var(--bg-alt);--tag-remove-btn-bg--hover:transparent;--tag-border-radius:2px;--tag-pad:.25rem .55rem;--tag-inset-shadow-size:1.35em;--placeholder-color:var(--text-muted);--placeholder-color-focus:var(--text-muted);--input-color:var(--text);--tag--min-width:0;width:100%;min-width:0;max-width:100%;box-sizing:border-box;border:1px solid var(--border);border-radius:2px;padding:.3rem .4rem;font-size:.85rem;font-family:inherit;background:#fff;line-height:1.5}
.f .tagify:hover{border-color:var(--border)}
.f .tagify--focus{border-color:var(--primary);box-shadow:0 0 0 2px rgba(15,23,42,.08)}
/* The pill box goes on .tagify__tag, NOT on its inner text div: the remove
   button is a sibling of that div, so bordering the div alone left the "x"
   sitting outside the pill. */
.f .tagify__tag{margin:.2rem .3rem .2rem 0;background:var(--bg-alt);border:1px solid var(--border);border-radius:2px;padding:.25rem .5rem}
.f .tagify__tag>div{padding:0;font-size:.78rem;line-height:1.45}
.f .tagify__tag>div::before{box-shadow:none}
.f .tagify__tag:hover:not([readonly]) div::before{box-shadow:none}
.f .tagify__tag__removeBtn{color:var(--text-muted);opacity:1}
.f .tagify__tag__removeBtn:hover{background:transparent;color:#b91c1c}
.f .tagify__input{margin:.2rem 0;padding:.25rem .2rem;font-size:.85rem}
.f .tagify__input:focus-visible{outline:0}

/* CV builder section blocks (templates/user/cv/builder.php). Small helpers so
   the page carries no inline styles - the grid itself is the single .cols on
   the page (knowledge/15 section 22). */
.sec-ctl{display:flex;gap:.3rem;align-items:center}
.sec-counts{margin:0 0 .6rem;font-size:.78rem;color:var(--text-muted);display:flex;gap:.9rem;flex-wrap:wrap}
.sec-sub{font-size:.76rem;color:var(--text-muted)}
.sec-when{font-size:.74rem;white-space:nowrap}
.sec-act{text-align:right;white-space:nowrap}
.sec-remove{margin-top:.6rem}
.sec-remove>summary{cursor:pointer;font-size:.8rem;color:var(--text-muted)}
.sec-remove>form{margin:.5rem 0 0}

/* CV row picker (templates/user/cv/builder.php). Plain <details> + checkboxes;
   "All"/"None" are ordinary submits, so the picker works without JS. */
.sec-pick{margin:.2rem 0 .8rem}
.sec-pick>summary{cursor:pointer;font-size:.82rem;color:var(--accent)}
.pick-list{list-style:none;margin:.5rem 0 .4rem;padding:0;max-height:15rem;overflow-y:auto}
.pick-list li{padding:.15rem 0}
.pick-list label{display:flex;gap:.5rem;align-items:flex-start;font-size:.82rem;font-weight:400;cursor:pointer}
.pick-list input{margin-top:.2rem;flex-shrink:0}
.pick-act{display:flex;gap:.4rem;flex-wrap:wrap;margin-top:.3rem}

/* W52 personal record pinning (spec .build/specs/w52-admin-record-pinning.md).
   The toggle is quiet until it is wanted: hidden on an unpinned row, revealed
   on hover. Hover alone would strand keyboard users (no :hover) and touch
   devices (no hover at all), so focus reveals it too. Once pinned it stops
   being a hover affordance and becomes state - always visible, always red. */
.pin-col{width:1.9rem;text-align:center}
.pin-btn{opacity:0;transition:opacity .15s;color:var(--text-muted);background:none;border:0;cursor:pointer;padding:.15rem;line-height:1;font-size:.82rem}
tr:hover .pin-btn,.pin-btn:focus-visible{opacity:1}
.pin-btn:hover{color:var(--text)}
.pin-btn.pinned{opacity:1;color:var(--danger)}
tr.pinned-row{background:rgba(239,68,68,.035)}
.pin-toggle-btn.pinned{color:var(--danger);border-color:var(--danger)}

/* CV section accordion (templates/user/cv/builder.php). Native <details>; the
   summary stays scannable when collapsed - name, kind, whether it is hidden,
   and how many rows the CV will actually print. */
details.sec-acc>summary{list-style:none;cursor:pointer;display:flex;align-items:center;gap:.5rem;flex-wrap:wrap}
details.sec-acc>summary::-webkit-details-marker{display:none}
details.sec-acc>summary::marker{content:""}
.sec-caret{color:var(--text-muted);font-size:.75rem;width:.7rem;flex-shrink:0;transition:transform .15s}
details.sec-acc[open]>summary .sec-caret{transform:rotate(90deg)}
details.sec-acc>summary:hover{color:var(--primary)}
details.sec-acc>summary:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
.sec-sum-name{font-weight:700;font-size:.95rem;color:var(--primary)}
.sec-sum-counts{font-size:.78rem;font-weight:600;color:var(--text-muted);background:var(--bg-alt);border:1px solid var(--border);border-radius:2px;padding:0 .35rem;line-height:1.5}
details.sec-acc[open]>summary{margin-bottom:.8rem;padding-bottom:.6rem;border-bottom:1px solid var(--border)}

/* "New CV" form on /user/cv: three fields side by side on desktop,
   stacked on narrow screens. Its own class because .cols is the
   content+aside page grid, not a field row. */
.cv-new-form{display:grid;grid-template-columns:2fr 1fr auto;gap:1rem;align-items:end}
@media (max-width:767.98px){.cv-new-form{grid-template-columns:1fr}}

/* Avatar: initials underneath, photo on top. A dead photo URL (they may be
   external) then falls back to the initials instead of painting the
   browser's broken-image glyph. */
.av{position:relative;overflow:hidden}
.av-ini{display:inline-flex;align-items:center;justify-content:center;width:100%;height:100%}
.av-img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;border-radius:2px}

