/* ============================================================
   QINTA — brand base layer (CORE)

   Font faces + reset + focus policy + the shared component classes
   (.btn, .card, .chip, .field, .pkt-tabs, .pkt-otp, .grain).

   This file holds NO design VALUES. Every colour, radius, weight,
   shadow and duration below is a var() read from the active theme's
   token contract, which is emitted by
   META-INF/resources/primefaces-<theme>/theme.css — see
   docs/theming-specification.md.

   Font: Exo 2 — self-hosted from the app font library
   (primefaces-pocketerr:fonts), NOT from Google Fonts. The font FILES
   are an asset and stay here; the font CHOICE is the --font token, so a
   theme can still swap family without touching these @font-face rules.
   ============================================================ */

/* ---------- Exo 2 (local, app font library) ---------- */
@font-face {
  font-family: 'Exo 2'; font-style: normal; font-weight: 300; font-display: swap;
  src: url("/jakarta.faces.resource/fonts/Exo2-Light.woff2.xhtml?ln=primefaces-pocketerr&v=15.0.16") format("woff2"),
       url("/jakarta.faces.resource/fonts/Exo2-Light.woff.xhtml?ln=primefaces-pocketerr&v=15.0.16") format("woff");
}
@font-face {
  font-family: 'Exo 2'; font-style: normal; font-weight: 400; font-display: swap;
  src: url("/jakarta.faces.resource/fonts/Exo2-Regular.woff2.xhtml?ln=primefaces-pocketerr&v=15.0.16") format("woff2"),
       url("/jakarta.faces.resource/fonts/Exo2-Regular.woff.xhtml?ln=primefaces-pocketerr&v=15.0.16") format("woff");
}
@font-face {
  font-family: 'Exo 2'; font-style: italic; font-weight: 400; font-display: swap;
  src: url("/jakarta.faces.resource/fonts/Exo2-Italic.woff2.xhtml?ln=primefaces-pocketerr&v=15.0.16") format("woff2"),
       url("/jakarta.faces.resource/fonts/Exo2-Italic.woff.xhtml?ln=primefaces-pocketerr&v=15.0.16") format("woff");
}
@font-face {
  font-family: 'Exo 2'; font-style: normal; font-weight: 500; font-display: swap;
  src: url("/jakarta.faces.resource/fonts/Exo2-Medium.woff2.xhtml?ln=primefaces-pocketerr&v=15.0.16") format("woff2"),
       url("/jakarta.faces.resource/fonts/Exo2-Medium.woff.xhtml?ln=primefaces-pocketerr&v=15.0.16") format("woff");
}
@font-face {
  font-family: 'Exo 2'; font-style: normal; font-weight: 600; font-display: swap;
  src: url("/jakarta.faces.resource/fonts/Exo2-SemiBold.woff2.xhtml?ln=primefaces-pocketerr&v=15.0.16") format("woff2"),
       url("/jakarta.faces.resource/fonts/Exo2-SemiBold.woff.xhtml?ln=primefaces-pocketerr&v=15.0.16") format("woff");
}
@font-face {
  font-family: 'Exo 2'; font-style: normal; font-weight: 700; font-display: swap;
  src: url("/jakarta.faces.resource/fonts/Exo2-Bold.woff2.xhtml?ln=primefaces-pocketerr&v=15.0.16") format("woff2"),
       url("/jakarta.faces.resource/fonts/Exo2-Bold.woff.xhtml?ln=primefaces-pocketerr&v=15.0.16") format("woff");
}
@font-face {
  font-family: 'Exo 2'; font-style: normal; font-weight: 800; font-display: swap;
  src: url("/jakarta.faces.resource/fonts/Exo2-ExtraBold.woff2.xhtml?ln=primefaces-pocketerr&v=15.0.16") format("woff2"),
       url("/jakarta.faces.resource/fonts/Exo2-ExtraBold.woff.xhtml?ln=primefaces-pocketerr&v=15.0.16") format("woff");
}

/* ============================================================
   TOKENS MOVED TO THE THEME (2026-08-10)

   The :root token block and the html[data-theme="dark"] remap that
   used to sit here now live in the SCSS themes:
     core/theme-src/themes/primefaces-material-3-pocketeer/_tokens.scss
     core/theme-src/themes/primefaces-qinta-award/_tokens.scss

   They HAD to move. PrimeFaces' HeadRenderer emits theme.css FIRST in
   <head> (moveResourceToTop), so this file loads after it — a :root
   block here would out-cascade every theme and no reskin could ever
   take effect. With the tokens in theme.css, swapping
   joinfaces.primefaces.theme reskins the whole application.

   Contract + rules: docs/theming-specification.md
   This file now owns only: @font-face, the reset, the focus policy and
   the shared component classes below — all expressed in var().
   ============================================================ */

/* Smooth in-place theme switch (no flash) */
html, body, .dash, .dash-side, .dash-main, .dash-appbar {
  transition: background-color .25s var(--ease-std), color .25s var(--ease-std), border-color .25s var(--ease-std);
}

/* ============================================================
   Reusable MD3 components — opt-in classes, safe alongside
   PrimeFaces (.ui-*). Use on plain markup where a PF component
   does not fit the design.
   ============================================================ */
/* Global reset — every page (standalone + templated) loads this file,
   so no page ever shows the default 8px body margin.
   text-size-adjust pins the type scale on WebKit: iOS Safari/WKWebView otherwise inflate text in
   blocks it judges too narrow, which silently breaks a layout designed in fixed px on exactly the
   phone widths this app targets. Chrome ignores the property, so Android/desktop stay as-is. */
html, body { margin: 0; padding: 0; }
html { -webkit-text-size-adjust: 100%; text-size-adjust: 100%; }

.pkt-root {
  font: var(--body-m);
  color: var(--on-surface);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
}
.pkt-root *, .pkt-root *::before, .pkt-root *::after { box-sizing: border-box; }
.pkt-root h1, .pkt-root h2, .pkt-root h3, .pkt-root h4, .pkt-root p { margin: 0; }
.pkt-root button { font-family: inherit; cursor: pointer; }
.pkt-root a { color: inherit; text-decoration: none; }

/* --- Focus ring policy (app-wide) ---
   Click/tap NEVER shows the browser's default blue focus outline on interactive
   elements — it reads as a rendering glitch on the MD3 skin. Keyboard navigation
   (:focus-visible) keeps an accessible ring, restyled to the brand gold instead
   of the UA blue. Text fields are excluded: they have their own focus idiom
   (gold border + 3px --p-90 halo). */
a:focus, button:focus, select:focus, summary:focus,
[tabindex]:focus, [role="button"]:focus {
  outline: none;
}
a:focus-visible, button:focus-visible, select:focus-visible, summary:focus-visible,
[tabindex]:focus-visible, [role="button"]:focus-visible {
  /* !important: older per-screen rules killed the outline entirely to dodge the UA blue
     ring on click — the :focus reset above now handles that, so the accessible keyboard
     ring must win over them everywhere. */
  outline:2px solid var(--primary-text) !important;
  outline-offset: 2px;
}

/* --- Touch tap feedback ---
   Kill the Chromium/WebView blue tap-highlight flash on every tap (the app shell
   already does this in modern/styles.css, but login and the public pages load only
   brand.css, so buttons there still flashed blue on touch devices). Button labels
   are also not selectable — a long-press otherwise starts text selection (blue
   highlight) instead of acting as a press. */
* { -webkit-tap-highlight-color: transparent; }
button, .btn, [role="button"], summary { user-select: none; }

/* ============================================================
   MOTION — app-wide interaction feedback (MD3).

   The design handoff contains no motion at all: nine prototype files, zero
   transitions, zero keyframes, zero hover states. So the language here comes
   from MD3 rather than from the prototype.

   MD3 models a press as a STATE LAYER (the content's own colour laid over the
   container at 8% hover / 10% focus / 10% pressed) plus an elevation change,
   and it animates transform+opacity — never layout. Two rules follow from that:
     * every control answers a press within --dur-0 (100ms), because the
       feedback has to beat the eye, not look like an animation;
     * nothing that moves may change the box, or the row below it shifts.

   Scoped to .pkt-root so it can never reach a PrimeFaces overlay's internals.
   ============================================================ */
.pkt-root .btn,
.pkt-root .pkt-tab,
.pkt-root .chip,
.pkt-root .ui-button,
.pkt-root .tx-toolbar .filter-btn,
.pkt-root .tx-toolbar .new-btn,
.pkt-root .tx-line .acts a,
.pkt-root .tx-pager .pages a,
.pkt-root .tx-pager .pages button {
  transition:
    background-color var(--dur-1) var(--ease-std),
    color            var(--dur-1) var(--ease-std),
    border-color     var(--dur-1) var(--ease-std),
    box-shadow       var(--dur-2) var(--ease-emph),
    transform        var(--dur-0) var(--ease-std);
}
/* Press: a 4% settle. MD3 pairs this with the elevation dropping a level, which
   the button rules below already do via --el-btn. */
.pkt-root .btn:active:not(:disabled),
.pkt-root .pkt-tab:active,
.pkt-root .ui-button:not(.ui-state-disabled):active,
.pkt-root .tx-toolbar .filter-btn:active,
.pkt-root .tx-toolbar .new-btn:active,
.pkt-root .tx-pager .pages a:active,
.pkt-root .tx-pager .pages button:active { transform: scale(.96); }
/* Icon-sized targets settle less — at 30px a 4% scale is invisible, and the
   glyph inside is what the eye tracks. */
.pkt-root .tx-line .acts a:active { transform: scale(.88); }

/* Rows and list items: hover is a state-layer tint, press adds the settle. */
.pkt-root .tx-line,
.pkt-root .pkt-dd-menu a,
.pkt-root .side-item {
  transition: background-color var(--dur-1) var(--ease-std),
              color var(--dur-1) var(--ease-std);
}

/* Cards that advertise interactivity lift exactly ONE elevation level on hover
   (MD3: elevated card 1 -> 2). The previous 3px jump plus a level-3 shadow read
   as the card leaving the page. */
.pkt-root .pkt-raise {
  transition: box-shadow var(--dur-2) var(--ease-emph),
              transform var(--dur-2) var(--ease-emph),
              border-color var(--dur-1) var(--ease-std);
}

/* WCAG 2.3.3: swap spatial motion for a plain state change, keep the duration
   so the interface still confirms the action. */
@media (prefers-reduced-motion: reduce) {
  .pkt-root *,
  .pkt-root *::before,
  .pkt-root *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: var(--dur-0) !important;
    scroll-behavior: auto !important;
  }
  .pkt-root .btn:active,
  .pkt-root .ui-button:active,
  .pkt-root .pkt-raise:hover,
  .pkt-root .pkt-fab:hover,
  .pkt-root .pkt-fab:active { transform: none !important; }
}

/* --- Buttons --- */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  font: var(--label-l); letter-spacing: 0.02em;
  padding: 14px 24px; border-radius: var(--r-btn);
  border: 0; cursor: pointer; transition: all var(--dur-2) var(--ease-emph);
  text-decoration: none; white-space: nowrap;
}
/* The neutral high-emphasis button. Its container/ink pair is a token role
   (--filled-bg / --on-filled) rather than --on-surface + white: on dark,
   --on-surface flips to near-white and a white label became invisible. */
.btn-filled  { background: var(--filled-bg); color: var(--on-filled); box-shadow: var(--el-1); }
.btn-filled:hover { background: var(--filled-bg-hover); box-shadow: var(--el-2); }
.btn-tonal   { background: var(--p-90); color: var(--p-20); }
.btn-tonal:hover { background: var(--p-80); }
.btn-outline { background: transparent; color: var(--on-surface); border: 1.5px solid var(--outline); }
.btn-outline:hover { background: var(--p-95); border-color: var(--primary); }
.btn-text    { background: transparent; color: var(--primary-text); padding: 12px 16px; }
.btn-text:hover { background: var(--p-95); }
.btn-lg { padding: 18px 32px; font-size: 16px; }
.btn-sm { padding: 10px 18px; font-size: 13px; }

/* Filled buttons keep white text + NO underline in ANY context, even as links /
   PF commandlinks — beats `.pkt-root a { color: inherit }` and the theme's
   `.ui-commandlink:hover { text-decoration: underline }`. ONE place, reused everywhere. */
a.btn-filled, a.btn-filled:hover, a.btn-filled:focus,
.ui-commandlink.btn-filled { color: var(--on-filled); }
.btn-filled svg { stroke: var(--on-filled); }
a.btn:hover, a.btn:focus,
.ui-commandlink.btn:hover, .ui-commandlink.btn:focus { text-decoration: none; }

/* --- Validation messages: drop the theme's red box background globally,
   keep just bold error text --- */
body .ui-message.ui-message-error { background: transparent; font-weight: bold; }

/* ============================================================
   ICON BUTTON (MD3) — app-wide component.

   MD3 draws an icon button as a 40dp circular container inside a 48dp touch
   target, with a state layer instead of a hover colour, and offers a small set
   of variants. We ship two: the default (no container) and `.outlined`, which
   is the one the public nav's menu button already used and the one the owner
   asked the app's drawer burger to match.

   This lives in brand.css, not core-components.css, because it is used on the
   PUBLIC pages too and those load brand.css only.

   Use: <button class="pkt-icon-btn outlined"><svg …></button>
   ============================================================ */
.pkt-icon-btn {
  display: inline-grid; place-items: center; box-sizing: border-box;
  /* 36px CONTAINER. MD3 sizes the visible container and the touch target
     separately, and the ::before halo below delivers the second:
     36 + 8 + 8 = 52px of tappable area, still over the 48px minimum.
     e2e/tests/drawer-repro.spec.js measures that effective target, not the circle. */
  width: 36px; height: 36px; padding: 0;
  border: 0; background: transparent; border-radius: var(--r-full);
  /* --surface-700 is the owner's pick. Note it comes from the stock PrimeFaces
     grey palette, NOT this project's token contract: it is a fixed #616161 that
     no theme remaps, so it does not follow dark mode — hence the override
     below, which is the only reason this component needs one. */
  color: var(--surface-700); cursor: pointer; position: relative;
  -webkit-tap-highlight-color: transparent;
  transition: background var(--dur-1) var(--ease-std), color var(--dur-1) var(--ease-std);
}
/* On the dark app bar #616161 measures 2.80:1 — under the 3:1 WCAG minimum for
   icons, i.e. the button starts disappearing. Dark mode takes the contract's own
   muted neutral instead (5.53:1), which keeps the "quiet grey" intent. */
html[data-theme="dark"] .pkt-icon-btn { color: var(--on-surface-muted); }
/* the hit halo. Kept at -8px: the drawer guard asserts this exact value. */
.pkt-icon-btn::before { content: ""; position: absolute; inset: -8px; border-radius: inherit; }
.pkt-icon-btn > svg { display: block; stroke: currentColor; }
/* State LAYER, not a colour: a tint of the icon's own ink at the opacity the
   theme publishes, so it reads correctly on any container the button sits on. */
.pkt-icon-btn:hover  { background: color-mix(in srgb, currentColor calc(var(--state-hover) * 100%), transparent); }
.pkt-icon-btn:active { background: color-mix(in srgb, currentColor calc(var(--state-press) * 100%), transparent); }
/* pointers that cannot hover would otherwise keep the tint after a tap */
@media (hover: none) { .pkt-icon-btn:hover { background: transparent; } }
/* The ring is drawn in currentColor, so the outline and the glyph are the SAME
   colour by construction — in every state, including focus and hover, without a
   second rule that could drift away from the first. Hover moves `color`, which
   moves both together. */
.pkt-icon-btn.outlined { box-shadow: inset 0 0 0 1px currentColor; }
.pkt-icon-btn.outlined:hover,
.pkt-icon-btn.outlined:focus-visible { color: var(--primary-text); }

/* --- Tabs (segmented) — app-wide component; mirrors the login
   Prijava | Registracija tabs. Use: a .pkt-tabs container of .pkt-tab
   buttons, active one gets .pkt-tab.on. --- */
.pkt-tabs {
  display: inline-flex; gap: 4px; padding: 4px;
  background: var(--surface-2); border-radius: var(--r-tabs);
}
.pkt-tab {
  border: 0; padding: 12px 18px; border-radius: var(--r-btn-sm);
  font: var(--label-l); cursor: pointer; text-align: center; white-space: nowrap;
  background: transparent; color: var(--on-surface-muted);
  transition: all var(--dur-2) var(--ease-emph);
}
.pkt-tab:hover { color: var(--on-surface); }
/* The ACTIVE tab. The login card has no way to put `.on` on a button — it flips
   `data-tab` on the card and lets CSS pick the winner — so its two selectors
   join this rule rather than restating the look. One declaration, one active
   tab, everywhere. */
.pkt-tab.on,
.lgn-card[data-tab='login'] .pkt-tab.lgn-tab-login,
.lgn-card[data-tab='register'] .pkt-tab.lgn-tab-register { background: var(--surface); color: var(--primary-text); box-shadow: var(--el-1); }
/* Mobile/narrow: the segmented pill is content-width (inline-flex), so many/long tabs (e.g. the
   import-config wizard's 3 tabs) overflow the viewport and end up off-screen with no way to reach
   them. Make the track scroll horizontally instead. Applies to EVERY .pkt-tabs (import-config
   wizard, editMenuItem, …); editMenuItem's own .mmi-tabs override is now redundant but harmless. */
@media (max-width: 760px) {
  .pkt-tabs { display: flex; width: 100%; flex-wrap: nowrap; overflow-x: auto; -webkit-overflow-scrolling: touch; scrollbar-width: none; }
  .pkt-tabs::-webkit-scrollbar { display: none; }
  .pkt-tabs .pkt-tab { flex: 0 0 auto; width: auto; }
  /* compact padding so more tabs fit before the track has to scroll. This lived
     in file-import-configurations-md3.css as a BARE `.pkt-tab` rule — unscoped,
     so one screen's stylesheet was re-padding every set of tabs in the product. */
  .pkt-tabs .pkt-tab { padding: 10px 14px; }
}

/* --- Card --- */
.card {
  background: var(--surface);
  border-radius: var(--r-xl);
  border: 1px solid var(--outline-variant);
  padding: var(--sp-7);
}
.card-elevated { box-shadow: var(--el-2); border-color: transparent; }

/* --- Chip / pill --- */
.chip {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 8px 14px; border-radius: var(--r-full);
  background: var(--p-90); color: var(--p-20);
  font: var(--label-m); letter-spacing: 0.04em; text-transform: uppercase;
}

/* --- Inputs --- */
.field { position: relative; display: block; width: 100%; }
.field input, .field select, .field textarea {
  font: var(--body-l); width: 100%;
  padding: 22px 16px 8px 16px;
  background: var(--surface-1);
  border: 1.5px solid var(--outline);
  border-radius: var(--r-sm);
  color: var(--on-surface);
  transition: border var(--dur-2) var(--ease-std), background var(--dur-2);
  outline: none;
}
.field input:hover { border-color: var(--on-surface-muted); }
.field input:focus, .field select:focus, .field textarea:focus {
  border-color: var(--primary);
  border-width: 2px;
  padding: 21px 15px 7px 15px;
  background: var(--surface);
}
.field label {
  position: absolute; left: 16px; top: 18px;
  font: var(--body-m); color: var(--on-surface-muted);
  pointer-events: none;
  transition: all var(--dur-2) var(--ease-emph);
  background: transparent;
}
.field input:focus + label,
.field input:not(:placeholder-shown) + label,
.field.filled label {
  top: 6px; font-size: 11px; font-weight: 600; color: var(--primary-text);
  letter-spacing: 0.04em; text-transform: uppercase;
}
.field-icon {
  position: absolute; right: 14px; top: 50%; transform: translateY(-50%);
  color: var(--on-surface-subtle); pointer-events: none;
}

/* --- Container --- */
.wrap { max-width: 1200px; margin: 0 auto; padding: 0 var(--sp-6); }

/* --- Money: tabular numerals everywhere amounts are shown --- */
.tnum { font-variant-numeric: tabular-nums; }

/* --- Subtle grain texture (overlay for dark surfaces) --- */
.grain::before {
  content: ''; position: absolute; inset: 0; pointer-events: none;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='200' height='200'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2'/><feColorMatrix values='0 0 0 0 0  0 0 0 0 0  0 0 0 0 0  0 0 0 0.06 0'/></filter><rect width='100%' height='100%' filter='url(%23n)'/></svg>");
  opacity: 0.6; mix-blend-mode: multiply;
}

/* ============ pkt-otp — segmented one-digit-per-box code input ============ */
/* .pkt-root prefix beats the generic .lgn-card .lgn-field input rules on the
   login screen (brand.css loads before login-md3.css there). */
.pkt-otp{display:flex;gap:8px}
.pkt-root .pkt-otp input.pkt-otp-box{
  width:42px;height:50px;padding:0;text-align:center;
  font-family:inherit;font-size:21px;font-weight:600;color:var(--on-surface);
  background:var(--surface);border:1.5px solid var(--outline-variant);border-radius:var(--r-field);
  outline:none;caret-color:var(--primary);box-shadow:none;
  transition:border-color .15s,box-shadow .15s;
}
.pkt-root .pkt-otp input.pkt-otp-box:focus{border-color:var(--primary);box-shadow:0 0 0 var(--focus-ring-w) var(--focus-ring-color)}
@media (max-width:380px){
  .pkt-root .pkt-otp input.pkt-otp-box{width:36px;height:44px;font-size:18px}
}

/* ============================================================
   Brand-mark fallback (templates/common/brandMark.xhtml)
   Rendered ONLY when the application ships no /pages/brand/mark.xhtml:
   a letter tile in the theme's primary colour. Size/font-size are
   inline (the include's `size` param); shape and colours are tokens.
   ============================================================ */
.pkt-mark-fallback {
  display: inline-grid; place-items: center; box-sizing: border-box;
  border-radius: 30%; background: var(--primary); color: var(--on-primary);
  font-family: var(--font); font-weight: 800; line-height: 1; user-select: none;
}
