/* =============================================================================
 * csp-utilities.css — utility classes do eliminacji statycznych style="..."
 * (etap L2: usuwanie style-src 'unsafe-inline').
 *
 * ZASADA NACZELNA (anty-regresja / faithful):
 *   KAŻDA klasa zawiera DOKŁADNIE JEDNĄ deklarację CSS, równą co do znaku
 *   zastępowanemu fragmentowi inline style="...". Migracja
 *   style="margin:0" -> class="m-0" MUSI dać identyczny render (zero zmiany
 *   wizualnej). Dlatego klasy są atomowe (jedna własność) — wiele atomów inline
 *   (np. style="margin:0;padding:0") = wiele klas (class="m-0 p-0").
 *
 * NAZEWNICTWO (Tailwind-like, skrócone):
 *   m/p = margin/padding; t/r/b/l/x/y = strony; liczby = px, sufiks "r" = rem
 *   (kropka -> brak; 0.5rem -> 05r, 1rem -> 1r). w/h = width/height.
 *   text-* = kolor/wyrównanie; fs-* = font-size; fw-* = font-weight;
 *   d-* = display; ai/jc = align-items/justify-content; gap-*; itd.
 *
 * MAPOWANIE: każdy blok ma komentarz "<- style=..." z dokładnym oryginałem.
 *
 * WARTOŚCI DYNAMICZNE (np. width: <?= $pct ?>%, color z danych) NIE należą
 * tutaj — obsługuje je nonce-owany helper data-css-* w dashboard.php (CSSOM nie
 * podlega style-src). Tu trafiają WYŁĄCZNIE wzorce statyczne.
 *
 * Plik jest CELOWO rozszerzalny: kolejne etapy dopisują atomy w odpowiednich
 * sekcjach, zachowując zasadę "jedna klasa = jedna faithful deklaracja".
 * Specyficzność: pojedyncza klasa (0,0,1,0). Migrowane elementy nie mają
 * konkurencyjnych reguł na tę własność, więc !important jest zbędne.
 * ========================================================================== */

/* ----------------------------------------------------------------------------
 * MARGIN
 * -------------------------------------------------------------------------- */
.m-0      { margin: 0; }                 /* <- style="margin:0" / "margin: 0" */
.m-0-auto { margin: 0 auto; }            /* <- style="margin:0 auto" */
.mt-0     { margin-top: 0; }             /* <- style="margin-top:0" */
.mb-0     { margin-bottom: 0; }          /* <- style="margin-bottom:0" */
.mb-05r   { margin-bottom: 0.5rem; }     /* <- style="margin-bottom: 0.5rem" / "margin-bottom:0.5rem" */
.mb-1r    { margin-bottom: 1rem; }       /* <- style="margin-bottom: 1rem" */
.mt-2px   { margin-top: 2px; }           /* <- style="margin-top:2px" */
.mr-4px   { margin-right: 4px; }         /* <- style="margin-right:4px" */
.mt-04r   { margin-top: 0.4rem; }        /* <- style="margin-top: 0.4rem" */
.mt-125r  { margin-top: 1.25rem; }       /* <- style="margin-top: 1.25rem" */
.p-0      { padding: 0; }                /* <- style="padding:0" / "padding: 0" */
.p-075r   { padding: 0.75rem; }          /* <- style="padding:0.75rem" */
.p-1r     { padding: 1rem; }             /* <- style="padding:1rem" */
.p-2r     { padding: 2rem; }             /* <- style="padding: 2rem" */
.px-125r  { padding: 0 1.25rem; }        /* <- style="padding: 0 1.25rem" */
.py-1r    { padding: 1rem 0; }           /* <- style="padding: 1rem 0" */
.p-spacing-lg { padding: var(--spacing-lg); } /* <- style="padding:var(--spacing-lg)" */

/* ----------------------------------------------------------------------------
 * WIDTH (px) — wartości statyczne z audytu. Dynamiczne szerokości (paski %)
 * idą przez data-css-width helper, NIE tutaj.
 * -------------------------------------------------------------------------- */
.w-auto { width: auto; }                 /* <- style="width:auto" */
.w-10   { width: 10px; }                 /* <- style="width:10px" */
.w-12   { width: 12px; }                 /* <- style="width:12px" / "width: 12px" */
.w-14   { width: 14px; }                 /* <- style="width: 14px" */
.w-40   { width: 40px; }                 /* <- style="width:40px" */
.w-50px { width: 50px; }                 /* <- style="width:50px" (px; .w-50=50% jest w app.css) */
.w-60   { width: 60px; }                 /* <- style="width:60px" / "width: 60px" */
.w-70   { width: 70px; }                 /* <- style="width: 70px" */
.w-80   { width: 80px; }                 /* <- style="width:80px" */
.w-100px{ width: 100px; }                /* <- style="width:100px" (px; .w-100=100% jest w app.css) */
.w-110  { width: 110px; }                /* <- style="width: 110px" */
.w-120  { width: 120px; }                /* <- style="width: 120px" */
.w-130  { width: 130px; }                /* <- style="width: 130px" */
.w-150  { width: 150px; }                /* <- style="width: 150px" */
.w-160  { width: 160px; }                /* <- style="width: 160px" */
.w-170  { width: 170px; }                /* <- style="width: 170px" */
.w-200  { width: 200px; }                /* <- style="width: 200px" */
.w-320  { width: 320px; }                /* <- style="width: 320px" */
.w-full { width: 100%; }                 /* <- style="width:100%" / "width: 100%" */

/* min-width / max-width (px) */
.minw-120 { min-width: 120px; }          /* <- style="min-width:120px" */
.minw-150 { min-width: 150px; }          /* <- style="min-width: 150px" / "min-width:150px" */
.minw-160 { min-width: 160px; }          /* <- style="min-width:160px" */
.minw-180 { min-width: 180px; }          /* <- style="min-width:180px" */
.minw-200 { min-width: 200px; }          /* <- style="min-width: 200px" / "min-width:200px" */
.minw-220 { min-width: 220px; }          /* <- style="min-width: 220px" */
.minw-280 { min-width: 280px; }          /* <- style="min-width: 280px" */
.maxw-250 { max-width: 250px; }          /* <- style="max-width:250px" */
.maxw-320 { max-width: 320px; }          /* <- style="max-width: 320px" */
.maxw-400 { max-width: 400px; }          /* <- style="max-width: 400px" */
.maxw-600 { max-width: 600px; }          /* <- style="max-width:600px" */
.maxw-700 { max-width: 700px; }          /* <- style="max-width:700px" */

/* ----------------------------------------------------------------------------
 * HEIGHT (px / %)
 * -------------------------------------------------------------------------- */
.h-6    { height: 6px; }                  /* <- style="height: 6px" */
.h-8    { height: 8px; }                  /* <- style="height:8px" */
.h-10   { height: 10px; }                 /* <- style="height:10px" */
.h-40   { height: 40px; }                 /* <- style="height:40px" */
.h-full { height: 100%; }                 /* <- style="height: 100%" */
.maxh-300 { max-height: 300px; }          /* <- style="max-height:300px" */

/* ----------------------------------------------------------------------------
 * COLOR — wyłącznie tokeny/kolory STAŁE. Kolory pochodzące z danych
 * (status/priority meta) idą przez data-css-color helper.
 * -------------------------------------------------------------------------- */
.text-muted-token { color: var(--color-text-muted); }  /* <- style="color: var(--color-text-muted)" / "color:var(--color-text-muted)" */
.text-secondary-token { color: var(--color-text-secondary); } /* <- style="color:var(--color-text-secondary)" */
.text-primary-token { color: var(--color-primary); }   /* <- style="color:var(--color-primary)" */
.text-white { color: #fff; }                            /* <- style="color: white" / "color:#fff" */

/* ----------------------------------------------------------------------------
 * TEXT-ALIGN / TRANSFORM / DECORATION / WHITE-SPACE / OVERFLOW-TEXT
 * -------------------------------------------------------------------------- */
.ta-center { text-align: center; }        /* <- style="text-align: center" */
.ta-left   { text-align: left; }          /* <- style="text-align: left" */
.tt-upper  { text-transform: uppercase; } /* <- style="text-transform: uppercase" */
.td-none   { text-decoration: none; }     /* <- style="text-decoration: none" */
.ws-nowrap   { white-space: nowrap; }     /* <- style="white-space:nowrap" */
.ws-prewrap  { white-space: pre-wrap; }   /* <- style="white-space: pre-wrap" */
.wb-breakall { word-break: break-all; }   /* <- style="word-break:break-all" / "word-break: break-all" */
.to-ellipsis { text-overflow: ellipsis; } /* <- style="text-overflow:ellipsis" */
.ls-8 { letter-spacing: 8px; }            /* <- style="letter-spacing: 8px" */

/* ----------------------------------------------------------------------------
 * FONT-SIZE — najczęstsze stałe wartości (rem + px + tokeny).
 * -------------------------------------------------------------------------- */
.fs-07r   { font-size: 0.7rem; }          /* <- style="font-size: 0.7rem" */
.fs-078r  { font-size: 0.78rem; }         /* <- style="font-size: 0.78rem" */
.fs-08r   { font-size: 0.8rem; }          /* <- style="font-size:0.8rem" / "font-size: 0.8rem" */
.fs-085r  { font-size: 0.85rem; }         /* <- style="font-size:0.85rem" / "font-size: 0.85rem" */
.fs-09r   { font-size: 0.9rem; }          /* <- style="font-size:0.9rem" / "font-size: 0.9rem" */
.fs-1r    { font-size: 1rem; }            /* <- style="font-size: 1rem" */
.fs-105r  { font-size: 1.05rem; }         /* <- style="font-size: 1.05rem" */
.fs-11r   { font-size: 1.1rem; }          /* <- style="font-size:1.1rem" */
.fs-1125r { font-size: 1.125rem; }        /* <- style="font-size: 1.125rem" */
.fs-115r  { font-size: 1.15rem; }         /* <- style="font-size: 1.15rem" */
.fs-15r   { font-size: 1.5rem; }          /* <- style="font-size: 1.5rem" */
.fs-175r  { font-size: 1.75rem; }         /* <- style="font-size: 1.75rem" */
.fs-2r    { font-size: 2rem; }            /* <- style="font-size: 2rem" / "font-size:2rem" */
.fs-25r   { font-size: 2.5rem; }          /* <- style="font-size: 2.5rem" / "font-size:2.5rem" */
.fs-3r    { font-size: 3rem; }            /* <- style="font-size:3rem" */
.fs-4r    { font-size: 4rem; }            /* <- style="font-size: 4rem" */
.fs-13px  { font-size: 13px; }            /* <- style="font-size:13px" */
.fs-xs    { font-size: var(--font-size-xs); }  /* <- style="font-size:var(--font-size-xs)" */

/* ----------------------------------------------------------------------------
 * FONT-WEIGHT / LINE-HEIGHT
 * -------------------------------------------------------------------------- */
.fw-400 { font-weight: 400; }             /* <- style="font-weight: 400" */
.fw-700 { font-weight: 700; }             /* <- style="font-weight:700" */
.lh-155 { line-height: 1.55; }            /* <- style="line-height: 1.55" */

/* ----------------------------------------------------------------------------
 * DISPLAY / FLEXBOX
 * -------------------------------------------------------------------------- */
.d-none   { display: none; }              /* <- style="display:none" */
.d-block  { display: block; }             /* <- style="display:block" */
.d-inline { display: inline; }            /* <- style="display:inline" / "display: inline" */
.d-inline-block { display: inline-block; }/* <- style="display:inline-block" */
.d-flex   { display: flex; }              /* <- style="display:flex" / "display: flex" */

.ai-center      { align-items: center; }      /* <- style="align-items:center" */
.ai-flex-start  { align-items: flex-start; }  /* <- style="align-items:flex-start" */
.jc-between     { justify-content: space-between; } /* <- style="justify-content:space-between" */
.fw-wrap        { flex-wrap: wrap; }           /* <- style="flex-wrap:wrap" */
.gap-075r       { gap: 0.75rem; }              /* <- style="gap:0.75rem" */
.gap-1r         { gap: 1rem; }                 /* <- style="gap:1rem" / "gap: 1rem" */
.flex-1         { flex: 1; }                   /* <- style="flex:1" / "flex: 1" */
.flex-shrink-0  { flex-shrink: 0; }            /* <- style="flex-shrink:0" */

/* ----------------------------------------------------------------------------
 * POSITION / OVERFLOW / Z-INDEX / MISC
 * -------------------------------------------------------------------------- */
.pos-relative { position: relative; }     /* <- style="position: relative" */
.z-1   { z-index: 1; }                     /* <- style="z-index: 1" */
.z-100 { z-index: 100; }                   /* <- style="z-index: 100" */

.ov-hidden  { overflow: hidden; }          /* <- style="overflow:hidden" / "overflow: hidden" */
.ov-auto    { overflow: auto; }            /* <- style="overflow:auto" */
.ovx-auto   { overflow-x: auto; }          /* <- style="overflow-x:auto" / "overflow-x: auto" */
.ovy-auto   { overflow-y: auto; }          /* <- style="overflow-y:auto" */

.cursor-pointer { cursor: pointer; }       /* <- style="cursor:pointer" */
.pe-none        { pointer-events: none; }  /* <- style="pointer-events:none" */
.ls-none        { list-style: none; }      /* <- style="list-style: none" */
.op-04 { opacity: 0.4; }                   /* <- style="opacity: 0.4" */
.op-05 { opacity: 0.5; }                   /* <- style="opacity:0.5" */
.op-08 { opacity: 0.8; }                   /* <- style="opacity: 0.8" */
.op-09 { opacity: 0.9; }                   /* <- style="opacity: 0.9" */
.va--2 { vertical-align: -2px; }           /* <- style="vertical-align:-2px" */
.bc-collapse { border-collapse: collapse; }/* <- style="border-collapse:collapse" (część "width:100%; border-collapse:collapse") */

/* ----------------------------------------------------------------------------
 * RISKO heatmap — atomy z renderHeatmap() (app/Views/risko/dashboard.php).
 * Statyczne fragmenty komórki/tabeli; dynamiczne background/opacity nie tu:
 * background → data-css-bg (helper); opacity ma 2 wartości → op-1 / op-035.
 * -------------------------------------------------------------------------- */
.h-50px { height: 50px; }                  /* <- style="...height:50px..." (px; .h-50=50% jest w app.css) */
.br-6 { border-radius: 6px; }              /* <- style="...border-radius:6px;" (komórka heatmap) */
.bc-separate { border-collapse: separate; }/* <- style="border-collapse:separate;..." (tabela heatmap) */
.bs-3 { border-spacing: 3px; }             /* <- style="...border-spacing:3px;" (tabela heatmap) */
.op-1   { opacity: 1; }                    /* <- style="...opacity:1..." (komórka z ryzykiem) */
.op-035 { opacity: 0.35; }                 /* <- style="...opacity:0.35..." (komórka pusta) */

/* ----------------------------------------------------------------------------
 * Atomy z konwersji widoku dashboard/index.php (etap L2).
 * Kazda klasa = jedna faithful deklaracja, rowna zastepowanemu fragmentowi
 * inline. Kolory arbitralne (hex/rgba) i border-left specyficzne dla tego
 * widoku trzymamy page-scoped w nonce-owanym <style> w samym index.php.
 * -------------------------------------------------------------------------- */
.mt-6px        { margin-top: 6px; }            /* <- style="margin-top: 6px" */
.mt-05r        { margin-top: 0.5rem; }         /* <- style="margin-top: 0.5rem" */
.m-05r-0-075r  { margin: 0.5rem 0 0.75rem; }   /* <- style="margin: 0.5rem 0 0.75rem" */
.m-0-0-05r-11r { margin: 0 0 0.5rem 1.1rem; }  /* <- style="margin: 0 0 0.5rem 1.1rem" */
.w-36          { width: 36px; }                /* <- style="width:36px" */
.h-36          { height: 36px; }               /* <- style="height:36px" */
.fs-125r       { font-size: 1.25rem; }         /* <- style="font-size:1.25rem" */
.fs-14px       { font-size: 14px; }            /* <- style="font-size: 14px" */
.lh-12         { line-height: 1.2; }           /* <- style="line-height:1.2" */
.fw-600        { font-weight: 600; }           /* <- style="font-weight: 600" */
.text-inherit  { color: inherit; }             /* <- style="color: inherit" */
.op-03         { opacity: 0.3; }               /* <- style="opacity:0.3" */
.op-085        { opacity: 0.85; }              /* <- style="opacity: 0.85" */
.cursor-default { cursor: default; }           /* <- style="cursor: default" */
.br-3          { border-radius: 3px; }         /* <- style="border-radius: 3px" */

/* ----------------------------------------------------------------------------
 * Atomy z konwersji widokow auth/* (etap L2 Stage 2: register, login,
 * reset-password, 2fa, forgot-password). Kazda klasa = jedna faithful
 * deklaracja, rowna co do znaku zastepowanemu fragmentowi inline. Kolory
 * arbitralne demo-bannera (login.php) trzymamy jako atomy faithful tutaj
 * (jedna deklaracja = jeden hex), bo widok nie ma wlasnego nonce-owanego <style>.
 * -------------------------------------------------------------------------- */
.fs-18r        { font-size: 1.8rem; }          /* <- style="font-size: 1.8rem" (2fa input) */
.maxw-300      { max-width: 300px; }           /* <- style="max-width: 300px" (forgot-password) */
.br-8          { border-radius: 8px; }         /* <- style="border-radius:8px" (login demo alert) */
.p-12-14       { padding: 12px 14px; }         /* <- style="padding:12px 14px" (login demo alert) */
.mb-16px       { margin-bottom: 16px; }        /* <- style="margin-bottom:16px" (login demo alert) */
.bg-FFF8E1     { background: #FFF8E1; }         /* <- style="background:#FFF8E1" (login demo alert) */
.border-1-FFC107 { border: 1px solid #FFC107; }/* <- style="border:1px solid #FFC107" (login demo alert) */

/* ----------------------------------------------------------------------------
 * Atomy z konwersji widokow organization/{api-keys,security-alerts,incidents,
 * webhooks}/index.php (etap L2 Stage 2 — partia org-1).
 * Kazda klasa = jedna faithful deklaracja, rowna co do znaku zastepowanemu
 * fragmentowi inline. Kolory arbitralne (hex/rgba) i shorthandy bg/border
 * specyficzne dla tych widokow trzymamy page-scoped w nonce-owanym <style>
 * w samym widoku (jak w dashboard/index.php). Tu wylacznie statyki reuzywalne.
 * Uwaga: .br-8 (border-radius:8px), .mb-05r (margin-bottom:0.5rem),
 * .maxw-600 (max-width:600px) juz istnieja wyzej — reuzywamy.
 * -------------------------------------------------------------------------- */
.mt-075r   { margin-top: 0.75rem; }       /* <- style="margin-top:0.75rem" */
.p-8px     { padding: 8px; }              /* <- style="padding:8px" */
.gap-05r   { gap: 0.5rem; }               /* <- style="gap:0.5rem" */
.gap-4px   { gap: 4px; }                  /* <- style="gap:4px" */
.maxh-120  { max-height: 120px; }         /* <- style="max-height:120px" */
.maxw-140  { max-width: 140px; }          /* <- style="max-width:140px" */
.maxw-160  { max-width: 160px; }          /* <- style="max-width:160px" */
.maxw-350  { max-width: 350px; }          /* <- style="max-width:350px" */
.w-8       { width: 8px; }                /* <- style="width:8px" */
.bg-secondary-token { background: var(--bg-secondary); } /* <- style="background:var(--bg-secondary)" */
.pos-absolute { position: absolute; }     /* <- style="position:absolute" */
.right-8px { right: 8px; }                /* <- style="right:8px" */
.top-8px   { top: 8px; }                  /* <- style="top:8px" */

/* ----------------------------------------------------------------------------
 * Atomy z konwersji widokow organization/{team,audit-log,subscription,
 * service-accounts}/index|show.php (etap L2 Stage 2 — partia org-2).
 * Kazda klasa = jedna faithful deklaracja, rowna co do znaku zastepowanemu
 * fragmentowi inline. Kolory arbitralne strefy "danger" (privacy/index.php)
 * trzymamy page-scoped w nonce-owanym <style> w samym widoku.
 * Uwaga: .maxw-300, .maxw-600, .d-inline, .d-none, .d-flex, .gap-1r, .fw-wrap,
 * .h-10, .h-full, .ov-hidden, .cursor-pointer, .pe-none, .m-0, .w-auto,
 * .fs-08r juz istnieja wyzej — reuzywamy.
 * -------------------------------------------------------------------------- */
.br-5      { border-radius: 5px; }        /* <- style="border-radius: 5px" (progress bar) */
.bg-color-border { background: var(--color-border, rgba(127,127,127,0.2)); } /* <- style="background: var(--color-border, rgba(127,127,127,0.2))" (progress track) */
.transition-width-06 { transition: width 0.6s ease; } /* <- style="transition: width 0.6s ease" (progress fill; width/bg dynamiczne -> data-css-*) */
.p-04e-08e { padding: 0.4em 0.8em; }      /* <- style="padding: 0.4em 0.8em" (role badge) */
.ff-mono   { font-family: monospace; }    /* <- style="font-family: monospace" (JWT textarea) */
.fs-11px   { font-size: 11px; }           /* <- style="font-size: 11px" (JWT textarea) */

/* ----------------------------------------------------------------------------
 * Atomy z konwersji widokow organization/{subscription/shop,subscription/
 * billing-history,incidents/create,import,domain-verification,backups}
 * (etap L2 Stage 2 — partia org-5).
 * Kazda klasa = jedna faithful deklaracja, rowna co do znaku zastepowanemu
 * fragmentowi inline. Arbitralny rgba kafelka "upsell" (shop.php) trzymamy jako
 * faithful atom tutaj (jedna deklaracja = jeden rgba) — jak demo-banner auth/login,
 * bo widok nie ma wlasnego nonce-owanego <style>.
 * Uwaga: .fs-2r, .d-block, .mb-05r, .maxw-700, .w-120, .m-0 juz istnieja wyzej
 * — reuzywamy (billing-history, incidents/create, backups, import).
 * -------------------------------------------------------------------------- */
.pl-15r    { padding-left: 1.5rem; }      /* <- style="padding-left:1.5rem" (import wskazowki <ul>) */
.fs-082r   { font-size: 0.82rem; }        /* <- style="font-size: 0.82rem" (domain-verification instrukcja <ol>) */
.bg-violet-005 { background: rgba(124, 58, 237, 0.05); } /* <- style="background: rgba(124, 58, 237, 0.05)" (shop upsell card) */

/* ----------------------------------------------------------------------------
 * Atomy z konwersji widokow organization/{reports/builder,notifications,
 * compliance-calendar,incidents/show,access-review} (etap L2 Stage 2 — partia
 * org-3). Kazda klasa = jedna faithful deklaracja, rowna co do znaku
 * zastepowanemu fragmentowi inline. Wartosci DYNAMICZNE (kolor severity/typu,
 * background statusu, border-left wg typu) ida przez helper data-css-*
 * (data-css-bg / data-css-color / data-css-border-left). Wartosc dwustanowa
 * cursor:pointer|default (notifications) -> warunkowa klasa .cursor-pointer/
 * .cursor-default (obie juz istnieja wyzej).
 * Uwaga: .minw-160, .maxw-250, .ovx-auto, .ov-hidden, .to-ellipsis, .d-inline,
 * .d-block, .mb-05r, .fs-2r, .ta-center, .fs-11r, .w-12, .d-inline-block,
 * .fs-085r, .text-white juz istnieja wyzej — reuzywamy.
 * -------------------------------------------------------------------------- */
.maxw-130 { max-width: 130px; }           /* <- style="max-width:130px" (builder filter input) */
.h-4      { height: 4px; }                /* <- style="...height:4px..." (legend swatch) */
.br-2     { border-radius: 2px; }         /* <- style="...border-radius:2px..." (legend swatch) */

/* ----------------------------------------------------------------------------
 * Atomy z konwersji widokow organization/{subscription/checkout,settings/index,
 * settings/ai_prompts,notification-preferences/index,escalation/index,cron/index}.php
 * (etap L2 Stage 2 — partia org-4).
 * Kazda klasa = jedna faithful deklaracja, rowna co do znaku zastepowanemu
 * fragmentowi inline. Kolor arbitralny z fallbackiem (notif-mod-row,
 * border-bottom var) trzymamy page-scoped w nonce-owanym <style> w samym
 * widoku (notification-preferences/index.php).
 * Uwaga: .d-none (display:none), .d-inline (display:inline), .w-80 (width:80px),
 * .flex-1 (flex:1) juz istnieja wyzej — reuzywamy (checkout, cron, escalation,
 * ai_prompts). W checkout.php .annual-price/.annual-total startuja z .d-none,
 * a toggleBilling() przelacza .d-none przez classList (CSSOM), bez inline style.
 * -------------------------------------------------------------------------- */
.minw-30   { min-width: 30px; }           /* <- style="min-width: 30px" (range output, settings/index) */
.w-48      { width: 48px; }               /* <- style="width: 48px; ..." (icon-zap, settings/index) */
.h-48      { height: 48px; }              /* <- style="...; height: 48px" (icon-zap, settings/index) */
.lh-17     { line-height: 1.7; }          /* <- style="line-height:1.7" (helper-info ul, ai_prompts) */
.maxw-1080 { max-width: 1080px; }         /* <- style="max-width: 1080px" (container, notification-preferences) */

/* ----------------------------------------------------------------------------
 * Atomy z konwersji widokow compass/{audits/run,surveys/result,roadmap,
 * audits/show,audits/checklists}.php (etap L2 Stage 2 — partia compass-2).
 * Kazda klasa = jedna faithful deklaracja, rowna co do znaku zastepowanemu
 * fragmentowi inline. Wartosc DYNAMICZNA paska postepu (run.php: width:<?=$percent?>%)
 * idzie przez helper data-css-width (nie tutaj).
 * Uwaga: .z-100 (z-index:100), .h-8 (height:8px), .w-200 (width:200px),
 * .minw-220 (min-width:220px), .cursor-pointer (cursor:pointer), .minw-120
 * (min-width:120px), .w-auto (width:auto), .fs-25r (font-size:2.5rem) juz
 * istnieja wyzej — reuzywamy.
 * -------------------------------------------------------------------------- */
.top-100   { top: 100px; }                /* <- style="top: 100px;" (sticky progress sidebar, run.php) */
.minw-320  { min-width: 320px; }          /* <- style="min-width: 320px;" (th Pytanie, surveys/result) */

/* ----------------------------------------------------------------------------
 * Atomy z konwersji widokow compass/{tasks/index,surveys/run,audits/index,
 * surveys/index}.php (etap L2 Stage 2 — partia compass-1).
 * Kazda klasa = jedna faithful deklaracja, rowna co do znaku zastepowanemu
 * fragmentowi inline. Wartosci DYNAMICZNE (szerokosc paska postepu
 * width:<?=$pct?>%) ida przez helper data-css-width. Border-left ze stalym
 * tokenem (--color-primary) jest faithful atomem tutaj. Wartosc dwustanowa
 * opacity:0.6 (zarchiwizowany run) -> warunkowa klasa .op-06.
 * Uwaga: .fs-115r, .fs-1r, .fs-105r, .fs-2r, .fs-15r, .mt-2px, .minw-220,
 * .minw-280, .w-70, .w-130, .w-120, .w-80, .w-60, .h-8, .h-6, .cursor-pointer
 * juz istnieja wyzej — reuzywamy.
 * -------------------------------------------------------------------------- */
.lh-15     { line-height: 1.5; }          /* <- style="line-height: 1.5" (survey card desc) */
.lh-16     { line-height: 1.6; }          /* <- style="line-height: 1.6" (survey intro <p>) */
.lh-18     { line-height: 1.8; }          /* <- style="line-height:1.8" (complete modal <ul>) */
.pl-11r    { padding-left: 1.1rem; }      /* <- style="padding-left: 1.1rem" (survey card <ul>) */
.op-06     { opacity: 0.6; }              /* <- style="opacity:0.6" (zarchiwizowany run <tr>) */
.w-140     { width: 140px; }              /* <- style="width: 140px" (tasks th Typ/Priorytet) */
.w-155     { width: 155px; }              /* <- style="width: 155px" (tasks status select) */
.w-220     { width: 220px; }              /* <- style="width: 220px" (tasks th Przypisane) */
.ws-preline { white-space: pre-line; }    /* <- style="white-space: pre-line" (task description) */
.transition-width-04 { transition: width 0.4s ease; } /* <- style="...transition: width 0.4s ease" (survey progress fill; width dynamiczne -> data-css-width) */
.border-left-4-primary { border-left: 4px solid var(--color-primary); } /* <- style="border-left: 4px solid var(--color-primary)" (survey intro card) */

/* ----------------------------------------------------------------------------
 * Atomy z konwersji widokow scribe/{documents,templates}/{index,show}.php
 * (etap L2 Stage 2 — partia scribe-1).
 * Kazda klasa = jedna faithful deklaracja, rowna co do znaku zastepowanemu
 * fragmentowi inline. Wartosci DYNAMICZNE (kolor act-badge wg aktu prawnego)
 * ida przez helper data-css-bg. Kolory arbitralne (amber button, ndoc-ic,
 * cytat odrzucenia) i szerokosci % kolumn tabeli trzymamy page-scoped w
 * nonce-owanym <style> w samych widokach.
 * Uwaga: .minw-200, .minw-150, .fs-2r, .flex-shrink-0, .ws-prewrap, .w-12,
 * .m-0 juz istnieja wyzej — reuzywamy.
 * -------------------------------------------------------------------------- */
.w-07em    { width: 0.7em; }              /* <- style="width:0.7em" (spinner generating, documents/index) */
.h-07em    { height: 0.7em; }             /* <- style="height:0.7em" (spinner generating, documents/index) */
.va--015em { vertical-align: -0.15em; }   /* <- style="vertical-align:-0.15em" (spinner generating, documents/index) */
.w-16      { width: 16px; }               /* <- style="width: 16px" (workflow icon, documents/show) */

/* ----------------------------------------------------------------------------
 * Atomy z konwersji widokow risko/{treatment_plans/index,risks/show,risks/edit,
 * risks/create}.php (etap L2 Stage 2 — partia risko).
 * Kazda klasa = jedna faithful deklaracja, rowna co do znaku zastepowanemu
 * fragmentowi inline. Wartosc DYNAMICZNA dwustanowa (banner incydentowy:
 * display:none|widoczny w risks/edit + risks/create) -> warunkowa klasa .d-none
 * (juz istnieje) przelaczana w JS przez classList (CSSOM, CSP-clean) zamiast
 * inline style.display. Arbitralne rgba/hex panelu residual (risks/edit) trzymamy
 * page-scoped w nonce-owanym <style> w samym widoku; arbitralny hex legendy
 * "Wysoki" (risks/create) — page-scoped w istniejacym nonce-owanym <style>.
 * Uwaga: .w-70, .w-130, .w-170, .w-160, .w-120, .w-200, .w-100, .lh-155, .d-none
 * juz istnieja wyzej — reuzywamy (treatment_plans/index th-y, risks/show karty
 * wyniku + paragrafy metodologii, banner edit/create).
 * -------------------------------------------------------------------------- */
.border-left-4-info { border-left: 4px solid var(--color-info); } /* <- style="border-left: 4px solid var(--color-info)" (methodology callout, risks/show) */

/* ----------------------------------------------------------------------------
 * Atomy z konwersji widokow scribe/{dashboard,generator/plan,generator/form,
 * documents/versions,documents/edit,documents/at-date}.php
 * (etap L2 Stage 2 — partia scribe-2).
 * Kazda klasa = jedna faithful deklaracja, rowna co do znaku zastepowanemu
 * fragmentowi inline. Przycisk "Generuj" (border-color:#FFC700;color:#a87800)
 * powtarza sie w dashboard.php (brak wlasnego nonce-owanego <style>) i plan.php
 * — arbitralne kolory hex trzymamy jako faithful atomy tutaj (jedna deklaracja
 * = jeden hex), reuzywalne w obu widokach (precedens: demo-banner auth/login).
 * Wartosci DYNAMICZNE pol path-a/path-b (form.php: display:none|widoczny wg trybu
 * A/B) ustawia nonce-owany skrypt setMode() w samym widoku (CSSOM, CSP-clean) —
 * stan poczatkowy przez warunkowa klasa .d-none (juz istnieje).
 * Uwaga: .fs-2r, .w-12, .w-14 juz istnieja wyzej — reuzywamy (versions, edit,
 * at-date).
 * -------------------------------------------------------------------------- */
.fs-092r      { font-size: 0.92rem; }    /* <- style="font-size:0.92rem" (form.php naglowek aktow prawnych) */
.bordc-FFC700 { border-color: #FFC700; } /* <- style="border-color:#FFC700" (przycisk Generuj, dashboard/plan) */
.text-a87800  { color: #a87800; }        /* <- style="color:#a87800" (przycisk Generuj, dashboard/plan) */
.text-92400E  { color: #92400E; }        /* ciemny amber — czytelny tekst na jasnym tle (#FFF8E1), niezalezny od motywu (baner demo na logowaniu) */

/* ----------------------------------------------------------------------------
 * Atomy z konwersji widokow guard/{monitoring/index,cve/my-cves,dashboard,
 * alert-rules/index,alert-rules/create,cve/index}.php (etap L2 Stage 2 — partia
 * guard). Kazda klasa = jedna faithful deklaracja, rowna co do znaku
 * zastepowanemu fragmentowi inline. Pary background/color ikon statystyk
 * (cve/my-cves: .stat-icon.si-*) oraz kolor placeholdera "—" z fallbackiem
 * (cve/index: .product-cell .pc-empty) trzymamy page-scoped w nonce-owanym
 * <style> w samych widokach. Kolor #fb923c (high-severity orange) powtarza sie
 * w guard/{dashboard,cve/my-cves} -> reuzywalny faithful atom tutaj.
 * Uwaga: .va--2, .mr-4px, .d-flex, .w-auto, .d-none, .flex-1, .minw-120,
 * .fs-2r, .fs-25r, .fs-15r, .op-04, .w-12, .text-primary-token,
 * .text-muted-token juz istnieja wyzej — reuzywamy.
 * Element vendorChecklist startuje z .d-none, a JS przelacza widocznosc przez
 * element.style.display (CSSOM, nadrzedne nad klasa) — bez inline style="".
 * -------------------------------------------------------------------------- */
.mt-1r      { margin-top: 1rem; }          /* <- style="margin-top:1rem" (vendorList) */
.gap-04r    { gap: 0.4rem; }               /* <- style="...gap:0.4rem" (vendor item actions) */
.p-05r-13r  { padding: 0.5rem 1.3rem; }    /* <- style="...padding:0.5rem 1.3rem" (vcSave button) */
.p-055r-15r { padding: 0.55rem 1.5rem; }   /* <- style="...padding:0.55rem 1.5rem;" (btnAddSystem) */
.text-orange-fb923c { color: #fb923c; }    /* <- style="color:#fb923c" (high-severity orange; guard dashboard/my-cves) */
.w-180      { width: 180px; }              /* <- style="width: 180px;" (cond-field select, alert-rules/create JS template) */

/* ----------------------------------------------------------------------------
 * Atomy z konwersji widokow dashboard/{profile,profile_2fa_setup,
 * profile_2fa_password}.php (etap L2 Stage 2 — partia dashboard-profile).
 * Kazda klasa = jedna faithful deklaracja, rowna co do znaku zastepowanemu
 * fragmentowi inline. Statyczne hex/rgba kafelka QR (profile_2fa_setup: tlo #fff
 * + box-shadow) trzymamy jako faithful atomy tutaj (jedna deklaracja = jeden
 * hex/shadow), bo widok nie ma wlasnego nonce-owanego <style> (precedens:
 * demo-banner auth/login, shop upsell). profile.php ma wlasny nonce-owany
 * <style>, ale konwertowane atomy sa reuzywalne, wiec ida tutaj.
 * Uwaga: .w-40, .h-40, .d-inline-block, .br-8, .fs-11r, .fs-15r, .ls-8,
 * .maxw-200, .maxw-250 juz istnieja wyzej — reuzywamy.
 * -------------------------------------------------------------------------- */
.ls-2          { letter-spacing: 2px; }    /* <- style="letter-spacing: 2px" / "letter-spacing:2px" (2fa secret code + verify input) */
.grid-col-span-2 { grid-column: span 2; }  /* <- style="grid-column: span 2;" (timezone form-group, profile) */
.p-16px        { padding: 16px; }          /* <- style="padding:16px" (qr-code box, profile_2fa_setup) */
.bg-white-fff  { background: #fff; }       /* <- style="background:#fff" (qr-code box, profile_2fa_setup) */
/* ----------------------------------------------------------------------------
 * Atomy z konwersji widokow admin/{audit-log,cron,templates/form,organizations}.php
 * (etap L2 Stage 2 — partia admin). Kazda klasa = jedna faithful deklaracja,
 * rowna co do znaku zastepowanemu fragmentowi inline.
 * Uwaga: .minw-200, .minw-150, .w-160, .w-50, .maxw-250 (audit-log filtry/tabela),
 * .ovx-auto, .fs-08r (cron crontab card), .ws-prewrap (cron <pre>), .fs-13px
 * (templates/form textarea) juz istnieja wyzej — reuzywamy. Czcionka monospace
 * 'JetBrains Mono' powtarza sie w cron/index.php (crontab card) i templates/form.php
 * (textarea HTML) -> jeden reuzywalny faithful atom (rozny od .ff-mono = czyste
 * monospace, wiec osobna klasa). Styl w organizations/index.php
 * (max-height:200px;overflow-y:auto) jest LITERALEM w JS template-literal
 * showOrgDetail() — pominiety zgodnie z zasada (literaly w JS pomijaj).
 * -------------------------------------------------------------------------- */
.ff-jetbrains-mono { font-family: 'JetBrains Mono', monospace; } /* <- style="font-family: 'JetBrains Mono', monospace" / "font-family:'JetBrains Mono',monospace" (cron crontab card, templates/form textarea) */
.shadow-qr     { box-shadow: 0 2px 8px rgba(0,0,0,0.1); } /* <- style="box-shadow:0 2px 8px rgba(0,0,0,0.1)" (qr-code box, profile_2fa_setup) */

/* ----------------------------------------------------------------------------
 * Atomy z konwersji layoutu app/Views/layouts/dashboard.php (etap L2 Stage 2 —
 * partia layout-dashboard). Kazda klasa = jedna faithful deklaracja, rowna co
 * do znaku zastepowanemu fragmentowi inline. Kolor markowy z fallbackiem
 * var(--color-primary, #FFC700) (przycisk "oznacz wszystkie jako przeczytane")
 * trzymamy jako faithful atom tutaj (jedna deklaracja = jeden token-z-fallbackiem),
 * bo layout nie ma wlasnego nonce-owanego <style> i nie wolno go dodawac
 * (precedens: .bg-color-border token-z-fallbackiem). Dwustanowy fragment
 * inline border-radius:0; [cursor:default] (powiadomienie bez linku) -> staly
 * atom .br-0 + warunkowa klasa .cursor-default (juz istnieje) przelaczana
 * przez PHP-ternary w atrybucie class, bez inline style.
 * Uwaga: .m-0 (margin:0), .p-0 (padding:0), .cursor-pointer (cursor:pointer),
 * .ovy-auto (overflow-y:auto), .cursor-default (cursor:default) juz istnieja
 * wyzej — reuzywamy.
 * -------------------------------------------------------------------------- */
.w-340      { width: 340px; }              /* <- style="width: 340px" (dropdown powiadomien) */
.maxh-360   { max-height: 360px; }         /* <- style="max-height: 360px" (lista powiadomien scroll) */
.minw-0     { min-width: 0; }              /* <- style="min-width: 0" (tresc powiadomienia, text-truncate) */
.br-0       { border-radius: 0; }          /* <- style="border-radius: 0" (dropdown-item powiadomienia) */
.bg-none    { background: none; }          /* <- style="background: none" (btn-link oznacz przeczytane) */
.border-none { border: none; }             /* <- style="border: none" (btn-link oznacz przeczytane) */
.text-primary-fallback { color: var(--color-primary, #FFC700); } /* <- style="color: var(--color-primary, #FFC700)" (btn-link oznacz przeczytane) */

/* L2 Stage 2 — domkniecie static (admin/dashboard) */
.h-14   { height: 14px; }            /* <- style="height:14px" */
.h-fit  { height: fit-content; }    /* <- style="height:fit-content" */

/* L2 Stage 3 — atomy dla styli wstrzykiwanych przez JS (innerHTML/template-literal) */
.bg-0f172a    { background: #0f172a; }      /* <- style="background:#0f172a" (bloki JSON) */
.maxh-200     { max-height: 200px; }       /* <- style="max-height:200px" */
.sev-critical { color: #ef4444; }           /* severity color (security-alerts modal) */
.sev-high     { color: #f59e0b; }
.sev-medium   { color: #3b82f6; }
.sev-low      { color: #22c55e; }
.sev-default  { color: #94a3b8; }

/* ----------------------------------------------------------------------------
 * UI-overhaul Faza C — symetria kafelkow (#COMPASS ankiety zgodnosci).
 * .mt-auto pcha rzad przyciskow akcji do dolu kafelka (card-body jako kolumna
 * flex), wyrownujac stopki kart w rzedzie niezaleznie od dlugosci opisu/listy.
 * Layout-only, bez zmiany logiki; reuzywalny atom (margin-top:auto).
 * -------------------------------------------------------------------------- */
.mt-auto { margin-top: auto; }
