/* ============================================================
   VLIG Partner Portal - brand overrides and app components.

   Loaded AFTER the Gentelella theme, so it only redefines the theme's
   CSS custom properties instead of fighting its selectors.

   Brand colours (from the logo):
     #0078BA  VLIG blue        - primary actions, links, active state
     #D7D5CA  warm light grey  - soft surfaces
     #474B4E  dark grey        - the brand mid-tone

   LEGIBILITY RULES followed throughout this file:
   1. Text colour is ALWAYS an explicit token - never `opacity` to dim text.
      Opacity compounds with parent opacity and with the surface underneath,
      which is how contrast silently drops below the readable threshold.
   2. Every text/background pair used for real content clears WCAG AA (4.5:1).
      The measured ratios are noted next to each token.
   3. #474B4E is the brand mid-tone, not a surface for small text. Large
      text-bearing surfaces use darker steps of the same hue ramp.
   ============================================================ */

:root {
    /* --- brand --- */
    --vlig-blue:       #0078BA;
    --vlig-blue-dark:  #00639B;
    --vlig-blue-tint:  #E8F2F8;
    --vlig-sand:       #D7D5CA;
    --vlig-sand-light: #F2F1EC;

    /* The third brand colour. Kept as the documented palette value; it is a
       mid-tone, too light to carry small text, so nothing currently uses it as
       a surface. (A darker ramp derived from it was replaced by the navy below.) */
    --vlig-graphite: #474B4E;

    /* The one dark surface in the system: sidebar and toasts, identical in both
       themes. A cool navy rather than a step of the graphite ramp - it leans
       toward the logo's blue and sits darker than any content surface, so
       navigation frames the app instead of reading as another panel. */
    --vlig-navy: #141D29;

    /* --- theme tokens replaced with brand values --- */
    --primary:    var(--vlig-blue);
    --primary-dk: var(--vlig-blue-dark);
    --primary-lt: #0078ba14;
    --blue:       var(--vlig-blue);
    --blue-lt:    #0078ba14;

    /* --- text ramp on light surfaces (ratios vs #fff) --- */
    --text:           #14181D;   /* 17.6:1  body copy, table cells, headings */
    --text-secondary: #45505C;   /*  8.0:1  supporting copy */
    --text-muted:     #5E6B7A;   /*  5.4:1  captions, hints, empty states */
    --text-disabled:  #A6B0BB;   /*  2.3:1  decorative only, never real content */

    --body-bg:              #F4F4F1;
    --bg-surface:           #FFFFFF;
    --bg-surface-secondary: #F8F8F6;
    --border-color:         #DFE2E0;
    --border-color-light:   #EAECEA;

    /* --- sidebar (ratios vs --sidebar-bg) --- */
    --sidebar-bg:          var(--vlig-navy);
    --sidebar-hover:       #ffffff14;
    --sidebar-active:      #0078ba4d;   /* a blue tint needs more weight on a blue-ish ground */
    --sidebar-text:        #C9CDD0;   /* 10.4:1  nav items */
    --sidebar-text-hover:  #FFFFFF;
    --sidebar-text-active: #FFFFFF;
    --sidebar-label:       #969DA1;   /*  6.1:1  group headings */
    --sidebar-dim:         #909799;   /*  5.6:1  "soon" badges */
    --sidebar-border:      #ffffff1f;

    --danger:     #C0392B;   /* 4.9:1 on #fff */
    --danger-lt:  #c0392b14;
    --success:    #1E7E4A;   /* 5.1:1 */
    --warning:    #8F5F00;   /* 5.0:1 as badge text - #B37700 only reached 3.4:1 */

    /* --- brand blue has two jobs; they need different values --- */
    /* FILL: button and bar backgrounds, where the text on top is white. */
    /* TEXT: brand-coloured text and icons ON a surface - must clear 4.5:1 there,
       which #0078BA does on white but NOT on the dark theme's surfaces. */
    --accent-text: #0078BA;   /* 4.8:1 on #fff */

    /* Links are one step deeper than the button blue, so a link never reads as a
       button and a badge never reads as a link. */
    --link:       #00639B;    /* 6.4:1 on #fff */
    --link-hover: #0078BA;
}

/* The dark theme keeps its own surfaces; the ramps move with them. */
@media (prefers-color-scheme: dark) {
    :root:not([data-theme="light"]) {
        --primary-lt: #0078ba2e;
        --blue-lt:    #0078ba2e;

        --text:           #E8EDF2;   /* 14.9:1 vs --bg-surface */
        --text-secondary: #B4BFCA;   /*  8.7:1 */
        --text-muted:     #8D99A6;   /*  5.4:1 */
        --text-disabled:  #5C666F;

        --body-bg:              #14181B;
        --bg-surface:           #1E2326;
        --bg-surface-secondary: #191D20;
        --border-color:         #333A3E;
        --border-color-light:   #272D31;

        /* the navigation surface is the same in both themes - it frames the app */
        --sidebar-bg:     var(--vlig-navy);
        --sidebar-text:   #C9CDD0;
        --sidebar-label:  #969DA1;
        --sidebar-dim:    #8A9194;

        --danger:    #E06B5F;
        --danger-lt: #e06b5f24;
        --success:   #5FB183;
        --warning:   #D2A03A;

        /* #0078BA is only 2.4:1 on the dark surface - brand text goes lighter */
        --accent-text: #6BB8E8;   /* 7.1:1 on #1E2326 */
        --link:        #7CC2EF;   /* 8.0:1 */
        --link-hover:  #A3D6F5;
    }
}

:root[data-theme="dark"] {
    --primary-lt: #0078ba2e;
    --blue-lt:    #0078ba2e;

    --text:           #E8EDF2;
    --text-secondary: #B4BFCA;
    --text-muted:     #8D99A6;
    --text-disabled:  #5C666F;

    --body-bg:              #14181B;
    --bg-surface:           #1E2326;
    --bg-surface-secondary: #191D20;
    --border-color:         #333A3E;
    --border-color-light:   #272D31;

    /* the navigation surface is the same in both themes - it frames the app */
    --sidebar-bg:     var(--vlig-navy);
    --sidebar-text:   #C9CDD0;
    --sidebar-label:  #969DA1;
    --sidebar-dim:    #8A9194;

    --danger:    #E06B5F;
    --danger-lt: #e06b5f24;
    --success:   #5FB183;
    --warning:   #D2A03A;

    --accent-text: #6BB8E8;
    --link:        #7CC2EF;
    --link-hover:  #A3D6F5;
}

/* ============================================================
   LEGIBILITY FIXES on the theme itself
   ============================================================ */

body {
    color: var(--text);
    line-height: 1.5;              /* theme ships 1.4286 - too tight for data rows */
    -webkit-font-smoothing: antialiased;
}

/* Table cells are primary content, not supporting text. */
.table td,
.table tbody td {
    color: var(--text);
}

.table th,
.table thead th {
    color: var(--text-secondary);
    font-weight: 600;
}

.card-title    { color: var(--text); font-weight: 600; }
.card-subtitle { color: var(--text-muted); }

.page-title    { color: var(--text); }
.page-pretitle { color: var(--text-muted); }

.breadcrumb .current { color: var(--text); }
.breadcrumb a        { color: var(--text-muted); }
.breadcrumb a:hover  { color: var(--primary); }

.footer { color: var(--text-muted); }

/* No underline on hover, anywhere.
   The theme sets a global `a:hover { text-decoration: underline }`, which also
   catches links that are really buttons (.btn, .btn-icon) and links inside table
   cells - there it reads as noise rather than as an affordance. */
a:hover,
a:focus,
.breadcrumb a:hover,
.btn:hover,
.btn:focus,
.menu-panel .panel-action:hover {
    text-decoration: none;
}

/* Link colour.
   Excluded throughout: buttons and nav items carry their own colour and hover
   state (recolouring them would wash out white text on a filled button), and
   .link-strong is the primary identifier in a table row - it stays ink-coloured
   so a list of names does not turn into a wall of blue.
   NOTE the :not() chain outweighs a plain class selector, which is exactly why
   .link-strong has to be listed here rather than relying on its own rule.

   The same goes for every COMPONENT that happens to be an <a>: a filter chip,
   an attachment pill, a dashboard step card. Each sets its own colour and gets
   overridden by this rule unless it is excluded here - which is how the active
   inbox chip ended up blue text on a blue background. New anchor components go
   on this list. */
a:not(.btn):not(.nav-link):not(.nav-sublink):not(.tb-btn):not(.brand-name):not(.link-strong):not(.filter-chip):not(.attachment):not(.step) {
    color: var(--link);
}

a:not(.btn):not(.nav-link):not(.nav-sublink):not(.tb-btn):not(.brand-name):not(.link-strong):not(.filter-chip):not(.attachment):not(.step):hover {
    color: var(--link-hover);
}

/* ============================================================
   BADGES

   The theme ships NO base .badge rule - only .nav-link .badge (scoped to the
   sidebar) plus three variants that set colour alone. In a table that renders a
   status as plain coloured text, and .badge-teal used the brand blue, so a
   status was indistinguishable from a link. Both are fixed here:
   a real pill shape, and semantic colours kept separate from the brand accent.

   The tint is derived from the badge's own text colour, so every variant works
   in both themes without a second set of tokens.
   ============================================================ */

.badge {
    display: inline-flex;
    align-items: center;
    gap: .25rem;
    padding: 2px 8px;
    border-radius: 999px;
    font-size: .6875rem;
    font-weight: 600;
    line-height: 1.55;
    letter-spacing: .01em;
    white-space: nowrap;
    vertical-align: middle;
    color: var(--text-secondary);
    background: color-mix(in srgb, currentColor 12%, transparent);
    border: 1px solid color-mix(in srgb, currentColor 24%, transparent);
}

.badge + .badge { margin-left: .25rem; }

/* Semantic, not brand: a status must never be mistaken for a link or a button. */
.badge-teal    { color: var(--success); }      /* active, current */
.badge-red     { color: var(--danger); }       /* ended, inactive, left */
.badge-warning { color: var(--warning); }      /* needs attention */
.badge-blue    { color: var(--accent-text); }  /* neutral / in progress */

a:focus-visible,
button:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible,
[tabindex]:focus-visible {
    outline: 2px solid var(--primary);
    outline-offset: 2px;
    border-radius: 3px;
}

/* ============================================================
   ICONS  (Lucide inline SVG via the icon() helper)
   ============================================================ */

.icon {
    display: inline-block;
    vertical-align: -.15em;
    flex: none;
}

.icon-danger  { color: var(--danger); }
.icon-muted   { color: var(--text-muted); }
.icon-primary { color: var(--accent-text); }
.icon-success { color: var(--success); }

.icon-spin { animation: vlig-spin 1s linear infinite; }

@keyframes vlig-spin { to { transform: rotate(360deg); } }

.spinner {
    display: inline-block;
    width: 14px;
    height: 14px;
    border: 2px solid currentColor;
    border-right-color: transparent;
    border-radius: 50%;
    vertical-align: -.2em;
    animation: vlig-spin .7s linear infinite;
}

.btn .icon { margin-right: .35em; }
.btn .icon:only-child { margin: 0; }

/* Square icon-only buttons for table rows */
.btn-icon {
    width: 30px;
    height: 30px;
    padding: 0;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: var(--radius, 6px);
}

.btn-icon .icon { margin: 0; }

.row-actions {
    display: inline-flex;
    gap: 2px;
    justify-content: flex-end;
    white-space: nowrap;
}

.row-actions .btn-icon { color: var(--text-secondary); }
.row-actions .btn-icon:hover { color: var(--accent-text); background: var(--primary-lt); }
.row-actions .btn-icon.is-danger:hover { color: var(--danger); background: var(--danger-lt); }

/* ============================================================
   LOGO / SIDEBAR / TOPBAR
   ============================================================ */

.sidebar-brand { gap: .625rem; }

.brand-logo {
    display: block;
    width: 58px;
    height: auto;
    background: #fff;
    border-radius: var(--radius, 6px);
    padding: 4px;
    flex: none;
}

.brand-name       { color: #fff; font-weight: 600; }
.brand-name small {
    display: block;
    font-size: .625rem;
    letter-spacing: .1em;
    text-transform: uppercase;
    color: var(--sidebar-label);
    margin-top: 1px;
}

.sidebar-nav .nav-label {
    color: var(--sidebar-label);
    font-weight: 600;
    letter-spacing: .08em;
}

.sidebar-nav .nav-link {
    color: var(--sidebar-text);
    font-weight: 450;
}

.sidebar-nav .nav-link:hover {
    color: var(--sidebar-text-hover);
    background: var(--sidebar-hover);
}

.sidebar-nav .nav-link.active {
    color: var(--sidebar-text-active);
    background: var(--sidebar-active);
    font-weight: 600;
    box-shadow: inset 3px 0 0 0 var(--vlig-blue);
}

.sidebar-nav .nav-link.active .icon { color: #fff; }

.nav-soon,
.nav-soon .nav-text { color: var(--sidebar-dim); cursor: default; }
.nav-soon:hover     { background: transparent; color: var(--sidebar-dim); }

.nav-badge {
    margin-left: auto;
    font-size: .625rem;
    letter-spacing: .04em;
    text-transform: uppercase;
    padding: 1px 6px;
    border-radius: 999px;
    border: 1px solid currentColor;
    color: var(--sidebar-dim);
    white-space: nowrap;
}

.tb-user {
    display: flex;
    flex-direction: column;
    line-height: 1.25;
    margin-right: .25rem;
    text-align: right;
}

.tb-user-name  { font-weight: 600; font-size: .8125rem; color: var(--text); }
.tb-user-roles { font-size: .6875rem; color: var(--text-muted); }
.tb-logout     { display: inline-flex; margin: 0; }

@media (max-width: 640px) { .tb-user { display: none; } }

/* ============================================================
   FLASH MESSAGES / HELPERS
   ============================================================ */

.alert {
    display: flex;
    align-items: flex-start;
    gap: .625rem;
    padding: .75rem 1rem;
    margin-bottom: 1rem;
    border-radius: var(--radius, 6px);
    border: 1px solid var(--border-color);
    border-left-width: 3px;
    font-size: .875rem;
    background: var(--bg-surface);
    color: var(--text);
}

.alert-success { border-left-color: var(--success); }
.alert-error   { border-left-color: var(--danger); }
.alert-info    { border-left-color: var(--vlig-blue); }
.alert-warning { border-left-color: var(--warning); }

.page-header-actions { display: flex; gap: .5rem; align-items: center; flex-wrap: wrap; }
.text-right { text-align: right; }
.text-muted { color: var(--text-muted); }

.num { font-variant-numeric: tabular-nums; text-align: right; white-space: nowrap; }

.empty {
    padding: 2.5rem 1rem;
    text-align: center;
    color: var(--text-muted);
    font-size: .875rem;
}

.code { font-family: var(--font-mono, monospace); font-size: .8125rem; color: inherit; }

.page-title-row { display: flex; align-items: center; gap: .625rem; }
.page-title-row .icon { color: var(--accent-text); }

.card-header .card-title .icon { color: var(--accent-text); margin-right: .35rem; vertical-align: -.2em; }

.count-pill {
    display: inline-block;
    min-width: 1.5rem;
    padding: 0 .45rem;
    border-radius: 999px;
    background: var(--primary-lt);
    color: var(--accent-text);
    font-size: .75rem;
    font-weight: 600;
    line-height: 1.5rem;
    text-align: center;
    margin-left: .4rem;
    font-variant-numeric: tabular-nums;
}

.empty-state {
    display: grid;
    place-items: center;
    gap: .5rem;
    padding: 3rem 1rem;
    text-align: center;
    color: var(--text-muted);
}

.empty-state .icon { color: var(--text-disabled); }
.empty-state strong { color: var(--text-secondary); font-weight: 600; }

/* ============================================================
   DATATABLES  (the theme already styles .dt-*; these are corrections)
   ============================================================ */

.dt-container { color: var(--text); }
.card .dt-container { position: relative; }

table.dataTable { width: 100% !important; }
table.dataTable tbody td { color: var(--text); vertical-align: middle; }
table.dataTable tbody tr:hover td { background: var(--bg-surface-secondary); }
table.dataTable tbody td.num { text-align: right; font-variant-numeric: tabular-nums; }
table.dataTable thead th.text-right .dt-column-header { justify-content: flex-end; }

/* the theme hard-codes its teal into the sort arrows - swap in VLIG blue */
table.dataTable thead th.dt-ordering-asc .dt-column-order {
    background-image: url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 10 14%27%3E%3Cpath fill=%27%230078BA%27 d=%27M5 0l5 6H0z%27/%3E%3Cpath fill=%27%23c4cbd3%27 d=%27M5 14L0 8h10z%27/%3E%3C/svg%3E");
}
table.dataTable thead th.dt-ordering-desc .dt-column-order {
    background-image: url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 10 14%27%3E%3Cpath fill=%27%23c4cbd3%27 d=%27M5 0l5 6H0z%27/%3E%3Cpath fill=%27%230078BA%27 d=%27M5 14L0 8h10z%27/%3E%3C/svg%3E");
}

.dt-processing {
    position: absolute;
    inset: 0;
    display: grid;
    place-items: center;
    background: color-mix(in srgb, var(--bg-surface) 70%, transparent);
    color: var(--text-secondary);
    font-size: .8125rem;
    z-index: 2;
}

/* ============================================================
   MODAL additions (theme provides .modal-backdrop / .modal-dialog)
   ============================================================ */

.modal-backdrop[hidden] { display: none !important; }
.modal-backdrop { display: flex; }

/* --- opening choreography -------------------------------------------------

   Backdrop and dialog run on the same clock but not the same curve:
   the backdrop only fades, the dialog rises and settles.

   The entry curve is an emphasised decelerate - it leaves fast and arrives
   softly, which is what makes a dialog feel PLACED rather than popped. Opacity
   finishes before the movement does (180ms vs 280ms), so the dialog is already
   readable while it is still settling; that reads as quick without being abrupt.

   Closing reverses it: shorter, accelerating, and it drops rather than rises.
   A dialog should leave promptly - waiting for a slow exit is what makes an
   interface feel sluggish.

   Only opacity and transform are animated, so this stays on the compositor.
   -------------------------------------------------------------------------- */

.modal-backdrop {
    transition: opacity 180ms cubic-bezier(.4, 0, .2, 1);
}

.modal-dialog {
    width: 100%;
    max-height: calc(100vh - 48px);
    display: flex;
    flex-direction: column;

    /* resting (closed) state */
    opacity: 0;
    transform: translateY(16px) scale(.97);

    transition:
        opacity   180ms cubic-bezier(.16, 1, .3, 1),
        transform 280ms cubic-bezier(.16, 1, .3, 1);
}

.modal-backdrop.show .modal-dialog {
    opacity: 1;
    transform: none;
}

/* JS adds .is-closing for the duration of the exit */
.modal-backdrop.is-closing {
    transition-duration: 140ms;
}

.modal-backdrop.is-closing .modal-dialog {
    transform: translateY(6px) scale(.985);
    transition:
        opacity   110ms cubic-bezier(.4, 0, 1, 1),
        transform 140ms cubic-bezier(.4, 0, 1, 1);
}

/* The body arrives over AJAX after the dialog is already open, so it fades in
   on its own beat instead of appearing mid-flight. */
.modal-body.is-swapping > * {
    animation: modal-content-in 220ms cubic-bezier(.16, 1, .3, 1) both;
}

@keyframes modal-content-in {
    from { opacity: 0; transform: translateY(6px); }
    to   { opacity: 1; transform: none; }
}

.modal-loading,
.modal-error {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: .5rem;
    padding: 2.5rem 1rem;
    color: var(--text-muted);
    font-size: .875rem;
}

.modal-error { color: var(--danger); }

/* a form loaded into the modal carries its own footer */
.modal-body .modal-footer {
    margin: 1rem -18px -16px;
    padding: 12px 18px;
    border-top: 1px solid var(--border-color-light);
    background: var(--bg-surface-secondary);
    border-radius: 0 0 var(--radius-lg, 8px) var(--radius-lg, 8px);
    display: flex;
    justify-content: flex-end;
    gap: .5rem;
}

.form-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 0 1rem; }
.form-grid .span-2 { grid-column: 1 / -1; }

@media (max-width: 640px) { .form-grid { grid-template-columns: 1fr; } }

.modal-form-row .form-control { width: 100%; }
.modal-form-row label { color: var(--text); font-weight: 600; }

/*
   A checkbox field in the grid, next to labelled inputs.

   It takes the same vertical rhythm as any other field: an empty line where
   the label would be, then the box centred in the height an input has. The two
   numbers are MEASURED from the rendered form, not guessed - a label is
   .8125rem x 1.5 line-height plus its .3125rem gap (24.5px), and a .form-control
   is 34px (2.125rem) tall. With those, the box sits on the input's centre line
   beside it, and two checkboxes in one row sit on each other's.
*/
.field-checkbox .label-spacer {
    display: block;
    height: calc(.8125rem * 1.5 + .3125rem);
}

.field-checkbox .checkbox-red {
    min-height: 2.125rem;
    align-items: center;
}

.field-checkbox .checkbox-red label { font-weight: 400; }

.confirm-row { display: flex; gap: .875rem; align-items: flex-start; }

.confirm-icon {
    flex: none;
    width: 40px;
    height: 40px;
    display: grid;
    place-items: center;
    border-radius: 50%;
    background: var(--danger-lt);
    color: var(--danger);
}

.confirm-row p { margin: .4rem 0 0; color: var(--text); line-height: 1.5; }

/* ============================================================
   TOASTS
   ============================================================ */

.toast-host {
    position: fixed;
    right: 20px;
    bottom: 20px;
    z-index: 1300;
    display: flex;
    flex-direction: column;
    gap: .5rem;
    max-width: min(380px, calc(100vw - 40px));
    pointer-events: none;
}

.toast {
    pointer-events: auto;
    display: flex;
    align-items: flex-start;
    gap: .625rem;
    padding: .75rem .875rem;
    border-radius: var(--radius, 6px);
    /* the same dark surface as the sidebar - one navigation/system colour */
    background: var(--vlig-navy);
    color: #fff;
    box-shadow: 0 10px 30px rgba(0, 0, 0, .3);
    border-left: 3px solid var(--vlig-blue);
    font-size: .875rem;
    line-height: 1.4;
    opacity: 0;
    transform: translateY(8px);
    transition: opacity .2s, transform .2s;
}

.toast.show { opacity: 1; transform: none; }

/* Toasts always sit on the dark surface, so these are fixed values rather than
   the theme's semantic tokens - those are tuned for light and dark CONTENT
   surfaces and would be too dark here. Ratios are against --vlig-navy. */
.toast-success { border-left-color: #2FB344; }
.toast-error   { border-left-color: #E05A4E; }
.toast-warning { border-left-color: #E0A93A; }
.toast-info    { border-left-color: var(--vlig-blue); }

.toast-success .toast-icon { color: #4FD164; }   /* 8.5:1 */
.toast-error   .toast-icon { color: #FF7B6F; }   /* 6.6:1 */
.toast-warning .toast-icon { color: #F0B849; }   /* 9.2:1 */
.toast-info    .toast-icon { color: #58B3E6; }   /* 7.1:1 */

.toast-icon { flex: none; display: inline-flex; margin-top: 1px; }
.toast-text { flex: 1; }

.toast-close {
    flex: none;
    background: none;
    border: 0;
    color: #C9CDD0;
    font-size: 1.1rem;
    line-height: 1;
    cursor: pointer;
    padding: 0 0 0 .25rem;
}

.toast-close:hover { color: #fff; }

/* Movement is the part that causes trouble; a short fade still communicates the
   change without it. Nothing here jumps straight to the end state. */
@media (prefers-reduced-motion: reduce) {
    .toast { transition: opacity 100ms linear; }

    .modal-backdrop,
    .modal-backdrop.is-closing { transition: opacity 100ms linear; }

    .modal-dialog,
    .modal-backdrop.is-closing .modal-dialog {
        transform: none;
        transition: opacity 100ms linear;
    }

    .modal-body.is-swapping > * { animation: none; }

    .icon-spin, .spinner { animation-duration: 2s; }
}

/* ============================================================
   FORMS (class names come from core/CrudController)
   ============================================================ */

.polje { margin-bottom: 1rem; }

.polje > label {
    display: block;
    margin-bottom: .3125rem;
    font-size: .8125rem;
    font-weight: 600;
    color: var(--text);
}

.obavezno { color: var(--danger); }

.pomoc { margin-top: .25rem; font-size: .75rem; color: var(--text-muted); }

.greska-tekst {
    margin-top: .25rem;
    font-size: .75rem;
    color: var(--danger);
    font-weight: 500;
}

.form-control.greska { border-color: var(--danger); }

.checkbox-red { display: flex; align-items: flex-start; gap: .5rem; }
.checkbox-red label { margin: 0; font-size: .875rem; font-weight: 400; color: var(--text); }

.forma-dugmad {
    display: flex;
    gap: .5rem;
    align-items: center;
    padding-top: .75rem;
    border-top: 1px solid var(--border-color);
    margin-top: 1.25rem;
}

/* role picker inside the user modal */
.roles-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(230px, 1fr));
    gap: .5rem;
}

.role-option {
    display: flex;
    gap: .625rem;
    align-items: flex-start;
    padding: .625rem .75rem;
    border: 1px solid var(--border-color);
    border-radius: var(--radius, 6px);
    background: var(--bg-surface);
    cursor: pointer;
    font-weight: 400;
    margin: 0;
}

.role-option:hover { border-color: var(--vlig-blue); background: var(--primary-lt); }
.role-option:has(input:checked) { border-color: var(--vlig-blue); box-shadow: inset 3px 0 0 0 var(--vlig-blue); }

.role-option input { margin-top: .2rem; flex: none; }
.role-option strong { display: block; font-size: .8125rem; color: var(--text); font-weight: 600; }
.role-option small  { display: block; font-size: .75rem; color: var(--text-muted); margin-top: .1rem; line-height: 1.35; }

/* ============================================================
   DETAIL CARD  (customer card; reused by lead / order / machine later)
   ============================================================ */

.card-grid {
    display: grid;
    grid-template-columns: minmax(0, 1.7fr) minmax(0, 1fr);
    gap: 1rem;
    align-items: start;
}

@media (max-width: 1100px) {
    .card-grid { grid-template-columns: 1fr; }
}

.stack { display: flex; flex-direction: column; gap: 1rem; min-width: 0; }

/* label / value pairs */
.kv-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: .875rem 1.25rem;
    margin: 0;
}

.kv-grid.one-col { grid-template-columns: 1fr; }
.kv-grid .span-2 { grid-column: 1 / -1; }

@media (max-width: 640px) {
    .kv-grid { grid-template-columns: 1fr; }
}

.kv dt {
    font-size: .6875rem;
    font-weight: 600;
    letter-spacing: .05em;
    text-transform: uppercase;
    color: var(--text-muted);
    margin-bottom: .2rem;
}

.kv dd { margin: 0; color: var(--text); font-size: .875rem; word-break: break-word; }

.link-strong { font-weight: 600; color: var(--text); }
.link-strong:hover { color: var(--link-hover); }

.plain-list { list-style: none; margin: 0; padding: 0; }

.plain-list li {
    padding: .625rem 0;
    border-bottom: 1px solid var(--border-color-light);
    font-size: .875rem;
}

.plain-list li:last-child { border-bottom: 0; }
.plain-list li:first-child { padding-top: 0; }

.modal-context {
    display: flex;
    align-items: center;
    gap: .4rem;
    margin: 0 0 1rem;
    padding: .5rem .75rem;
    border-radius: var(--radius, 6px);
    background: var(--bg-surface-secondary);
    color: var(--text-secondary);
    font-size: .8125rem;
}

.modal-context .icon { color: var(--accent-text); }

/* ============================================================
   DUPLICATE REVIEW QUEUE
   ============================================================ */

.dup-list { display: flex; flex-direction: column; gap: .875rem; }

.dup-group {
    border: 1px solid var(--border-color);
    border-radius: var(--radius, 6px);
    padding: .875rem 1rem;
    background: var(--bg-surface);
}

.dup-head {
    display: flex;
    align-items: center;
    gap: .5rem;
    flex-wrap: wrap;
    margin-bottom: .75rem;
    font-size: .8125rem;
}

.dup-reason { color: var(--text-secondary); }

.dup-cards {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
    gap: .625rem;
}

.dup-card {
    padding: .625rem .75rem;
    border: 1px solid var(--border-color-light);
    border-radius: var(--radius, 6px);
    background: var(--bg-surface-secondary);
    font-size: .8125rem;
}

.dup-card > div { margin-top: .15rem; }

.dup-actions {
    display: flex;
    align-items: center;
    gap: .5rem;
    flex-wrap: wrap;
    margin-top: .75rem;
    padding-top: .75rem;
    border-top: 1px solid var(--border-color-light);
    font-size: .8125rem;
}

/* ============================================================
   LEAD CARD  (step 03)

   Three parts, in the order the specification asks for them:
   the header answers "where are we", the timeline answers "what happened",
   the sales card answers "whose is it".
   ============================================================ */

.lead-head-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
    gap: .875rem 1.25rem;
}

/* --- the stage rail ------------------------------------------------------
   Reads left to right like the deal does. Done steps carry the brand accent,
   the current step is the only solid fill on the card, and everything ahead
   stays muted - so "where are we" is answerable at a glance, from across
   the desk. White on --vlig-blue is 4.8:1 and identical in both themes;
   the closed states use the badge tint instead, because --success and
   --danger move with the theme and white would not stay legible on them.
   ------------------------------------------------------------------------ */

.stage-rail {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: .5rem 1.1rem;
    margin-top: 1.125rem;
    padding-top: 1rem;
    border-top: 1px solid var(--border-color-light);
}

.stage-step {
    position: relative;
    padding: .3rem .75rem;
    border-radius: 999px;
    border: 1px solid var(--border-color);
    background: var(--bg-surface-secondary);
    color: var(--text-muted);
    font-size: .75rem;
    font-weight: 600;
    white-space: nowrap;
}

/* the connector, drawn outside the pill so it never sits on the label */
.stage-step:not(:last-child)::after {
    content: "";
    position: absolute;
    right: -.72rem;
    top: 50%;
    width: .34rem;
    height: .34rem;
    border-top: 1.5px solid var(--border-color);
    border-right: 1.5px solid var(--border-color);
    transform: translateY(-50%) rotate(45deg);
}

.stage-step.is-done {
    color: var(--accent-text);
    background: var(--primary-lt);
    border-color: color-mix(in srgb, var(--accent-text) 35%, transparent);
}

.stage-step.is-current {
    color: #FFFFFF;
    background: var(--vlig-blue);
    border-color: var(--vlig-blue);
}

.stage-step.is-current.is-won,
.stage-step.is-current.is-lost {
    background: color-mix(in srgb, currentColor 14%, transparent);
    border-color: color-mix(in srgb, currentColor 32%, transparent);
}

.stage-step.is-current.is-won  { color: var(--success); }
.stage-step.is-current.is-lost { color: var(--danger); }

.stage-actions {
    display: flex;
    align-items: center;
    gap: .5rem;
    flex-wrap: wrap;
    margin-top: .875rem;
    padding-top: .875rem;
    border-top: 1px solid var(--border-color-light);
    font-size: .8125rem;
}

/* --- the one timeline ----------------------------------------------------
   Everything about the deal in a single column. The dot is coloured only for
   things a PERSON did with the customer - calls, meetings, WhatsApp, email.
   Stage moves, reassignments and system entries stay muted, so scanning the
   column separates the conversation from the bookkeeping without reading it.
   ------------------------------------------------------------------------ */

.timeline {
    list-style: none;
    margin: 0;
    padding: 0;
    position: relative;
}

/* the rail stops at the first and last dot instead of dangling past them */
.timeline::before {
    content: "";
    position: absolute;
    left: 13px;
    top: 14px;
    bottom: 14px;
    width: 2px;
    background: var(--border-color-light);
}

.tl-item {
    position: relative;
    display: flex;
    gap: .75rem;
    padding-bottom: 1.125rem;
}

.tl-item:last-child { padding-bottom: 0; }

.tl-dot {
    position: relative;
    z-index: 1;
    flex: none;
    width: 28px;
    height: 28px;
    display: grid;
    place-items: center;
    border-radius: 50%;
    background: var(--bg-surface);
    border: 1px solid var(--border-color);
    color: var(--text-muted);
}

.tl-body { flex: 1; min-width: 0; }

.tl-head {
    display: flex;
    align-items: baseline;
    gap: .5rem;
    flex-wrap: wrap;
}

.tl-type {
    font-size: .6875rem;
    font-weight: 600;
    letter-spacing: .05em;
    text-transform: uppercase;
    color: var(--text-muted);
}

.tl-when {
    font-size: .75rem;
    color: var(--text-muted);
    font-variant-numeric: tabular-nums;
}

.tl-title {
    margin-top: .1rem;
    font-size: .875rem;
    font-weight: 600;
    color: var(--text);
}

.tl-text {
    margin-top: .25rem;
    font-size: .8125rem;
    line-height: 1.55;
    color: var(--text-secondary);
    word-break: break-word;
}

.tl-meta {
    margin-top: .3rem;
    font-size: .75rem;
    color: var(--text-muted);
}

.tl-call .tl-dot,
.tl-meeting .tl-dot,
.tl-whatsapp .tl-dot,
.tl-email_in .tl-dot,
.tl-email_out .tl-dot {
    color: var(--accent-text);
    background: var(--bg-surface);
    border-color: color-mix(in srgb, var(--accent-text) 40%, var(--border-color));
}

.tl-call .tl-type,
.tl-meeting .tl-type,
.tl-whatsapp .tl-type,
.tl-email_in .tl-type,
.tl-email_out .tl-type { color: var(--accent-text); }

/* --- attribution ---------------------------------------------------------
   Who brought the lead, kept beside - never merged into - who works it now.
   ------------------------------------------------------------------------ */

.attribution {
    margin-top: 1rem;
    padding-top: .875rem;
    border-top: 1px solid var(--border-color-light);
}

.attribution-head {
    display: flex;
    align-items: center;
    gap: .35rem;
    flex-wrap: wrap;
    margin-bottom: .5rem;
    font-size: .6875rem;
    font-weight: 600;
    letter-spacing: .05em;
    text-transform: uppercase;
    color: var(--text-muted);
}

.attribution-head .icon { color: var(--text-muted); }

/* the aside inside the heading is a sentence, not a label */
.attribution-head .text-muted {
    font-weight: 500;
    letter-spacing: 0;
    text-transform: none;
}

/* --- forms ---------------------------------------------------------------
   "And then?" is a block of its own inside the activity form: writing up a
   call is the moment you know what happens next, and it should not look like
   just two more fields.
   ------------------------------------------------------------------------ */

.next-action-block {
    margin-top: 1rem;
    padding: .875rem 1rem;
    border: 1px solid var(--border-color);
    border-radius: var(--radius, 6px);
    background: var(--bg-surface-secondary);
}

.next-action-head {
    display: flex;
    align-items: center;
    gap: .35rem;
    margin-bottom: .625rem;
    font-size: .6875rem;
    font-weight: 600;
    letter-spacing: .05em;
    text-transform: uppercase;
    color: var(--text-secondary);
}

.next-action-head .icon { color: var(--accent-text); }

/* text written by someone else, quoted back to the person deciding */
.quote-block {
    padding: .625rem .875rem;
    border-left: 3px solid var(--border-color);
    border-radius: 0 var(--radius, 6px) var(--radius, 6px) 0;
    background: var(--bg-surface-secondary);
    color: var(--text-secondary);
    font-size: .875rem;
    line-height: 1.55;
    word-break: break-word;
}

/* ============================================================
   EMAIL  (step 04)
   ============================================================ */

/* --- filter chips ---------------------------------------------------------
   The inbox filters are links, not a dropdown, because "Unassigned: 3" has to
   be readable without opening anything. It is a number the user is meant to
   want at zero.
   ------------------------------------------------------------------------ */

.filter-bar {
    display: flex;
    align-items: center;
    gap: .4rem;
    flex-wrap: wrap;
    padding: .75rem 1rem;
    border-bottom: 1px solid var(--border-color-light);
}

.filter-chip {
    display: inline-flex;
    align-items: center;
    gap: .4rem;
    padding: .3rem .7rem;
    border-radius: 999px;
    border: 1px solid var(--border-color);
    background: var(--bg-surface-secondary);
    color: var(--text-secondary);
    font-size: .75rem;
    font-weight: 600;
    white-space: nowrap;
}

.filter-chip:hover { color: var(--text); border-color: var(--text-disabled); }

/* white on --vlig-blue is 4.8:1 in both themes - the fill never changes with the theme */
.filter-chip.is-on,
.filter-chip.is-on:hover {
    color: #FFFFFF;
    background: var(--vlig-blue);
    border-color: var(--vlig-blue);
}

.chip-count {
    display: inline-block;
    min-width: 1.1rem;
    padding: 0 .3rem;
    border-radius: 999px;
    background: color-mix(in srgb, currentColor 18%, transparent);
    font-variant-numeric: tabular-nums;
    text-align: center;
}

.chip-count.chip-warning { color: var(--warning); }
.chip-count.chip-blue    { color: var(--accent-text); }
.filter-chip.is-on .chip-count { color: #FFFFFF; background: #ffffff2e; }

.filter-sep {
    width: 1px;
    height: 1.1rem;
    margin: 0 .25rem;
    background: var(--border-color);
}

/* an unread conversation is marked, not shouted about */
.unread-dot {
    display: inline-block;
    width: 7px;
    height: 7px;
    margin-right: .45rem;
    border-radius: 50%;
    background: var(--vlig-blue);
    vertical-align: middle;
}

/* --- the conversation ---------------------------------------------------- */

.thread-head {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
    gap: .875rem 1.25rem;
}

.thread-actions,
.thread-foot {
    display: flex;
    align-items: center;
    gap: .5rem;
    flex-wrap: wrap;
    margin-top: .875rem;
    padding-top: .875rem;
    border-top: 1px solid var(--border-color-light);
}

.thread-foot { border-top: 0; padding-top: 0; margin-top: 1rem; }

.thread { display: flex; flex-direction: column; gap: .75rem; margin-top: 1rem; }

/*
   Incoming and outgoing are told apart by a coloured edge, not by chat-style
   alignment. Business email is long; half-width bubbles would make every
   message harder to read to save a distinction one border already makes.
*/
.mail {
    border: 1px solid var(--border-color);
    border-left: 3px solid var(--border-color);
    border-radius: var(--radius, 8px);
    background: var(--bg-surface);
    padding: .875rem 1rem;
    min-width: 0;
}

.mail-in  { border-left-color: var(--vlig-blue); }
.mail-out { border-left-color: var(--text-disabled); background: var(--bg-surface-secondary); }

.mail-head {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: .75rem;
    flex-wrap: wrap;
}

.mail-who { display: flex; align-items: flex-start; gap: .6rem; min-width: 0; }

.mail-avatar {
    flex: none;
    width: 26px;
    height: 26px;
    display: grid;
    place-items: center;
    border-radius: 50%;
    background: var(--primary-lt);
    color: var(--accent-text);
}

.mail-out .mail-avatar { background: var(--bg-surface); color: var(--text-muted); }

.mail-who strong { font-size: .875rem; color: var(--text); }

.mail-when {
    flex: none;
    display: flex;
    align-items: center;
    gap: .4rem;
    font-size: .75rem;
    color: var(--text-muted);
    font-variant-numeric: tabular-nums;
}

.mail-subject {
    margin-top: .6rem;
    font-size: .8125rem;
    font-weight: 600;
    color: var(--text-secondary);
}

/*
   The body is HTML somebody else wrote. It is sanitised before it gets here,
   but it still has to be stopped from deciding our layout: it scrolls inside
   its own box rather than widening the page, and its images and tables are
   capped at the width they were given.
*/
.mail-body {
    margin-top: .625rem;
    max-width: 100%;
    overflow-x: auto;
    font-size: .875rem;
    line-height: 1.6;
    color: var(--text);
    word-break: break-word;
}

.mail-body img   { max-width: 100%; height: auto; }
.mail-body table { max-width: 100%; border-collapse: collapse; }
.mail-body td,
.mail-body th    { padding: .25rem .5rem; }
.mail-body a     { color: var(--link); }
.mail-body blockquote {
    margin: .5rem 0;
    padding-left: .75rem;
    border-left: 2px solid var(--border-color);
    color: var(--text-muted);
}
.mail-body pre {
    overflow-x: auto;
    padding: .5rem .625rem;
    border-radius: var(--radius, 6px);
    background: var(--bg-surface-secondary);
    font-size: .8125rem;
}

/* a blocked remote image leaves a visible gap, never a silent one */
.mail-body img[data-blocked-src] {
    display: inline-block;
    min-width: 90px;
    min-height: 28px;
    padding: .3rem .5rem;
    border: 1px dashed var(--border-color);
    border-radius: 4px;
    background: var(--bg-surface-secondary);
    color: var(--text-muted);
    font-size: .6875rem;
}

.mail-attachments {
    display: flex;
    flex-wrap: wrap;
    gap: .4rem;
    margin-top: .75rem;
    padding-top: .625rem;
    border-top: 1px solid var(--border-color-light);
}

.attachment {
    display: inline-flex;
    align-items: center;
    gap: .35rem;
    padding: .3rem .6rem;
    border: 1px solid var(--border-color);
    border-radius: 999px;
    background: var(--bg-surface-secondary);
    color: var(--text);
    font-size: .75rem;
    max-width: 100%;
}

.attachment:hover { border-color: var(--accent-text); color: var(--accent-text); }
.attachment .icon { color: var(--text-muted); flex: none; }
.attachment span:nth-of-type(1) { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* --- the reply form ------------------------------------------------------
   The reminder is the second half of the interaction, not a footnote, so it
   gets its own panel and a border that says the form is not finished above it.
   ------------------------------------------------------------------------ */

.follow-up-block { border-color: var(--accent-text); }

.follow-up-choices { display: flex; flex-wrap: wrap; gap: .4rem; }

.follow-up-choice {
    display: inline-flex;
    align-items: center;
    gap: .4rem;
    padding: .35rem .7rem;
    border: 1px solid var(--border-color);
    border-radius: 999px;
    background: var(--bg-surface);
    color: var(--text-secondary);
    font-size: .8125rem;
    cursor: pointer;
}

.follow-up-choice input { margin: 0; accent-color: var(--vlig-blue); }

.follow-up-choice:hover { border-color: var(--accent-text); color: var(--text); }

.follow-up-choice:focus-within,
.choice-group label.is-on {
    border-color: var(--vlig-blue);
    background: var(--primary-lt);
    color: var(--accent-text);
    font-weight: 600;
}

.quote-toggle { margin-top: .75rem; }

.quote-toggle summary {
    cursor: pointer;
    font-size: .75rem;
    font-weight: 600;
    letter-spacing: .04em;
    text-transform: uppercase;
    color: var(--text-muted);
    list-style: none;
}

.quote-toggle summary::-webkit-details-marker { display: none; }
.quote-toggle summary:hover { color: var(--text-secondary); }
.quote-toggle .quote-block { margin-top: .5rem; }

.sender-card {
    display: flex;
    align-items: center;
    gap: .6rem;
    margin-bottom: 1rem;
    padding: .625rem .875rem;
    border: 1px solid var(--border-color);
    border-radius: var(--radius, 6px);
    background: var(--bg-surface-secondary);
}

.sender-card .icon { color: var(--accent-text); flex: none; }

.check-row {
    display: flex;
    align-items: flex-start;
    gap: .6rem;
    margin-top: 1rem;
    font-size: .875rem;
    color: var(--text);
    cursor: pointer;
}

.check-row input { margin-top: .25rem; accent-color: var(--vlig-blue); }
.check-row .pomoc { margin-top: .15rem; }

/* --- follow-ups list ----------------------------------------------------- */

.followup-list { list-style: none; margin: 0; padding: 0; }

/*
   The row wraps rather than squeezing. This list appears in a full-width card
   and in the narrow right-hand column of the same page, and a title crushed
   into four words per line is harder to scan than one that took a second line.
*/
.followup {
    display: flex;
    align-items: flex-start;
    gap: .5rem .75rem;
    flex-wrap: wrap;
    padding: .75rem 0;
    border-bottom: 1px solid var(--border-color-light);
}

.followup:last-child  { border-bottom: 0; }
.followup:first-child { padding-top: 0; }

.followup-when { flex: none; min-width: 5.5rem; }
.followup-what { flex: 1 1 14rem; min-width: 0; font-size: .875rem; }

.followup-do {
    flex: none;
    display: flex;
    align-items: center;
    gap: .35rem;
    flex-wrap: wrap;
}

@media (max-width: 720px) {
    .followup { flex-wrap: wrap; }
    .followup-do { width: 100%; }
}

/* ============================================================
   CONFIGURATOR AND CATALOGUE  (step 05)
   ============================================================ */

/* --- choosing options ---------------------------------------------------
   A whole row is the target, not a 13px box. The row a person has chosen is
   tinted; a row the ENGINE chose is tinted and marked, because "I picked this"
   and "this came with it" must not look like the same act.
   ------------------------------------------------------------------------ */

.option-row {
    display: flex;
    align-items: flex-start;
    gap: .75rem;
    padding: .6rem .75rem;
    margin: 0 -.75rem;
    border-radius: var(--radius, 6px);
    cursor: pointer;
    border: 1px solid transparent;
}

.option-row:hover { background: var(--bg-surface-secondary); }

.option-row.is-chosen {
    background: var(--primary-lt);
    border-color: color-mix(in srgb, var(--accent-text) 30%, transparent);
}

.option-row.is-locked { cursor: default; opacity: 1; }
.option-row.is-locked:hover { background: var(--primary-lt); }

.option-row input { margin-top: .2rem; flex: none; accent-color: var(--vlig-blue); }

.option-row.is-auto .option-name::after {
    content: "added by a rule";
    display: inline-block;
    margin-left: .4rem;
    padding: 1px 6px;
    border-radius: 999px;
    background: color-mix(in srgb, var(--accent-text) 14%, transparent);
    color: var(--accent-text);
    font-size: .625rem;
    font-weight: 600;
    letter-spacing: .02em;
    vertical-align: middle;
}

.option-main { flex: 1; min-width: 0; }

.option-name {
    display: block;
    font-size: .875rem;
    color: var(--text);
}

.option-desc {
    display: block;
    margin-top: .15rem;
    font-size: .75rem;
    line-height: 1.45;
    color: var(--text-muted);
}

.option-price {
    flex: none;
    font-size: .8125rem;
    color: var(--text-secondary);
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

.option-row.is-chosen .option-price { color: var(--text); font-weight: 600; }

/* the whole form dims while the engine is answering - it is the engine's
   number that counts, so the old one should not look current */
[data-configurator].is-working .option-price { color: var(--text-disabled); }

/* --- the price panel ----------------------------------------------------- */

.summary-card { position: sticky; top: 1rem; }

@media (max-width: 1100px) {
    .summary-card { position: static; }
}

.price-lines { display: flex; flex-direction: column; gap: .35rem; }

.price-row {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 1rem;
    font-size: .875rem;
    color: var(--text);
    font-variant-numeric: tabular-nums;
}

.price-row-option { font-size: .8125rem; color: var(--text-secondary); }

.price-total {
    margin-top: .35rem;
    padding-top: .5rem;
    border-top: 1px solid var(--border-color);
    font-size: 1rem;
}

.price-discount { color: var(--success); font-size: .8125rem; }

.price-final strong { color: var(--accent-text); font-size: 1.125rem; }

.price-note {
    display: flex;
    align-items: flex-start;
    gap: .35rem;
    margin-top: .625rem;
    padding-top: .5rem;
    border-top: 1px dashed var(--border-color-light);
    font-size: .75rem;
    line-height: 1.45;
    color: var(--warning);
}

.price-note .icon { flex: none; margin-top: .1rem; }

/* --- why it cannot be quoted --------------------------------------------- */

.problem-list { list-style: none; margin: 0; padding: 0; }

.problem {
    display: flex;
    align-items: flex-start;
    gap: .45rem;
    padding: .4rem 0;
    font-size: .8125rem;
    line-height: 1.5;
    color: var(--text);
    border-bottom: 1px solid var(--border-color-light);
}

.problem:last-child { border-bottom: 0; }
.problem .icon { flex: none; margin-top: .15rem; color: var(--warning); }

/* --- the catalogue matrix ------------------------------------------------ */

.catalog-group { margin-bottom: 1.25rem; }
.catalog-group:last-child { margin-bottom: 0; }

.catalog-group-head {
    display: flex;
    align-items: center;
    gap: .5rem;
    margin-bottom: .35rem;
    padding-bottom: .35rem;
    border-bottom: 1px solid var(--border-color-light);
    font-size: .8125rem;
}

.catalog-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: .75rem;
    padding: .3rem 0;
    font-size: .875rem;
}

.catalog-toggle {
    display: flex;
    align-items: center;
    gap: .5rem;
    cursor: pointer;
    min-width: 0;
}

.catalog-toggle input { accent-color: var(--vlig-blue); flex: none; }
.catalog-row:not(.is-on) .catalog-toggle span { color: var(--text-muted); }

.catalog-flags { display: flex; gap: .3rem; flex: none; }

.chip-toggle {
    padding: 2px 8px;
    border-radius: 999px;
    border: 1px solid var(--border-color);
    background: transparent;
    color: var(--text-muted);
    font-size: .625rem;
    font-weight: 600;
    letter-spacing: .02em;
    cursor: pointer;
}

.chip-toggle:hover:not(:disabled) { border-color: var(--accent-text); color: var(--accent-text); }
.chip-toggle:disabled { cursor: default; }

.chip-toggle.is-on {
    border-color: var(--vlig-blue);
    background: var(--primary-lt);
    color: var(--accent-text);
}

.rule-row {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: .75rem;
}

/* --- price list editing --------------------------------------------------
   The cell saves itself when you leave it. A price list has a hundred numbers
   and no natural moment to press Save; the flash is the receipt.
   ------------------------------------------------------------------------ */

.price-input {
    width: 100%;
    max-width: 10rem;
    text-align: right;
    font-variant-numeric: tabular-nums;
    transition: border-color 140ms ease, background-color 140ms ease;
}

.price-input.is-saved {
    border-color: var(--success);
    background: color-mix(in srgb, var(--success) 10%, transparent);
}

.price-input.is-error {
    border-color: var(--danger);
    background: color-mix(in srgb, var(--danger) 10%, transparent);
}

/* ============================================================
   MATRIX / LOGIN / HOME / ERROR PAGES
   ============================================================ */

.matrix { width: 100%; border-collapse: collapse; color: var(--text); }

.matrix th,
.matrix td { padding: .45rem .5rem; border-bottom: 1px solid var(--border-color-light); }

.matrix thead th {
    position: sticky;
    top: 0;
    z-index: 1;
    background: var(--bg-surface);
    color: var(--text-secondary);
    font-size: .6875rem;
    font-weight: 600;
    letter-spacing: .05em;
    text-transform: uppercase;
    white-space: nowrap;
    border-bottom: 1px solid var(--border-color);
}

.matrix td.mark { text-align: center; font-variant-numeric: tabular-nums; }

.matrix tbody tr.group td {
    font-weight: 600;
    font-size: .75rem;
    letter-spacing: .05em;
    text-transform: uppercase;
    color: var(--text-secondary);
    background: var(--bg-surface-secondary);
    padding-top: .75rem;
    padding-bottom: .75rem;
}

.matrix tbody tr:hover td { background: var(--primary-lt); }

.has   { color: var(--accent-text); font-weight: 700; }
.lacks { color: var(--text-disabled); }

.login-screen {
    min-height: 100vh;
    display: grid;
    place-items: center;
    padding: 1.5rem;
    background: var(--body-bg);
    color: var(--text);
}

.login-box   { width: 100%; max-width: 380px; }
.login-brand { text-align: center; margin-bottom: 1.5rem; }
.login-brand img { width: 96px; height: auto; margin-bottom: .75rem; }
.login-brand h1  { margin: 0; font-size: 1.0625rem; font-weight: 600; color: var(--text); }
.login-brand p   { margin: .25rem 0 0; font-size: .8125rem; color: var(--text-muted); }

.tiles {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
    gap: .75rem;
    margin-bottom: 1.5rem;
}

.tile { display: flex; align-items: center; gap: .875rem; }

.tile-icon {
    flex: none;
    width: 42px;
    height: 42px;
    display: grid;
    place-items: center;
    border-radius: 10px;
    background: var(--primary-lt);
    color: var(--accent-text);
}

.tile-value {
    font-size: 1.6rem;
    font-weight: 600;
    line-height: 1.1;
    color: var(--text);
    font-variant-numeric: tabular-nums;
}

.tile-label { font-size: .75rem; color: var(--text-muted); margin-top: .15rem; }

.steps { display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); gap: .75rem; }

.step {
    display: flex;
    gap: .75rem;
    align-items: flex-start;
    padding: .875rem 1rem;
    border: 1px solid var(--border-color);
    border-radius: var(--radius, 8px);
    background: var(--bg-surface);
}

.step-no   { font-family: var(--font-mono, monospace); font-size: .75rem; color: var(--text-muted); min-width: 1.5rem; }
.step-name { font-size: .8125rem; font-weight: 600; line-height: 1.35; color: var(--text); }

.step-state {
    display: block;
    margin-top: .25rem;
    font-size: .6875rem;
    font-weight: 600;
    letter-spacing: .04em;
    text-transform: uppercase;
    color: var(--text-muted);
}

.step.done  { border-color: var(--vlig-blue); box-shadow: inset 3px 0 0 0 var(--vlig-blue); }
.step.done  .step-state { color: var(--accent-text); }
.step.wip   { border-color: var(--warning); box-shadow: inset 3px 0 0 0 var(--warning); }
.step.wip   .step-state { color: var(--warning); }
.step.queued { background: var(--bg-surface-secondary); }
.step.queued .step-name { color: var(--text-secondary); font-weight: 500; }

/* a finished step is a link to the screen it produced */
a.step:hover { border-color: var(--accent-text); }
a.step:hover .step-name { color: var(--accent-text); }

.step-note {
    display: inline-flex;
    align-items: center;
    gap: .2rem;
    margin-left: .4rem;
    color: var(--warning);
}

/* the note is said in full, not hidden behind a tooltip - a caveat nobody
   reads is a caveat that was not made */
.step-note-text {
    display: block;
    margin-top: .3rem;
    font-size: .6875rem;
    line-height: 1.45;
    color: var(--text-muted);
    text-transform: none;
    letter-spacing: 0;
}

.progress-rail {
    height: 4px;
    margin-bottom: 1rem;
    border-radius: 999px;
    background: var(--border-color-light);
    overflow: hidden;
}

.progress-done {
    display: block;
    height: 100%;
    border-radius: 999px;
    background: var(--vlig-blue);
}

.activity-list { list-style: none; margin: 0; padding: 0; }

.activity-item {
    display: flex;
    gap: .75rem;
    align-items: flex-start;
    padding: .625rem 0;
    border-bottom: 1px solid var(--border-color-light);
    font-size: .8125rem;
}

.activity-item:last-child { border-bottom: 0; }
.activity-icon { flex: none; color: var(--text-muted); margin-top: .1rem; }
.activity-text { flex: 1; color: var(--text); }
.activity-time { flex: none; color: var(--text-muted); font-size: .75rem; white-space: nowrap; }

.quick-actions { display: flex; flex-wrap: wrap; gap: .5rem; }

.error-page {
    min-height: 100vh;
    display: grid;
    place-content: center;
    justify-items: center;
    gap: .5rem;
    padding: 2rem 1.5rem;
    text-align: center;
    background: var(--body-bg);
    color: var(--text);
}

.error-page img { width: 100px; height: auto; margin-bottom: .5rem; }

.error-code {
    font-size: 3.5rem;
    font-weight: 700;
    line-height: 1;
    color: var(--accent-text);
    font-variant-numeric: tabular-nums;
}

.error-page p { margin: 0 0 .75rem; color: var(--text-secondary); max-width: 44ch; }

.error-page pre {
    text-align: left;
    margin-top: 2rem;
    max-width: min(900px, 90vw);
    overflow-x: auto;
    font-size: .75rem;
    padding: 1rem;
    border-radius: var(--radius, 6px);
    background: var(--bg-surface-secondary);
    border: 1px solid var(--border-color);
    color: var(--text-secondary);
}
