/* ============================================================
   Regnskrap — modern accounting UI
   ============================================================
   Design philosophy:
   - One restrained accent color (indigo). Primary buttons appear at most
     once per page; everything else is neutral.
   - Borders, not shadows, for hierarchy. Shadows reserved for popovers/modals.
   - Tabular numbers throughout (the entire app is numerical data).
   - 4px spacing scale. Two border-radius values: 6px (controls), 10px (cards).
   ============================================================ */

/* ----- Design tokens ----- */
:root {
    /* Neutrals — Tailwind/Linear-style gray ramp */
    --gray-50:  #FAFAFA;
    --gray-100: #F3F4F6;
    --gray-150: #ECEEF1;
    --gray-200: #E5E7EB;
    --gray-300: #D1D5DB;
    --gray-400: #9CA3AF;
    --gray-500: #6B7280;
    --gray-600: #4B5563;
    --gray-700: #374151;
    --gray-800: #1F2937;
    --gray-900: #111827;

    /* Accent — royal blue. The single "red thread" color used across the app:
       primary buttons, nav icons, active states, focus rings, links. */
    --primary-50:  #EDF2FF;
    --primary-100: #D6E1FF;
    --primary-300: #6F8DFF;
    --primary-500: #2D5BFA;   /* lighter — for hover backgrounds, icons in bright contexts */
    --primary-600: #0A41FA;   /* default primary — the user's chosen accent */
    --primary-700: #0834D0;
    --primary-800: #052BAB;
    --primary-on:  #FFFFFF;

    /* Semantic — full 50/200/500/600/700/800 ramps so anything in the app
       can pull from tokens without falling back to literals. */
    --success-50:  #ECFDF5;
    --success-200: #BBF7D0;
    --success-500: #10B981;
    --success-600: #16A34A;
    --success-700: #047857;
    --success-800: #065F46;
    --warning-50:  #FFFBEB;
    --warning-100: #FEF3C7;
    --warning-200: #FDE68A;
    --warning-500: #F59E0B;
    --warning-600: #D97706;
    --warning-700: #B45309;
    --warning-800: #92400E;
    --danger-50:   #FEF2F2;
    --danger-200:  #FECACA;
    --danger-500:  #EF4444;
    --danger-600:  #DC2626;
    --danger-700:  #B91C1C;
    --info-50:     #EFF6FF;
    /* -200 and -800 are the border and text of the notice boxes; ten pages
       used them before they existed, and got a black border and plain text. */
    --info-200:    #BFDBFE;
    --info-500:    #3B82F6;
    --info-700:    #1D4ED8;
    --info-800:    #1E40AF;
    /* Auxiliary accents reserved for visual variety inside dashboard widgets
       (e.g. AR/AP sparklines pick a non-primary tint so they read as a
       distinct series, not as the page's primary action). */
    --accent-violet-50:  #F5F3FF;
    --accent-violet-600: #7C3AED;
    --accent-violet-700: #6D28D9;

    /* Surfaces (light theme defaults) */
    --bg:            var(--gray-50);
    --surface:       #FFFFFF;
    --surface-alt:   var(--gray-100);    /* neutral grey fill — used sparingly */
    --surface-tint:  #F2F5FF;            /* soft blue tint — table headers, hovers, accents */
    --surface-tint-strong: #E6ECFF;      /* stronger blue tint — selected rows, active states */
    --border:        var(--gray-200);
    --border-strong: var(--gray-300);
    --text:          var(--gray-900);
    --text-muted:    var(--gray-500);
    --text-subtle:   var(--gray-400);
    /* Ambient page-background blooms — two soft radial gradients
       layered on body so the frosted navbar has warm + cool tints
       to refract through, even at scrollTop 0. Subtle on purpose:
       readable on top, distinct enough that the glass effect reads
       as glass and not as a flat tinted bar. */
    --ambient-warm:  #FFEEE7;            /* very pale peach,    top-left bloom */
    --ambient-cool:  #ECF0FF;            /* very pale periwinkle, top-right bloom */
    --ambient-intensity: 1;              /* 0..1 multiplier applied to the body::before bloom layer */

    /* Compatibility shim — keep old MD3 names mapping to new tokens so any
       lingering references in templates don't visually break. */
    --md-sys-color-primary: var(--primary-600);
    --md-sys-color-on-primary: var(--primary-on);
    --md-sys-color-primary-container: var(--primary-50);
    --md-sys-color-on-primary-container: var(--primary-700);
    --md-sys-color-secondary: var(--gray-700);
    --md-sys-color-on-secondary: #FFFFFF;
    --md-sys-color-secondary-container: var(--gray-100);
    --md-sys-color-on-secondary-container: var(--gray-900);
    --md-sys-color-tertiary: var(--primary-500);
    --md-sys-color-error: var(--danger-600);
    --md-sys-color-error-container: var(--danger-50);
    --md-sys-color-on-error: #FFFFFF;
    --md-sys-color-on-error-container: var(--danger-700);
    --md-sys-color-background: var(--bg);
    --md-sys-color-on-background: var(--text);
    --md-sys-color-surface: var(--surface);
    --md-sys-color-on-surface: var(--text);
    --md-sys-color-surface-variant: var(--surface-alt);
    --md-sys-color-on-surface-variant: var(--text-muted);
    --md-sys-color-outline: var(--border-strong);
    --md-sys-color-outline-variant: var(--border);
    --md-sys-color-inverse-on-surface: var(--gray-50);
    --md-sys-color-inverse-surface: var(--gray-900);
    --md-sys-color-inverse-primary: var(--primary-500);

    /* Layout */
    --top-bar-height: 60px;
    --content-max-width: 1680px;

    /* Radii */
    --radius-sm: 6px;   /* inputs, buttons, badges */
    --radius-md: 10px;  /* cards, modals */
    --radius-pill: 999px;

    /* Scrim behind a modal or lightbox. Was written inline as a literal on
       every page that needed one, and on /invoices as a var() fallback —
       which drifts, because the fallback is what actually renders. */
    --overlay: rgba(17, 24, 39, 0.4);

    /* Shadows — reserved for floating elements */
    --shadow-sm: 0 1px 2px rgba(17, 24, 39, 0.04);
    --shadow-md: 0 4px 12px rgba(17, 24, 39, 0.08), 0 0 0 1px rgba(17, 24, 39, 0.04);
    --shadow-lg: 0 16px 32px rgba(17, 24, 39, 0.12), 0 0 0 1px rgba(17, 24, 39, 0.04);

    /* Motion */
    --transition-fast: 120ms ease-out;
    --transition: 160ms ease-out;

    /* Focus ring */
    --focus-ring: 0 0 0 3px rgba(99, 102, 241, 0.25);
}

.theme-dark {
    --bg:                  #0B0D11;
    --surface:             #15171C;
    --surface-alt:         #1F2127;
    --surface-tint:        #1A1F3A;   /* dark version of the blue tint */
    --surface-tint-strong: #232A4A;
    --border:              #2A2D34;
    --border-strong:       #383B43;
    --text:                #F3F4F6;
    --text-muted:          #9CA3AF;
    --text-subtle:         #6B7280;

    --primary-50:  #1E1B4B;
    --primary-100: #2D2A6B;
    --primary-500: #818CF8;
    --primary-600: #818CF8;
    --primary-700: #A5B4FC;
    --primary-on:  #1E1B4B;

    --success-50: #052E1F;
    --success-200: #14532D;
    --success-600: #4ADE80;
    --warning-50: #2A1E08;
    --warning-100: #2A1E08;
    --warning-200: #3A2A0A;
    --warning-600: #FBBF24;
    --warning-800: #FCD34D;
    --danger-50:  #2A0F0F;
    --info-50:    #0F1B2D;

    /* The -700 tokens are the TEXT colour of every badge, alert and .text-*
       pair whose background is the -50 above. They were never redefined here,
       so they kept their light-mode values — dark ink on a dark ground, around
       2.7:1 against the 4.5:1 the rest of the system holds itself to. This is
       systemic: it affected every page, not only the ones being worked on. */
    --success-700: #6EE7B7;
    --success-800: #A7F3D0;
    --warning-700: #FCD34D;
    --danger-700:  #FCA5A5;
    --info-700:    #93C5FD;
    --info-800:    #BFDBFE;
    --info-200:    #1E3A8A;
    /* Border partner of --danger-50; light-mode #FECACA glowed on dark. */
    --danger-200:  #7F1D1D;
    --accent-violet-50:  #1F1A3A;
    --accent-violet-600: #A78BFA;
    --accent-violet-700: #C4B5FD;
    /* Dark-mode ambient blooms — saturated enough to give the glass
       something to refract, but dim so the page stays readable. */
    --ambient-warm:  #2A1820;            /* deep plum/wine */
    --ambient-cool:  #14182A;            /* deep navy */

    /* Tweak MD shim too */
    --md-sys-color-primary: var(--primary-500);
    --md-sys-color-on-primary: var(--primary-on);
    --md-sys-color-primary-container: var(--primary-50);
    --md-sys-color-on-primary-container: var(--primary-700);
    --md-sys-color-background: var(--bg);
    --md-sys-color-on-background: var(--text);
    --md-sys-color-surface: var(--surface);
    --md-sys-color-on-surface: var(--text);
    --md-sys-color-surface-variant: var(--surface-alt);
    --md-sys-color-on-surface-variant: var(--text-muted);
    --md-sys-color-outline: var(--border-strong);
    --md-sys-color-outline-variant: var(--border);

    /* Darker on a dark ground — the light scrim all but disappears there. */
    --overlay: rgba(0, 0, 0, 0.6);

    --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.4);
    --shadow-md: 0 4px 12px rgba(0, 0, 0, 0.5), 0 0 0 1px rgba(255, 255, 255, 0.04);
    --shadow-lg: 0 16px 32px rgba(0, 0, 0, 0.6), 0 0 0 1px rgba(255, 255, 255, 0.04);
}

/* ----- Base ----- */
* { box-sizing: border-box; }

body {
    font-family: 'Inter', system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
    font-feature-settings: 'cv11', 'ss01', 'ss03';
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    background-color: var(--bg);
    color: var(--text);
    margin: 0;
    padding: 0;
    line-height: 1.5;
    font-size: 14px;
    position: relative;     /* anchor for ::before */
}
/* Ambient page-background blooms — fixed-position pseudo-element so
   the gradient stays pinned to the viewport while content scrolls
   above it. Using a pseudo (rather than `background-attachment: fixed`
   on body) because Safari has known repaint glitches with that pattern
   when combined with `backdrop-filter` elsewhere on the page.

   z-index: -1 puts it behind body content; pointer-events: none keeps
   it from intercepting clicks. The two radial gradients bloom in from
   opposite top corners and fade out by ~55% so the rest of the page
   falls through to the body's --bg colour. */
body::before {
    content: '';
    position: fixed;
    inset: 0;
    z-index: -1;
    pointer-events: none;
    background-image:
        radial-gradient(ellipse 120% 80% at 0% 0%,    var(--ambient-warm) 0%, transparent 55%),
        radial-gradient(ellipse 120% 80% at 100% 0%,  var(--ambient-cool) 0%, transparent 55%);
    /* User-driven intensity (0..1) — multiplied on top of the gradients
       so the entire ambient layer can be dimmed or boosted without
       touching the individual colour values. Theme drawer ships an
       intensity slider that writes this token to documentElement. */
    opacity: var(--ambient-intensity, 1);
    transition: opacity 160ms ease-out;
}

/* Numeric data should always use tabular figures so columns align */
.table, .table td, .table th,
.number, .num, .amount, .balance,
input[type="number"], .form-control {
    font-variant-numeric: tabular-nums;
}

h1, h2, h3, h4, h5, h6 {
    font-family: 'Inter', system-ui, -apple-system, sans-serif;
    color: var(--text);
    font-weight: 600;
    letter-spacing: -0.01em;
    margin: 0 0 0.5rem;
}
h1 { font-size: 24px; line-height: 1.25; letter-spacing: -0.02em; }
h2 { font-size: 20px; line-height: 1.3; }
h3 { font-size: 17px; line-height: 1.35; }
h4 { font-size: 15px; }
h5 { font-size: 14px; }
h6 { font-size: 13px; text-transform: uppercase; letter-spacing: 0.05em; color: var(--text-muted); font-weight: 500; }

a {
    color: var(--primary-600);
    text-decoration: none;
    transition: color var(--transition-fast);
}
a:hover { color: var(--primary-700); text-decoration: none; }

/* Focus rings — visible only when navigating via KEYBOARD, never
   after a mouse click. Two parts to this rule:

   (1) Strip the default `:focus` ring entirely. Without this, clicking
       a button leaves the browser's focus ring stuck around it until
       the user clicks elsewhere — visually noisy on a button-heavy UI.

   (2) Put the ring back for `:focus-visible`, which only fires when
       focus arrived via keyboard navigation (Tab / Shift-Tab / arrow
       keys). Keyboard users still see exactly where focus is.

   This also overrides Bootstrap 4's `.btn:focus { box-shadow: 0 0 0
   0.2rem ... }` rule, which uses plain `:focus` and therefore shows
   on every click — a separate `.btn` block below kills that
   box-shadow on mouse focus while keeping a proper keyboard ring. */
:focus { outline: none; }
:focus-visible {
    outline: 2px solid var(--primary-500);
    outline-offset: 2px;
}

/* Bootstrap 4 puts a 0.2rem box-shadow ring on :focus for buttons,
   form-controls, dropdown-toggles, etc. That's mouse-click focus too,
   not just keyboard. Strip the shadow when focus arrived via mouse;
   re-add a 3px ring on :focus-visible so keyboard users still see
   focus. */
.btn:focus,
.btn.focus,
button:focus,
.dropdown-toggle:focus,
.dropdown-item:focus,
.nav-link:focus {
    box-shadow: none;
    outline: none;
}
.btn:focus-visible,
button:focus-visible,
.dropdown-toggle:focus-visible,
.dropdown-item:focus-visible,
.nav-link:focus-visible {
    outline: 2px solid var(--primary-500);
    outline-offset: 2px;
    box-shadow: none;            /* outline alone is enough; no double ring */
}

/* ----- Layout ----- */
.app-container {
    display: flex;
    flex-direction: column;
    min-height: 100vh;
}

/* ----- Top navigation ----- */
/* Three-column layout: brand on the left, nav centered, controls on the right.
   This gives the nav a visual "anchor" in the middle of the page regardless
   of how many controls live on either side. */
.navbar {
    height: var(--top-bar-height);
    /* Frosted-glass effect: semi-transparent surface + backdrop blur so
       page content scrolling underneath shows through as a soft tint.
       The `color-mix` keeps the navbar surface keyed to the active
       theme — in dark mode the same rule produces a tinted-dark glass.
       Fallback (no @supports backdrop-filter) is a near-opaque surface
       so older browsers still get a usable bar. */
    background-color: var(--navbar-bg-fallback, var(--surface));
    border-bottom: 1px solid var(--border);
    display: grid;
    grid-template-columns: 1fr auto 1fr;
    align-items: center;
    padding: 0 24px;
    position: sticky;
    top: 0;
    z-index: 1000;
    box-shadow: none;
    gap: 16px;
}
@supports ((backdrop-filter: blur(10px)) or (-webkit-backdrop-filter: blur(10px))) {
    .navbar {
        /* Base translucency — 56% so the ambient bloom bleeds through
           in the middle, but the bar still reads as a distinct plane
           sitting above the page rather than blending in. The inner
           color-mix tints the surface ~10% with gray-400 so it reads
           as actual glass (slight grey hue) rather than "frosted
           white". */
        /* Translucent enough to read as glass (the ambient bloom + content
           blur through it), while the solid bottom border + tight outer
           shadow below — NOT the opacity — are what keep it distinct from the
           near-white page. That separation of concerns lets the bar stay
           glassy without blending in. */
        background-color: color-mix(in srgb,
            color-mix(in srgb, var(--surface) 97%, var(--gray-400)) 64%,
            transparent);
        -webkit-backdrop-filter: saturate(200%) blur(24px);
                backdrop-filter: saturate(200%) blur(24px);

        /* Internal "glass" depth — works even at scrollTop 0. Four
           layered effects:

           1. Two RADIAL corner sheens (top-left + top-right). Radials
              fall off in all directions so they don't produce the
              edge-band that a linear-gradient leaves at its terminal
              stop — that was the source of the visible "diagonal
              stripes" earlier.

           2. Inset top highlight. The bright 1px white line that real
              glass shows along its beveled leading edge.

           3. Inset bottom shadow. Soft inner shadow at the lower edge
              gives the bar a sense of thickness — glass has volume,
              not just surface.

           4. Stronger outer drop shadow + clearer bottom border. Pushes
              the bar off the page so it reads as a separate plane
              sitting *above* the ambient gradient, not blended into it. */
        background-image:
            radial-gradient(ellipse 80% 140% at 0% 0%,   rgba(255, 255, 255, 0.32) 0%, transparent 70%),
            radial-gradient(ellipse 80% 140% at 100% 0%, rgba(255, 255, 255, 0.24) 0%, transparent 70%);
        /* Solid bottom border (not the faint transparent mix) so the bar has a
           crisp edge against the near-white page. */
        border-bottom-color: var(--border);
        /* Inset glass highlights + a TIGHT, soft outer shadow. This is the
           separation cue that was missing once the deep shadow was removed —
           but it's close and low (2-4px), so the bar reads as sitting gently on
           the page, not floating high above it like the old 28px blur did. */
        box-shadow:
            inset 0 1px 0 rgba(255, 255, 255, 0.75),
            inset 0 -1px 0 rgba(255, 255, 255, 0.18),
            0 1px 1px rgba(15, 23, 42, 0.05),
            0 4px 10px -6px rgba(15, 23, 42, 0.12);
    }
}

/* In dark mode the same gradient reads as "moonlit glass" — lower
   highlight opacities so the white sheen reads as subtle reflection,
   not a chrome strip painted on dark plastic. */
.theme-dark .navbar {
    /* Same radial corner-sheens as light mode but lower opacities so
       the white reflections read as subtle moonlit-glass rather than
       chrome strips on a dark surface. */
    background-image:
        radial-gradient(ellipse 80% 140% at 0% 0%,   rgba(255, 255, 255, 0.10) 0%, transparent 70%),
        radial-gradient(ellipse 80% 140% at 100% 0%, rgba(255, 255, 255, 0.08) 0%, transparent 70%);
    box-shadow:
        inset 0 1px 0 rgba(255, 255, 255, 0.22),
        inset 0 -1px 0 rgba(255, 255, 255, 0.05),
        0 1px 1px rgba(0, 0, 0, 0.25),
        0 4px 10px -6px rgba(0, 0, 0, 0.45);
}

.navbar-brand {
    font-family: 'Inter', sans-serif;
    font-size: 16px;
    font-weight: 600;
    color: var(--text);
    text-decoration: none;
    letter-spacing: -0.01em;
    justify-self: start;
}
.navbar-brand:hover { color: var(--text); text-decoration: none; }

/* The collapse wraps .navbar-nav. Center it in the middle column. */
.navbar-collapse {
    display: flex;
    justify-content: center;
    grid-column: 2;
}

.navbar-nav {
    display: flex;
    align-items: center;
    gap: 4px;
    flex-wrap: nowrap;
}

/* Right-side controls (theme toggle + company switcher) — column 3, right-aligned. */
.navbar > .d-flex.ml-auto,
.navbar > .d-flex:last-child {
    grid-column: 3;
    justify-self: end;
    margin-left: 0 !important;  /* override Bootstrap .ml-auto */
    gap: 8px;
}

/* The menu button only shows when the menu has folded (.nav-menu-folded). */
.navbar-toggler { display: none; }

/* The company name can be shortened; the chip carries it whole in its title. */
.company-chip__name {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* ----- When the bar does not fit ----- */
/* fitNavbar() in base.html adds these one step at a time, until the bar fits,
   so nothing goes before the width demands it (DESIGN.md §7). The labels in
   the menu never go: when even the last step is not enough, the menu folds
   behind the menu button and the steps start over for what is left. */
.navbar.nav-fit-1 .navbar-nav .nav-link > .material-symbols-rounded { display: none; }
.navbar.nav-fit-2 { padding: 0 16px; gap: 8px; }
.navbar.nav-fit-2 > .d-flex.ml-auto { gap: 4px; }
.navbar.nav-fit-2 .navbar-nav .nav-link { padding-left: 6px; padding-right: 6px; }
.navbar.nav-fit-2 .lang-toggle__btn { padding-left: 6px; padding-right: 6px; }
.navbar.nav-fit-3 .navbar-brand { display: none; }
.navbar.nav-fit-4 .company-chip__name { max-width: 90px; }
.navbar.nav-fit-5 .company-chip__name { display: none; }

/* The folded menu: a panel under the bar, the headers stacked, each
   dropdown opening in place under its header. */
.navbar.nav-menu-folded { grid-template-columns: auto auto 1fr; }
.navbar.nav-menu-folded .navbar-toggler {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    order: -1;
}
.navbar.nav-menu-folded .navbar-collapse:not(.show):not(.collapsing) { display: none !important; }
.navbar.nav-menu-folded .navbar-collapse.show,
.navbar.nav-menu-folded .navbar-collapse.collapsing {
    /* grid-column: auto, or the panel is placed in the menu's own column. */
    grid-column: auto;
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    display: block !important;
    max-height: calc(100vh - var(--top-bar-height));
    overflow-y: auto;
    padding: 8px 16px;
    background: var(--surface);
    border-bottom: 1px solid var(--border);
    box-shadow: var(--shadow-md);
}
.navbar.nav-menu-folded .navbar-nav {
    flex-direction: column;
    align-items: stretch;
    gap: 2px;
}
.navbar.nav-menu-folded .navbar-nav .nav-link { width: 100%; }
.navbar.nav-menu-folded .navbar-nav .dropdown-menu {
    position: static;
    min-width: 0;
    margin: 0 0 4px 24px;
    padding: 0;
    border: 0;
    box-shadow: none;
}

.nav-link {
    display: inline-flex;
    align-items: center;
    height: 34px;
    padding: 0 12px;
    border-radius: var(--radius-sm);
    color: var(--text);
    font-weight: 500;
    font-size: 13px;
    text-decoration: none;
    cursor: pointer;
    transition: background-color var(--transition-fast), color var(--transition-fast);
    user-select: none;
    border: none;
    background: transparent;
}

.nav-link:hover, .nav-link.show, .nav-link:focus {
    background-color: var(--primary-50);
    color: var(--primary-700);
    text-decoration: none;
}

.nav-link .material-symbols-rounded {
    margin-right: 6px;
    font-size: 19px;
    color: var(--primary-600);
}
.nav-link:hover .material-symbols-rounded, .nav-link.show .material-symbols-rounded {
    color: var(--primary-700);
}

/* Dropdown caret — keep but slim it down */
.nav-link.dropdown-toggle::after {
    border-top-color: currentColor;
    margin-left: 4px;
    opacity: 0.6;
}

/* ----- Dropdown menus ----- */
.dropdown-menu {
    position: absolute;
    top: 100%;
    left: 0;
    z-index: 1050;
    display: none;
    min-width: 220px;
    padding: 4px;
    margin: 4px 0 0;
    background-color: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    box-shadow: var(--shadow-md);
}
.dropdown-menu.show { display: block; }

.dropdown-menu-right {
    left: auto;
    right: 0;
}

.dropdown-item {
    display: flex;
    align-items: center;
    width: 100%;
    padding: 8px 10px;
    border-radius: var(--radius-sm);
    font-weight: 400;
    font-size: 13px;
    color: var(--text);
    text-decoration: none;
    white-space: nowrap;
    background-color: transparent;
    border: 0;
    cursor: pointer;
    transition: background-color var(--transition-fast);
}
.dropdown-item:hover, .dropdown-item:focus {
    background-color: var(--surface-alt);
    color: var(--text);
    text-decoration: none;
}
.dropdown-item.active {
    background-color: var(--primary-50);
    color: var(--primary-700);
    font-weight: 500;
}
.dropdown-item.disabled {
    color: var(--text-subtle);
    pointer-events: none;
}
.dropdown-item .material-symbols-rounded {
    margin-right: 10px;
    font-size: 18px;
    color: var(--primary-600);
}
.dropdown-item:hover .material-symbols-rounded { color: var(--primary-700); }
.dropdown-item.active .material-symbols-rounded { color: var(--primary-700); }

.dropdown-divider {
    height: 1px;
    margin: 4px 0;
    background-color: var(--border);
    border: 0;
}

/* Count pill in the navbar — how many documents wait in the inbox. Inline
   after the label, not absolutely positioned like .info-nav-btn__badge: a
   nav link is a text row and has to stay on one line. White on a saturated
   fill is one of the three documented colour exceptions. */
.nav-link__count {
    display: inline-block;
    min-width: 16px;
    margin-left: 6px;
    padding: 0 5px;
    border-radius: var(--radius-pill);
    background: var(--primary-600);
    color: #fff;
    font-size: 10px;
    font-weight: 700;
    line-height: 16px;
    text-align: center;
    font-variant-numeric: tabular-nums;
}
.nav-link:hover .nav-link__count,
.nav-link.show .nav-link__count { background: var(--primary-700); }

/* Section label inside a dropdown — groups items without adding a second
   menu level (Reskontro under Bilag, innleveringer under Rapporter). */
.dropdown-section {
    padding: 6px 14px 2px;
    color: var(--text-muted);
    font-size: 11px;
    font-weight: 600;
    letter-spacing: 0.04em;
    text-transform: uppercase;
}

/* ----- Main content area ----- */
.main-content {
    flex: 1;
    padding: 24px;
    width: 100%;
    max-width: var(--content-max-width);
    margin: 0 auto;
}

/* ----- Page headers ----- */
.page-header {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 16px;
    padding-bottom: 16px;
    margin-bottom: 24px;
    border-bottom: 1px solid var(--border);
}
.page-header__title {
    font-size: 22px;
    font-weight: 600;
    margin: 0;
    letter-spacing: -0.02em;
    color: var(--text);
}
.page-header__subtitle { color: var(--text-muted); font-size: 13px; margin-top: 4px; }
.page-header__actions { display: flex; gap: 8px; align-items: center; flex-shrink: 0; }

/* Icon decoration in titles — apply by adding a .material-symbols-rounded
   inside .page-header__title for a colored leading icon. */
.page-header__title .material-symbols-rounded {
    color: var(--primary-600);
    margin-right: 8px;
    font-size: 24px;
    vertical-align: -4px;
}

/* ----- Buttons ----- */
/* The system has three button shapes:
   1) .btn-primary  — solid indigo, ONE per page (the main action)
   2) .btn-secondary / default .btn — white with border, neutral
   3) .btn-ghost    — no chrome, hover background only
   4) .btn-icon     — square 32×32, just an icon (also: .btn-icon.btn-sm = 28px)
   Color variants (.btn-success, .btn-danger, .btn-warning, .btn-info) only
   apply when the action is genuinely categorical (e.g. delete = danger). */

.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    height: 36px;
    padding: 0 14px;
    font-family: inherit;
    font-size: 13px;
    font-weight: 500;
    line-height: 1;
    border: 1px solid var(--border-strong);
    border-radius: var(--radius-sm);
    background-color: var(--surface);
    color: var(--text);
    cursor: pointer;
    text-decoration: none;
    transition: background-color var(--transition-fast), border-color var(--transition-fast), color var(--transition-fast), box-shadow var(--transition-fast), transform var(--transition-fast);
    white-space: nowrap;
    user-select: none;
}
.btn:hover {
    background-color: var(--surface-alt);
    border-color: var(--border-strong);
    color: var(--text);
    text-decoration: none;
}
.btn:active { transform: translateY(0.5px); }
.btn:focus-visible { outline: 2px solid var(--primary-500); outline-offset: 2px; }
.btn:disabled, .btn[disabled] {
    opacity: 0.5;
    cursor: not-allowed;
    pointer-events: none;
}

.btn-sm { height: 28px; padding: 0 10px; font-size: 12px; }
.btn-lg { height: 42px; padding: 0 18px; font-size: 14px; }

/* Primary — solid indigo, reserved for the main action */
.btn-primary {
    background-color: var(--primary-600);
    border-color: var(--primary-600);
    color: var(--primary-on);
}
.btn-primary:hover {
    background-color: var(--primary-700);
    border-color: var(--primary-700);
    color: var(--primary-on);
}

/* Secondary (alias for default) — explicit class for readability */
.btn-secondary,
.btn-outline-secondary {
    background-color: var(--surface);
    border-color: var(--border-strong);
    color: var(--text);
}
.btn-secondary:hover,
.btn-outline-secondary:hover {
    background-color: var(--surface-alt);
    color: var(--text);
}

/* btn-outline-primary — same shape as secondary but indigo text + hover */
.btn-outline-primary {
    background-color: var(--surface);
    border-color: var(--primary-600);
    color: var(--primary-600);
}
.btn-outline-primary:hover {
    background-color: var(--primary-50);
    border-color: var(--primary-700);
    color: var(--primary-700);
}

/* Color icons inside secondary/ghost buttons — gives a subtle blue accent
   on the icon without making the whole button colored. */
.btn-secondary .material-symbols-rounded,
.btn-outline-secondary .material-symbols-rounded,
.btn-outline-primary .material-symbols-rounded {
    color: var(--primary-600);
}

/* Semantic */
.btn-success {
    background-color: var(--success-500);
    border-color: var(--success-500);
    color: #FFF;
}
.btn-success:hover { background-color: var(--success-700); border-color: var(--success-700); color: #FFF; }

.btn-danger {
    background-color: var(--surface);
    border-color: var(--border-strong);
    color: var(--danger-600);
}
.btn-danger:hover {
    background-color: var(--danger-50);
    border-color: var(--danger-500);
    color: var(--danger-700);
}

.btn-warning {
    background-color: var(--surface);
    border-color: var(--border-strong);
    color: var(--warning-700);
}
.btn-warning:hover { background-color: var(--warning-50); border-color: var(--warning-500); color: var(--warning-700); }

.btn-info {
    background-color: var(--surface);
    border-color: var(--border-strong);
    color: var(--info-700);
}
.btn-info:hover { background-color: var(--info-50); border-color: var(--info-500); color: var(--info-700); }

/* Ghost — no border, just text + hover bg */
.btn-ghost,
.btn-link {
    background-color: transparent;
    border-color: transparent;
    color: var(--text-muted);
    padding: 0 10px;
}
.btn-ghost:hover,
.btn-link:hover {
    background-color: var(--surface-alt);
    color: var(--text);
    text-decoration: none;
}

/* Icon-only buttons */
.btn-icon {
    width: 32px;
    height: 32px;
    padding: 0;
    border-radius: var(--radius-sm);
    background-color: transparent;
    border-color: transparent;
    color: var(--text-muted);
}
.btn-icon:hover {
    background-color: var(--surface-alt);
    color: var(--text);
    border-color: transparent;
}
.btn-icon.btn-sm { width: 28px; height: 28px; }
.btn-icon.btn-lg { width: 40px; height: 40px; }

.btn .material-symbols-rounded {
    font-size: 18px;
    line-height: 1;
}
.btn-sm .material-symbols-rounded { font-size: 16px; }

/* Button groups — slim them */
.btn-group .btn { border-radius: 0; }
.btn-group .btn:first-child { border-top-left-radius: var(--radius-sm); border-bottom-left-radius: var(--radius-sm); }
.btn-group .btn:last-child { border-top-right-radius: var(--radius-sm); border-bottom-right-radius: var(--radius-sm); }
.btn-group .btn + .btn { margin-left: -1px; }

/* ----- Forms ----- */
/* Two selector groups:
   1) The Bootstrap-style classes (.form-control, .form-select) — explicit opt-in
   2) Bare inputs without any class — a fallback so templates with `<input type=text>`
      still look right. Excludes special types (checkbox, radio, file, range, color)
      and elements explicitly opted out via .form-control-plaintext. */
.form-control, .form-select,
select.form-control, input.form-control, textarea.form-control,
input[type="text"]:not(.form-control-plaintext):not(.no-style),
input[type="email"]:not(.no-style),
input[type="password"]:not(.no-style),
input[type="number"]:not(.no-style),
input[type="tel"]:not(.no-style),
input[type="url"]:not(.no-style),
input[type="search"]:not(.no-style),
input[type="date"]:not(.no-style),
input[type="datetime-local"]:not(.no-style),
input[type="time"]:not(.no-style),
input[type="month"]:not(.no-style),
select:not([multiple]):not(.no-style),
textarea:not(.no-style) {
    display: block;
    width: 100%;
    height: 36px;
    padding: 0 12px;
    font-size: 13px;
    font-family: inherit;
    line-height: 1.4;
    color: var(--text);
    background-color: var(--surface);
    border: 1px solid var(--border-strong);
    border-radius: var(--radius-sm);
    transition: border-color var(--transition-fast), box-shadow var(--transition-fast);
    box-shadow: none;
    box-sizing: border-box;
}
textarea.form-control, textarea:not(.no-style) {
    height: auto;
    min-height: 80px;
    padding: 8px 12px;
}
.form-control:focus, .form-select:focus,
input:not([type="checkbox"]):not([type="radio"]):not([type="file"]):not(.no-style):focus,
select:not([multiple]):not(.no-style):focus,
textarea:not(.no-style):focus {
    border-color: var(--primary-500);
    box-shadow: var(--focus-ring);
    outline: none;
}
.form-control:disabled, .form-control[readonly] {
    background-color: var(--surface-alt);
    color: var(--text-muted);
}
.form-control::placeholder { color: var(--text-subtle); }
.form-control.is-invalid { border-color: var(--danger-500); }
.form-control.is-invalid:focus { box-shadow: 0 0 0 3px rgba(239, 68, 68, 0.2); }

.form-control-sm { height: 30px; padding: 0 10px; font-size: 12px; }
.form-control-lg { height: 42px; padding: 0 14px; font-size: 14px; }

.form-group { margin-bottom: 16px; }
.form-group label,
label.form-label {
    display: block;
    font-size: 12px;
    font-weight: 500;
    color: var(--text-muted);
    margin-bottom: 6px;
    letter-spacing: 0.01em;
}

.form-check-input { margin-right: 6px; }
.form-check-label { font-size: 13px; }

/* Destructive icon button. The only rule for .danger used to be scoped to
   `.row-actions .btn-icon.danger`, so every icon button that was not inside a
   table's action cell — the invoice line remover, the credit-note button —
   carried a class that did nothing. */
.btn-icon.danger:hover,
.btn-icon.danger:focus-visible {
    color: var(--danger-600);
    background: var(--danger-50);
}

/* Hint under a field. Was already used on a couple of pages with no rule
   behind it, so it rendered at body size and competed with the value. */
.form-help {
    display: block;
    margin-top: 5px;
    font-size: 11.5px;
    line-height: 1.45;
    color: var(--text-muted);
}

/* ---- .fields-underline ----
   Utility class. Apply to a card-body (or any container) to switch all
   inputs/selects inside to a Tripletex-style underline (no boxes).
   Used on header cards like "Bilagsdetaljer" where the form is simple
   and visual chrome should be minimal. Specificity-bumped via :not()
   chain so it beats the default `.form-control` rules above. */
.fields-underline .form-control,
.fields-underline input[type="text"]:not(.no-style),
.fields-underline input[type="email"]:not(.no-style),
.fields-underline input[type="number"]:not(.no-style),
.fields-underline input[type="date"]:not(.no-style),
.fields-underline input[type="month"]:not(.no-style),
.fields-underline input[type="search"]:not(.no-style),
.fields-underline input[type="tel"]:not(.no-style),
.fields-underline input[type="url"]:not(.no-style),
.fields-underline select:not([multiple]):not(.no-style),
.fields-underline textarea:not(.no-style) {
    height: 34px;
    padding: 0 0 4px;
    background: transparent !important;
    border: none !important;
    border-bottom: 1px solid var(--border-strong) !important;
    border-radius: 0 !important;
    box-shadow: none !important;
}
.fields-underline textarea:not(.no-style) {
    height: auto;
    min-height: 60px;
    padding: 4px 0 4px;
}
.fields-underline .form-control:focus,
.fields-underline input:not(.no-style):focus,
.fields-underline select:not(.no-style):focus,
.fields-underline textarea:not(.no-style):focus {
    border-bottom: 2px solid var(--primary-600) !important;
    box-shadow: none !important;
    padding-bottom: 3px;
    outline: none;
}
.fields-underline select:not([multiple]):not(.no-style) {
    appearance: none;
    -webkit-appearance: none;
    -moz-appearance: none;
    background-image: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6' viewBox='0 0 10 6' fill='none' stroke='%236B7280' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'%3e%3cpolyline points='1 1 5 5 9 1'%3e%3c/polyline%3e%3c/svg%3e") !important;
    background-repeat: no-repeat !important;
    background-position: right 2px center !important;
    background-size: 10px 6px !important;
    padding-right: 16px !important;
}
.fields-underline label,
.fields-underline .form-group label {
    font-size: 11px;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--text-muted);
    margin-bottom: 4px;
    font-weight: 500;
    /* LÅST I PIKSLER, ikke et forholdstall. Etiketten bytter skriftstørrelse
       når den flyter ned i feltet (11px → 13px), og med line-height: 1.5
       vokser boksen fra 16,5 til 19,5 px. Boksen blir stående i flyten, så
       feltet under starter tre piksler lenger ned enn naboen sitt — to felt
       på samme rad havner på hver sin grunnlinje alt etter om de er tomme.
       16,5 px er det 11px-etikettene allerede hadde, så ingenting flytter
       seg; det er bare den flytende tilstanden som kommer på linje. */
    line-height: 16.5px;
}

/* ---- Flytende etiketter -------------------------------------------------
   Etiketten ligger NEDE I FELTET så lenge feltet er tomt og uten fokus, og
   flyter opp i det man tar tak i det eller det har en verdi. Tomt skjema blir
   roligere: én tekst per felt i stedet for etikett og plassholder samtidig.

   FLYTTES MED transform, IKKE MED position. Etiketten beholder boksen sin i
   flyten øverst; transform maler den bare et annet sted. Det gir tre ting
   gratis: høyden på feltgruppa er den samme i alle tilstander (frigjorde vi
   plassen, ville skjemaet hoppet nedover mens man fyller det ut), ingen
   padding å reservere, og ingen spesifisitetskamp.

   Den kampen var reell. Første forsøk brukte position: absolute pluss
   padding-top på gruppa, og .fields-underline .form-row > .form-group
   { padding: 0 } — tre klasser mot mine to — slo den ut. På hver eneste
   rutenettbaserte side la etiketten seg da OPPÅ feltet.

   HINTET GÅR IKKE TAPT. 47 av feltene i appen har en plassholder som sier noe
   ETIKETTEN IKKE SIER — «f.eks. 6800», «Bare hvis den avviker fra
   kundeadressen». Den gjøres gjennomsiktig når feltet ikke har fokus, og
   kommer tilbake i det man begynner å skrive. Da står den der den er nyttig,
   framfor å konkurrere med etiketten hele tiden.

   HVA SOM IKKE FLYTER, og hvorfor:
     · nedtrekk — de har ingen tom tilstand å vise en etikett i, og nedtrekket
       viser sin egen «Velg …»-tekst.
     · dato, måned og klokkeslett — de tegner alltid dd.mm.åååå selv når de er
       tomme, så feltet er aldri visuelt ledig.
     · felt uten <label> — varelinjeradene har kolonneoverskrifter i stedet.
     · etiketter som OMSLUTTER sin egen kontroll — avkrysninger, radioknapper,
       opplastingssoner. Det finnes 30 av dem på 17 sider, og uten unntaket
       arvet kontrollen inni pointer-events: none og lot seg ikke klikke.

   :has() framfor å snu rekkefølgen på label og input i 140 felt over 20 sider.
   Ingen markup er rørt. */
.fields-underline .form-group:has(> label):not(:has(> label :is(input, select, textarea))) > label {
    display: block;
    max-width: 100%;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    transform-origin: left top;
    transition: transform var(--transition-fast),
                font-size var(--transition-fast),
                color var(--transition-fast);
}
/* Nede i feltet: leses som en plassholder, altså feltets egen skriftstørrelse
   og vanlig setningsform — ikke en liten kapitélbildetekst inni feltet.
   pointer-events: none så klikket går gjennom til feltet under. */
.fields-underline .form-group:has(> label):not(:has(> label :is(input, select, textarea))):has(> input:placeholder-shown:not(:focus)) > label,
.fields-underline .form-group:has(> label):not(:has(> label :is(input, select, textarea))):has(> textarea:placeholder-shown:not(:focus)) > label {
    transform: translateY(21px);
    font-size: 13px;                   /* samme som feltets egen tekst */
    text-transform: none;
    letter-spacing: 0;
    color: var(--text-subtle);
    pointer-events: none;
}
/* Datofeltene tegner dd.mm.åååå og er aldri visuelt tomme. */
.fields-underline .form-group:has(> label):has(> input[type="date"]) > label,
.fields-underline .form-group:has(> label):has(> input[type="month"]) > label,
.fields-underline .form-group:has(> label):has(> input[type="time"]) > label,
.fields-underline .form-group:has(> label):has(> input[type="datetime-local"]) > label {
    transform: none;
    font-size: 11px;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--text-muted);
    pointer-events: auto;
}
/* Hintet holder seg unna til man faktisk skriver i feltet. */
.fields-underline .form-group:has(> label) > input:not(:focus)::placeholder,
.fields-underline .form-group:has(> label) > textarea:not(:focus)::placeholder {
    color: transparent;
}

/* Replace Bootstrap col-md-* fixed-width layout with a CONTAINER-responsive
   flex layout. Bootstrap collapses cols based on VIEWPORT width (the md
   breakpoint), but our forms sit inside resizable panes where the container
   is what matters. Fields now wrap to the next row when the container gets
   narrow enough that their flex-basis can't fit. */
.fields-underline .form-row {
    display: flex;
    flex-wrap: wrap;
    gap: 14px 16px;
    margin: 0 0 8px;
}
.fields-underline .form-row > .form-group,
.fields-underline .form-row > [class*="col-"] {
    flex: 1 1 auto;
    min-width: 140px;
    max-width: 100%;
    padding: 0;
    margin-bottom: 0;
}
/* Hele skalaen, ikke bare halve: et felt med en col-klasse som ikke sto
   her fikk flex-basis: auto, vokste til full bredde og dyttet alt etter seg
   ned på hver sin linje. Det traff seks steder i appen. Verdiene under 140
   px er med for skalaens skyld — min-width over løfter dem dit uansett. */
.fields-underline .form-row > .col-md-1  { flex-basis: 60px; }
.fields-underline .form-row > .col-md-2  { flex-basis: 95px; }
.fields-underline .form-row > .col-md-3  { flex-basis: 130px; }
.fields-underline .form-row > .col-md-4  { flex-basis: 180px; }
.fields-underline .form-row > .col-md-5  { flex-basis: 220px; }
.fields-underline .form-row > .col-md-6  { flex-basis: 260px; }
.fields-underline .form-row > .col-md-7  { flex-basis: 310px; }
.fields-underline .form-row > .col-md-8  { flex-basis: 360px; }
.fields-underline .form-row > .col-md-9  { flex-basis: 410px; }
.fields-underline .form-row > .col-md-10 { flex-basis: 460px; }
.fields-underline .form-row > .col-md-11 { flex-basis: 510px; }
.fields-underline .form-row > .col-md-12 { flex-basis: 100%; }

/* File input — Bootstrap 4 uses .form-control-file */
.form-control-file {
    display: block;
    width: 100%;
    padding: 6px 0;
    font-size: 13px;
    color: var(--text);
}

/* ----- Tables ----- */
.table {
    width: 100%;
    margin-bottom: 16px;
    color: var(--text);
    border-collapse: separate;
    border-spacing: 0;
    font-size: 13px;
}
.table th {
    /* Plain tinted column header at rest; frosts (blurs the rows behind it)
       only when they scroll under the sticky header. No grey tint, sheen or
       bevel — just the normal surface-tint colour, made translucent so
       backdrop-filter has something to reveal on scroll.
       - position: sticky + top: var(--top-bar-height) parks it just below the
         navbar; z-index 5 sits above tbody rows, below the navbar.
       Header LABEL color is the regular text color, NOT primary-blue — blue is
       reserved for clickables. See DESIGN.md → primary-blue reservation. */
    background-color: color-mix(in srgb, var(--surface-tint) 75%, transparent);
    -webkit-backdrop-filter: saturate(180%) blur(20px);
            backdrop-filter: saturate(180%) blur(20px);
    position: sticky;
    top: var(--top-bar-height);
    z-index: 5;
    color: var(--text);
    font-weight: 600;
    font-size: 11px;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    text-align: left;
    padding: 10px 12px;
    border-bottom: 1px solid var(--border);
    white-space: nowrap;
}
.table td {
    padding: 12px;
    border-bottom: 1px solid var(--border);
    border-top: none;
    vertical-align: middle;
    color: var(--text);
}
.table tbody tr {
    transition: background-color var(--transition-fast);
}
.table tbody tr:hover {
    background-color: var(--surface-tint);
}
.table tbody tr:last-child td { border-bottom: none; }

.table td.number, .table th.number,
.table td.amount, .table th.amount,
.table td.text-right, .table th.text-right {
    text-align: right;
    font-variant-numeric: tabular-nums;
}

/* Striped table — alternative pattern (alternating tinted rows). Useful for
   large data tables where row separation matters more than scanning lines. */
.table-striped tbody tr:nth-of-type(odd) { background-color: var(--surface-tint); }
.table-striped tbody tr:hover { background-color: var(--surface-tint-strong); }

/* Sticky table headers — opt-in via .table-sticky on a wrapper */
.table-sticky { max-height: 600px; overflow: auto; }
.table-sticky thead th {
    position: sticky;
    top: 0;
    background-color: var(--surface-tint);
    z-index: 1;
    box-shadow: inset 0 -1px 0 var(--border);
}

/* Bootstrap also ships .thead-light — neutralize its grey backdrop.
   !important needed because Bootstrap's `.thead-light th` is itself
   specified with high specificity; the frosted glass + sticky come
   from the base .table th rule above and stay in effect. */
.thead-light th, thead.thead-light th {
    /* Match the frosted-glass bg from .table th (kept in sync). */
    background-color: color-mix(in srgb, var(--surface-tint) 75%, transparent) !important;
    color: var(--text) !important;
}

/* "Reference" table — the polished pattern for transactional data.
   Compact, expandable rows with right-aligned amounts and inline actions.
   Apply via class .table.table-data on the <table> element.
   Inherits the frosted-glass + sticky behaviour from .table th above,
   we just override padding/font weight here. */
.table-data thead th {
    padding: 11px 14px;
    font-weight: 600;
    /* Header LABEL color = text. Blue is reserved for clickables. */
    color: var(--text);
    border-top: 1px solid var(--border);
}
.table-data thead th:first-child { border-top-left-radius: var(--radius-md); }
.table-data thead th:last-child  { border-top-right-radius: var(--radius-md); }
.table-data tbody td {
    padding: 12px 14px;
    border-bottom: 1px solid var(--border);
    vertical-align: middle;
}
.table-data tbody tr { cursor: default; }
.table-data tbody tr.is-expandable { cursor: pointer; }
.table-data tbody tr:hover { background-color: var(--surface-tint); }
.table-data tbody tr.is-expanded { background-color: var(--surface-tint); }
.table-data tbody tr.is-expanded + tr.detail-row { background-color: var(--surface-tint); }

/* Detail (drill-down) row that appears under an expanded data row */
.table-data tr.detail-row > td {
    padding: 0 14px 14px;
    border-bottom: 1px solid var(--border);
}
.table-data tr.detail-row .detail-card {
    background-color: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    padding: 12px 14px;
    box-shadow: var(--shadow-sm);
}
.table-data tr.detail-row table {
    width: 100%;
    font-size: 12px;
    margin: 0;
}
.table-data tr.detail-row table th,
.table-data tr.detail-row table td {
    background: transparent;
    /* Nested detail-row tables shouldn't stick — they're already in an
       expanded row inside the parent table. Unset the sticky + glass
       from the base .table th rule. */
    position: static;
    -webkit-backdrop-filter: none;
            backdrop-filter: none;
    padding: 6px 8px;
    border-bottom: 1px dashed var(--border);
    text-transform: none;
    letter-spacing: 0;
    font-size: 12px;
    color: var(--text);
}
.table-data tr.detail-row table tr:last-child td {
    border-bottom: none;
}
.table-data tr.detail-row table thead th {
    color: var(--text-muted);
    font-weight: 500;
    font-size: 11px;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    background: transparent;
}

/* Expand caret in the first column. Rotates when row is expanded. */
.table-data .expand-caret {
    display: inline-flex;
    width: 18px;
    height: 18px;
    align-items: center;
    justify-content: center;
    color: var(--text-muted);
    transition: transform var(--transition-fast);
}
.table-data tr.is-expanded .expand-caret { transform: rotate(90deg); color: var(--primary-600); }

/* Inline cell badges (lines count, status pills) */
.cell-badge {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    padding: 2px 7px;
    font-size: 11px;
    font-weight: 500;
    color: var(--text-muted);
    background-color: var(--surface-alt);
    border-radius: var(--radius-pill);
}
.cell-badge--blue { color: var(--primary-700); background-color: var(--primary-50); }

/* Row actions: icon buttons, right-aligned in the last cell.
   NEVER set display:flex/inline-flex on a <td> — a flex cell drops out of
   table layout, so it stops stretching to the row height. Its bottom border
   then lands short of the neighbouring cells, which shows up as a visible
   step in the row separator on any row taller than the buttons (two-line
   content, a wrapped badge, etc). Lay the buttons out inline instead so the
   cell stays a real table-cell.
   font-size:0 collapses the whitespace between inline buttons so the spacing
   stays the intended 2px; .btn sets its own font-size, so nothing inherits it. */
.row-actions { text-align: right; white-space: nowrap; font-size: 0; }
.row-actions > * { vertical-align: middle; }
.row-actions > * + * { margin-left: 2px; }
.row-actions .btn-icon { color: var(--text-muted); }
.row-actions .btn-icon:hover { color: var(--text); background-color: var(--surface); }
.row-actions .btn-icon.danger:hover { color: var(--danger-600); background-color: var(--danger-50); }

/* Dialogen (.bank-modal, DESIGN.md §3). Siden viser og skjuler den med
   style.display = 'block' / 'none', ikke 'flex': dialogen står midt på med
   margin auto. Reglene lå før som en kopi i hver side, kopiene hadde drevet
   fra hverandre (6, 8 og 10vh fra toppen, 12 eller 14px under hodet), og
   MVA-meldinger hadde ingen, så dialogen der ble en vanlig blokk i siden.
   Det en side trenger annerledes, som en bredere dialog eller mer høyde til
   et langt skjema, skriver den selv, avgrenset med dialogens id:
     #ibItemsModal .bank-modal__dialog { max-width: 1020px; margin-top: 6vh; max-height: 88vh; } */
.bank-modal {
    display: none;
    position: fixed;
    inset: 0;
    background: var(--overlay);
    z-index: 2000;
}
.bank-modal__dialog {
    background: var(--surface);
    border-radius: var(--radius-md);
    padding: 20px;
    margin: 10vh auto;
    max-width: 520px;
    max-height: 80vh;
    overflow-y: auto;
    box-shadow: var(--shadow-lg);
}
.bank-modal__header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 14px;
    padding-bottom: 10px;
    border-bottom: 1px solid var(--border);
}
.bank-modal__title { margin: 0; font-size: 16px; font-weight: 600; }
.bank-modal__footer {
    display: flex;
    justify-content: flex-end;
    align-items: center;
    flex-wrap: wrap;
    gap: 8px;
    margin-top: 16px;
    padding-top: 12px;
    border-top: 1px solid var(--border);
}

/* A table inside a modal must NOT use the app's sticky header. The sticky
   offset is measured against the viewport (top: var(--top-bar-height), so it
   sits under the navbar), but a modal has its own scroll container — the
   header then floats into the middle of the dialog and covers the first rows.
   That holds for every dialog, not just Bootstrap's .modal: the plain-CSS
   .bank-modal pattern and page dialogs (role="dialog") scroll the same way.
   A table that should keep its header inside a dialog opts back in with
   .table-sticky, as on the page. */
.modal .table-data thead th,
.modal .table thead th,
.bank-modal .table thead th,
[role="dialog"] .table thead th {
    position: static;
    top: auto;
}
[role="dialog"] .table-sticky thead th,
.bank-modal .table-sticky thead th {
    position: sticky;
    top: 0;
}

/* Same inside Bootstrap's .table-responsive: overflow-x:auto makes the
   wrapper a scroll container in BOTH axes, so it — not the page — becomes
   the sticky header's scrollport. The header is then held --top-bar-height
   below the wrapper's own top edge, i.e. shifted down over the first rows,
   whether or not the page has scrolled. A table that should keep its header
   while its body scrolls goes in a .table-sticky wrapper (top: 0) instead. */
.table-responsive .table-data thead th,
.table-responsive .table thead th {
    position: static;
    top: auto;
}

/* Toolbar above a table: search box on the left, result count on the right.
   Shared so every list page gets the same search affordance (accounts.html
   has its own scoped copy that still wins on specificity). */
.table-toolbar {
    display: flex;
    align-items: center;
    gap: 12px;
    flex-wrap: wrap;
    margin-bottom: 12px;
}
.toolbar-search {
    position: relative;
    flex: 1 1 280px;
    max-width: 420px;
}
.toolbar-search input.form-control { padding-left: 40px; }
.toolbar-search .material-symbols-rounded,
.toolbar-search .toolbar-search__icon {
    position: absolute;
    left: 12px;
    top: 50%;
    transform: translateY(-50%);
    color: var(--text-muted);
    font-size: 18px;
    pointer-events: none;
    z-index: 2;
}
.table-toolbar__count {
    font-size: 12.5px;
    color: var(--text-muted);
    font-variant-numeric: tabular-nums;
}

/* Wrap a table in .table-card for the panel look */
.table-card {
    background-color: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    overflow: hidden;
}
.table-card .table { margin-bottom: 0; }
.table-card .table th:first-child,
.table-card .table td:first-child { padding-left: 16px; }
.table-card .table th:last-child,
.table-card .table td:last-child { padding-right: 16px; }

/* ----- Cards ----- */
.card {
    background-color: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    box-shadow: none;
    transition: none;
}
.card:hover { box-shadow: none; }
.card-header {
    background-color: var(--surface-tint);
    border-bottom: 1px solid var(--border);
    padding: 14px 18px;
    font-weight: 600;
    font-size: 14px;
    color: var(--text);
    border-top-left-radius: var(--radius-md);
    border-top-right-radius: var(--radius-md);
}
.card-title {
    font-size: 15px;
    font-weight: 600;
    margin: 0 0 4px;
    color: var(--text);
}
.card-body { padding: 18px; }
.card-footer {
    background-color: var(--surface-alt);
    border-top: 1px solid var(--border);
    padding: 12px 18px;
}

/* ----- Modals ----- */
.modal-content {
    border-radius: var(--radius-md);
    border: 1px solid var(--border);
    background-color: var(--surface);
    box-shadow: var(--shadow-lg);
}
.modal-header {
    border-bottom: 1px solid var(--border);
    padding: 16px 20px;
}
.modal-title { font-size: 16px; font-weight: 600; }
.modal-body { padding: 20px; }
.modal-footer {
    border-top: 1px solid var(--border);
    padding: 12px 20px;
    gap: 8px;
}

.close {
    color: var(--text-muted);
    opacity: 0.7;
    font-size: 22px;
    font-weight: 400;
    text-shadow: none;
}
.close:hover { color: var(--text); opacity: 1; }

/* ----- Badges / chips ----- */
.badge {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    padding: 2px 8px;
    font-size: 11px;
    font-weight: 500;
    line-height: 1.4;
    border-radius: var(--radius-pill);
    background-color: var(--surface-alt);
    color: var(--text);
    border: 1px solid var(--border);
}
.badge-primary { background-color: var(--primary-50); color: var(--primary-700); border-color: transparent; }
.badge-success { background-color: var(--success-50); color: var(--success-700); border-color: transparent; }
.badge-warning { background-color: var(--warning-50); color: var(--warning-700); border-color: transparent; }
.badge-danger  { background-color: var(--danger-50);  color: var(--danger-700);  border-color: transparent; }
.badge-info    { background-color: var(--info-50);    color: var(--info-700);    border-color: transparent; }

/* ----- Alerts ----- */
.alert {
    padding: 12px 16px;
    margin-bottom: 16px;
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    font-size: 13px;
    color: var(--text);
    background-color: var(--surface);
    display: flex;
    align-items: flex-start;
    gap: 10px;
}
.alert-success { background-color: var(--success-50); border-color: var(--success-500); color: var(--success-700); }
.alert-danger  { background-color: var(--danger-50);  border-color: var(--danger-500);  color: var(--danger-700); }
.alert-warning { background-color: var(--warning-50); border-color: var(--warning-500); color: var(--warning-700); }
.alert-info    { background-color: var(--info-50);    border-color: var(--info-500);    color: var(--info-700); }

/* ----- List groups ----- */
.list-group {
    border-radius: var(--radius-md);
    overflow: hidden;
}
.list-group-item {
    background-color: var(--surface);
    border: 1px solid var(--border);
    border-bottom-width: 0;
    padding: 12px 14px;
    color: var(--text);
    transition: background-color var(--transition-fast);
}
.list-group-item:first-child {
    border-top-left-radius: var(--radius-md);
    border-top-right-radius: var(--radius-md);
}
.list-group-item:last-child {
    border-bottom-width: 1px;
    border-bottom-left-radius: var(--radius-md);
    border-bottom-right-radius: var(--radius-md);
}
.list-group-item.active {
    background-color: var(--primary-50);
    color: var(--primary-700);
    border-color: var(--primary-100);
    z-index: auto;
}
.list-group-item-action {
    cursor: pointer;
}
.list-group-item-action:hover {
    background-color: var(--surface-alt);
}

/* ----- Material Symbols icon font ----- */
.material-symbols-rounded {
    font-variation-settings: 'FILL' 0, 'wght' 400, 'GRAD' 0, 'opsz' 24;
    font-size: 18px;
    vertical-align: middle;
    user-select: none;
}

/* ----- Utility classes ----- */
.text-muted { color: var(--text-muted) !important; }
.text-subtle { color: var(--text-subtle) !important; }
.text-success { color: var(--success-700) !important; }
.text-danger  { color: var(--danger-600) !important; }
.text-warning { color: var(--warning-700) !important; }
.text-info    { color: var(--info-700) !important; }

.bg-light, .bg-surface-alt { background-color: var(--surface-alt) !important; }
.bg-white { background-color: var(--surface) !important; }

.shadow-sm { box-shadow: var(--shadow-sm) !important; }
.shadow    { box-shadow: var(--shadow-md) !important; }
.shadow-lg { box-shadow: var(--shadow-lg) !important; }

/* Numeric column convenience */
.num, .number { font-variant-numeric: tabular-nums; text-align: right; }

/* Compatibility — keep Bootstrap helpers working naturally */
.mr-1 { margin-right: 4px; }
.mr-2 { margin-right: 8px; }
.mr-3 { margin-right: 12px; }
.ml-1 { margin-left: 4px; }
.ml-2 { margin-left: 8px; }
.ml-3 { margin-left: 12px; }

/* ----- Empty states ----- */
.empty-state {
    padding: 48px 24px;
    text-align: center;
    color: var(--text-muted);
}
.empty-state .material-symbols-rounded {
    font-size: 48px;
    color: var(--text-subtle);
    margin-bottom: 12px;
    display: block;
}
.empty-state__title { font-size: 15px; font-weight: 500; color: var(--text); margin-bottom: 4px; }
.empty-state__hint { font-size: 13px; }

/* ----- Skeleton loader ----- */
@keyframes skeleton-shimmer {
    0%   { background-position: -200px 0; }
    100% { background-position: calc(200px + 100%) 0; }
}
.skeleton {
    display: inline-block;
    height: 12px;
    background: linear-gradient(90deg, var(--surface-alt) 0%, var(--gray-150) 50%, var(--surface-alt) 100%);
    background-size: 200px 100%;
    background-repeat: no-repeat;
    border-radius: var(--radius-sm);
    animation: skeleton-shimmer 1.4s ease-in-out infinite;
}

/* ----- Drill-down breadcrumb -----
   The way back from a detail view: a text link with a left arrow in the
   accent, sitting top-left under the page header. Not a button — a button
   competes with the page's real actions, and this is navigation.

   Lifted here from accounts.html, where it started, because it is the house
   pattern for every drill-down rather than one page's furniture. Use it on
   any page reached from a list. */
.drilldown-breadcrumb {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-bottom: 12px;
    font-size: 14px;
    color: var(--text-muted);
    line-height: 1.4;
}
/* Explicit flex with the icon vertically centred, so the underline — which
   renders only under the text, the icon being its own inline-flex child —
   does not look misaligned with the arrow. The icon is nudged up 1px to sit
   optically level with the text. */
.drilldown-breadcrumb .back-link {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    color: var(--primary-600);
    font-weight: 500;
    text-decoration: none;
}
.drilldown-breadcrumb .back-link .material-symbols-rounded {
    font-size: 18px;
    line-height: 1;
    position: relative;
    top: -1px;
}
.drilldown-breadcrumb .back-link .back-link__text {
    text-decoration: underline;
    text-underline-offset: 3px;
    text-decoration-thickness: 1px;
}
.drilldown-breadcrumb .back-link:hover .back-link__text { text-decoration-thickness: 2px; }
.drilldown-breadcrumb .separator { color: var(--border-strong); }
.drilldown-breadcrumb .current { color: var(--text); font-weight: 500; }

/* ----- Kebab menu -----
   Row actions collapsed behind one ⋮ trigger. Lives here because it was
   copy-pasted into voucher_inbox.html and bank_matching.html, and the two
   copies had already drifted apart (240px vs 220px, and a hardcoded rgba
   shadow instead of the token).

   The panel is `position: fixed` on purpose: a row-level menu inside a table
   with `overflow: auto` gets clipped by the scroll container if it is
   absolutely positioned. Fixed escapes it, and the opener positions the panel
   from the trigger's bounding rect. z-index sits above the floating action
   bar (1100) and below modals. */
.kebab-menu { position: relative; display: inline-block; }
.kebab-menu__panel {
    position: fixed;
    min-width: 240px;
    padding: 4px 0;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    box-shadow: var(--shadow-md);
    z-index: 1500;
}
.kebab-menu__item {
    display: flex;
    align-items: center;
    gap: 10px;
    width: 100%;
    padding: 8px 14px;
    font-size: 13px;
    text-align: left;
    color: var(--text);
    background: transparent;
    border: none;
    cursor: pointer;
}
.kebab-menu__item:hover:not(:disabled) { background: var(--surface-tint); }
.kebab-menu__item:disabled { color: var(--text-subtle); cursor: not-allowed; }
.kebab-menu__item.danger { color: var(--danger-700); }
.kebab-menu__item.danger:hover:not(:disabled) { background: var(--danger-50); }
.kebab-menu__item .material-symbols-rounded { font-size: 18px; }
.kebab-menu__sep { height: 1px; margin: 4px 0; background: var(--border); }

/* ----- Compatibility: Bootstrap-style structural classes ----- */
/* (Bootstrap 4 still loaded for grid + utility — these are visual overrides only) */
.btn-block { display: flex; width: 100%; }

/* Tooltip-style title hint for icon-only buttons (uses native title) */
[data-tooltip] {
    position: relative;
}

/* Subtle dividers */
hr, .divider {
    border: 0;
    border-top: 1px solid var(--border);
    margin: 16px 0;
}

/* ============================================================ */
/* Period selector — shared component for saldobalanse, hovedbok,
   and any other report that needs a date-range picker. JS lives
   in /static/js/period_selector.js; consumers render an empty
   <div data-period-selector></div> and the JS fills it in. */
/* ============================================================ */
.period-bar {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 16px;
    padding: 10px 14px;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
}
.period-bar__pills {
    display: inline-flex;
    background: var(--surface-alt);
    border-radius: var(--radius-md);
    padding: 2px;
}
.period-bar__pill {
    border: none;
    background: transparent;
    color: var(--text-muted);
    font-size: 13px;
    font-weight: 500;
    padding: 5px 12px;
    border-radius: var(--radius-sm);
    cursor: pointer;
    transition: background-color var(--transition-fast), color var(--transition-fast);
}
.period-bar__pill:hover:not(.is-active) { color: var(--text); }
.period-bar__pill.is-active {
    background: var(--surface);
    color: var(--primary-600);
    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
}
.period-bar__nav {
    display: inline-flex;
    align-items: center;
    gap: 4px;
}
.period-bar__nav .btn-icon {
    width: 28px;
    height: 28px;
}
.period-bar__label {
    min-width: 160px;
    text-align: center;
    font-size: 14px;
    font-weight: 600;
    color: var(--text);
}
.period-bar__custom {
    display: inline-flex;
    align-items: center;
    gap: 8px;
}
.period-bar__custom input[type="date"] {
    border: none;
    border-bottom: 1px solid var(--border);
    background: transparent;
    padding: 4px 0;
    font-size: 13px;
    color: var(--text);
    outline: none;
}
.period-bar__custom input[type="date"]:focus {
    border-bottom-color: var(--primary-600);
}
.period-bar__custom .arrow {
    color: var(--text-muted);
    font-size: 13px;
}
.period-bar__spacer { flex: 1; }
.period-bar__actions {
    display: inline-flex;
    align-items: center;
    gap: 6px;
}

/* ============================================================ */
/* Tripletex-style horizontal ribbon — rendered by PeriodSelector
   below the pill row. Each row (Year/Quarter/Termin/Month) lays
   out cells in proportion to the months they span, so columns
   align vertically. Click a cell to set the period to that
   cell's range; drag the two handles to fine-tune to a custom
   month-aligned range. */
/* ============================================================ */
.period-bar { flex-direction: column; align-items: stretch; }
.period-bar__top {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 16px;
}
/* Ribbon is collapsed by default — clicking the period label toggles it.
   width:100% + max-width:100% keep its scrollable area inside the card so
   the inner timeline can be 5x12 months wide without overflowing the page. */
.period-ribbon {
    position: relative;
    overflow-x: auto;
    overflow-y: visible;
    margin-top: 12px;
    padding-top: 14px;
    padding-bottom: 6px;
    width: 100%;
    max-width: 100%;
    box-sizing: border-box;
    scrollbar-width: thin;
    display: none;
}
.period-bar.is-ribbon-open .period-ribbon { display: block; }

/* Clickable period label — small affordance so users discover the toggle. */
.period-bar__label {
    cursor: pointer;
    padding: 2px 8px;
    border-radius: var(--radius-sm);
    transition: background-color var(--transition-fast);
}
.period-bar__label:hover { background: var(--surface-tint); }

/* ============================================================
   MVA-låst — locked VAT selector indicator
   ============================================================
   Used on bilag/leverandørfaktura lines whose chosen account has
   vat_locked = true on the chart of accounts. The wrapper holds
   the <select> + an absolute-positioned lock icon. */
.vat-lock-wrap.is-vat-locked select:disabled,
.vat-lock-wrap select:disabled {
    background-color: var(--surface-alt);
    color: var(--text-muted);
    cursor: not-allowed;
}
.vat-lock-icon {
    cursor: help;
    user-select: none;
}
.period-bar__label::after {
    content: '';
    display: inline-block;
    margin-left: 6px;
    width: 0;
    height: 0;
    border-left: 4px solid transparent;
    border-right: 4px solid transparent;
    border-top: 4px solid var(--text-muted);
    transform: translateY(-1px);
    transition: transform var(--transition-fast);
}
.period-bar.is-ribbon-open .period-bar__label::after {
    transform: translateY(-1px) rotate(180deg);
}
.period-ribbon__inner {
    position: relative;       /* anchor for absolutely-positioned highlight + handles */
    display: flex;
    flex-direction: column;
    /* width set in JS = months * MONTH_W */
}
.period-ribbon__row {
    display: flex;
    flex-direction: row;
    height: 26px;
}
.period-ribbon__cell {
    box-sizing: border-box;
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    font-size: 11px;
    color: var(--text-muted);
    background: var(--surface);
    border-right: 1px solid var(--border);
    border-bottom: 1px solid var(--border);
    user-select: none;
    transition: background-color var(--transition-fast), color var(--transition-fast);
}
.period-ribbon__cell:first-child { border-left: 1px solid var(--border); }
.period-ribbon__row:first-child .period-ribbon__cell { border-top: 1px solid var(--border); }
.period-ribbon__cell:hover { background: var(--surface-tint); color: var(--text); }
.period-ribbon__cell--year   { font-weight: 600; color: var(--text); }
.period-ribbon__cell--quarter { font-weight: 500; }
.period-ribbon__cell--month  { font-size: 11px; }

/* Highlight band — spans the selected range across every row. */
.period-ribbon__highlight {
    position: absolute;
    top: 0;
    bottom: 0;
    background: rgba(10, 65, 250, 0.10);
    border-left: 2px solid var(--primary-600);
    border-right: 2px solid var(--primary-600);
    pointer-events: none;
    z-index: 1;
    transition: left 60ms linear, width 60ms linear;
}

/* Draggable from/to handles — sit on the side edges of the highlight,
   carry a date label above. */
.period-ribbon__handle {
    position: absolute;
    top: -14px;
    width: 22px;
    height: calc(100% + 14px);
    cursor: ew-resize;
    z-index: 2;
    transform: translateX(-50%);
}
.period-ribbon__handle::after {
    content: '';
    position: absolute;
    top: 14px;
    bottom: 0;
    left: 50%;
    width: 6px;
    transform: translateX(-50%);
    background: var(--primary-600);
    border-radius: 2px;
}
.period-ribbon__handle-label {
    position: absolute;
    top: -2px;
    left: 50%;
    transform: translateX(-50%);
    font-size: 10px;
    font-weight: 600;
    color: var(--primary-600);
    background: var(--surface);
    padding: 0 4px;
    white-space: nowrap;
    pointer-events: none;
    border-radius: var(--radius-sm);
}
body.ribbon-dragging { cursor: ew-resize; user-select: none; }
body.ribbon-dragging * { cursor: ew-resize !important; user-select: none !important; }

/* ----- Forhåndsutfylt -----
   Et felt systemet har fylt ut — fra dokumentet, fra et annet felt, fra
   forrige føring — får en svak blå bakgrunn til brukeren endrer det selv.
   Da ser man hva man bør se over, og hva man har skrevet selv. Settes og
   fjernes av window.markAutofilled() i base.html, aldri for hånd.

   Tonen strekkes 4 px ut til venstre med en skygge i stedet for med padding:
   padding flytter teksten, og da hoppet den sidelengs i det man begynte å
   skrive og tonen forsvant. Samme spesifisitet som understrek-reglene, men
   senere i fila — derfor vinner den også når feltet har fokus. */
.fields-underline input.is-autofilled:not(.no-style),
.fields-underline textarea.is-autofilled:not(.no-style) {
    background-color: var(--primary-50) !important;
    box-shadow: -4px 0 0 var(--primary-50) !important;
}
.fields-underline select.is-autofilled:not(.ts-hidden-accessible):not(.no-style) {
    background-color: var(--primary-50) !important;
}

/* ----- Ugyldig verdi -----
   Rød tekst og rød strek, og en liten tekst under feltet. Man kan gå videre
   fra feltet — det er bokføringen som stopper, ikke tabulatoren. Bootstraps
   is-invalid-ikon og -ramme slår ikke gjennom understrek-stilen, så fargen
   settes her. */
.fields-underline input.is-invalid:not(.no-style) {
    color: var(--danger-600) !important;
    border-bottom-color: var(--danger-500) !important;
}
.field-error {
    display: block;
    margin-top: 3px;
    font-size: 11.5px;
    line-height: 1.3;
    color: var(--danger-600);
}
.field-error[hidden] { display: none; }

/* ----- Enhetsregisteret (REGLER §37) -----
   Boksen under org.nr. i firmaprofilen og på kunde- og leverandørkortet, og
   forslagene under navnefeltet. Fylles av static/js/brreg.js. */
.brreg {
    margin: -6px 0 10px;
    padding: 10px 12px;
    font-size: 13px;
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    background: var(--surface-alt);
}
.brreg[hidden] { display: none; }
.brreg__head { display: flex; align-items: center; gap: 8px; min-height: 28px; }
.brreg__label {
    font-size: 10.5px; font-weight: 600; letter-spacing: .04em; text-transform: uppercase;
    color: var(--text-muted);
}
.brreg__name { font-weight: 500; }
.brreg__head .btn-icon { margin-left: auto; }
.brreg__notes { list-style: none; margin: 4px 0 0; padding: 0; }
.brreg__notes li {
    display: flex; align-items: center; flex-wrap: wrap; gap: 4px 10px; margin-top: 6px;
    color: var(--text-muted);
}
.brreg__notes li.is-warn { color: var(--warning-700); }
.brreg__notes li.is-bad { color: var(--danger-700); }
.brreg-chip {
    display: inline-block; margin: 4px 4px 0 0; padding: 1px 8px; border-radius: var(--radius-pill);
    font-size: 10.5px; font-weight: 600; letter-spacing: .04em; text-transform: uppercase;
}
.brreg-chip--ok { background: var(--success-50); color: var(--success-700); }
.brreg-chip--muted { background: var(--surface-tint); color: var(--text-muted); }
.brreg-chip--warn { background: var(--warning-50); color: var(--warning-700); }
.brreg-chip--bad { background: var(--danger-50); color: var(--danger-700); }
.brreg-forslag {
    position: absolute; left: 0; right: 0; top: 100%; z-index: 1050;
    list-style: none; margin: 2px 0 0; padding: 4px 0;
    max-height: 320px; overflow-y: auto;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    box-shadow: var(--shadow-md);
}
.brreg-forslag[hidden] { display: none; }
.brreg-forslag li { display: flex; flex-direction: column; padding: 6px 12px; cursor: pointer; }
.brreg-forslag li.is-active,
.brreg-forslag li:hover { background: var(--primary-50); }
.brreg-forslag__navn { font-size: 13px; color: var(--text); }
.brreg-forslag__meta { font-size: 11.5px; color: var(--text-muted); font-variant-numeric: tabular-nums; }
.brreg-forslag__status { color: var(--danger-700); }

/* ----- Faner -----
   Husets fanelinje: understreket aktiv fane i primaerfargen, ikke Bootstrap
   nav-tabs. Kom fra bilagsfoeringen; staar her fordi fakturasiden bruker den
   samme, og to kopier av samme regel driver fra hverandre. */
.tabs-bar {
    display: flex;
    gap: 4px;
    margin-bottom: 12px;
    border-bottom: 1px solid var(--border);
}
.tab-btn {
    background: transparent;
    border: none;
    padding: 10px 16px;
    font-size: 13px;
    font-weight: 500;
    color: var(--text-muted);
    cursor: pointer;
    border-bottom: 2px solid transparent;
    transition: color var(--transition-fast), border-color var(--transition-fast);
}
.tab-btn:hover { color: var(--text); }
.tab-btn.is-active {
    color: var(--primary-700);
    border-bottom-color: var(--primary-600);
}
.tab-btn .tab-count {
    margin-left: 4px;
    font-size: 11px;
    color: var(--text-subtle);
    font-weight: 400;
}
.tab-btn.is-active .tab-count { color: var(--primary-500); }

/* "Legg til linje" — en stiplet plussknapp UNDER radene, ikke en merket knapp
   oppe i korthodet. En ny rad hører hjemme der neste rad kommer, og den
   stiplede kanten sier «her er det plass til mer» uten å konkurrere med
   kortets egne handlinger. Ingen tekst: pluss under en tabell er entydig.
   Kom fra bilagsføringen; står her fordi fakturaskjemaet bruker den samme. */
.btn-icon-add {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 32px;
    height: 32px;
    border-radius: var(--radius-sm);
    border: 1px dashed var(--border-strong);
    background: transparent;
    color: var(--text-muted);
    font-size: 18px;
    line-height: 1;
    cursor: pointer;
    transition: background-color var(--transition-fast),
                border-color var(--transition-fast),
                color var(--transition-fast);
}
.btn-icon-add:hover {
    background-color: var(--primary-50);
    border-color: var(--primary-500);
    color: var(--primary-700);
}

/* ============================================================================
   Infotavle (info board)
   ========================================================================= */

/* Shared slide-over shell. The #themePrefs drawer in base.html predates this
   and keeps its own copy; new drawers use this one rather than adding a third
   near-identical block. Same geometry and timings, so the two feel identical. */
.side-drawer {
    position: fixed;
    inset: 0;
    z-index: 1300;          /* above modals (1050), below alerts — as themePrefs */
    pointer-events: none;
}
.side-drawer[hidden] { display: none !important; }
.side-drawer__backdrop {
    position: absolute;
    inset: 0;
    background: rgba(0, 0, 0, 0.3);
    opacity: 0;
    transition: opacity 200ms ease-out;
    pointer-events: auto;
}
.side-drawer.is-open .side-drawer__backdrop { opacity: 1; }
.side-drawer__panel {
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    width: 420px;           /* wider than themePrefs: this one holds prose */
    max-width: 94vw;
    background: var(--surface);
    border-left: 1px solid var(--border);
    display: flex;
    flex-direction: column;
    transform: translateX(100%);
    transition: transform 220ms ease-out;
    pointer-events: auto;
    box-shadow: -8px 0 24px rgba(15, 23, 42, 0.06);
}
.side-drawer.is-open .side-drawer__panel { transform: translateX(0); }
.side-drawer__header {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 12px;
    padding: 16px 20px 12px;
    border-bottom: 1px solid var(--border);
}
.side-drawer__title { margin: 0; font-size: 16px; font-weight: 600; }
.side-drawer__subtitle { margin-top: 2px; font-size: 12px; color: var(--text-muted); }
.side-drawer__body { flex: 1 1 auto; overflow-y: auto; padding: 16px 20px; }
.side-drawer__footer {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    padding: 12px 20px;
    border-top: 1px solid var(--border);
}

/* Nav button badge — count of posts flagged important, amber when the facts
   are overdue for confirmation. */
.info-nav-btn { position: relative; }
.info-nav-btn__badge {
    position: absolute;
    top: 1px;
    right: 1px;
    min-width: 15px;
    height: 15px;
    padding: 0 4px;
    border-radius: var(--radius-pill);
    background: var(--primary-600);
    color: #fff;
    font-size: 9.5px;
    font-weight: 700;
    line-height: 15px;
    text-align: center;
    pointer-events: none;
}
.info-nav-btn__badge[hidden] { display: none !important; }
.info-nav-btn__badge.is-stale { background: var(--warning-600); }

/* ----- Post cards (shared by the drawer and the page) ----- */
.info-post {
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    background: var(--surface);
    padding: 12px 14px;
    margin-bottom: 10px;
}
.info-post { --info-flate: var(--surface); }
.info-post.is-important { --info-flate: var(--warning-50); border-color: var(--warning-200); background: var(--warning-50); }
.info-post__head {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 8px;
}
.info-post__title { margin: 0; font-size: 14px; font-weight: 600; line-height: 1.35; }
.info-post__meta {
    margin-top: 3px;
    font-size: 11.5px;
    color: var(--text-muted);
    display: flex;
    align-items: center;
    gap: 6px;
    flex-wrap: wrap;
}
.info-meta__del + .info-meta__del::before { content: "·"; content: "·" / ""; margin-right: 6px; }
.info-post__body {
    margin-top: 8px;
    font-size: 13px;
    line-height: 1.55;
    color: var(--text);
    overflow-wrap: anywhere;
}
.info-post__body p { margin: 0 0 8px; }
.info-post__body p:last-child { margin-bottom: 0; }
.info-post__body ul,
.info-post__body ol { margin: 0 0 8px; padding-left: 20px; }
.info-post__body li { margin-bottom: 3px; }
.info-post__body code {
    background: var(--surface-alt);
    border-radius: 4px;
    padding: 1px 4px;
    font-size: 12px;
}
.info-post__body a { color: var(--primary-700); text-decoration: underline; }
.ib-md-img {
    max-width: 100%;
    height: auto;
    border-radius: var(--radius-sm);
    border: 1px solid var(--border);
    margin: 6px 0;
    display: block;
}

/* "Shared with client" must be impossible to miss — it is the whole difference
   between a private note and something the client reads. */
.info-visibility {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    padding: 2px 8px;
    border-radius: var(--radius-pill);
    font-size: 11px;
    font-weight: 600;
    white-space: nowrap;
}
.info-visibility .material-symbols-rounded { font-size: 13px; }
.info-visibility--internal { color: var(--text-muted); background: var(--surface-alt); }
.info-visibility--shared { color: #047857; background: var(--success-50); }

.info-attachments { margin-top: 10px; display: flex; flex-wrap: wrap; gap: 6px; }
.info-attachment {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    padding: 4px 9px;
    border: 1px solid var(--border);
    border-radius: var(--radius-pill);
    background: var(--surface-alt);
    font-size: 11.5px;
    color: var(--text);
    text-decoration: none;
    max-width: 100%;
}
.info-attachment:hover { border-color: var(--primary-600); color: var(--primary-700); text-decoration: none; }
.info-attachment .material-symbols-rounded { font-size: 15px; color: var(--text-muted); }
.info-attachment__name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* ----- Facts panel ----- */
.info-facts-group { margin-bottom: 22px; }
.info-facts-group__title {
    font-size: 11px;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--text-muted);
    font-weight: 600;
    margin: 0 0 8px;
}
.info-fact {
    display: grid;
    grid-template-columns: minmax(150px, 34%) 1fr;
    gap: 12px;
    padding: 9px 0;
    border-bottom: 1px solid var(--border);
    align-items: start;
}
.info-fact:last-child { border-bottom: none; }
.info-fact__label { font-size: 12.5px; color: var(--text-muted); line-height: 1.4; }
.info-fact__value { font-size: 13.5px; color: var(--text); white-space: pre-wrap; overflow-wrap: anywhere; }
.info-fact__value.is-empty { color: var(--text-muted); font-style: italic; }
.info-fact textarea.form-control { min-height: 38px; resize: vertical; font-size: 13.5px; }
@media (max-width: 640px) {
    .info-fact { grid-template-columns: 1fr; gap: 4px; }
}

/* Freshness. The board is only worth reading if you can tell fresh from
   forgotten, so "last confirmed" gets its own affordance instead of hiding
   inside an edit timestamp. */
.info-freshness {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    flex-wrap: wrap;
    padding: 10px 14px;
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    background: var(--surface-alt);
    font-size: 12.5px;
    color: var(--text-muted);
    margin-bottom: 16px;
}
.info-freshness.is-stale { border-color: var(--warning-200); background: var(--warning-50); color: var(--warning-800); }

.info-handover__list { margin: 8px 0 0; padding-left: 18px; font-size: 12.5px; color: var(--text-muted); }
.info-handover__list li { margin-bottom: 3px; }

.info-empty {
    text-align: center;
    padding: 28px 16px;
    color: var(--text-muted);
    font-size: 13px;
    line-height: 1.6;
}

/* Markdown editor: plain textarea plus a button row, no contenteditable. */
.info-md-toolbar { display: flex; gap: 4px; flex-wrap: wrap; margin-bottom: 6px; }
.info-md-preview {
    border: 1px dashed var(--border);
    border-radius: var(--radius-sm);
    padding: 10px 12px;
    min-height: 60px;
    background: var(--surface-alt);
}
.info-editor-drop.is-dragover { outline: 2px dashed var(--primary-600); outline-offset: 3px; }

/* Per-page info-board button. Injected into .page-header by base.html on any
   page whose path maps to a category, so no template carries markup for it.
   Secondary by construction: it sits next to the page's primary action and must
   never compete with it. */
.info-page-btn {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    height: 34px;
    padding: 0 12px 0 9px;
    background: var(--surface);
    color: var(--text);
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    font-size: 13px;
    font-weight: 500;
    font-family: inherit;
    cursor: pointer;
    white-space: nowrap;
    transition: border-color .13s ease, background-color .13s ease;
}
.info-page-btn:hover { border-color: var(--primary-600); }
.info-page-btn svg { display: block; flex: 0 0 auto; }
.info-page-btn__n { font-variant-numeric: tabular-nums; font-weight: 600; }
/* Empty board: dashed and muted, so it recedes next to the primary action and
   reads as an invitation rather than a control that opens nothing. */
.info-page-btn--empty { color: var(--text-muted); border-style: dashed; }
/* Facts overdue for confirmation. Amber, not red — nothing is broken. */
.info-page-btn--warn {
    border-color: var(--warning-200);
    background: var(--warning-50);
    color: var(--warning-800);
}


/* ----- Stale-facts marker on the drawer footer link -----
   All that is left of a banner that used to head the drawer. It sits on the
   button that takes you to where the facts are actually edited. */
.info-stale-dot {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 15px;
    height: 15px;
    margin-left: 5px;
    padding: 0 4px;
    border-radius: var(--radius-pill);
    background: var(--warning-600);
    color: #fff;
    font-size: 9.5px;
    font-weight: 700;
    line-height: 1;
}
.info-stale-dot[hidden] { display: none !important; }

/* ----- Compact cards -----
   Every card gets the same maximum height in a list, so one long note cannot
   push everything else below the fold. The overflow fades rather than cutting
   mid-letter, which is the visual cue that there is more behind the click. */
.info-post--clickable { cursor: pointer; }
.info-post--clickable:hover { border-color: var(--primary-600); }
.info-post--compact .info-post__body {
    max-height: 92px;
    overflow: hidden;
    position: relative;
}
/* The fade only when the text is actually cut (info-board.js sets is-kuttet):
   over a one-line note it turned the whole line pale grey (runde 6b). It fades
   into the card's own surface (--info-flate), so an important card or a row
   under the pointer does not get a white band. */
.info-post--compact .info-post__body.is-kuttet::after {
    content: '';
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    height: 34px;
    background: linear-gradient(to bottom, transparent, var(--info-flate));
    pointer-events: none;
}
/* One pasted screenshot would otherwise fill the whole card on its own. */
.info-post--compact .ib-md-img { max-height: 64px; width: auto; margin: 4px 0; }
.info-post--compact .info-attachments { display: none; }

/* ----- Drill-down -----
   The drawer widens when a note is open: 420px is right for scanning a list,
   too narrow for reading a note with a screenshot in it. */
.side-drawer__panel.is-wide { width: 660px; }
@media (max-width: 700px) { .side-drawer__panel.is-wide { width: 94vw; } }

.info-detail__back {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    background: none;
    border: 0;
    padding: 0;
    margin-bottom: 10px;
    font: inherit;
    font-size: 12.5px;
    color: var(--text-muted);
    cursor: pointer;
}
.info-detail__back:hover { color: var(--primary-700); }
.info-detail__back .material-symbols-rounded { font-size: 16px; }
.info-detail__title { margin: 0 0 4px; font-size: 17px; font-weight: 600; line-height: 1.3; }
.info-detail__meta {
    display: flex;
    align-items: center;
    gap: 7px;
    flex-wrap: wrap;
    font-size: 12px;
    color: var(--text-muted);
    margin-bottom: 14px;
    padding-bottom: 12px;
    border-bottom: 1px solid var(--border);
}
.info-detail__body { font-size: 14px; line-height: 1.6; }
.info-detail__body .ib-md-img { max-height: none; }

/* ----- Category sections -----
   Always grouped, so the drawer looks the same for every client; only how much
   is unfolded changes with how full the board is. */
.info-group { margin-bottom: 8px; }
.info-group__head {
    display: flex;
    align-items: center;
    gap: 8px;
    width: 100%;
    padding: 8px 10px;
    background: none;
    border: 1px solid transparent;
    border-radius: var(--radius-sm);
    font: inherit;
    font-size: 12.5px;
    font-weight: 600;
    color: var(--text);
    cursor: pointer;
    text-align: left;
}
.info-group__head:hover { background: var(--surface-alt); }
.info-group__caret {
    font-size: 18px;
    color: var(--text-muted);
    transition: transform .15s ease;
    flex: 0 0 auto;
}
.info-group.is-open .info-group__caret { transform: rotate(90deg); }
.info-group__label { flex: 1 1 auto; }
.info-group__count {
    font-variant-numeric: tabular-nums;
    font-weight: 600;
    font-size: 11px;
    color: var(--text-muted);
    background: var(--surface-alt);
    border-radius: var(--radius-pill);
    padding: 1px 7px;
}
.info-group__body { padding-top: 8px; }
.info-group:not(.is-open) .info-group__body { display: none; }
/* The section for the page you are on, so it reads as "yours" among the rest. */
.info-group--current .info-group__head { color: var(--primary-700); }
.info-group--current .info-group__count { background: var(--primary-50); color: var(--primary-700); }

.info-search-summary {
    font-size: 12px;
    color: var(--text-muted);
    margin-bottom: 10px;
}

/* Save/cancel row for the editor. It travels with the form, so it works both
   inside the modal (on /infotavle) and inline in the drawer. */
.info-editor__actions {
    display: flex;
    justify-content: flex-end;
    gap: 8px;
    margin-top: 16px;
    padding-top: 14px;
    border-top: 1px solid var(--border);
}

/* Collapsible client-facts card. Sixteen fields expanded pushed every note
   below the fold — the reference material was standing in front of the part
   people come back to daily. */
.info-facts-toggle {
    display: flex;
    align-items: center;
    gap: 10px;
    width: 100%;
    padding: 16px 20px;
    background: none;
    border: 0;
    font: inherit;
    color: var(--text);
    cursor: pointer;
    text-align: left;
}
.info-facts-toggle__caret {
    font-size: 20px;
    color: var(--text-muted);
    transition: transform .15s ease;
    flex: 0 0 auto;
}
#factsCard.is-open .info-facts-toggle__caret { transform: rotate(90deg); }
.info-facts-toggle__text { flex: 1 1 auto; }
.info-facts-toggle__title { display: block; font-size: 16px; font-weight: 600; }
.info-facts-toggle__sub { display: block; font-size: 12.5px; color: var(--text-muted); margin-top: 2px; }
/* The flag is what lets the card stay shut: it says there is something to do
   in here without spending the vertical space to prove it. */
.info-facts-flag {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 20px;
    height: 20px;
    padding: 0 6px;
    border-radius: var(--radius-pill);
    background: var(--warning-600);
    color: #fff;
    font-size: 12px;
    font-weight: 700;
}
.info-facts-flag[hidden] { display: none !important; }


/* Øktene (REGLER §44): kontosiden og brukerlista. static/js/okter.js lager
   radene; denne økta er merket og har ingen knapp. */
.okt-liste {
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
}
.okt-rad { display: flex; align-items: center; gap: 12px; padding: 10px 12px; }
.okt-rad + .okt-rad { border-top: 1px solid var(--border); }
.okt-rad__ikon { flex: none; font-size: 22px; color: var(--text-muted); }
.okt-rad__tekst { flex: 1; min-width: 0; }
.okt-rad__navn { font-size: 13.5px; font-weight: 500; color: var(--text); }
.okt-rad__meta { font-size: 12px; color: var(--text-muted); font-variant-numeric: tabular-nums; }
.okt-rad__meta > span { white-space: nowrap; }
.okt-rad__denne {
    display: inline-block;
    margin-left: 8px;
    padding: 1px 8px;
    border-radius: var(--radius-pill);
    background: var(--success-50);
    color: var(--success-700);
    font-size: 10.5px;
    font-weight: 600;
    letter-spacing: .05em;
    text-transform: uppercase;
    vertical-align: 1px;
}
.okt-rad .btn { flex: none; }
.okt-tom { padding: 12px; font-size: 12.5px; color: var(--text-muted); }
/* På telefonen får teksten hele bredden, og knappen står under den. */
@media (max-width: 480px) {
    .okt-rad { flex-wrap: wrap; row-gap: 8px; }
    .okt-rad__tekst { flex-basis: calc(100% - 34px); }
    .okt-rad .btn { margin-left: 34px; }
}

/* Hengelåsen over et låst bilag eller en låst side av en linje, og vinduet
   som sier hvor låsen er fra (REGLER §47). static/js/laas.js lager begge.
   Grå, fordi låsen er en tilstand og ikke en handling; lenken i vinduet er
   blå, for den er det man klikker. */
.lock-ind {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 22px;
    height: 22px;
    padding: 0;
    border: 0;
    border-radius: var(--radius-sm);
    background: transparent;
    color: var(--text-subtle);
    cursor: help;
    flex: none;
}
.lock-ind .material-symbols-rounded { font-size: 16px; }
.lock-ind:hover,
.lock-ind[aria-expanded="true"] { color: var(--text-muted); background: var(--surface-alt); }
.lock-ind:focus { outline: none; }
.lock-ind:focus-visible { outline: 2px solid var(--primary-600); outline-offset: 1px; }
.lock-ind.lock-ind--row { width: 28px; height: 28px; }
.lock-ind.lock-ind--row .material-symbols-rounded { font-size: 18px; }
.lock-pop {
    position: fixed;
    z-index: 1600;
    width: max-content;
    max-width: min(340px, calc(100vw - 16px));
    max-height: calc(100vh - 16px);
    overflow-y: auto;
    padding: 10px 12px 12px;
    background: var(--surface);
    color: var(--text);
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    box-shadow: var(--shadow-md);
    font-size: 12.5px;
    line-height: 1.45;
    text-align: left;
    white-space: normal;
    opacity: 0;
    transform: translateY(-3px);
    transition: opacity var(--transition-fast), transform var(--transition-fast);
}
.lock-pop.is-above { transform: translateY(3px); }
.lock-pop.is-visible { opacity: 1; transform: none; }
.lock-pop__head { display: flex; align-items: center; gap: 6px; font-size: 13px; font-weight: 600; }
.lock-pop__head .material-symbols-rounded { font-size: 16px; color: var(--text-subtle); }
.lock-pop__sub { margin-top: 2px; color: var(--text-muted); }
.lock-pop__item { display: flex; gap: 8px; margin-top: 10px; padding-top: 10px; border-top: 1px solid var(--border); }
.lock-pop__icon { flex: none; font-size: 18px; color: var(--text-muted); }
.lock-pop__body { min-width: 0; }
.lock-pop__title { font-weight: 600; }
.lock-pop__meta { color: var(--text-muted); font-variant-numeric: tabular-nums; }
.lock-pop__action { margin-top: 2px; color: var(--text-muted); }
.lock-pop__link {
    display: inline-flex;
    align-items: center;
    gap: 2px;
    margin-top: 6px;
    color: var(--primary-600);
    font-weight: 600;
    text-decoration: none;
}
.lock-pop__link:hover { color: var(--primary-700); text-decoration: underline; }
.lock-pop__link .material-symbols-rounded { font-size: 16px; }

/* «Se som» (REGLER §49): stripa nede til venstre mens admin ser appen som en
   klientbruker. Advarselsfargen, fordi det man ser ikke er ens egen visning;
   den står over alt annet, så veien ut aldri er dekket. */
.se-som-stripe {
    position: fixed;
    left: 16px;
    bottom: 16px;
    z-index: 1250;
    display: flex;
    align-items: center;
    gap: 10px;
    max-width: calc(100vw - 32px);
    padding: 8px 10px 8px 12px;
    background: var(--warning-50);
    color: var(--warning-800);
    border: 1px solid var(--warning-200);
    border-radius: var(--radius-md);
    box-shadow: var(--shadow-md);
    font-size: 12.5px;
    line-height: 1.35;
}
.se-som-stripe > .material-symbols-rounded { flex: none; font-size: 20px; }
.se-som-stripe__text { display: flex; flex-direction: column; min-width: 0; }
.se-som-stripe__text strong { font-weight: 600; }
.se-som-stripe .btn { flex: none; }

/* =========================================================================
   Feedback drawer
   =========================================================================
   Reports about the PROGRAM, filed from wherever the reporter was standing.
   Shares the .side-drawer shell and the .info-* detail vocabulary with the
   info board; everything below is what feedback needs on top of that.
   ========================================================================= */

/* Type picker. A segmented control rather than a <select>: there are exactly
   three kinds, choosing one is the first thing you do, and a dropdown would
   hide two thirds of the answer behind a click. */
.fb-kinds { display: flex; gap: 8px; margin-bottom: 4px; }
.fb-kind {
    flex: 1 1 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 4px;
    padding: 10px 6px;
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    background: var(--surface);
    color: var(--text-muted);
    font: inherit;
    font-size: 12px;
    font-weight: 600;
    line-height: 1.2;
    cursor: pointer;
    transition: border-color .12s ease, background-color .12s ease, color .12s ease;
}
.fb-kind .material-symbols-rounded { font-size: 20px; }
.fb-kind:hover { border-color: var(--border-strong); color: var(--text); }
.fb-kind.is-active {
    border-color: var(--primary-600);
    background: var(--surface-tint);
    color: var(--primary-700);
}

/* Where the reporter was. Shown in the editor BEFORE saving, on purpose: the
   whole promise of the feature is "you don't have to explain which page", and
   the reporter should be able to see that promise being kept. */
.fb-ctx {
    display: flex;
    align-items: flex-start;
    gap: 8px;
    padding: 9px 12px;
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    background: var(--surface-alt);
    font-size: 12px;
    color: var(--text-muted);
    line-height: 1.45;
}
.fb-ctx .material-symbols-rounded { font-size: 16px; margin-top: 1px; }
.fb-ctx__path {
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-size: 11.5px;
    color: var(--text);
    overflow-wrap: anywhere;
}

/* ----- List ----- */
.fb-filters {
    display: flex;
    gap: 6px;
    flex-wrap: wrap;
    margin-bottom: 12px;
}
.fb-filter {
    padding: 4px 11px;
    border: 1px solid var(--border);
    border-radius: var(--radius-pill);
    background: var(--surface);
    color: var(--text-muted);
    font: inherit;
    font-size: 12px;
    font-weight: 500;
    cursor: pointer;
    white-space: nowrap;
}
.fb-filter:hover { border-color: var(--border-strong); color: var(--text); }
.fb-filter.is-active {
    border-color: var(--primary-600);
    background: var(--surface-tint);
    color: var(--primary-700);
    font-weight: 600;
}

.fb-item {
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    background: var(--surface);
    padding: 11px 13px;
    margin-bottom: 8px;
    cursor: pointer;
    transition: border-color .12s ease;
}
.fb-item:hover { border-color: var(--primary-600); }
.fb-item__top {
    display: flex;
    align-items: center;
    gap: 6px;
    margin-bottom: 5px;
    flex-wrap: wrap;
}
.fb-item__title {
    font-size: 13.5px;
    font-weight: 600;
    line-height: 1.35;
    margin: 0 0 3px;
    overflow-wrap: anywhere;
}
.fb-item__meta {
    font-size: 11.5px;
    color: var(--text-muted);
    display: flex;
    align-items: center;
    gap: 6px;
    flex-wrap: wrap;
}
/* The page it was filed from is the most useful thing on the card after the
   title, so it gets monospace and does not wrap into the rest of the meta. */
.fb-item__where {
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-size: 11px;
    max-width: 100%;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.fb-badge {
    display: inline-flex;
    align-items: center;
    gap: 3px;
    padding: 2px 8px;
    border-radius: var(--radius-pill);
    font-size: 11px;
    font-weight: 600;
    white-space: nowrap;
}
.fb-badge .material-symbols-rounded { font-size: 13px; }
.fb-badge--bug   { color: var(--danger-700); background: var(--danger-50); }
.fb-badge--wish  { color: var(--accent-violet-700); background: var(--accent-violet-50); }
.fb-badge--idea  { color: var(--info-700); background: var(--info-50); }

.fb-status {
    display: inline-flex;
    align-items: center;
    padding: 2px 8px;
    border-radius: var(--radius-pill);
    border: 1px solid var(--border);
    font-size: 11px;
    font-weight: 600;
    color: var(--text-muted);
    background: var(--surface-alt);
    white-space: nowrap;
}
.fb-status--new         { color: var(--primary-700); background: var(--surface-tint); border-color: transparent; }
.fb-status--planned     { color: var(--info-700); background: var(--info-50); border-color: transparent; }
.fb-status--in_progress { color: var(--warning-800); background: var(--warning-50); border-color: transparent; }
.fb-status--done        { color: var(--success-700); background: var(--success-50); border-color: transparent; }
.fb-status--declined    { color: var(--text-muted); background: var(--surface-alt); }

/* Blocking bugs earn a marker; "normal" and "minor" do not, or the marker
   stops meaning anything. */
.fb-sev--high { color: var(--danger-600); font-weight: 600; }

/* ----- Screenshots -----
   Attachments that are images get shown, not listed: a report is usually a
   picture with a sentence attached, and a filename pill hides the evidence. */
.fb-shots { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 10px; }
.fb-shot {
    position: relative;
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    overflow: hidden;
    background: var(--surface-alt);
    line-height: 0;
}
.fb-shot img { display: block; max-height: 110px; max-width: 180px; object-fit: cover; }
.fb-shot__del {
    position: absolute;
    top: 3px;
    right: 3px;
    width: 20px;
    height: 20px;
    display: flex;
    align-items: center;
    justify-content: center;
    border: 0;
    border-radius: 50%;
    background: rgba(0, 0, 0, .55);
    color: #fff;
    cursor: pointer;
    padding: 0;
}
.fb-shot__del .material-symbols-rounded { font-size: 14px; }
.fb-detail .fb-shot img { max-height: 320px; max-width: 100%; object-fit: contain; }

/* Paste target. The fastest path from "this looks wrong" to a filed report is
   PrtScn then Ctrl+V, so the hint says so out loud. */
.fb-drop {
    border: 1px dashed var(--border-strong);
    border-radius: var(--radius-md);
    padding: 12px;
    text-align: center;
    font-size: 12px;
    color: var(--text-muted);
    cursor: pointer;
}
.fb-drop:hover { border-color: var(--primary-600); color: var(--primary-700); }
.fb-drop.is-dragover { border-color: var(--primary-600); background: var(--surface-tint); }

.fb-detail__section {
    margin-top: 16px;
    padding-top: 12px;
    border-top: 1px solid var(--border);
}
.fb-detail__label {
    font-size: 11px;
    text-transform: uppercase;
    letter-spacing: .06em;
    color: var(--text-muted);
    font-weight: 600;
    margin-bottom: 6px;
}
/* Reports are stored as plain text — no editor HTML from a client user gets
   rendered in a reader's browser — so line breaks have to survive in CSS. */
.fb-body { font-size: 13.5px; line-height: 1.6; white-space: pre-wrap; overflow-wrap: anywhere; }
.fb-history { font-size: 11.5px; color: var(--text-muted); line-height: 1.7; }

/* The severity question only applies to bugs; [hidden] must win over any
   .form-group display rule that lands here later. */
#fbSeverityRow[hidden] { display: none !important; }
.fb-drop.is-busy { opacity: .6; pointer-events: none; }

/* ----- Konsollsporet -----
   Diagnostikk, ikke innhold: den skal være lett å hoppe over når den ikke
   trengs, og lesbar linje for linje når den gjør det. */
.fb-log {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-top: 10px;
    padding: 8px 10px;
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    background: var(--surface-alt);
    font-size: 12px;
    color: var(--text-muted);
}
.fb-log .material-symbols-rounded { font-size: 16px; }
.fb-log__text { flex: 1 1 auto; min-width: 0; }
.fb-log__toggle {
    background: none;
    border: 0;
    padding: 0 4px;
    font: inherit;
    font-weight: 600;
    color: var(--primary-700);
    cursor: pointer;
}
.fb-log__body {
    margin: 8px 0 0;
    padding: 10px 12px;
    max-height: 320px;
    overflow: auto;
    background: var(--surface-alt);
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-size: 11px;
    line-height: 1.55;
    color: var(--text-muted);
    white-space: pre-wrap;
    overflow-wrap: anywhere;
}
.fb-log__body[hidden] { display: none !important; }
.fb-log__line { display: flex; gap: 8px; align-items: baseline; }
.fb-log__line + .fb-log__line { margin-top: 2px; }
.fb-log__t { flex: 0 0 auto; color: var(--text-subtle); }
/* Nivået i fast bredde, så meldingene står i én kolonne og lar seg skumme. */
.fb-log__lvl {
    flex: 0 0 58px;
    text-transform: uppercase;
    font-size: 10px;
    letter-spacing: .04em;
}
.fb-log__line--error   .fb-log__lvl,
.fb-log__line--uncaught .fb-log__lvl { color: var(--danger-700); }
.fb-log__line--error,
.fb-log__line--uncaught { color: var(--text); }
.fb-log__line--warn .fb-log__lvl { color: var(--warning-700); }
.fb-log__line--http .fb-log__lvl { color: var(--accent-violet-700); }
.fb-log__line--http { color: var(--text); }
