/* ==========================================================================
   CorpRaasta app shell + dashboard.

   Built to the client's own design canvas ("ERP Suite v2.dc.html"): Poppins,
   the zinc token set, 9-10px controls, 12px cards on a hairline border with a
   whisper of shadow. Values below are lifted from that file, not approximated.

   Own `cra-` namespace so nothing collides with the older `.cr-*` rules in
   the minified corpraasta-theme.css, which still dresses the legacy screens.

   Layout contract
   ---------------
   .cra-shell   grid: [rail] [main] — the only place widths are decided
   .cra-side    the rail; width follows --cra-rail
   .cra-main    column: topbar (sticky) + its own scroll area
   Collapsed desktop and open-drawer mobile are class flags on .cra-shell, so
   no inline style can strand them.
   ========================================================================== */

:root {
    --bg: #ffffff;
    --fg: #09090b;
    --card: #ffffff;
    --muted: #f4f4f5;
    --muted2: #fafafa;
    --muted-fg: #71717a;
    --border: #e4e4e7;
    --primary: #18181b;
    --primary-fg: #fafafa;
    --sidebar: #ffffff;
    --ring: #a1a1aa;

    --g1: #d4d4d8;
    --g2: #71717a;
    --g3: #a1a1aa;

    --blue: #2563eb;
    --bluebg: #dbeafe;
    --green: #16a34a;
    --greenbg: #dcfce7;
    --red: #dc2626;
    --redbg: #fee2e2;
    --amb: #b45309;
    --ambbg: #fef3c7;
    --vio: #7c3aed;
    --viobg: #ede9fe;

    --shadow: 0 1px 2px rgba(16, 24, 40, .04);
    --shadow-pop: 0 12px 32px -10px rgba(16, 24, 40, .18);
    --ease: cubic-bezier(.4, 0, .2, 1);

    --cra-rail: 256px;
    --cra-rail-collapsed: 64px;
    --cra-topbar-h: 64px;
}

[data-cr-theme="dark"] {
    --bg: #09090b;
    --fg: #fafafa;
    --card: #131316;
    --muted: #27272a;
    --muted2: #1c1c1f;
    --muted-fg: #a1a1aa;
    --border: #27272a;
    --primary: #fafafa;
    --primary-fg: #18181b;
    --sidebar: #0c0c0e;
    --ring: #52525b;

    --g1: #3f3f46;
    --g2: #a1a1aa;
    --g3: #71717a;

    --blue: #60a5fa;
    --bluebg: #172554;
    --green: #4ade80;
    --greenbg: #052e16;
    --red: #f87171;
    --redbg: #450a0a;
    --amb: #fbbf24;
    --ambbg: #451a03;
    --vio: #a78bfa;
    --viobg: #2e1065;

    --shadow: none;
    --shadow-pop: 0 12px 32px -10px rgba(0, 0, 0, .7);
}

/* ── shell ─────────────────────────────────────────────────────────────── */

.cra-shell {
    display: grid;
    grid-template-columns: var(--cra-rail) minmax(0, 1fr);
    height: 100vh;
    background: var(--bg);
    color: var(--fg);
    font-family: Poppins, system-ui, -apple-system, sans-serif;
    font-size: 14px;
    -webkit-font-smoothing: antialiased;
    transition: grid-template-columns .2s var(--ease);
}

.cra-shell.is-collapsed {
    grid-template-columns: var(--cra-rail-collapsed) minmax(0, 1fr);
}

/* POS and the customer display are served without a rail, so main is the only
   child of the grid — and it landed in the rail track, which is why the whole
   POS screen was squeezed into a 256px column with the rest of the viewport
   blank. With no sidebar to place, there is only one track. */
.cra-shell:not(:has(> .cra-side)),
.cra-shell.is-collapsed:not(:has(> .cra-side)) {
    grid-template-columns: minmax(0, 1fr);
}

.cra-shell *,
.cra-shell *::before,
.cra-shell *::after { box-sizing: border-box; }

.cra-shell :focus-visible {
    outline: 2px solid var(--ring);
    outline-offset: 1px;
    border-radius: 6px;
}

/* The legacy sheets style bare h1..h6, table and p with their own colour and
   family. Element selectors beat inheritance, so the shell has to say it. */
.cra-shell h1, .cra-shell h2, .cra-shell h3,
.cra-shell h4, .cra-shell h5, .cra-shell h6 {
    margin: 0;
    color: var(--fg);
    font-family: inherit;
    font-weight: 600;
    line-height: 1.3;
}

.cra-shell p, .cra-shell td, .cra-shell th,
.cra-shell label, .cra-shell small,
.cra-shell b, .cra-shell strong {
    font-family: inherit;
    color: inherit;
}

.cra-shell table { background: transparent; }

/* The legacy sheet paints every anchor accent blue via `.cr a`, and the body
   carries `.cr`. A blanket `color: inherit` beats the component rules too —
   it swallowed the label on the solid button — so each thing that happens to
   be a link states its own colour at a weight `.cr a` cannot reach. */
.cra-shell a { text-decoration: none; }

.cra-shell .cra-side__brand,
.cra-shell .cra-nav__item,
.cra-shell .cra-btn,
.cra-shell .cra-pop a { color: var(--fg); }

.cra-shell .cra-btn--solid { color: var(--primary-fg); }
.cra-shell .cra-btn--solid:hover { color: var(--primary-fg); }
.cra-shell .cra-crumb__home,
.cra-shell .cra-card__more { color: var(--muted-fg); }

.cra-shell .cra-card__more:hover { color: var(--fg); }
.cra-shell .cra-crumb__home:hover { color: var(--fg); }
.cra-shell .cra-pop a.is-danger { color: var(--red); }

.cra-shell .cra-nav__sub .cra-nav__item { color: var(--muted-fg); }
.cra-shell .cra-nav__sub .cra-nav__item:hover,
.cra-shell .cra-nav__sub .cra-nav__item.is-active { color: var(--fg); }
.cra-shell ::-webkit-scrollbar { width: 8px; height: 8px; }
.cra-shell ::-webkit-scrollbar-thumb { background: var(--border); border-radius: 8px; }

/* ── rail ──────────────────────────────────────────────────────────────── */

.cra-side {
    position: sticky;
    top: 0;
    height: 100vh;
    display: flex;
    flex-direction: column;
    min-width: 0;
    background: var(--sidebar);
    border-inline-end: 1px solid var(--border);
    overflow: hidden;
}

.cra-side__brand {
    display: flex;
    align-items: center;
    gap: 10px;
    height: var(--cra-topbar-h);
    padding: 0 16px;
    flex-shrink: 0;
    color: var(--fg);
    text-decoration: none;
}

.cra-side__brand:hover { color: var(--fg); }

.cra-side__mark {
    display: grid;
    place-items: center;
    width: 34px;
    height: 34px;
    border-radius: 9px;
    flex-shrink: 0;
    background: var(--primary);
    color: var(--primary-fg);
    font-size: 13px;
    font-weight: 700;
    text-transform: uppercase;
}

.cra-side__id { min-width: 0; line-height: 1.2; }

.cra-side__id b {
    display: block;
    font-size: 13px;
    font-weight: 600;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.cra-side__id small {
    display: flex;
    align-items: center;
    gap: 5px;
    font-size: 11px;
    color: var(--green);
    white-space: nowrap;
}

.cra-side__id small i {
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: var(--green);
    flex-shrink: 0;
}

/* menu filter */
.cra-side__find {
    display: flex;
    align-items: center;
    gap: 8px;
    height: 36px;
    margin: 0 12px 12px;
    padding: 0 10px;
    border: 1px solid var(--border);
    border-radius: 9px;
    background: var(--muted2);
    color: var(--muted-fg);
    flex-shrink: 0;
}

.cra-side__find svg { width: 14px; height: 14px; flex-shrink: 0; }

.cra-side__find input {
    flex: 1;
    min-width: 0;
    border: 0;
    outline: 0;
    background: transparent;
    color: var(--fg);
    font: inherit;
    font-size: 13px;
}

.cra-side__find input::placeholder { color: var(--muted-fg); }
.cra-side__find input::-webkit-search-cancel-button { display: none; }

.cra-side__find kbd {
    font-size: 10px;
    font-family: inherit;
    border: 1px solid var(--border);
    border-radius: 4px;
    padding: 1px 5px;
    background: var(--card);
    color: var(--muted-fg);
}

.cra-side__scroll {
    flex: 1;
    min-height: 0;
    overflow-y: auto;
    overflow-x: hidden;
    padding: 0 10px 12px;
}

/* ── nav ───────────────────────────────────────────────────────────────── */

.cra-nav { display: flex; flex-direction: column; gap: 2px; }

.cra-nav__item {
    position: relative;
    display: flex;
    align-items: center;
    gap: 10px;
    min-height: 36px;
    padding: 0 10px;
    border-radius: 9px;
    color: var(--fg);
    font-size: 13px;
    font-weight: 500;
    text-decoration: none;
    white-space: nowrap;
    transition: background .12s var(--ease);
}

.cra-nav__item:hover { background: var(--muted); color: var(--fg); }
.cra-nav__item.is-active { background: var(--muted); color: var(--fg); }
.cra-nav__item.is-open { color: var(--fg); }

.cra-nav__ic {
    display: grid;
    place-items: center;
    width: 19px;
    height: 19px;
    flex-shrink: 0;
    color: var(--muted-fg);
}

.cra-nav__ic svg { width: 19px; height: 19px; display: block; }
.cra-nav__ic i { font-size: 15px; line-height: 1; }
.cra-nav__item.is-active .cra-nav__ic { color: var(--fg); }

.cra-nav__label {
    flex: 1;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
}

.cra-nav__chev {
    width: 14px;
    height: 14px;
    flex-shrink: 0;
    color: var(--muted-fg);
    transition: transform .18s var(--ease);
}

.cra-nav__item.is-open .cra-nav__chev { transform: rotate(90deg); }

.cra-nav__head {
    padding: 12px 10px 4px;
    font-size: 11px;
    font-weight: 500;
    letter-spacing: .02em;
    color: var(--muted-fg);
    white-space: nowrap;
}

.cra-nav__divider {
    height: 1px;
    margin: 8px 10px;
    background: var(--border);
}

.cra-nav__none {
    margin: 10px;
    font-size: 12.5px;
    color: var(--muted-fg);
}

/* menu filter state — the rail's search hides rows with a class so nothing
   about their open or active state is disturbed, and a group holding a match
   is forced open for as long as the query stands. */
.cra-nav__item.is-hidden,
.cra-nav__head.is-hidden,
.cra-nav__group.is-hidden { display: none; }

.cra-nav__sub.is-found { grid-template-rows: 1fr; }

/* submenu — animated on rows, never display, so it can reverse mid-flight */
.cra-nav__group { display: flex; flex-direction: column; }

.cra-nav__sub {
    display: grid;
    grid-template-rows: 0fr;
    transition: grid-template-rows .2s var(--ease);
}

.cra-nav__sub.is-open { grid-template-rows: 1fr; }
.cra-nav__sub > div { overflow: hidden; min-height: 0; }

.cra-nav__sub .cra-nav__item {
    min-height: 32px;
    margin-inline-start: 18px;
    padding-inline-start: 12px;
    border-inline-start: 1px solid var(--border);
    border-radius: 0 9px 9px 0;
    font-size: 13px;
    font-weight: 400;
    color: var(--muted-fg);
}

.cra-nav__sub .cra-nav__item:hover { color: var(--fg); }

.cra-nav__sub .cra-nav__item.is-active {
    background: var(--muted);
    border-inline-start-color: var(--fg);
    color: var(--fg);
    font-weight: 500;
}

.cra-nav__sub .cra-nav__ic { display: none; }

/* ── collapsed rail ────────────────────────────────────────────────────── */

.cra-shell.is-collapsed .cra-side__id,
.cra-shell.is-collapsed .cra-nav__label,
.cra-shell.is-collapsed .cra-nav__chev,
.cra-shell.is-collapsed .cra-nav__head,
.cra-shell.is-collapsed .cra-side__find { display: none; }

.cra-shell.is-collapsed .cra-side__brand,
.cra-shell.is-collapsed .cra-nav__item {
    justify-content: center;
    padding: 0;
}

.cra-shell.is-collapsed .cra-side__scroll { padding-inline: 8px; }
.cra-shell.is-collapsed .cra-nav__sub { grid-template-rows: 0fr; }

/* the label returns as a tooltip so an icon-only rail stays legible */
.cra-shell.is-collapsed .cra-nav__item[data-label]::after {
    content: attr(data-label);
    position: absolute;
    inset-inline-start: calc(100% + 8px);
    top: 50%;
    transform: translateY(-50%);
    padding: 5px 10px;
    border-radius: 7px;
    background: var(--primary);
    color: var(--primary-fg);
    font-size: 12px;
    font-weight: 500;
    white-space: nowrap;
    opacity: 0;
    pointer-events: none;
    transition: opacity .12s var(--ease);
    z-index: 60;
}

.cra-shell.is-collapsed .cra-nav__item:hover::after { opacity: 1; }

/* ── main column ───────────────────────────────────────────────────────── */

.cra-main {
    display: flex;
    flex-direction: column;
    min-width: 0;
    height: 100%;
    overflow: hidden;
}

.cra-topbar {
    position: sticky;
    top: 0;
    z-index: 25;
    display: flex;
    align-items: center;
    gap: 10px;
    min-height: var(--cra-topbar-h);
    padding: 8px 24px;
    background: var(--bg);
    border-bottom: 1px solid var(--border);
    flex-wrap: wrap;
}

.cra-crumb {
    display: flex;
    align-items: center;
    gap: 8px;
    min-width: 0;
    font-size: 13px;
    color: var(--muted-fg);
}

.cra-crumb b {
    color: var(--fg);
    font-weight: 500;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.cra-crumb__home {
    color: var(--muted-fg);
    text-decoration: none;
    white-space: nowrap;
}

.cra-crumb__home:hover { color: var(--fg); }

.cra-spacer { flex: 1; min-width: 0; }

.cra-scroll {
    flex: 1;
    min-width: 0;
    min-height: 0;
    overflow-y: auto;
    overflow-x: hidden;
    padding: 24px;
}

/* ── controls ──────────────────────────────────────────────────────────── */

.cra-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 7px;
    height: 32px;
    padding: 0 12px;
    border: 1px solid var(--border);
    border-radius: 8px;
    background: var(--card);
    color: var(--fg);
    font: inherit;
    font-size: 12px;
    font-weight: 500;
    white-space: nowrap;
    cursor: pointer;
    text-decoration: none;
    transition: background .12s var(--ease);
}

.cra-btn:hover { background: var(--muted); color: var(--fg); }

.cra-btn--solid {
    height: 34px;
    padding: 0 14px;
    border-radius: 9px;
    border-color: var(--primary);
    background: var(--primary);
    color: var(--primary-fg);
    font-size: 13px;
}

.cra-btn--solid:hover { background: var(--primary); color: var(--primary-fg); opacity: .9; }

.cra-ico { width: 32px; padding: 0; flex-shrink: 0; color: var(--muted-fg); }
.cra-ico:hover { color: var(--fg); }
.cra-btn svg { width: 15px; height: 15px; flex-shrink: 0; }

.cra-has-dot { position: relative; }

.cra-dot {
    position: absolute;
    top: 6px;
    inset-inline-end: 7px;
    width: 7px;
    height: 7px;
    border-radius: 50%;
    background: var(--red);
    border: 2px solid var(--card);
}

/* segmented range switch */
.cra-seg {
    display: inline-flex;
    align-items: center;
    padding: 3px;
    border-radius: 9px;
    background: var(--muted);
}

.cra-seg button {
    padding: 6px 12px;
    border: 0;
    border-radius: 7px;
    background: transparent;
    color: var(--muted-fg);
    font: inherit;
    font-size: 12px;
    font-weight: 500;
    white-space: nowrap;
    cursor: pointer;
    transition: background .12s var(--ease), color .12s var(--ease);
}

/* Some segmented controls are radios in labels rather than buttons — the
   project list is, because project.js listens for a change on .project_view
   and needs the input to stay. The label wears the segment; the radio itself
   is only there to be read. */
.cra-seg label {
    position: relative;
    margin: 0;
    padding: 6px 12px;
    border-radius: 7px;
    color: var(--muted-fg);
    font-size: 12px;
    font-weight: 500;
    white-space: nowrap;
    cursor: pointer;
    transition: background .12s var(--ease), color .12s var(--ease);
}

.cra-seg label input[type="radio"],
.cra-seg label input[type="checkbox"] {
    position: absolute;
    opacity: 0;
    width: 0;
    height: 0;
    margin: 0;
    pointer-events: none;
}

.cra-seg label:hover { color: var(--fg); }

.cra-seg label.is-active,
.cra-seg label.active,
.cra-seg label:has(input:checked) {
    background: var(--card);
    color: var(--fg);
    box-shadow: var(--shadow);
}

.cra-seg label:focus-within { outline: 2px solid var(--ring); outline-offset: 1px; }

.cra-seg button:hover { color: var(--fg); }

.cra-seg button.is-active {
    background: var(--card);
    color: var(--fg);
    box-shadow: var(--shadow);
}

.cra-select {
    height: 34px;
    padding: 0 12px;
    border: 1px solid var(--border);
    border-radius: 9px;
    background: var(--card);
    color: var(--fg);
    font: inherit;
    font-size: 12px;
    font-weight: 500;
    cursor: pointer;
}

/* ── account ───────────────────────────────────────────────────────────── */

.cra-who { position: relative; }

.cra-who > summary {
    list-style: none;
    display: flex;
    align-items: center;
    gap: 9px;
    padding-inline-start: 10px;
    margin-inline-start: 4px;
    border-inline-start: 1px solid var(--border);
    cursor: pointer;
    user-select: none;
}

.cra-who > summary::-webkit-details-marker { display: none; }

.cra-who__av {
    display: grid;
    place-items: center;
    width: 32px;
    height: 32px;
    border-radius: 8px;
    flex-shrink: 0;
    background: var(--vio);
    color: #fff;
    font-size: 12px;
    font-weight: 600;
    text-transform: uppercase;
}

.cra-who__txt { line-height: 1.25; text-align: start; max-width: 160px; }

.cra-who__txt b {
    display: block;
    font-size: 12px;
    font-weight: 600;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.cra-who__txt small {
    display: block;
    font-size: 11px;
    color: var(--muted-fg);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.cra-pop {
    position: absolute;
    top: calc(100% + 8px);
    inset-inline-end: 0;
    min-width: 224px;
    padding: 5px;
    border: 1px solid var(--border);
    border-radius: 12px;
    background: var(--card);
    box-shadow: var(--shadow-pop);
    z-index: 50;
}

.cra-pop__head {
    margin: 0;
    padding: 9px 10px;
    font-size: 12px;
    color: var(--muted-fg);
    line-height: 1.45;
}

.cra-pop__head b { color: var(--fg); font-size: 13px; }

.cra-pop a {
    display: flex;
    align-items: center;
    gap: 9px;
    padding: 8px 10px;
    border-radius: 8px;
    color: var(--fg);
    font-size: 13px;
    text-decoration: none;
}

.cra-pop a:hover { background: var(--muted); color: var(--fg); }
.cra-pop a svg { width: 15px; height: 15px; flex-shrink: 0; color: var(--muted-fg); }
.cra-pop a.is-danger { color: var(--red); }
.cra-pop a.is-danger svg { color: var(--red); }
.cra-pop__sep { height: 1px; margin: 4px 6px; background: var(--border); }

/* The language list can run to forty entries; the panel scrolls rather than
   growing past the viewport. */
.cra-pop--scroll { max-height: min(60vh, 420px); overflow-y: auto; }
.cra-pop a.is-active { background: var(--muted); font-weight: 500; }

/* Language switcher — the same control as the user chip beside it. */
.cra-lang { position: relative; }

.cra-lang > summary {
    list-style: none;
    display: flex;
    align-items: center;
    gap: 7px;
    height: 32px;
    padding-inline: 9px;
    border: 1px solid var(--border);
    border-radius: 8px;
    background: var(--card);
    color: var(--fg);
    font-size: 12.5px;
    font-weight: 500;
    cursor: pointer;
    user-select: none;
}

.cra-lang > summary::-webkit-details-marker { display: none; }
.cra-lang > summary:hover { background: var(--muted); }
.cra-lang > summary svg { width: 15px; height: 15px; color: var(--muted-fg); flex-shrink: 0; }
.cra-lang__txt { white-space: nowrap; }

/* On a narrow topbar the globe carries the meaning on its own. */
@media (max-width: 1279px) {
    .cra-lang__txt { display: none; }
    .cra-lang > summary { padding-inline: 8px; }
}

/* ══════════════════════════════════════════════════════════════════════════
   Dashboard
   ══════════════════════════════════════════════════════════════════════════ */

.cra-page { display: flex; flex-direction: column; gap: 20px; }

.cra-head {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 20px;
    flex-wrap: wrap;
}

.cra-head h1 {
    margin: 0;
    font-size: 26px;
    font-weight: 600;
    letter-spacing: -.02em;
}

.cra-head p {
    margin: 6px 0 0;
    font-size: 13px;
    color: var(--muted-fg);
}

.cra-head__acts {
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
}

/* auto-fit bands, as the canvas lays them out */
.cra-band {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
    gap: 16px;
}

.cra-band--wide {
    grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
}

/* Full bleed across whatever the band produced. How many figures fit a row
   changes with the width, so spanning a fixed number of cells would leave a
   hole at some of them. 1 / -1 has no such width. */
.cra-span-all { grid-column: 1 / -1; }

/* …except when the figures do not divide evenly into the row. Six of them in
   four columns wrap to 4 + 2 and leave two cells empty, and a full-width ad
   under that reads as a band below a hole. In that case it takes the cells
   that were going unused.

   The band is `repeat(auto-fit, minmax(240px, 1fr))` with a 16px gap, so the
   column count follows from the band's own width: n columns need
   n*240 + (n-1)*16. Six figures leave a remainder only at four columns (two
   cells spare) and five (four spare); every other count divides evenly and
   the ad keeps the whole row.

   The six is the $stats array in home/index.blade.php, a flat list with no
   conditions on it. Add or remove a figure there and these two spans have to
   be recomputed: n - (count mod n), for each n where that is not zero.

   Measured against the band rather than the viewport, because the rail can be
   collapsed — the same viewport gives a different column count with it open
   or shut, and a viewport media query would place the ad by a number that is
   no longer true. */
/* The container is the band, not the page.

   container-type makes an element the containing block for its fixed-position
   descendants, and every modal in the app is markup inside .cra-page — so
   putting it there stopped modals being fixed to the viewport. The Create
   Project dialog opened a third of the way down the page with a backdrop that
   covered only part of it. The band's own width is what decides the column
   count anyway, which is what these queries actually want to read. */
/* Not the band itself either. In WebKit — Safari, and hiSAI's own browser — a grid
   that is also a size container lays out auto-fit tracks against a width of zero:
   every figure card on the dashboard came out 42px wide, some 2px, while Chromium
   drew them at 318px. Measured in WKWebView with the band as container, then with
   the container on a wrapper: 42px → 253px, and the ad still spans four columns.
   So the container is a plain block around the grid, .cra-band-wrap, used only
   where a band holds a .cra-span-all ad (home). Nothing else reads these queries. */
.cra-band-wrap { container-type: inline-size; container-name: cra-band; }

@container cra-band (min-width: 1008px) and (max-width: 1263.98px) {
    .cra-band:not(.cra-band--wide) > .cra-ad.cra-span-all { grid-column: span 2; }
}

@container cra-band (min-width: 1264px) and (max-width: 1519.98px) {
    .cra-band:not(.cra-band--wide) > .cra-ad.cra-span-all { grid-column: span 4; }
}

/* Sharing a row with the figures means matching their height, not setting the
   row's own from a banner's aspect ratio. */
.cra-band:not(.cra-band--wide) > .cra-ad.cra-span-all:not([style*="grid-column: 1"]) {
    min-height: 0;
}

.cra-card {
    display: flex;
    flex-direction: column;
    min-width: 0;
    background: var(--card);
    border: 1px solid var(--border);
    border-radius: 12px;
    box-shadow: var(--shadow);
}

.cra-card--pad { padding: 20px; }

.cra-card__head {
    display: flex;
    align-items: flex-start;
    gap: 12px;
    padding: 18px 20px;
}

.cra-card__more {
    margin-inline-start: auto;
    flex-shrink: 0;
    font-size: 13px;
    color: var(--muted-fg);
    white-space: nowrap;
}

.cra-card__head--row {
    display: flex;
    justify-content: space-between;
    align-items: flex-start;
    gap: 14px;
    flex-wrap: wrap;
}

.cra-card__title { font-weight: 600; font-size: 14px; }

.cra-card__desc {
    margin: 2px 0 0;
    font-size: 13px;
    color: var(--muted-fg);
    line-height: 1.5;
}

.cra-card__side { font-size: 13px; color: var(--muted-fg); white-space: nowrap; }

.cra-card__foot {
    margin-top: 14px;
    padding-top: 14px;
    border-top: 1px solid var(--border);
    font-size: 12px;
    color: var(--muted-fg);
}

.cra-card__foot b { color: var(--fg); font-weight: 600; }

/* stat */
.cra-stat__top {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    min-height: 20px;
}

.cra-stat__label { font-size: 13px; font-weight: 500; color: var(--muted-fg); }

.cra-stat__badge {
    display: none;
    align-items: center;
    font-size: 11px;
    font-weight: 600;
    padding: 2px 8px;
    border-radius: 999px;
    background: var(--muted);
    color: var(--muted-fg);
    white-space: nowrap;
}

.cra-stat__badge.is-on { display: inline-flex; }
.cra-stat__badge.is-good { background: var(--greenbg); color: var(--green); }
.cra-stat__badge.is-bad { background: var(--redbg); color: var(--red); }

.cra-stat__value {
    margin-top: 14px;
    font-size: 28px;
    font-weight: 600;
    letter-spacing: -.03em;
    line-height: 1.15;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.cra-stat--due .cra-stat__value { color: var(--red); }
.cra-stat--net .cra-stat__value { color: var(--green); }

.cra-stat__note {
    margin-top: 6px;
    min-height: 18px;
    font-size: 12px;
    color: var(--muted-fg);
}

/* chart */
.cra-chart { position: relative; width: 100%; }

.cra-chart svg {
    width: 100%;
    height: 240px;
    margin-top: 18px;
    overflow: visible;
    display: block;
}

.cra-chart__x {
    display: flex;
    justify-content: space-between;
    font-size: 11px;
    color: var(--muted-fg);
    margin-top: 8px;
}

.cra-empty {
    padding: 40px 0;
    text-align: center;
    color: var(--muted-fg);
    font-size: 13px;
}

/* ══════════════════════════════════════════════════════════════════════════
   Contacts overview
   ══════════════════════════════════════════════════════════════════════════ */

.cra-split {
    display: grid;
    grid-template-columns: minmax(0, 1.1fr) minmax(0, 1fr);
    gap: 16px;
    align-items: start;
}

@media (max-width: 1100px) {
    .cra-split { grid-template-columns: minmax(0, 1fr); }
}

/* segment card — a filter that also reports */
.cra-seg-card {
    display: flex;
    flex-direction: column;
    gap: 12px;
    text-align: start;
    padding: 18px;
    border: 1px solid var(--border);
    border-radius: 12px;
    background: var(--card);
    box-shadow: var(--shadow);
    color: var(--fg);
    font: inherit;
    cursor: pointer;
    transition: border-color .12s var(--ease), background .12s var(--ease);
}

.cra-seg-card:hover { background: var(--muted2); }
.cra-seg-card.is-on { background: var(--muted2); }

.cra-seg-card__top {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
}

.cra-seg-card__share { font-size: 11px; color: var(--muted-fg); }

.cra-seg-card__n {
    display: block;
    font-size: 24px;
    font-weight: 600;
    letter-spacing: -.02em;
}

.cra-seg-card__sub {
    display: block;
    font-size: 12px;
    color: var(--muted-fg);
    margin-top: 2px;
}

.cra-seg-card__track {
    display: block;
    height: 5px;
    background: var(--muted);
    border-radius: 99px;
    overflow: hidden;
}

.cra-seg-card__track i { display: block; height: 100%; border-radius: 99px; }

.cra-pill {
    display: inline-flex;
    align-items: center;
    font-size: 11px;
    font-weight: 600;
    padding: 3px 9px;
    border-radius: 999px;
    white-space: nowrap;
    text-transform: capitalize;
}

/* list */
.cra-card__head--tools {
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
    padding: 16px 20px;
}

.cra-input {
    flex: 1;
    min-width: 160px;
    height: 34px;
    padding: 0 12px;
    border: 1px solid var(--border);
    border-radius: 9px;
    background: var(--bg);
    color: var(--fg);
    font: inherit;
    font-size: 13px;
    outline: none;
}

.cra-input:focus { border-color: var(--ring); }

/* `display` on a class out-ranks the hidden attribute, and several of these
   components are toggled with `el.hidden`. Settle it once for the shell. */
.cra-shell [hidden] { display: none !important; }

.cra-filterbar {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 0 20px 12px;
    font-size: 12px;
    color: var(--muted-fg);
}

.cra-filterbar b { color: var(--fg); text-transform: capitalize; }

.cra-filterbar button {
    margin-inline-start: auto;
    border: 0;
    background: transparent;
    color: var(--muted-fg);
    font: inherit;
    font-size: 12px;
    text-decoration: underline;
    cursor: pointer;
}

.cra-filterbar button:hover { color: var(--fg); }

.cra-rows--contact { grid-template-columns: 2fr 1fr 1fr; }

.cra-listfoot {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 12px 20px;
    border-top: 1px solid var(--border);
    font-size: 12px;
    color: var(--muted-fg);
}

.cra-pager {
    margin-inline-start: auto;
    display: inline-flex;
    align-items: center;
    gap: 6px;
}

.cra-pager button {
    height: 26px;
    padding: 0 10px;
    border: 1px solid var(--border);
    border-radius: 7px;
    background: var(--card);
    color: var(--fg);
    font: inherit;
    font-size: 12px;
    cursor: pointer;
}

.cra-pager button:hover:not(:disabled) { background: var(--muted); }
.cra-pager button:disabled { opacity: .45; cursor: default; }
.cra-pager > span { font-size: 12px; color: var(--muted-fg); }

.cra-row--pick {
    width: 100%;
    border-inline: 0;
    border-bottom: 0;
    background: transparent;
    font: inherit;
    text-align: start;
    color: var(--fg);
    cursor: pointer;
}

.cra-row--pick:hover { background: var(--muted2); }
.cra-row--pick.is-on { background: var(--muted); }

/* panel */
.cra-panel { position: sticky; top: 0; }

.cra-panel__head {
    display: flex;
    align-items: flex-start;
    gap: 14px;
    padding: 20px;
    border-bottom: 1px solid var(--border);
}

.cra-panel__av {
    display: grid;
    place-items: center;
    width: 48px;
    height: 48px;
    border-radius: 12px;
    flex: none;
    color: #fff;
    font-size: 15px;
    font-weight: 600;
}

.cra-panel__id { flex: 1; min-width: 0; }

.cra-panel__id b {
    display: block;
    font-size: 17px;
    font-weight: 600;
    letter-spacing: -.01em;
    overflow: hidden;
    text-overflow: ellipsis;
}

.cra-panel__id > span {
    display: block;
    font-size: 12px;
    color: var(--muted-fg);
    margin-top: 3px;
    text-transform: capitalize;
}

.cra-metrics {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(130px, 1fr));
}

.cra-metric {
    padding: 16px 20px;
    border-inline-end: 1px solid var(--border);
    border-bottom: 1px solid var(--border);
    min-width: 0;
}

.cra-metric span { display: block; font-size: 12px; color: var(--muted-fg); }

.cra-metric b {
    display: block;
    font-size: 18px;
    font-weight: 600;
    margin-top: 5px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.cra-panel__block { padding: 18px 20px; border-bottom: 1px solid var(--border); }
.cra-panel__block:last-child { border-bottom: 0; }

.cra-panel__title { font-size: 13px; font-weight: 600; margin-bottom: 12px; }

.cra-panel__row {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 12px;
    font-size: 12.5px;
    color: var(--muted-fg);
    padding: 3px 0;
}

.cra-panel__row b { color: var(--fg); font-weight: 600; text-align: end; word-break: break-word; }
.cra-panel__row a { font-size: 12px; color: var(--muted-fg); }

.cra-meter {
    height: 7px;
    background: var(--muted);
    border-radius: 99px;
    margin-top: 9px;
    overflow: hidden;
}

.cra-meter i { display: block; height: 100%; }

.cra-panel__legend {
    display: flex;
    gap: 16px;
    font-size: 11px;
    color: var(--muted-fg);
    margin-top: 9px;
}

.cra-led {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 9px 0;
    border-top: 1px solid var(--border);
    font-size: 13px;
}

.cra-led__main { flex: 1; min-width: 0; }
.cra-led__main b { display: block; font-weight: 500; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cra-led__main span { display: block; font-size: 11px; color: var(--muted-fg); }
.cra-led__amt { font-weight: 600; white-space: nowrap; }

.cra-panel__acts { display: flex; gap: 8px; margin-top: 16px; flex-wrap: wrap; }
.cra-panel__acts .cra-btn { flex: 1; min-width: 110px; justify-content: center; }

/* ── forms (settings screens on the shell) ────────────────────────────── */

.cra-form { display: flex; flex-direction: column; gap: 14px; }

.cra-field { display: flex; flex-direction: column; gap: 6px; }

.cra-field > span {
    font-size: 13px;
    font-weight: 500;
    color: var(--fg);
}

.cra-field input[type="url"],
.cra-field input[type="text"],
.cra-field input[type="file"] {
    width: 100%;
    min-width: 0;
    height: 38px;
    padding: 0 12px;
    border: 1px solid var(--border);
    border-radius: 9px;
    background: var(--bg);
    color: var(--fg);
    font: inherit;
    font-size: 13px;
    outline: none;
}

.cra-field input[type="file"] {
    padding: 7px 10px;
    height: auto;
    background: var(--muted2);
}

.cra-field input:focus { border-color: var(--ring); }
.cra-field small { font-size: 11.5px; color: var(--muted-fg); }

.cra-check {
    display: flex;
    align-items: center;
    gap: 8px;
    font-size: 13px;
    color: var(--fg);
    cursor: pointer;
}

.cra-check input { accent-color: var(--primary); }

.cra-form__acts { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 2px; }

.cra-ad-preview {
    display: grid;
    place-items: center;
    padding: 12px;
    margin-bottom: 16px;
    border: 1px solid var(--border);
    border-radius: 10px;
    background: var(--muted2);
}

.cra-ad-preview img { max-width: 100%; height: auto; display: block; }

/* ── sponsored slot ────────────────────────────────────────────────────
   Same card as its neighbours so it sits in the grid rather than on top of
   it, with the space reserved from first paint — a creative arriving late,
   or not at all, must not shift the figures beside it.
--------------------------------------------------------------------- */
.cra-ad {
    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;
    min-width: 0;
    min-height: 104px;
    padding: 14px 16px;
    border: 1px solid var(--border);
    border-radius: 12px;
    background: var(--card);
    box-shadow: var(--shadow);
    overflow: hidden;
}

.cra-ad img,
.cra-ad svg,
.cra-ad iframe {
    max-width: 100%;
    height: auto;
    display: block;
}

.cra-ad__mark {
    position: absolute;
    top: 8px;
    inset-inline-end: 10px;
    font-size: 9.5px;
    font-weight: 500;
    letter-spacing: .06em;
    text-transform: uppercase;
    color: var(--muted-fg);
    opacity: .7;
    pointer-events: none;
}

/* unsold: a quiet dashed hold, not a broken-looking box */
.cra-ad--empty {
    border-style: dashed;
    background: var(--muted2);
    box-shadow: none;
}

.cra-ad__placeholder {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 3px;
    text-align: center;
}

.cra-ad__name {
    font-size: 12.5px;
    font-weight: 500;
    color: var(--muted-fg);
    text-transform: capitalize;
}

.cra-ad__size { font-size: 11px; color: var(--muted-fg); opacity: .65; }

/* chart legend — a chip per series, clicking one drops it out of the plot */
.cra-keys {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    margin-top: 14px;
}

.cra-key {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    padding: 4px 10px;
    border: 1px solid var(--border);
    border-radius: 999px;
    background: var(--card);
    color: var(--fg);
    font: inherit;
    font-size: 12px;
    font-weight: 500;
    cursor: pointer;
    transition: background .12s var(--ease), opacity .12s var(--ease);
}

.cra-key:hover { background: var(--muted); }
.cra-key i { width: 9px; height: 9px; border-radius: 2px; flex-shrink: 0; }
.cra-key.is-off { opacity: .45; }
.cra-key.is-off i { background: var(--g1) !important; }

/* world map */
.cra-map { margin-top: 16px; }
.cra-map svg { width: 100%; height: auto; display: block; }

.cra-land {
    fill: var(--muted);
    stroke: var(--border);
    stroke-width: .4;
    transition: fill .14s var(--ease);
}

.cra-land.lvl1 { fill: color-mix(in srgb, var(--blue) 25%, var(--muted)); }
.cra-land.lvl2 { fill: color-mix(in srgb, var(--blue) 55%, var(--muted)); }
.cra-land.lvl3 { fill: var(--blue); }

/* country bars */
.cra-bars {
    display: flex;
    flex-direction: column;
    gap: 14px;
    margin-top: 20px;
    flex: 1;
}

.cra-bar { display: flex; flex-direction: column; gap: 7px; }

.cra-bar__top {
    display: flex;
    justify-content: space-between;
    gap: 12px;
    font-size: 13px;
}

.cra-bar__name { display: flex; align-items: center; gap: 8px; min-width: 0; }

.cra-bar__name i {
    width: 9px;
    height: 9px;
    border-radius: 2px;
    flex-shrink: 0;
}

.cra-bar__name span {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.cra-bar__val { color: var(--muted-fg); white-space: nowrap; }

.cra-bar__track {
    height: 6px;
    background: var(--muted);
    border-radius: 99px;
    overflow: hidden;
}

.cra-bar__fill { height: 100%; border-radius: 99px; }

.cra-legend {
    display: flex;
    gap: 14px;
    flex-wrap: wrap;
    font-size: 11px;
    color: var(--muted-fg);
    margin-top: 18px;
    border-top: 1px solid var(--border);
    padding-top: 14px;
}

.cra-legend span { display: flex; align-items: center; gap: 6px; }
.cra-legend i { width: 9px; height: 9px; border-radius: 2px; }

/* data rows — a grid, not a table, so columns line up across cards */
.cra-rows__head,
.cra-row {
    display: grid;
    gap: 12px;
    align-items: center;
    padding: 8px 20px;
    border-top: 1px solid var(--border);
}

.cra-rows__head {
    font-size: 12px;
    font-weight: 500;
    color: var(--muted-fg);
    background: var(--muted2);
}

.cra-row { padding: 12px 20px; font-size: 13px; }

.cra-rows--3 .cra-rows__head,
.cra-rows--3 .cra-row { grid-template-columns: 2fr 1fr 1fr; }

.cra-rows--who .cra-rows__head,
.cra-rows--who .cra-row { grid-template-columns: 1.6fr 1fr 1fr; }

.cra-row__end { text-align: end; font-weight: 600; white-space: nowrap; }
.cra-rows__head .cra-row__end { font-weight: 500; }
.cra-row__dim { color: var(--muted-fg); overflow: hidden; text-overflow: ellipsis; }

.cra-row__lead { display: flex; align-items: center; gap: 10px; min-width: 0; }

.cra-row__av {
    width: 30px;
    height: 30px;
    border-radius: 8px;
    background: var(--muted);
    display: grid;
    place-items: center;
    font-size: 11px;
    font-weight: 600;
    flex-shrink: 0;
    text-transform: uppercase;
}

.cra-row__main { min-width: 0; }
.cra-row__main b { display: block; font-weight: 500; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.cra-row__sub {
    display: block;
    font-size: 11px;
    color: var(--muted-fg);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.cra-row__sku { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 12px; }

.cra-chip {
    display: inline-flex;
    align-items: center;
    font-size: 11px;
    font-weight: 600;
    padding: 3px 8px;
    border-radius: 6px;
    background: var(--muted);
    color: var(--muted-fg);
    white-space: nowrap;
}

.cra-chip--bad { background: var(--redbg); color: var(--red); }
.cra-chip--warn { background: var(--ambbg); color: var(--amb); }
.cra-chip--ok { background: var(--greenbg); color: var(--green); }

.cra-rows__empty {
    padding: 28px 20px;
    text-align: center;
    color: var(--muted-fg);
    font-size: 13px;
    border-top: 1px solid var(--border);
}

/* skeleton */
.cra-sk {
    display: block;
    border-radius: 6px;
    background: linear-gradient(90deg, var(--muted) 25%, var(--border) 37%, var(--muted) 63%);
    background-size: 400% 100%;
    animation: cra-sheen 1.3s ease-in-out infinite;
}

.cra-sk--val { height: 26px; width: 58%; }

@keyframes cra-sheen {
    0% { background-position: 100% 50%; }
    100% { background-position: 0 50%; }
}

/* ══════════════════════════════════════════════════════════════════════════
   Legacy screens inside the shell

   Everything that is not yet rebuilt still renders AdminLTE and Bootstrap
   markup dressed by the minified corpraasta-theme.css, which was drawn for
   the old warm-grey, Ubuntu design. Beside the new chrome those pages read as
   a different product — washed-out modal fields, a blue statement table, tabs
   stacked on top of each other. Rather than restyle each screen, the handful
   of components they are all built from are brought into this palette here.

   Everything is scoped under .cra-shell so nothing leaks to the POS screen,
   which keeps its own layout.
   ══════════════════════════════════════════════════════════════════════════ */

.cra-scroll .box,
.cra-scroll .panel,
.cra-scroll .well {
    background: var(--card);
    border: 1px solid var(--border);
    border-radius: 12px;
    box-shadow: var(--shadow);
    color: var(--fg);
}

.cra-scroll .box-header,
.cra-scroll .panel-heading {
    background: transparent;
    border-bottom: 1px solid var(--border);
    color: var(--fg);
    padding: 16px 20px;
    border-radius: 12px 12px 0 0;
}

.cra-scroll .box-title,
.cra-scroll .panel-title {
    font-size: 15px;
    font-weight: 600;
    letter-spacing: -.01em;
}

.cra-scroll .box-body,
.cra-scroll .panel-body { padding: 18px 20px; }

/* tables, including DataTables' wrapper */
.cra-scroll table.table,
.cra-scroll table.dataTable {
    background: transparent;
    color: var(--fg);
    border-color: var(--border);
}

.cra-scroll table.table > thead > tr > th,
.cra-scroll table.dataTable thead th {
    background: var(--muted2);
    border-bottom: 1px solid var(--border) !important;
    border-top: 0 !important;
    color: var(--muted-fg);
    font-size: 12px;
    font-weight: 500;
    white-space: nowrap;
    padding: 10px 12px;
}

.cra-scroll table.table > tbody > tr > td,
.cra-scroll table.dataTable tbody td {
    border-top: 1px solid var(--border) !important;
    padding: 11px 12px;
    font-size: 13px;
    vertical-align: middle;
}

.cra-scroll table.table > tbody > tr:hover > td,
.cra-scroll table.dataTable tbody tr:hover td { background: var(--muted2); }

.cra-scroll table.dataTable tfoot th,
.cra-scroll table.table > tfoot > tr > th {
    background: var(--muted2);
    border-top: 1px solid var(--border) !important;
    color: var(--fg);
    font-size: 13px;
    padding: 11px 12px;
}

.cra-scroll .dataTables_wrapper .dataTables_length,
.cra-scroll .dataTables_wrapper .dataTables_filter,
.cra-scroll .dataTables_wrapper .dataTables_info,
.cra-scroll .dataTables_wrapper .dataTables_paginate {
    color: var(--muted-fg);
    font-size: 12.5px;
}

/* controls */
.cra-scroll .form-control,
.cra-scroll .select2-container--default .select2-selection--single,
.cra-scroll .select2-container--default .select2-selection--multiple,
.cra-scroll .input-group-addon {
    background: var(--bg);
    border: 1px solid var(--border);
    border-radius: 9px;
    color: var(--fg);
    box-shadow: none;
    font-size: 13px;
}

.cra-scroll .form-control:focus,
.cra-scroll .select2-container--default.select2-container--focus .select2-selection--multiple {
    border-color: var(--ring);
    box-shadow: none;
}

.cra-scroll .form-control::placeholder { color: var(--muted-fg); }
.cra-scroll .input-group-addon { background: var(--muted2); color: var(--muted-fg); }
.cra-scroll label,
.cra-scroll .control-label { color: var(--fg); font-size: 13px; font-weight: 500; }
.cra-scroll .help-block { color: var(--muted-fg); font-size: 12px; }

.cra-scroll .select2-container--default .select2-selection--single .select2-selection__rendered {
    color: var(--fg);
    line-height: 34px;
}

.cra-scroll .btn {
    border-radius: 9px;
    border: 1px solid var(--border);
    background: var(--card);
    color: var(--fg);
    font-size: 13px;
    font-weight: 500;
    box-shadow: none;
}

.cra-scroll .btn:hover { background: var(--muted); color: var(--fg); }

.cra-scroll .btn-primary,
.cra-scroll .btn-success,
.cra-scroll .btn-info {
    background: var(--primary);
    border-color: var(--primary);
    color: var(--primary-fg);
}

.cra-scroll .btn-primary:hover,
.cra-scroll .btn-success:hover,
.cra-scroll .btn-info:hover { opacity: .9; background: var(--primary); color: var(--primary-fg); }

.cra-scroll .btn-danger {
    background: var(--red);
    border-color: var(--red);
    color: #fff;
}

/* tabs — the contact view stacks its icon tabs without this */
.cra-scroll .nav-tabs {
    border-bottom: 1px solid var(--border);
    display: flex;
    flex-wrap: wrap;
    gap: 2px;
}

/* nav-justified gives each item width:1%, which inside a flex row collapses
   the anchors to 28px and stacks the labels on top of one another. */
.cra-scroll .nav-tabs > li,
.cra-scroll .nav-tabs.nav-justified > li {
    display: block;
    float: none;
    width: auto;
    flex: 0 1 auto;
    margin: 0;
}

.cra-scroll .nav-tabs > li > a {
    display: flex;
    align-items: center;
    gap: 7px;
    border: 0;
    border-bottom: 2px solid transparent;
    border-radius: 0;
    margin: 0;
    padding: 11px 14px;
    color: var(--muted-fg);
    font-size: 13px;
    font-weight: 500;
    line-height: 1.2;
    white-space: nowrap;
    background: transparent;
}

.cra-scroll .nav-tabs > li > a:hover { background: var(--muted2); color: var(--fg); }

.cra-scroll .nav-tabs > li.active > a,
.cra-scroll .nav-tabs > li.active > a:hover,
.cra-scroll .nav-tabs > li.active > a:focus {
    background: transparent;
    border: 0;
    border-bottom: 2px solid var(--fg);
    color: var(--fg);
}

.cra-scroll .tab-content { padding-top: 18px; }

/* AdminLTE hard-codes white on these wrappers. In dark mode the text is
   inherited near-white from the shell, so the whole panel came out white on
   white — the contact ledger was invisible rather than merely off-palette. */
.cra-scroll .nav-tabs-custom,
.cra-scroll .nav-tabs-custom > .tab-content,
.cra-scroll .content-wrapper,
.cra-scroll .tab-pane {
    background: var(--card);
    color: var(--fg);
}

.cra-scroll .nav-tabs-custom {
    border: 1px solid var(--border);
    border-radius: 12px;
    box-shadow: var(--shadow);
    overflow: hidden;
}

.cra-scroll .nav-tabs-custom > .nav-tabs { background: transparent; margin: 0; }
.cra-scroll .nav-tabs-custom > .tab-content { padding: 18px 20px; }

/* Card headers and the DataTables toolbar are rendered into the same strip,
   which is why the Add button was sitting on top of the export buttons. Let
   the strip wrap and give each cluster its own place in it. */
.cra-scroll .box-header,
.cra-scroll .cr-card__head {
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
}

.cra-scroll .box-tools {
    position: static;
    float: none;
    margin-inline-start: auto;
    display: inline-flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
}

.cra-scroll .dataTables_wrapper .dt-buttons,
.cra-scroll .dataTables_wrapper .dataTables_length,
.cra-scroll .dataTables_wrapper .dataTables_filter {
    float: none;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    flex-wrap: wrap;
    margin: 0;
}

.cra-scroll .dataTables_wrapper .dataTables_filter { margin-inline-start: auto; }
.cra-scroll .dataTables_wrapper .dt-buttons .btn { font-size: 12px; padding: 6px 11px; }

/* The legacy Add button ships an indigo gradient pill from another palette. */
.cra-scroll .btn-modal.tw-dw-btn,
.cra-scroll a.tw-dw-btn[class*="tw-from-"],
.cra-scroll button.tw-dw-btn[class*="tw-from-"] {
    background: var(--primary) !important;
    background-image: none !important;
    border: 1px solid var(--primary) !important;
    border-radius: 9px !important;
    color: var(--primary-fg) !important;
    font-weight: 500 !important;
    height: 34px;
    min-height: 34px;
    padding: 0 14px;
}

/* the ledger statement ships its own steel blue headings */
.cra-scroll .blue-heading,
.cra-scroll .table > thead > tr > th[style*="background"],
.cra-scroll .table td[style*="background"] {
    background: var(--muted2) !important;
    color: var(--fg) !important;
    border-radius: 8px;
}

/* headings and muted text */
.cra-scroll .page-title,
.cra-scroll .box-title small { color: var(--fg); }
.cra-scroll .text-muted { color: var(--muted-fg) !important; }

/* AdminLTE's fixed greys. Ledger format 3 bands its rows with these, and in
   dark mode the inherited near-white text sat on a light grey. */
.cra-scroll .bg-gray,
.cra-scroll .bg-light-gray,
.cra-scroll .bg-gray-light,
.cra-scroll .row-border,
.cra-scroll .well {
    background: var(--muted2) !important;
    color: var(--fg) !important;
}

.cra-scroll .bg-gray *,
.cra-scroll .bg-light-gray * { color: inherit; }

/* dropdowns */
.cra-scroll .dropdown-menu,
.modal-content .dropdown-menu {
    background: var(--card);
    border: 1px solid var(--border);
    border-radius: 10px;
    box-shadow: var(--shadow-pop);
    padding: 5px;
    min-width: 180px;
}

.cra-scroll .dropdown-menu > li > a,
.modal-content .dropdown-menu > li > a {
    color: var(--fg);
    font-size: 13px;
    padding: 8px 10px;
    border-radius: 7px;
    display: flex;
    align-items: center;
    gap: 8px;
}

.cra-scroll .dropdown-menu > li > a:hover,
.cra-scroll .dropdown-menu > li > a:focus,
.modal-content .dropdown-menu > li > a:hover {
    background: var(--muted);
    color: var(--fg);
}

.cra-scroll .dropdown-menu .divider,
.modal-content .dropdown-menu .divider {
    background: var(--border);
    margin: 4px 6px;
}

.cra-scroll .dropdown-header { color: var(--muted-fg); font-size: 11px; padding: 6px 10px; }

/* select2 */
.cra-scroll .select2-container--default .select2-selection--single,
.cra-scroll .select2-container--default .select2-selection--multiple,
.modal-content .select2-container--default .select2-selection--single,
.modal-content .select2-container--default .select2-selection--multiple {
    min-height: 38px;
    padding: 2px 4px;
}

.select2-dropdown {
    background: var(--card);
    border: 1px solid var(--border);
    border-radius: 10px;
    color: var(--fg);
    box-shadow: var(--shadow-pop);
    z-index: 1060;
}

.select2-container--default .select2-results__option {
    color: var(--fg);
    font-size: 13px;
    padding: 8px 12px;
}

.select2-container--default .select2-results__option--highlighted[aria-selected],
.select2-container--default .select2-results__option[aria-selected="true"] {
    background: var(--muted);
    color: var(--fg);
}

.select2-container--default .select2-search--dropdown .select2-search__field {
    background: var(--bg);
    border: 1px solid var(--border);
    border-radius: 8px;
    color: var(--fg);
    padding: 7px 10px;
}

.select2-container--default .select2-selection--multiple .select2-selection__choice {
    background: var(--muted);
    border: 1px solid var(--border);
    border-radius: 7px;
    color: var(--fg);
    padding: 2px 8px;
}

.select2-container--default .select2-selection__placeholder { color: var(--muted-fg); }
.select2-container--default .select2-selection__arrow b { border-top-color: var(--muted-fg); }

/* pagination */
.cra-scroll .pagination > li > a,
.cra-scroll .pagination > li > span {
    background: var(--card);
    border: 1px solid var(--border);
    color: var(--fg);
    font-size: 12.5px;
    margin: 0 2px;
    border-radius: 8px;
    padding: 6px 11px;
}

.cra-scroll .pagination > li > a:hover { background: var(--muted); }

.cra-scroll .pagination > .active > a,
.cra-scroll .pagination > .active > span,
.cra-scroll .pagination > .active > a:hover {
    background: var(--primary);
    border-color: var(--primary);
    color: var(--primary-fg);
}

.cra-scroll .pagination > .disabled > a,
.cra-scroll .pagination > .disabled > span { opacity: .45; }

/* badges, labels and alerts */
.cra-scroll .label,
.cra-scroll .badge,
.modal-content .label,
.modal-content .badge {
    font-size: 11px;
    font-weight: 600;
    padding: 3px 9px;
    border-radius: 999px;
    background: var(--muted);
    color: var(--muted-fg);
}

.cra-scroll .label-success, .cra-scroll .badge-success { background: var(--greenbg); color: var(--green); }
.cra-scroll .label-danger, .cra-scroll .badge-danger { background: var(--redbg); color: var(--red); }
.cra-scroll .label-warning, .cra-scroll .badge-warning { background: var(--ambbg); color: var(--amb); }
.cra-scroll .label-info, .cra-scroll .label-primary { background: var(--bluebg); color: var(--blue); }

.cra-scroll .alert {
    border: 1px solid var(--border);
    border-radius: 10px;
    background: var(--muted2);
    color: var(--fg);
    font-size: 13px;
    padding: 12px 14px;
}

.cra-scroll .alert-success { background: var(--greenbg); color: var(--green); border-color: transparent; }
.cra-scroll .alert-danger { background: var(--redbg); color: var(--red); border-color: transparent; }
.cra-scroll .alert-warning { background: var(--ambbg); color: var(--amb); border-color: transparent; }
.cra-scroll .alert-info { background: var(--bluebg); color: var(--blue); border-color: transparent; }

/* button groups keep one seam rather than two */
.cra-scroll .btn-group > .btn { border-radius: 0; }
.cra-scroll .btn-group > .btn:first-child { border-radius: 9px 0 0 9px; }
.cra-scroll .btn-group > .btn:last-child { border-radius: 0 9px 9px 0; }
.cra-scroll .btn-group > .btn:only-child { border-radius: 9px; }
.cra-scroll .btn-group > .btn + .btn { margin-inline-start: -1px; }

/* colour helpers the legacy screens lean on */
.cra-scroll .text-danger, .modal-content .text-danger { color: var(--red) !important; }
.cra-scroll .text-success, .modal-content .text-success { color: var(--green) !important; }
.cra-scroll .text-warning, .modal-content .text-warning { color: var(--amb) !important; }
.cra-scroll .text-info, .modal-content .text-info { color: var(--blue) !important; }

/* modals — these are appended to <body>, outside .cra-shell, so they are
   scoped by the theme stamp instead */
.modal-content {
    background: var(--card);
    border: 1px solid var(--border);
    border-radius: 14px;
    box-shadow: var(--shadow-pop);
    color: var(--fg);
}

.modal-header,
.modal-footer {
    border-color: var(--border);
    padding: 16px 20px;
}

.modal-title { font-size: 16px; font-weight: 600; letter-spacing: -.01em; }
.modal-body { padding: 18px 20px; }

.modal-content .form-control,
.modal-content .select2-container--default .select2-selection--single,
.modal-content .input-group-addon {
    background: var(--bg);
    border: 1px solid var(--border);
    border-radius: 9px;
    color: var(--fg);
    font-size: 13px;
}

.modal-content .input-group-addon { background: var(--muted2); color: var(--muted-fg); }
.modal-content label, .modal-content .control-label { color: var(--fg); font-size: 13px; font-weight: 500; }

.modal-content .btn {
    border-radius: 9px;
    border: 1px solid var(--border);
    background: var(--card);
    color: var(--fg);
    font-size: 13px;
    font-weight: 500;
}

.modal-content .btn-primary,
.modal-content .btn-success {
    background: var(--primary);
    border-color: var(--primary);
    color: var(--primary-fg);
}

/* the payment modal opens with its summary panels blank until the fetch
   lands; give them a visible resting state rather than white on white */
.modal-content .well,
.modal-content .box { background: var(--muted2); border: 1px solid var(--border); border-radius: 10px; }

.modal-content .close { color: var(--muted-fg); opacity: 1; text-shadow: none; font-weight: 400; }
.modal-content .close:hover { color: var(--fg); }
.modal-backdrop.in { opacity: .5; }
.modal-content .bg-gray,
.modal-content .bg-light-gray { background: var(--muted2) !important; color: var(--fg) !important; }

/* ══════════════════════════════════════════════════════════════════════════
   Default components

   Buttons, inputs, dropdowns and tables as the legacy screens declare them,
   brought fully into this palette — sizes, states and the widgets Bootstrap
   and DataTables draw for themselves. `.cra-scope` covers both places these
   appear: inside the shell's scroll area, and in modals, which Bootstrap
   appends to <body> outside it.
   ══════════════════════════════════════════════════════════════════════════ */

/* ── buttons ──────────────────────────────────────────────────────────── */

.cra-scroll .btn,
.modal-content .btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 7px;
    height: 34px;
    padding: 0 14px;
    border: 1px solid var(--border);
    border-radius: 9px;
    background: var(--card);
    color: var(--fg);
    font-size: 13px;
    font-weight: 500;
    line-height: 1;
    white-space: nowrap;
    box-shadow: none;
    text-shadow: none;
    transition: background .12s var(--ease), opacity .12s var(--ease);
}

.cra-scroll .btn:hover,
.cra-scroll .btn:focus,
.modal-content .btn:hover { background: var(--muted); color: var(--fg); outline: none; }

.cra-scroll .btn-xs, .modal-content .btn-xs { height: 26px; padding: 0 9px; font-size: 11.5px; border-radius: 7px; }
.cra-scroll .btn-sm, .modal-content .btn-sm { height: 30px; padding: 0 11px; font-size: 12.5px; border-radius: 8px; }
.cra-scroll .btn-lg, .modal-content .btn-lg { height: 40px; padding: 0 18px; font-size: 14px; border-radius: 10px; }
.cra-scroll .btn-block, .modal-content .btn-block { width: 100%; }

.cra-scroll .btn-primary, .cra-scroll .btn-success, .cra-scroll .btn-info,
.modal-content .btn-primary, .modal-content .btn-success, .modal-content .btn-info {
    background: var(--primary);
    border-color: var(--primary);
    color: var(--primary-fg);
}

.cra-scroll .btn-primary:hover, .cra-scroll .btn-success:hover, .cra-scroll .btn-info:hover,
.modal-content .btn-primary:hover, .modal-content .btn-success:hover {
    background: var(--primary);
    color: var(--primary-fg);
    opacity: .9;
}

.cra-scroll .btn-danger, .modal-content .btn-danger {
    background: var(--red); border-color: var(--red); color: #fff;
}

.cra-scroll .btn-warning, .modal-content .btn-warning {
    background: var(--amb); border-color: var(--amb); color: #fff;
}

.cra-scroll .btn-link, .modal-content .btn-link {
    border-color: transparent;
    background: transparent;
    color: var(--muted-fg);
    text-decoration: none;
    height: auto;
    padding: 4px 6px;
}

.cra-scroll .btn-link:hover { background: transparent; color: var(--fg); text-decoration: underline; }

.cra-scroll .btn[disabled],
.cra-scroll .btn.disabled,
.modal-content .btn[disabled] { opacity: .5; box-shadow: none; }

.cra-scroll .btn:focus-visible,
.modal-content .btn:focus-visible { outline: 2px solid var(--ring); outline-offset: 1px; }

/* ── inputs ───────────────────────────────────────────────────────────── */

.cra-shell .cra-scroll .form-control,
.cra-shell .cra-scroll .form-control.input-sm,
.cra-shell .cra-scroll .form-control.input-lg,
.cra-scroll .form-control,
.cra-scroll select.form-control,
.cra-scroll input[type="text"], .cra-scroll input[type="email"], .cra-scroll input[type="number"],
.cra-scroll input[type="password"], .cra-scroll input[type="date"], .cra-scroll input[type="search"],
.cra-scroll input[type="tel"], .cra-scroll input[type="url"], .cra-scroll textarea, .cra-scroll select,
.modal-content .form-control, .modal-content input[type="text"], .modal-content input[type="number"],
.modal-content textarea, .modal-content select {
    height: 38px;
    padding: 0 12px;
    border: 1px solid var(--border);
    border-radius: 9px;
    background: var(--bg);
    color: var(--fg);
    font-size: 13px;
    box-shadow: none;
    transition: border-color .12s var(--ease);
}

.cra-scroll textarea, .cra-scroll textarea.form-control,
.modal-content textarea { height: auto; min-height: 84px; padding: 10px 12px; line-height: 1.5; }

.cra-shell .cra-scroll .input-sm,
.cra-shell .cra-scroll select.input-sm {
    height: 32px;
    padding: 0 10px;
    border-radius: 8px;
    font-size: 12.5px;
}

.cra-shell .cra-scroll .input-lg { height: 42px; border-radius: 10px; font-size: 14px; }

.cra-scroll select, .cra-scroll select.form-control,
.modal-content select {
    /* the native arrow is drawn by the platform and ignores the palette */
    appearance: none;
    -webkit-appearance: none;
    padding-inline-end: 32px;
    background-image: linear-gradient(45deg, transparent 50%, currentColor 50%),
                      linear-gradient(135deg, currentColor 50%, transparent 50%);
    background-position: calc(100% - 17px) 16px, calc(100% - 12px) 16px;
    background-size: 5px 5px, 5px 5px;
    background-repeat: no-repeat;
    cursor: pointer;
}

[dir="rtl"] .cra-scroll select {
    background-position: 12px 16px, 17px 16px;
    padding-inline-end: 12px;
    padding-inline-start: 32px;
}

.cra-scroll .form-control:focus,
.cra-scroll input:focus, .cra-scroll textarea:focus, .cra-scroll select:focus,
.modal-content .form-control:focus {
    border-color: var(--ring);
    box-shadow: none;
    outline: none;
}

.cra-scroll .form-control[disabled], .cra-scroll .form-control[readonly],
.cra-scroll input[disabled], .cra-scroll select[disabled] {
    background: var(--muted2);
    color: var(--muted-fg);
    cursor: not-allowed;
}

.cra-scroll input[type="checkbox"], .cra-scroll input[type="radio"],
.modal-content input[type="checkbox"], .modal-content input[type="radio"] {
    width: 15px;
    height: 15px;
    accent-color: var(--primary);
    margin-inline-end: 6px;
    vertical-align: -2px;
    cursor: pointer;
}

.cra-scroll input[type="file"], .modal-content input[type="file"] {
    height: auto;
    padding: 8px 10px;
    background: var(--muted2);
    font-size: 12.5px;
}

.cra-scroll .form-group { margin-bottom: 16px; }
.cra-scroll .checkbox label, .cra-scroll .radio label { font-weight: 400; }

/* Input groups: one seam between the field and whatever is bolted to it.
   .input-group is a CSS table and every child has to be a table-cell for the
   row to hold together. An earlier version of this file gave the addon
   `display: flex` to centre its icon, which took it out of the table: each
   child then became its own anonymous row, so on Add Sale the little map-pin
   and calendar addons sat stacked *above* their fields instead of beside
   them. The cells are declared here rather than left to Bootstrap, so the
   row does not depend on which parts of that bundle are still loaded. */
.cra-scroll .input-group,
.modal-content .input-group {
    display: table;
    border-collapse: separate;
    width: 100%;
}

.cra-scroll .input-group > .form-control,
.modal-content .input-group > .form-control {
    display: table-cell;
    float: none;
    width: 100%;
    margin: 0;
}

/* select2 stamps an inline width on its container, copied from the field it
   replaced at init — and the Add Sale customer picker inherited 26px that
   way, a sliver of a control. Inside an input group the container is a cell
   and the cell decides the width, so the inline value has to be overruled. */
.cra-scroll .input-group > .select2-container,
.modal-content .input-group > .select2-container {
    display: table-cell;
    float: none;
    width: 100% !important;
    margin: 0;
}

.cra-scroll .input-group > .input-group-addon,
.cra-scroll .input-group > .input-group-btn,
.modal-content .input-group > .input-group-addon,
.modal-content .input-group > .input-group-btn {
    display: table-cell;
    vertical-align: middle;
    white-space: nowrap;
    width: 1%;
}

.cra-scroll .input-group .form-control { border-radius: 0; }
.cra-scroll .input-group .form-control:first-child { border-radius: 9px 0 0 9px; }
.cra-scroll .input-group .form-control:last-child { border-radius: 0 9px 9px 0; }

.cra-scroll .input-group-addon,
.modal-content .input-group-addon {
    background: var(--muted2);
    border: 1px solid var(--border);
    color: var(--muted-fg);
    font-size: 13px;
    padding: 0 12px;
    border-radius: 9px 0 0 9px;
    text-align: center;
}

.cra-scroll .input-group-addon:last-child { border-radius: 0 9px 9px 0; }
.cra-scroll .input-group-btn .btn { border-radius: 0 9px 9px 0; height: 38px; }

/* Some uploads go through the styled Browse button, others are left as the
   browser's own file input — the product brochure field sits next to a styled
   one and reads as unfinished beside it. The native control takes the same
   shape as every other field, and its button the same shape as every other
   button. */
.cra-scroll input[type="file"]:not(.upload-element),
.modal-content input[type="file"]:not(.upload-element) {
    display: block;
    width: 100%;
    height: 38px;
    padding: 0;
    border: 1px solid var(--border);
    border-radius: 9px;
    background: var(--bg);
    color: var(--muted-fg);
    font-size: 13px;
    line-height: 36px;
}

.cra-scroll input[type="file"]:not(.upload-element)::file-selector-button,
.modal-content input[type="file"]:not(.upload-element)::file-selector-button {
    height: 36px;
    margin-inline-end: 10px;
    padding: 0 14px;
    border: 0;
    border-inline-end: 1px solid var(--border);
    border-radius: 8px 0 0 8px;
    background: var(--muted);
    color: var(--fg);
    font-family: inherit;
    font-size: 12.5px;
    font-weight: 500;
    cursor: pointer;
}

.cra-scroll input[type="file"]:not(.upload-element)::file-selector-button:hover,
.modal-content input[type="file"]:not(.upload-element)::file-selector-button:hover {
    background: var(--border);
}

/* ── form rhythm ────────────────────────────────────────────────────────
   Three columns of a form only read as three columns if every row in them
   starts and ends on the same line. On Add Sale they did not: a label with a
   tooltip icon in it stood 19px tall against its neighbours' 16px, the gaps
   under them were 5px and 6px, and select2 rendered its control at 40px
   beside a 38px input. Every label gets the same box whatever is inside it,
   and every control lands on the same 38px. */
.cra-scroll .form-group { margin-bottom: 16px; }

/* Not every field label lives directly under .form-group — the Pay term one
   sits in a .multi-input wrapper — so the rule follows what a field label
   actually is: one carrying `for`. Labels that wrap their own control (the
   DataTables "Show N entries") carry no `for`, and a checkbox's label must
   stay on the box's line, so its parent is excluded. */
.cra-scroll :not(.checkbox):not(.radio):not(.form-check) > label[for],
.cra-scroll .control-label,
.modal-content :not(.checkbox):not(.radio):not(.form-check) > label[for] {
    /* inline-block, not block: several of these labels are followed by a
       tooltip icon that is their sibling, not their child. As a block the
       label pushed that icon onto a line of its own, which grew the Pay term
       group and reflowed the whole three-column row. */
    display: inline-block;
    margin: 0 0 6px;
    padding: 0;
    font-size: 12.5px;
    font-weight: 500;
    line-height: 18px;
    color: var(--fg);
}

/* A tooltip or link icon rides inside the label's line box rather than
   stretching it — that 3px was the whole misalignment. */
.cra-scroll label[for] i,
.cra-scroll label[for] + i,
.cra-scroll .control-label i,
.cra-scroll .control-label + i,
.modal-content label[for] i,
.modal-content label[for] + i {
    font-size: 12px;
    line-height: 18px;
    vertical-align: middle;
}

.cra-scroll .form-control:not(textarea):not([multiple]),
.cra-scroll .input-group,
.modal-content .form-control:not(textarea):not([multiple]) { height: 38px; }

.cra-scroll .select2-container--default .select2-selection--single,
.modal-content .select2-container--default .select2-selection--single { height: 38px; }

.cra-scroll .select2-container--default .select2-selection--single .select2-selection__rendered,
.modal-content .select2-container--default .select2-selection--single .select2-selection__rendered {
    line-height: 36px;
    padding-inline-start: 12px;
}

.cra-scroll .select2-container--default .select2-selection--single .select2-selection__arrow,
.modal-content .select2-container--default .select2-selection--single .select2-selection__arrow { height: 36px; }

.cra-scroll .select2-container--default .select2-selection--multiple { min-height: 38px; }

/* ── the blue that was left over ────────────────────────────────────────
   The tooltip, add and open-in-new icons still carried FontAwesome's
   .text-info and .text-primary — three different blues on one screen, in a
   design that has none. They read as what they are by shape. */
.cra-scroll i.text-info,
.cra-scroll i.text-primary,
.cra-scroll i.text-blue,
.modal-content i.text-info,
.modal-content i.text-primary { color: var(--muted-fg) !important; }

.cra-scroll a:hover > i.text-info,
.cra-scroll a:hover > i.text-primary,
.cra-scroll i.text-primary:hover { color: var(--fg) !important; }

/* Selected text in a field was a flat grey slab over the value. */
.cra-shell ::selection { background: var(--muted); color: var(--fg); }

/* ── date picker ────────────────────────────────────────────────────────
   The picker opened as stock Bootstrap: 14px numerals in a plain grid, #999
   for the neighbouring months, a blue .btn-primary block on the selected day
   and a blue clock beneath. It is a popover like any other in this design. */
/* The picker is rendered inside its own .input-group, and that group's column
   sits earlier in the document than the columns beside it. Every one of those
   columns is position:relative with z-index auto, so they paint in document
   order and the Attach Document button landed on top of the calendar. Lifting
   the group that currently holds a picker takes its whole subtree above the
   later columns; nothing else on the page changes, because the selector only
   matches while a picker is open inside it. */
.cra-scroll .input-group:has(> .bootstrap-datetimepicker-widget),
.cra-scroll .form-group:has(> .bootstrap-datetimepicker-widget),
.modal-content .input-group:has(> .bootstrap-datetimepicker-widget) {
    position: relative;
    z-index: 1200;
}

.bootstrap-datetimepicker-widget {
    z-index: 1200;
    padding: 8px;
    border: 1px solid var(--border);
    border-radius: 12px;
    background: var(--card);
    box-shadow: var(--shadow-pop);
    color: var(--fg);
    font-size: 13px;
}

/* The panel was 247px wide around a 297px table, so the last two day columns
   and the selected day fell outside its white box and floated, transparent,
   over whatever was behind — which is what made the Attach Document button
   look like it was painted on top of the calendar. The table is made to fit
   the panel rather than the panel chased after the table. */
.bootstrap-datetimepicker-widget { width: 272px; }

.bootstrap-datetimepicker-widget table {
    table-layout: fixed;
    width: 100%;
    margin: 0;
}

.bootstrap-datetimepicker-widget .picker-switch,
.bootstrap-datetimepicker-widget th.picker-switch {
    font-size: 13px;
    font-weight: 600;
    color: var(--fg);
    padding: 6px 0;
}

.bootstrap-datetimepicker-widget th.prev,
.bootstrap-datetimepicker-widget th.next {
    width: 30px;
    height: 30px;
    border-radius: 8px;
    color: var(--muted-fg);
}

.bootstrap-datetimepicker-widget th.dow {
    font-size: 11px;
    font-weight: 500;
    color: var(--muted-fg);
    padding-bottom: 4px;
}

.bootstrap-datetimepicker-widget td.day,
.bootstrap-datetimepicker-widget td.hour,
.bootstrap-datetimepicker-widget td.minute,
.bootstrap-datetimepicker-widget td.second,
.bootstrap-datetimepicker-widget span.month,
.bootstrap-datetimepicker-widget span.year,
.bootstrap-datetimepicker-widget span.decade {
    height: 32px;
    line-height: 32px;
    border-radius: 8px;
    font-size: 13px;
    color: var(--fg);
}

.bootstrap-datetimepicker-widget td.day.old,
.bootstrap-datetimepicker-widget td.day.new { color: var(--muted-fg); opacity: .55; }

.bootstrap-datetimepicker-widget th.prev:hover,
.bootstrap-datetimepicker-widget th.next:hover,
.bootstrap-datetimepicker-widget th.picker-switch:hover,
.bootstrap-datetimepicker-widget td.day:hover,
.bootstrap-datetimepicker-widget td.hour:hover,
.bootstrap-datetimepicker-widget td.minute:hover,
.bootstrap-datetimepicker-widget span.month:hover,
.bootstrap-datetimepicker-widget span.year:hover {
    background: var(--muted);
    color: var(--fg);
}

/* today is outlined; the chosen day is filled — never both competing */
.bootstrap-datetimepicker-widget td.today {
    background: transparent;
    box-shadow: inset 0 0 0 1px var(--border);
    font-weight: 600;
}

.bootstrap-datetimepicker-widget td.today::before { display: none; }

/* The old theme paints the chosen day with its own --cr-accent blue from a
   selector carrying .cr-scope, which outweighs a plain widget selector even
   with !important. Repeating the widget class buys the weight back without
   inventing a wrapper that does not exist. */
.bootstrap-datetimepicker-widget.bootstrap-datetimepicker-widget td.active,
.bootstrap-datetimepicker-widget.bootstrap-datetimepicker-widget td.active:hover,
.bootstrap-datetimepicker-widget.bootstrap-datetimepicker-widget td.active.active,
.bootstrap-datetimepicker-widget.bootstrap-datetimepicker-widget td.day.active,
.bootstrap-datetimepicker-widget.bootstrap-datetimepicker-widget span.active {
    background: var(--primary) !important;
    background-image: none !important;
    color: var(--primary-fg) !important;
    box-shadow: none !important;
    text-shadow: none !important;
}

.bootstrap-datetimepicker-widget td.disabled,
.bootstrap-datetimepicker-widget td.disabled:hover { color: var(--muted-fg); opacity: .35; background: transparent; }

.bootstrap-datetimepicker-widget .glyphicon,
.bootstrap-datetimepicker-widget a[data-action] { color: var(--muted-fg); }
.bootstrap-datetimepicker-widget a[data-action]:hover { color: var(--fg); background: var(--muted); border-radius: 8px; }

.bootstrap-datetimepicker-widget .timepicker-picker .btn,
.bootstrap-datetimepicker-widget .btn-primary {
    background: var(--card) !important;
    border: 1px solid var(--border) !important;
    color: var(--fg) !important;
    border-radius: 8px !important;
    box-shadow: none !important;
}

.bootstrap-datetimepicker-widget .separator { color: var(--muted-fg); }

/* validation */
.cra-scroll .has-error .form-control,
.cra-scroll .has-error input, .cra-scroll .has-error select { border-color: var(--red); }
.cra-scroll .has-error .control-label, .cra-scroll .has-error .help-block { color: var(--red); }
.cra-scroll .has-success .form-control { border-color: var(--green); }

/* the date-range widget draws its own calendar */
.daterangepicker {
    background: var(--card);
    border: 1px solid var(--border);
    border-radius: 12px;
    box-shadow: var(--shadow-pop);
    color: var(--fg);
    font-family: inherit;
}

.daterangepicker .calendar-table { background: var(--card); border: 0; }
.daterangepicker td, .daterangepicker th { color: var(--fg); border-radius: 7px; }
.daterangepicker td.off { color: var(--muted-fg); opacity: .5; }
.daterangepicker td.available:hover, .daterangepicker th.available:hover { background: var(--muted); }
.daterangepicker td.active, .daterangepicker td.active:hover {
    background: var(--primary); color: var(--primary-fg);
}
.daterangepicker td.in-range { background: var(--muted); color: var(--fg); }
.daterangepicker .ranges li { color: var(--fg); font-size: 13px; border-radius: 7px; }
.daterangepicker .ranges li:hover { background: var(--muted); }
.daterangepicker .ranges li.active { background: var(--primary); color: var(--primary-fg); }
.daterangepicker:after, .daterangepicker:before { display: none; }
.daterangepicker .drp-buttons { border-top-color: var(--border); }

/* ── tables ───────────────────────────────────────────────────────────── */

.cra-scroll .table-striped > tbody > tr:nth-of-type(odd) > td { background: transparent; }
.cra-scroll .table-striped > tbody > tr:nth-of-type(even) > td { background: var(--muted2); }
.cra-scroll .table-bordered, .cra-scroll .table-bordered > * > tr > * { border-color: var(--border) !important; }
.cra-scroll .table-condensed > tbody > tr > td { padding: 7px 10px; }

/* DataTables draws its own sort arrows as background images */
.cra-scroll table.dataTable thead .sorting,
.cra-scroll table.dataTable thead .sorting_asc,
.cra-scroll table.dataTable thead .sorting_desc {
    background-image: none;
    position: relative;
    padding-inline-end: 22px;
    cursor: pointer;
}

.cra-scroll table.dataTable thead .sorting::after,
.cra-scroll table.dataTable thead .sorting_asc::after,
.cra-scroll table.dataTable thead .sorting_desc::after {
    content: "";
    position: absolute;
    inset-inline-end: 8px;
    top: 50%;
    width: 7px;
    height: 7px;
    margin-top: -3px;
    border-inline-start: 1.5px solid currentColor;
    border-bottom: 1.5px solid currentColor;
    opacity: .3;
    transform: rotate(-45deg);
}

.cra-scroll table.dataTable thead .sorting_asc::after { opacity: .85; transform: rotate(135deg); margin-top: -1px; }
.cra-scroll table.dataTable thead .sorting_desc::after { opacity: .85; }

.cra-scroll .dataTables_wrapper .dataTables_processing {
    background: var(--card);
    border: 1px solid var(--border);
    border-radius: 10px;
    box-shadow: var(--shadow-pop);
    color: var(--fg);
    font-size: 13px;
    padding: 12px 18px;
}

.cra-scroll .dataTables_scrollHead,
.cra-scroll .dataTables_scrollBody { background: transparent; }
.cra-scroll .dataTables_scrollBody { border-color: var(--border) !important; }

/* The count and the pager are bare block children of the wrapper, so they
   stacked as two full-width lines under the table. They belong on one. */
.cra-scroll .dataTables_wrapper > .dataTables_info {
    float: inline-start;
    width: auto;
    padding-top: 14px;
}

.cra-scroll .dataTables_wrapper > .dataTables_paginate {
    float: inline-end;
    width: auto;
    padding-top: 8px;
}

.cra-scroll .dataTables_wrapper::after {
    content: '';
    display: block;
    clear: both;
}

/* DataTables lays its toolbar out as a Bootstrap 3 grid — col-sm-1 for the
   length control, col-sm-8 for the export buttons, col-sm-3 for search — and
   the fractions were chosen for a different type size. "Show 25 entries" needs
   166px and its column is 102px wide, so it spilled straight over the export
   buttons. Fixed fractions cannot hold controls whose width is content; the
   row becomes a flex line and each column takes the space it needs. */
.cra-scroll .dataTables_wrapper > .row {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 12px;
    margin-inline: 0;
    text-align: start;
}

.cra-scroll .dataTables_wrapper > .row > [class*="col-"] {
    float: none;
    width: auto;
    max-width: 100%;
    flex: 0 0 auto;
    padding-inline: 0;
}

/* Search sits at the end of the line whichever fraction the page gave it. */
.cra-scroll .dataTables_wrapper > .row > [class*="col-"]:has(.dataTables_filter) {
    margin-inline-start: auto;
}

/* The export cluster absorbs the slack between the two. */
.cra-scroll .dataTables_wrapper > .row > [class*="col-"]:has(.dt-buttons) {
    flex: 1 1 auto;
    min-width: 0;
}

/* The Add button, moved out of the card header by corpraasta-shell.js, sits
   at the end of the toolbar beside the search box. */
.cra-scroll .dataTables_wrapper > .row > .box-tools.cra-toolbar-add {
    float: none;
    display: inline-flex;
    align-items: center;
    gap: 8px;
    margin: 0;
    padding: 0;
    flex: 0 0 auto;
}

/* Search no longer claims the slack — the pair travels to the end together. */
.cra-scroll .dataTables_wrapper > .row:has(> [class*="col-"] .dt-buttons) > [class*="col-"]:has(.dataTables_filter) {
    margin-inline-start: 0;
}

.cra-scroll .dataTables_wrapper > .row:has(> .box-tools.cra-toolbar-add) > [class*="col-"]:has(.dataTables_filter) {
    margin-inline-start: auto;
}

/* The band the layout parks off-screen until a list is found for it. */
.cra-list-ad { margin-bottom: 20px; }
.cra-list-ad[hidden] { display: none !important; }
.cra-list-ad .cra-ad { min-height: 90px; }

/* "Show [25] entries" and "Search: [ ]" are each one label wrapping a field.
   Left inline the phrase broke across two lines and "entries" was clipped to
   "ent.", so the strip stood 43px tall and nothing on it shared a baseline.
   The label is the flex row; the field carries no margin of its own. */
.cra-scroll .dataTables_wrapper .dataTables_length label,
.cra-scroll .dataTables_wrapper .dataTables_filter label {
    display: flex;
    align-items: center;
    gap: 8px;
    margin: 0;
    white-space: nowrap;
    font-weight: 400;
}

.cra-scroll .dataTables_wrapper .dataTables_length select,
.cra-scroll .dataTables_wrapper .dataTables_filter input {
    height: 32px;
    font-size: 12.5px;
    border-radius: 8px;
    margin: 0;
    display: inline-block;
    width: auto;
    min-width: 70px;
}

.cra-scroll .dataTables_wrapper .dataTables_filter input { min-width: 200px; }

/* Under scrollX DataTables locks each column's width at draw time, so a long
   address dropped into a narrow locked column wraps instead of widening it —
   one customer measured 416px tall, four rows to a screen. Cells that hold
   plain content are held to a single line and ellipsed; the hover title in
   corpraasta-shell.js gives the full value back. Cells that hold real UI —
   the action buttons, images, status badges, inline form fields — are left
   alone, because clipping those would clip the controls themselves. */
.cra-scroll table.dataTable tbody td:not(:has(button, .btn, .tw-dw-btn, .dropdown, img, ul, table, .label, .badge, input, select, svg)) {
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    max-width: 240px;
}

/* The lists built from the canvas — the contacts overview — and the legacy
   DataTables were reading as two different products. The old theme styles its
   headers at .cr-scope .cr-card table.dataTable thead th, three classes to
   this file's two, so it kept winning: 10.5px UPPERCASE with 0.08em tracking
   in its own grey, over rows a third shorter than the ones next door. These
   selectors carry .cra-shell to outweigh it, and the numbers are the hand-
   built list's own: a 34px header at 12px in sentence case, and 59px rows.
   Every legacy row leads with an Actions button, so the padding is set from
   that button's height rather than from the text, and the rows land on one
   measure instead of two. */
.cra-shell .cra-scroll table.dataTable thead th,
.cra-shell .cra-scroll table.table > thead > tr > th {
    font-size: 12px;
    font-weight: 500;
    text-transform: none;
    letter-spacing: normal;
    color: var(--muted-fg);
    background: var(--muted2);
    padding: 8px 14px;
    vertical-align: middle;
}

.cra-shell .cra-scroll table.dataTable tbody td,
.cra-shell .cra-scroll table.table > tbody > tr > td {
    font-size: 13px;
    color: var(--fg);
    padding: 16px 14px;
}

/* Some forms build a section header as bare <th> inside a <tbody>, with a
   colour of their own — .add-product-price-table in app.css paints a
   Bootstrap-success bar straight across Add Product. A th is a header cell
   wherever it sits, so it takes the header's grey like every other one. The
   DataTables rules above are more specific and keep their own treatment. */
.cra-shell .cra-scroll table th {
    background: var(--muted2);
    color: var(--muted-fg);
    font-size: 12px;
    font-weight: 500;
    text-transform: none;
    letter-spacing: normal;
    padding: 8px 14px;
    vertical-align: middle;
    border-color: var(--border);
}

/* AdminLTE's colour utilities are used as section headers inside forms and
   reports — <tr class="bg-green"> over the pricing block on Add Product, and
   129 uses of bg-gray elsewhere — which painted a Bootstrap-success bar right
   through the middle of the page. On a table these are structure, not status,
   so they take the header's own grey. The same class on a .label is a real
   status badge and is deliberately left alone. */
.cra-shell .cra-scroll table > tr[class*="bg-"],
.cra-shell .cra-scroll table > tr[class*="bg-"] > th,
.cra-shell .cra-scroll table > tr[class*="bg-"] > td,
.cra-shell .cra-scroll tbody > tr[class*="bg-"],
.cra-shell .cra-scroll tbody > tr[class*="bg-"] > th,
.cra-shell .cra-scroll thead > tr[class*="bg-"] > th,
.cra-shell .cra-scroll tfoot > tr[class*="bg-"] > th,
.cra-shell .cra-scroll tfoot > tr[class*="bg-"] > td,
.cra-shell .cra-scroll th[class*="bg-"],
.cra-shell .cra-scroll table[class*="bg-"] {
    background: var(--muted2) !important;
    color: var(--fg) !important;
    border-color: var(--border) !important;
}

.cra-shell .cra-scroll thead > tr[class*="bg-"] > th,
.cra-shell .cra-scroll table > tr[class*="bg-"] > th {
    color: var(--muted-fg) !important;
}

/* The list breathes at the card's edge the way the hand-built one does. */
.cra-shell .cra-scroll table.dataTable thead th:first-child,
.cra-shell .cra-scroll table.dataTable tbody td:first-child,
.cra-shell .cra-scroll table.table > thead > tr > th:first-child,
.cra-shell .cra-scroll table.table > tbody > tr > td:first-child { padding-inline-start: 20px; }

.cra-shell .cra-scroll table.dataTable thead th:last-child,
.cra-shell .cra-scroll table.dataTable tbody td:last-child,
.cra-shell .cra-scroll table.table > thead > tr > th:last-child,
.cra-shell .cra-scroll table.table > tbody > tr > td:last-child { padding-inline-end: 20px; }

/* Row controls sit on the 28px the padding was measured against. */
.cra-shell .cra-scroll table.dataTable tbody td .btn,
.cra-shell .cra-scroll table.dataTable tbody td .tw-dw-btn {
    height: 28px;
    min-height: 28px;
    line-height: 1;
}

/* Amounts read as figures, not prose — same weight as the hand-built list. */
.cra-shell .cra-scroll table.dataTable tfoot th,
.cra-shell .cra-scroll table.dataTable tfoot td {
    font-size: 13px;
    font-weight: 600;
    padding: 14px;
}

/* Rows settle on one height. Without this a long address wraps to six lines
   and the row grows to ~150px, so a screen holds four customers. */
.cra-shell .cra-scroll table.dataTable tbody td {
    vertical-align: middle;
    line-height: 1.45;
}

.cra-shell .cra-scroll table.dataTable thead th {
    vertical-align: middle;
    white-space: nowrap;
}

/* The action column is a button group; it must never wrap or be squeezed. */
.cra-shell .cra-scroll table.dataTable tbody td:first-child,
.cra-shell .cra-scroll table.dataTable thead th:first-child {
    white-space: nowrap;
}

/* A wide table scrolls in its own box, so that box draws its own scrollbar —
   and the default one stays light grey in dark mode, reading as a white band
   across the card. It gets the theme's colours like everything else. */
.cra-scroll .table-responsive,
.cra-scroll .dataTables_scrollBody {
    scrollbar-width: thin;
    scrollbar-color: var(--border) transparent;
}

.cra-scroll .table-responsive::-webkit-scrollbar,
.cra-scroll .dataTables_scrollBody::-webkit-scrollbar {
    width: 8px;
    height: 8px;
}

.cra-scroll .table-responsive::-webkit-scrollbar-track,
.cra-scroll .dataTables_scrollBody::-webkit-scrollbar-track {
    background: transparent;
}

.cra-scroll .table-responsive::-webkit-scrollbar-thumb,
.cra-scroll .dataTables_scrollBody::-webkit-scrollbar-thumb {
    background: var(--border);
    border-radius: 999px;
}

.cra-scroll .table-responsive::-webkit-scrollbar-thumb:hover,
.cra-scroll .dataTables_scrollBody::-webkit-scrollbar-thumb:hover {
    background: var(--muted-fg);
}

/* a table that will not fit scrolls inside its own card */
.cra-scroll .table-responsive {
    border: 0;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
}

/* The old design made every control a pill and the theme still enforces that
   with !important — on the DataTables search and length controls, the export
   buttons, and anything carrying a tw- utility class. An inline style cannot
   beat those, so the weight is matched here rather than worked around. */
.cra-shell .cra-scroll .dataTables_wrapper .dataTables_filter input,
.cra-shell .cra-scroll .dataTables_wrapper .dataTables_length select {
    border-radius: 8px !important;
    background: var(--bg) !important;
    border: 1px solid var(--border) !important;
    color: var(--fg) !important;
}

.cra-shell .cra-scroll .dt-button,
.cra-shell .cra-scroll a.dt-button,
.cra-shell .cra-scroll button.dt-button,
.cra-shell .cra-scroll div.dt-button {
    border-radius: 8px !important;
    background: var(--card) !important;
    border: 1px solid var(--border) !important;
    color: var(--fg) !important;
    font-size: 12px !important;
    font-weight: 500 !important;
    padding: 7px 11px !important;
    box-shadow: none !important;
}

.cra-shell .cra-scroll .dt-button:hover { background: var(--muted) !important; }

.cra-shell .cra-scroll .tw-dw-btn,
.cra-shell .cra-scroll a[class*="tw-bg-gradient"],
.cra-shell .cra-scroll button[class*="tw-bg-gradient"] {
    border-radius: 9px !important;
}

.cra-shell .cra-scroll .dataTables_wrapper .dataTables_paginate .paginate_button.current,
.cra-shell .cra-scroll .dataTables_wrapper .dataTables_paginate .paginate_button.current:hover {
    border-radius: 8px !important;
    background: var(--primary) !important;
    color: var(--primary-fg) !important;
}

/* Bootstrap's variants are handled above; the bulk-action strip under the
   product table uses daisyUI's semantic set instead, and -error and -warning
   still painted themselves pastel pink and mustard. The design has three
   button meanings — primary, neutral, destructive — so the eight variants
   collapse onto those. */
.cra-shell .cra-scroll .tw-dw-btn-neutral,
.cra-shell .cra-scroll .tw-dw-btn-accent,
.cra-shell .cra-scroll .tw-dw-btn-secondary,
.cra-shell .cra-scroll .tw-dw-btn-info,
.cra-shell .cra-scroll .tw-dw-btn-success,
.cra-shell .cra-scroll .tw-dw-btn-warning {
    background: var(--card) !important;
    background-image: none !important;
    border: 1px solid var(--border) !important;
    color: var(--fg) !important;
    box-shadow: none !important;
}

.cra-shell .cra-scroll .tw-dw-btn-neutral:hover,
.cra-shell .cra-scroll .tw-dw-btn-accent:hover,
.cra-shell .cra-scroll .tw-dw-btn-secondary:hover,
.cra-shell .cra-scroll .tw-dw-btn-info:hover,
.cra-shell .cra-scroll .tw-dw-btn-success:hover,
.cra-shell .cra-scroll .tw-dw-btn-warning:hover {
    background: var(--muted) !important;
}

.cra-shell .cra-scroll .tw-dw-btn-primary {
    background: var(--primary) !important;
    background-image: none !important;
    border: 1px solid var(--primary) !important;
    color: var(--primary-fg) !important;
    box-shadow: none !important;
}

/* A row's Edit link is marked up as an *outline* primary, so it should not
   render as the heaviest thing on the page — the one solid button per screen
   is the Add in the card header. Outline wins over the variant's fill. */
.cra-shell .cra-scroll .tw-dw-btn-outline.tw-dw-btn-primary {
    background: var(--card) !important;
    border: 1px solid var(--border) !important;
    color: var(--fg) !important;
}

.cra-shell .cra-scroll .tw-dw-btn-outline.tw-dw-btn-primary:hover {
    background: var(--muted) !important;
}

/* Red is spent only on the one thing that cannot be undone. */
.cra-shell .cra-scroll .tw-dw-btn-error,
.cra-shell .cra-scroll .tw-dw-btn-danger {
    background: var(--card) !important;
    background-image: none !important;
    border: 1px solid var(--red) !important;
    color: var(--red) !important;
    box-shadow: none !important;
}

.cra-shell .cra-scroll .tw-dw-btn-error:hover,
.cra-shell .cra-scroll .tw-dw-btn-danger:hover {
    background: var(--red) !important;
    color: #fff !important;
}

/* The pill action chips under the product table come from another palette. */
.cra-shell .cra-scroll [class*="tw-bg-"][class*="tw-rounded"] { border-radius: 8px !important; }

/* ── mobile drawer ─────────────────────────────────────────────────────── */

.cra-backdrop {
    position: fixed;
    inset: 0;
    z-index: 39;
    background: rgba(9, 9, 11, .5);
    opacity: 0;
    visibility: hidden;
    transition: opacity .2s var(--ease), visibility .2s var(--ease);
}

.cra-btn.cra-burger { display: none; }

@media (max-width: 1023px) {
    .cra-shell,
    .cra-shell.is-collapsed { grid-template-columns: minmax(0, 1fr); }

    .cra-side {
        position: fixed;
        top: 0;
        inset-inline-start: 0;
        z-index: 40;
        width: var(--cra-rail);
        transform: translateX(-102%);
        transition: transform .22s var(--ease);
        box-shadow: var(--shadow-pop);
    }

    [dir="rtl"] .cra-side { transform: translateX(102%); }
    .cra-shell.is-drawer .cra-side { transform: none; }
    .cra-shell.is-drawer .cra-backdrop { opacity: 1; visibility: visible; }

    /* the rail is never icon-only on mobile — the drawer shows it in full */
    .cra-shell.is-collapsed .cra-side__id,
    .cra-shell.is-collapsed .cra-nav__label,
    .cra-shell.is-collapsed .cra-nav__chev,
    .cra-shell.is-collapsed .cra-nav__head,
    .cra-shell.is-collapsed .cra-side__find { display: revert; }

    .cra-shell.is-collapsed .cra-side__brand,
    .cra-shell.is-collapsed .cra-nav__item {
        justify-content: flex-start;
        padding: 0 10px;
    }

    .cra-shell.is-collapsed .cra-nav__item[data-label]::after { content: none; }

    .cra-btn.cra-burger { display: inline-flex; }
    .cra-collapse { display: none; }

    body.cra-locked { overflow: hidden; }
}

@media (max-width: 760px) {
    .cra-scroll { padding: 16px; }
    .cra-head h1 { font-size: 22px; }
    .cra-head__acts { width: 100%; }
    .cra-seg { overflow-x: auto; max-width: 100%; }

    /* Ten actions do not fit across a phone, and wrapping them turned the bar
       into two ragged rows with the avatar stranded under the burger. One row
       that scrolls instead: the menu button stays pinned at the start and the
       account chip at the end — the two you always need — and everything
       between them slides. Nothing is taken away. */
    .cra-topbar {
        flex-wrap: nowrap;
        overflow-x: auto;
        overflow-y: hidden;
        padding: 8px 12px;
        gap: 8px;
        scrollbar-width: none;
    }

    .cra-topbar::-webkit-scrollbar { display: none; }
    .cra-topbar > * { flex-shrink: 0; }

    .cra-burger {
        position: sticky;
        inset-inline-start: 0;
        z-index: 2;
        background: var(--bg);
    }

    .cra-who {
        position: sticky;
        inset-inline-end: 0;
        z-index: 2;
        background: var(--bg);
        box-shadow: -10px 0 10px -6px var(--bg);
    }

    /* The trail is noise on a phone; the page's own name is not. */
    .cra-crumb { min-width: 0; }
    .cra-crumb > a,
    .cra-crumb > span { display: none; }
    .cra-crumb > b { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

    .cra-spacer { display: none; }
}

@media (max-width: 600px) {
    .cra-who__txt { display: none; }
    .cra-who > summary { padding-inline-start: 8px; }
}

@media (prefers-reduced-motion: reduce) {
    .cra-shell, .cra-side, .cra-nav__sub, .cra-backdrop,
    .cra-nav__chev, .cra-sk {
        transition-duration: .01ms;
        animation-duration: .01ms;
    }
}

@media print {
    .cra-side, .cra-topbar, .cra-backdrop { display: none !important; }

    /* Printing needs the whole document, not one viewport of it. */
    .cra-shell, .cra-main, .cra-scroll {
        display: block;
        height: auto;
        overflow: visible;
    }
}

/* ══════════════════════════════════════════════════════════════════════════
   Dashboard breakdowns
   ══════════════════════════════════════════════════════════════════════════ */

/* A ranked row. The bar is the share of the largest row rather than of the
   total: one state carries most of this business, and against the total every
   other bar would be a hairline and the ranking unreadable. */
.cra-bar { padding: 9px 0; border-top: 1px solid var(--border); }
.cra-bar:first-child { border-top: 0; }

.cra-bar__row {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 12px;
    margin-bottom: 6px;
}

.cra-bar__name {
    font-size: 13px;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    text-transform: capitalize;
}

.cra-bar__val { font-size: 13px; font-weight: 600; white-space: nowrap; }

.cra-bar__track {
    height: 6px;
    border-radius: 999px;
    background: var(--muted);
    overflow: hidden;
}

.cra-bar__track i {
    display: block;
    height: 100%;
    border-radius: 999px;
    background: var(--primary);
    transition: width .4s var(--ease);
}

.cra-bar__note { display: block; margin-top: 5px; font-size: 11px; color: var(--muted-fg); }

.cra-empty { margin: 12px 0 0; font-size: 13px; color: var(--muted-fg); }

.cra-key {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    margin-inline-end: 8px;
    font-size: 11.5px;
    color: var(--muted-fg);
    text-transform: capitalize;
}

.cra-key b { color: var(--fg); font-weight: 600; }

/* ── the insight panel ─────────────────────────────────────────────────────
   Three orbs that drift while the figures are being read, then settle. The
   lines it prints are arithmetic on numbers already on the page, so it can
   never assert something the cards below it contradict. */
.cra-insight {
    display: flex;
    align-items: flex-start;
    gap: 16px;
    padding: 16px 20px;
    border: 1px solid var(--border);
    border-radius: 14px;
    background: var(--card);
    box-shadow: var(--shadow);
}

.cra-insight__orbs {
    display: flex;
    align-items: center;
    gap: 5px;
    padding-top: 4px;
    flex-shrink: 0;
}

.cra-insight__orbs span {
    width: 9px;
    height: 9px;
    border-radius: 999px;
    background: var(--primary);
    opacity: .28;
}

.cra-insight[data-state="thinking"] .cra-insight__orbs span {
    animation: cra-orb 1.15s var(--ease) infinite;
}

.cra-insight[data-state="thinking"] .cra-insight__orbs span:nth-child(2) { animation-delay: .16s; }
.cra-insight[data-state="thinking"] .cra-insight__orbs span:nth-child(3) { animation-delay: .32s; }

/* Settled: the three read as a small mark rather than a stalled animation. */
.cra-insight[data-state="done"] .cra-insight__orbs span { opacity: .9; }
.cra-insight[data-state="done"] .cra-insight__orbs span:nth-child(2) { opacity: .55; }
.cra-insight[data-state="done"] .cra-insight__orbs span:nth-child(3) { opacity: .28; }

@keyframes cra-orb {
    0%, 100% { opacity: .22; transform: translateY(0); }
    50%      { opacity: .95; transform: translateY(-3px); }
}

@media (prefers-reduced-motion: reduce) {
    .cra-insight[data-state="thinking"] .cra-insight__orbs span { animation: none; opacity: .6; }
}

.cra-insight__body { min-width: 0; }

.cra-insight__title {
    font-size: 13px;
    font-weight: 600;
    margin-bottom: 6px;
}

.cra-insight[data-state="thinking"] .cra-insight__list { opacity: .35; }

.cra-insight__list {
    margin: 0;
    padding: 0;
    list-style: none;
    display: flex;
    flex-direction: column;
    gap: 5px;
    transition: opacity .25s var(--ease);
}

.cra-insight__list li { font-size: 13px; color: var(--muted-fg); line-height: 1.5; }
.cra-insight__list li b { color: var(--fg); font-weight: 600; }

/* ── India choropleth ───────────────────────────────────────────────────── */
.cra-india { margin: 4px 0 14px; }
.cra-india svg { width: 100%; height: auto; max-height: 300px; display: block; }
.cra-india[hidden] { display: none; }

.cra-india .cra-land {
    fill: var(--muted);
    stroke: var(--card);
    stroke-width: .6;
    transition: fill .2s var(--ease);
}

.cra-india .cra-land--0 { fill: var(--muted); }
.cra-india .cra-land--1 { fill: color-mix(in srgb, var(--primary) 22%, var(--muted)); }
.cra-india .cra-land--2 { fill: color-mix(in srgb, var(--primary) 45%, var(--muted)); }
.cra-india .cra-land--3 { fill: color-mix(in srgb, var(--primary) 70%, var(--muted)); }
.cra-india .cra-land--4 { fill: var(--primary); }

/* ══════════════════════════════════════════════════════════════════════════
   Earth from orbit — the dashboard backdrop
   ══════════════════════════════════════════════════════════════════════════

   Drawn, not filmed. This screen sits open all day; a looping video would
   spend bandwidth, battery and a core on decoding something nobody looks at
   directly. Gradients cost one paint and theme themselves.

   Two faces: the sunlit hemisphere under the light palette, the night side
   with its city lights under the dark one. Both sit behind a veil, because
   the figures on top have to stay readable — that is not negotiable for a
   backdrop.

   Dark is selected on [data-cr-theme="dark"] and nothing else. An earlier
   pass guarded it on :not([data-theme="light"]), an attribute this app never
   sets, so the night side painted itself over light mode and swallowed the
   greeting.
   ══════════════════════════════════════════════════════════════════════════ */

.cra-page { position: relative; }
/* Lift the page's own blocks above the sky behind them — but not a modal.
   A modal that is markup inside .cra-page is still a direct child, and giving
   it position: relative takes away the position: fixed Bootstrap relies on:
   the dialog drops into the flow of the page and opens wherever it happens to
   land, well below the fold, while its backdrop covers the viewport as
   normal. */
.cra-page > *:not(.cra-sky):not(.modal) { position: relative; z-index: 1; }

.cra-sky {
    position: absolute;
    inset-inline: -20px;
    top: -20px;
    height: 134px;
    z-index: 0;
    overflow: hidden;
    border-radius: 18px;
    pointer-events: none;
    /* Day: the sky above the limb is a pale high-altitude blue. */
    background: linear-gradient(180deg, #bcd8f2 0%, #dceaf8 55%, transparent 100%);
}

/* The planet: a sphere far wider than the panel, sitting mostly below it, so
   only the curve of the horizon shows — the view from low orbit. */
.cra-sky__earth {
    position: absolute;
    left: 50%;
    top: 54px;
    width: 1900px;
    height: 1900px;
    margin-inline-start: -950px;
    border-radius: 50%;
    overflow: hidden;
    background: radial-gradient(130% 96% at 50% 0%,
        #8fc0e8 0%, #5b9ad2 30%, #3576ae 58%, #205684 100%);
}

/* Land and cloud, turning. A wide strip translated sideways rather than a
   moving background-position: one composited layer instead of a repaint. */
.cra-sky__surface {
    position: absolute;
    inset: -2% -100% -2% -100%;
    opacity: .7;
    animation: cra-spin 240s linear infinite;
    will-change: transform;
    background:
        radial-gradient(closest-side, rgba(255,255,255,.9), transparent 70%) 6% 2.28% / 5.4% .9% no-repeat,
        radial-gradient(closest-side, rgba(255,255,255,.7), transparent 70%) 13% 3.8% / 7.4% .8% no-repeat,
        radial-gradient(closest-side, rgba(126,172,110,.8), transparent 74%) 21% 2.85% / 4.4% 1.1% no-repeat,
        radial-gradient(closest-side, rgba(255,255,255,.8), transparent 70%) 30% 1.9% / 6.4% .9% no-repeat,
        radial-gradient(closest-side, rgba(150,182,118,.75), transparent 76%) 38% 3.42% / 5.0% 1.2% no-repeat,
        radial-gradient(closest-side, rgba(255,255,255,.65), transparent 70%) 47% 2.66% / 8.0% .8% no-repeat,
        radial-gradient(closest-side, rgba(122,164,104,.78), transparent 74%) 57% 3.04% / 4.6% 1.0% no-repeat,
        radial-gradient(closest-side, rgba(255,255,255,.85), transparent 70%) 66% 2.09% / 6.0% .9% no-repeat,
        radial-gradient(closest-side, rgba(160,186,128,.7), transparent 76%) 75% 3.61% / 4.2% 1.1% no-repeat,
        radial-gradient(closest-side, rgba(255,255,255,.7), transparent 70%) 84% 2.47% / 7.0% .8% no-repeat,
        radial-gradient(closest-side, rgba(134,174,112,.75), transparent 74%) 93% 3.23% / 4.4% 1.0% no-repeat;
}

/* The atmosphere, caught along the limb. */
.cra-sky__rim {
    position: absolute;
    left: 50%;
    top: 44px;
    width: 1936px;
    height: 1936px;
    margin-inline-start: -968px;
    border-radius: 50%;
    background: radial-gradient(closest-side,
        transparent 0%, transparent 92.9%,
        rgba(168, 212, 250, .95) 93.5%,
        rgba(168, 212, 250, .3) 95%,
        transparent 96.6%);
}

/* Whatever the sky does, the text on top of it wins. */
.cra-sky__veil {
    position: absolute;
    inset: 0;
    background: linear-gradient(180deg,
        rgba(255, 255, 255, .22) 0%,
        rgba(255, 255, 255, .30) 48%,
        rgba(255, 255, 255, .80) 84%,
        var(--bg) 100%);
}

.cra-sky__stars { display: none; }

@keyframes cra-spin {
    from { transform: translate3d(0, 0, 0); }
    to   { transform: translate3d(-33.333%, 0, 0); }
}

/* ── the night side ────────────────────────────────────────────────────────
   Same geometry, the unlit hemisphere: a near-black ocean, cities burning
   along the coasts, and the atmosphere lit only where dawn is coming. */
:root[data-cr-theme="dark"] .cra-sky {
    background: linear-gradient(180deg, #04060c 0%, #070b14 55%, transparent 100%);
}

:root[data-cr-theme="dark"] .cra-sky__stars {
    display: block;
    position: absolute;
    inset: 0 0 62% 0;
    opacity: .9;
    background:
        radial-gradient(1.4px 1.4px at 9%  34%, #fff, transparent 100%),
        radial-gradient(1px 1px     at 21% 16%, rgba(255,255,255,.85), transparent 100%),
        radial-gradient(1.6px 1.6px at 33% 46%, #fff, transparent 100%),
        radial-gradient(1px 1px     at 44% 13%, rgba(255,255,255,.75), transparent 100%),
        radial-gradient(1.3px 1.3px at 56% 38%, #fff, transparent 100%),
        radial-gradient(1px 1px     at 67% 20%, rgba(255,255,255,.8), transparent 100%),
        radial-gradient(1.5px 1.5px at 78% 44%, #fff, transparent 100%),
        radial-gradient(1px 1px     at 88% 24%, rgba(255,255,255,.7), transparent 100%),
        radial-gradient(1.2px 1.2px at 96% 40%, #fff, transparent 100%);
}

:root[data-cr-theme="dark"] .cra-sky__earth {
    background: radial-gradient(130% 96% at 50% 0%,
        #14283f 0%, #0e1e30 34%, #081321 68%, #050a12 100%);
}

/* City lights: warm clusters along the top of the limb, where the coastlines
   would be. Small and few — a lit-up planet would drown the page. */
:root[data-cr-theme="dark"] .cra-sky__surface {
    opacity: 1;
    /* Pulled up against the limb: that band is where the veil is thinnest,
       and lights placed lower were sitting under 60% of it. */
    inset: -2% -100% -2% -100%;
    filter: blur(.2px);
    background:
        radial-gradient(closest-side, rgba(255,198,124,1),  transparent 66%) 7% 1.04% / 2.2% .8% no-repeat,
        radial-gradient(closest-side, rgba(255,216,156,.8), transparent 70%) 12% 1.99% / 3.2% 1.0% no-repeat,
        radial-gradient(closest-side, rgba(255,188,112,.95), transparent 66%) 22% 1.42% / 2.0% .7% no-repeat,
        radial-gradient(closest-side, rgba(255,208,144,.75), transparent 70%) 30% 2.18% / 3.6% 1.1% no-repeat,
        radial-gradient(closest-side, rgba(255,196,120,1),  transparent 66%) 39% 0.95% / 2.2% .8% no-repeat,
        radial-gradient(closest-side, rgba(255,212,150,.78), transparent 70%) 46% 1.8% / 3.8% 1.0% no-repeat,
        radial-gradient(closest-side, rgba(255,190,114,.95), transparent 66%) 57% 1.33% / 2.1% .7% no-repeat,
        radial-gradient(closest-side, rgba(255,210,146,.75), transparent 70%) 65% 2.09% / 3.2% 1.1% no-repeat,
        radial-gradient(closest-side, rgba(255,198,126,1),  transparent 66%) 75% 1.04% / 2.2% .8% no-repeat,
        radial-gradient(closest-side, rgba(255,214,152,.72), transparent 70%) 83% 1.9% / 3.6% 1.0% no-repeat,
        radial-gradient(closest-side, rgba(255,192,116,.95), transparent 66%) 93% 1.48% / 2.0% .7% no-repeat;
}

:root[data-cr-theme="dark"] .cra-sky__rim {
    background: radial-gradient(closest-side,
        transparent 0%, transparent 92.9%,
        rgba(112, 176, 240, .85) 93.5%,
        rgba(70, 126, 190, .26) 95.2%,
        transparent 96.6%);
}

:root[data-cr-theme="dark"] .cra-sky__veil {
    background: linear-gradient(180deg,
        rgba(9, 9, 11, .06) 0%,
        rgba(9, 9, 11, .12) 52%,
        rgba(9, 9, 11, .68) 84%,
        var(--bg) 100%);
}

/* ── the filmed version ────────────────────────────────────────────────────
   If a clip has been dropped into public/media it plays over the drawing.
   The drawing stays underneath rather than being replaced, so there is never
   a blank band while the file buffers or if it fails to load at all. Only the
   clip for the current palette is shown; the other is not even decoded. */
.cra-sky__film {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    object-position: 50% 42%;
    display: none;
    pointer-events: none;
}

.cra-sky.has-film .cra-sky__film--day { display: block; }
.cra-sky.has-film .cra-sky__film--night { display: none; }

:root[data-cr-theme="dark"] .cra-sky.has-film .cra-sky__film--day { display: none; }
:root[data-cr-theme="dark"] .cra-sky.has-film .cra-sky__film--night { display: block; }

/* Only one clip supplied: it plays under both palettes, dimmed to suit the
   one it was not shot for rather than left glaring. */
:root[data-cr-theme="dark"] .cra-sky.has-film .cra-sky__film--day:only-of-type {
    display: block;
    filter: brightness(.42) saturate(.8);
}

.cra-sky.has-film .cra-sky__film--night:only-of-type {
    display: block;
    filter: brightness(1.5) saturate(1.1);
}

/* Nobody who asked for stillness gets a turning planet — or a moving one. */
@media (prefers-reduced-motion: reduce) {
    .cra-sky__surface { animation: none; }
    .cra-sky__film { display: none !important; }
}

/* On a small screen the backdrop is mostly hidden behind the cards anyway. */
@media (max-width: 767px) {
    .cra-sky { height: 104px; }
    .cra-sky__earth { top: 42px; }
    .cra-sky__rim { top: 34px; }
}

/* A message attached to one card — used by the sponsored slots when a save is
   refused, which used to happen silently. */
.cra-note {
    margin: 0 0 14px;
    padding: 10px 12px;
    border: 1px solid var(--border);
    border-radius: 10px;
    background: var(--muted2);
    font-size: 12.5px;
    color: var(--fg);
}

.cra-note p { margin: 0; }
.cra-note p + p { margin-top: 4px; }

.cra-note--bad {
    border-color: var(--red);
    background: var(--redbg);
    color: var(--red);
}

/* ══════════════════════════════════════════════════════════════════════════
   CRM dashboard
   ══════════════════════════════════════════════════════════════════════════ */

/* A monochrome ramp for slices. The design's donut is greyscale — colour on a
   share chart implies a meaning each source does not have. */
:root {
    --cra-slice-0: #18181b;
    --cra-slice-1: #52525b;
    --cra-slice-2: #71717a;
    --cra-slice-3: #a1a1aa;
    --cra-slice-4: #d4d4d8;
    --cra-slice-5: #e4e4e7;
}

[data-cr-theme="dark"] {
    --cra-slice-0: #fafafa;
    --cra-slice-1: #d4d4d8;
    --cra-slice-2: #a1a1aa;
    --cra-slice-3: #71717a;
    --cra-slice-4: #52525b;
    --cra-slice-5: #3f3f46;
}

.cra-donut {
    position: relative;
    width: 190px;
    height: 190px;
    margin: 18px auto 4px;
    border-radius: 50%;
    background: conic-gradient(var(--slices));
}

.cra-donut__hole {
    position: absolute;
    inset: 27%;
    border-radius: 50%;
    background: var(--card);
    display: grid;
    place-content: center;
    text-align: center;
}

.cra-donut__hole b { display: block; font-size: 26px; font-weight: 600; line-height: 1.1; }
.cra-donut__hole small { font-size: 11px; color: var(--muted-fg); }

.cra-donut__keys {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 8px 14px;
    margin-top: 16px;
}

.cra-donut__key {
    display: flex;
    align-items: center;
    gap: 7px;
    min-width: 0;
    font-size: 11.5px;
    color: var(--muted-fg);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.cra-donut__key i { width: 8px; height: 8px; border-radius: 3px; flex-shrink: 0; }
.cra-donut__key b { color: var(--fg); font-weight: 600; margin-inline-start: auto; }

/* The completion ring. One conic sweep, no library. */
.cra-ring__card { flex-direction: row; align-items: center; gap: 16px; }

.cra-ring {
    position: relative;
    width: 62px;
    height: 62px;
    flex-shrink: 0;
    border-radius: 50%;
    display: grid;
    place-items: center;
    background: conic-gradient(var(--primary) calc(var(--pct) * 1%), var(--muted) 0);
}

.cra-ring::after {
    content: '';
    position: absolute;
    inset: 7px;
    border-radius: 50%;
    background: var(--card);
}

.cra-ring span { position: relative; font-size: 13px; font-weight: 600; }
.cra-ring__txt { min-width: 0; }

/* A follow-up, as the design draws a task. */
.cra-task {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    padding: 11px 0;
    border-top: 1px solid var(--border);
}

.cra-task:first-of-type { border-top: 0; }

.cra-task__box {
    width: 15px;
    height: 15px;
    margin-top: 2px;
    flex-shrink: 0;
    border: 1.5px solid var(--border);
    border-radius: 4px;
}

.cra-task.is-done .cra-task__box {
    background: var(--primary);
    border-color: var(--primary);
    /* the tick, drawn rather than pulled from an icon font */
    background-image: linear-gradient(45deg, transparent 42%, var(--primary-fg) 42%, var(--primary-fg) 56%, transparent 56%),
                      linear-gradient(-45deg, transparent 58%, var(--primary-fg) 58%, var(--primary-fg) 72%, transparent 72%);
    background-size: 60% 60%, 60% 60%;
    background-position: 62% 62%, 30% 55%;
    background-repeat: no-repeat;
}

.cra-task__body { min-width: 0; }
.cra-task__body b { display: block; font-size: 13px; font-weight: 500; }
.cra-task__body small { display: block; font-size: 11.5px; color: var(--muted-fg); margin-top: 1px; }
.cra-task.is-done .cra-task__body b { text-decoration: line-through; color: var(--muted-fg); }

.cra-task__meta {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-top: 6px;
    font-size: 11px;
    color: var(--muted-fg);
}

.cra-chip--ok { background: var(--tealbg, var(--muted)); color: var(--teal, var(--muted-fg)); }

.cra-rows--crm .cra-rows__head,
.cra-row.cra-rows--crm { grid-template-columns: 2fr 1.4fr 1fr 1fr; }

/* A cell holding a paragraph — a follow-up's itinerary, a long note. Measured
   and wrapped by corpraasta-shell.js, because the height is what matters and
   only the browser knows it. The nowrap clamp above cannot do this: a <br>
   breaks the line whatever white-space says, and this content is made of them. */
.cra-scroll table.dataTable tbody td.cra-cell--tall,
.cra-scroll table.table > tbody > tr > td.cra-cell--tall {
    white-space: normal;
    max-width: 320px;
    cursor: pointer;
}

.cra-cell__inner {
    display: -webkit-box;
    -webkit-line-clamp: 3;
    line-clamp: 3;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

/* A cell whose content is a table or a list: capped by height rather than by
   line count, because a -webkit-box cannot hold either. */
.cra-cell__inner--block {
    display: block;
    max-height: 62px;
    overflow: hidden;
}

td.cra-cell--tall.is-open .cra-cell__inner {
    display: block;
    max-height: none;
    overflow: visible;
}

/* The cell says it can be opened, quietly. */
td.cra-cell--tall::after {
    content: '';
    display: block;
    width: 14px;
    height: 2px;
    margin-top: 6px;
    border-radius: 999px;
    background:
        radial-gradient(circle, var(--muted-fg) 45%, transparent 50%) 0 0 / 4px 2px repeat-x;
    opacity: .55;
}

td.cra-cell--tall.is-open::after { opacity: 0; }
td.cra-cell--tall:hover::after { opacity: .9; }
td.cra-cell--tall:focus-visible { outline: 2px solid var(--ring); outline-offset: -2px; }

/* A follow-up row opens the follow-ups screen; it is a link, and reads like
   the rest of the card rather than like one. */
a.cra-task { color: inherit; text-decoration: none; }
a.cra-task:hover { background: var(--muted2); }
a.cra-task:hover .cra-task__body b { text-decoration: underline; }
a.cra-task:focus-visible { outline: 2px solid var(--ring); outline-offset: -2px; border-radius: 8px; }

/* ── Finance dashboard ─────────────────────────────────────────────────── */

/* A column chart drawn from the values themselves — six bars, no library. */
.cra-cols {
    display: flex;
    align-items: flex-end;
    gap: 10px;
    height: 168px;
    margin: 18px 0 4px;
}

.cra-cols__col {
    flex: 1 1 0;
    min-width: 0;
    height: 100%;
    display: flex;
    flex-direction: column;
    justify-content: flex-end;
    gap: 8px;
}

.cra-cols__col i {
    display: block;
    width: 100%;
    border-radius: 6px 6px 3px 3px;
    background: var(--muted);
    transition: height .35s var(--ease);
}

.cra-cols__col:hover i { background: var(--primary); }

.cra-cols__col span {
    font-size: 11px;
    color: var(--muted-fg);
    text-align: center;
}

/* A payment account. The design draws these as filled cards; here the balance
   is the loudest thing on the row and the number behind it stays quiet. */
.cra-acct { padding: 11px 0; border-top: 1px solid var(--border); }
.cra-acct:first-of-type { border-top: 0; }

.cra-acct__row {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 12px;
    font-size: 13px;
}

.cra-acct__row b { font-weight: 500; }
.cra-acct__row > span { font-weight: 600; white-space: nowrap; }

.cra-acct__no {
    display: block;
    margin-top: 3px;
    font-size: 11px;
    color: var(--muted-fg);
    font-variant-numeric: tabular-nums;
}

.cra-amt--in { color: var(--teal, #1d8f52); font-weight: 600; }
.cra-amt--out { color: var(--fg); font-weight: 600; }

.cra-rows--fin .cra-rows__head,
.cra-row.cra-rows--fin { grid-template-columns: 2fr 1.4fr .9fr 1fr; }

/* ── Project board ─────────────────────────────────────────────────────── */
.cra-dot {
    display: inline-block;
    width: 7px;
    height: 7px;
    border-radius: 999px;
    margin-inline-end: 6px;
    background: var(--muted-fg);
    vertical-align: middle;
}

.cra-dot--low { background: var(--muted-fg); }
.cra-dot--medium { background: var(--amb, #9a6b00); }
.cra-dot--high { background: var(--red); }
.cra-dot--urgent { background: var(--red); box-shadow: 0 0 0 3px var(--redbg); }

.cra-rows--proj .cra-rows__head,
.cra-row.cra-rows--proj { grid-template-columns: 2fr 1.4fr 1fr .9fr .6fr; }

/* ── AdminLTE leftovers used across every module ───────────────────────────
   .callout and .info-box are the two shapes the module views reach for when
   they want a notice or a figure. Untouched they arrive in AdminLTE's palette
   — a bright cyan slab for "Projects not found!" — which is louder than
   anything on the page it interrupts. Styled once here rather than per
   module, because every one of them uses these. */

/* The vendor bundle paints .callout.callout-info, .alert-info and .bg-aqua
   from one rule carrying !important, so the weight has to be matched rather
   than argued with. */
.cra-scroll .callout,
.cra-scroll .callout.callout-info,
.cra-scroll .callout.callout-warning,
.cra-scroll .callout.callout-danger,
.cra-scroll .callout.callout-success {
    margin: 0 0 16px;
    padding: 14px 16px;
    border: 1px solid var(--border) !important;
    border-inline-start: 3px solid var(--muted-fg) !important;
    border-radius: 10px;
    background: var(--muted2) !important;
    color: var(--fg) !important;
    box-shadow: none;
}

.cra-scroll .callout h4 {
    margin: 0;
    font-size: 13.5px;
    font-weight: 500;
    color: var(--fg);
    display: flex;
    align-items: center;
    gap: 8px;
}

.cra-scroll .callout h4 i { font-size: 13px; color: var(--muted-fg); }
.cra-scroll .callout p { margin: 6px 0 0; font-size: 12.5px; color: var(--muted-fg); }

.cra-scroll .callout.callout-info { border-inline-start-color: var(--muted-fg) !important; }
.cra-scroll .callout.callout-warning { border-inline-start-color: var(--amb, #9a6b00) !important; }
.cra-scroll .callout.callout-danger { border-inline-start-color: var(--red) !important; }
.cra-scroll .callout.callout-success { border-inline-start-color: var(--teal, #1d8f52) !important; }

/* Same rule, same treatment: an alert is a notice, not a billboard. */
.cra-scroll .alert.alert-info,
.cra-scroll .alert.alert-success,
.cra-scroll .alert.alert-warning {
    border: 1px solid var(--border) !important;
    border-radius: 10px;
    background: var(--muted2) !important;
    color: var(--fg) !important;
    box-shadow: none;
}

/* A figure tile. AdminLTE hangs a coloured square on the left of each; the
   colour carries no meaning here, so it becomes a quiet glyph. */
.cra-scroll .info-box {
    display: flex;
    align-items: center;
    gap: 14px;
    min-height: 0;
    margin-bottom: 16px;
    padding: 16px 18px;
    border: 1px solid var(--border);
    border-radius: 12px;
    background: var(--card);
    box-shadow: var(--shadow);
    color: var(--fg);
}

.cra-scroll .info-box-icon {
    display: grid;
    place-items: center;
    width: 42px;
    height: 42px;
    flex-shrink: 0;
    border-radius: 10px;
    background: var(--muted) !important;
    color: var(--muted-fg) !important;
    font-size: 16px;
    line-height: 1;
}

.cra-scroll .info-box-content { margin: 0; padding: 0; min-width: 0; }

.cra-scroll .info-box-text {
    display: block;
    font-size: 12px;
    font-weight: 500;
    color: var(--muted-fg);
    text-transform: none;
    letter-spacing: normal;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.cra-scroll .info-box-number {
    display: block;
    margin-top: 2px;
    font-size: 22px;
    font-weight: 600;
    color: var(--fg);
}

.cra-scroll .progress,
.cra-scroll .info-box .progress {
    height: 6px;
    margin: 8px 0 0;
    border-radius: 999px;
    background: var(--muted);
    box-shadow: none;
}

.cra-scroll .progress-bar {
    background: var(--primary);
    border-radius: 999px;
    box-shadow: none;
}

/* ── HR board ──────────────────────────────────────────────────────────── */
.cra-cols__col.is-today i { background: var(--primary); }

/* A meeting: the date as a block, then what and when. */
.cra-meet {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 10px 0;
    border-top: 1px solid var(--border);
    color: inherit;
    text-decoration: none;
}

.cra-meet:first-of-type { border-top: 0; }
.cra-meet:hover { background: var(--muted2); }
.cra-meet:hover .cra-meet__body b { text-decoration: underline; }

.cra-meet__when {
    display: grid;
    place-items: center;
    width: 42px;
    height: 42px;
    flex-shrink: 0;
    border: 1px solid var(--border);
    border-radius: 10px;
    background: var(--muted2);
    line-height: 1.1;
}

.cra-meet__when b { font-size: 15px; font-weight: 600; }
.cra-meet__when small { font-size: 10px; color: var(--muted-fg); text-transform: uppercase; }

.cra-meet__body { min-width: 0; }
.cra-meet__body b { display: block; font-size: 13px; font-weight: 500; }
.cra-meet__body small { display: block; margin-top: 2px; font-size: 11.5px; color: var(--muted-fg); }

.cra-rows--hr .cra-rows__head,
.cra-row.cra-rows--hr { grid-template-columns: 2fr 1.6fr 1.2fr .8fr; }

/* ── the POS tab pattern ───────────────────────────────────────────────────
   A left rail of links and a stack of panels, one of which carries .active.
   Accounting's Transactions screen uses it, and so do the POS screens.

   app.css sets `div.pos-tab-container { background-color: #ffffff }` and
   nothing else touches it, so under the dark palette the container stayed
   white while its text inherited near-white — the tables were there and
   unreadable. The same hard-coded white broke the contact ledger earlier.

   The DOM contract is left exactly as common.js expects it — it toggles
   .active on `div.pos-tab-menu > div.list-group > a` and on the matching
   `div.pos-tab > div.pos-tab-content` by index — so only the dress changes. */

.cra-scroll div.pos-tab-container {
    background: transparent !important;
    border-radius: 0;
    box-shadow: none;
    display: flex;
    gap: 16px;
    align-items: flex-start;
}

.cra-scroll div.pos-tab-menu {
    flex: 0 0 210px;
    max-width: 210px;
    width: auto;
    padding: 0;
}

.cra-scroll div.pos-tab-menu div.list-group {
    display: flex;
    flex-direction: column;
    gap: 2px;
    margin: 0;
    padding: 5px;
    border: 1px solid var(--border);
    border-radius: 12px;
    background: var(--card);
    box-shadow: var(--shadow);
}

.cra-scroll div.pos-tab-menu div.list-group > a {
    display: block;
    margin: 0;
    padding: 9px 12px;
    border: 0 !important;
    border-radius: 8px !important;
    background: transparent !important;
    color: var(--muted-fg) !important;
    font-size: 13px;
    text-align: start;
    text-decoration: none;
}

.cra-scroll div.pos-tab-menu div.list-group > a:hover {
    background: var(--muted) !important;
    color: var(--fg) !important;
}

/* The active tab is the one thing here that gets weight. */
.cra-scroll div.pos-tab-menu div.list-group > a.active,
.cra-scroll div.pos-tab-menu div.list-group > a.active:hover {
    background: var(--primary) !important;
    background-image: none !important;
    color: var(--primary-fg) !important;
    font-weight: 500;
}

.cra-scroll div.pos-tab-menu div.list-group > a.active::after { display: none !important; }

/* The panels share one column; only the active one is in flow. */
.cra-scroll div.pos-tab {
    flex: 1 1 auto;
    min-width: 0;
    width: auto;
    padding: 0;
}

.cra-scroll div.pos-tab:not(:has(> .pos-tab-content.active)) { display: none; }

/* The panel is a column, not a card. Its contents already bring their own:
   the filter strip renders a .cr-card, and the table gets one below. Making
   the panel a card too put a card inside a card — two borders, two paddings,
   for one block of content. */
.cra-scroll div.pos-tab > div.pos-tab-content {
    padding: 0;
    border: 0;
    background: transparent;
    box-shadow: none;
    min-width: 0;
}

/* The row that holds the table becomes that card, and scrolls inside it. The
   table is a bare <table> with no .table-responsive around it, so once
   DataTables widened it past the panel it simply ran off the side of the page
   — the last two columns were unreachable. */
.cra-scroll div.pos-tab-content > .row:has(table) {
    margin: 0;
    padding: 20px;
    border: 1px solid var(--border);
    border-radius: 12px;
    background: var(--card);
    box-shadow: var(--shadow);
}

.cra-scroll div.pos-tab-content > .row:has(table) > [class*="col-"] {
    padding: 0;
    min-width: 0;
    overflow-x: auto;
}

/* The filter row above it. Only the purchases panel renders the shared
   filters card; the other three drop bare form fields straight into a row,
   which left them floating above the table with nothing around them. Those
   get a card of their own — the one that already has one is left alone. */
.cra-scroll div.pos-tab-content > .row:not(:has(table)):not(:has(.cr-card)) {
    margin: 0 0 16px;
    padding: 16px 20px 4px;
    border: 1px solid var(--border);
    border-radius: 12px;
    background: var(--card);
    box-shadow: var(--shadow);
}

.cra-scroll div.pos-tab-content > .row:has(.cr-card) { margin: 0; }
.cra-scroll div.pos-tab-content > .row > .cr-card { margin-bottom: 16px !important; }

@media (max-width: 900px) {
    .cra-scroll div.pos-tab-container { flex-direction: column; }
    .cra-scroll div.pos-tab-menu { flex: 1 1 auto; max-width: none; width: 100%; }
    .cra-scroll div.pos-tab-menu div.list-group { flex-direction: row; overflow-x: auto; }
    .cra-scroll div.pos-tab-menu div.list-group > a { white-space: nowrap; }
}

/* ── the messages board ────────────────────────────────────────────────────
   Not a chat: a message has a sender, a body and a location, and no
   recipient — it is a notice posted to everyone at that location. So it
   reads as a feed rather than as two columns of bubbles. */
.cra-chat { overflow: hidden; }

.cra-chat__log {
    max-height: 62vh;
    overflow-y: auto;
    padding: 6px 20px;
}

.cra-msg {
    display: flex;
    gap: 12px;
    padding: 14px 0;
    border-top: 1px solid var(--border);
}

.cra-msg:first-child { border-top: 0; }

.cra-msg__av {
    display: grid;
    place-items: center;
    width: 32px;
    height: 32px;
    flex-shrink: 0;
    border-radius: 9px;
    background: var(--muted);
    color: var(--fg);
    font-size: 12px;
    font-weight: 600;
    text-transform: uppercase;
}

.cra-msg__body { min-width: 0; flex: 1 1 auto; }

.cra-msg__head {
    display: flex;
    align-items: baseline;
    gap: 8px;
    margin-bottom: 3px;
}

.cra-msg__head b { font-size: 13px; font-weight: 600; }
.cra-msg__head small { font-size: 11px; color: var(--muted-fg); }

.cra-msg__del {
    margin-inline-start: auto;
    padding: 0 4px;
    color: var(--muted-fg);
    font-size: 16px;
    line-height: 1;
    text-decoration: none;
}

.cra-msg__del:hover { color: var(--red); }

.cra-msg__body p {
    margin: 0;
    font-size: 13px;
    line-height: 1.55;
    overflow-wrap: anywhere;
}

/* One line: what to say, where it goes, and send. */
.cra-chat__compose {
    display: flex;
    align-items: flex-end;
    gap: 10px;
    padding: 14px 20px;
    border-top: 1px solid var(--border);
    background: var(--muted2);
}

.cra-chat__compose form {
    display: contents;
}

.cra-chat__compose textarea#chat-msg {
    flex: 1 1 auto;
    min-width: 0;
    min-height: 38px;
    max-height: 120px;
    resize: vertical;
}

.cra-chat__compose select { flex: 0 0 180px; max-width: 180px; }
.cra-chat__compose .cra-btn { flex-shrink: 0; }

@media (max-width: 700px) {
    .cra-chat__compose { flex-wrap: wrap; }
    .cra-chat__compose textarea#chat-msg { flex: 1 1 100%; }
    .cra-chat__compose select { flex: 1 1 auto; max-width: none; }
}

/* ── the project kanban ────────────────────────────────────────────────────
   jKanban: .kanban-container holds a .kanban-board per status, each with a
   .kanban-board-header and a .kanban-drag people drop cards into.

   Out of the box each column arrives painted in its status colour — a pale
   red slab for Not Started, a solid blue one for In progress, mustard for On
   hold — over a flat grey body. Five saturated blocks side by side, none of
   which say more than a dot would. The colour moves to a dot in the header
   and the columns become cards like everything else. */

.cra-scroll .kanban-container {
    display: flex;
    gap: 14px;
    align-items: flex-start;
    overflow-x: auto;
    padding-bottom: 8px;
}

.cra-scroll .kanban-board {
    flex: 0 0 296px;
    max-width: 296px;
    margin: 0 !important;
    border: 1px solid var(--border) !important;
    border-radius: 12px !important;
    background: var(--muted2) !important;
    box-shadow: none !important;
}

.cra-scroll .kanban-board-header {
    padding: 12px 14px !important;
    border: 0 !important;
    border-radius: 12px 12px 0 0 !important;
    background: transparent !important;
    color: var(--fg) !important;
}

.cra-scroll .kanban-board-header .kanban-title-board,
.cra-scroll .kanban-board-header .board-title {
    display: flex;
    align-items: center;
    gap: 8px;
    margin: 0;
    font-size: 12.5px;
    font-weight: 600;
    color: var(--fg) !important;
}

/* The status reads as a dot rather than a wash across the whole column. The
   dot goes on the innermost title only — .board-title sits inside
   .kanban-title-board, and putting it on both drew two. */
.cra-scroll .kanban-board-header .board-title::before {
    content: '';
    width: 8px;
    height: 8px;
    flex-shrink: 0;
    border-radius: 999px;
    background: var(--muted-fg);
}

.cra-scroll .kanban-board.new .board-title::before { background: var(--muted-fg); }
.cra-scroll .kanban-board.info .board-title::before { background: var(--vio, #8f6fe8); }
.cra-scroll .kanban-board.warning .board-title::before { background: var(--amb, #9a6b00); }
.cra-scroll .kanban-board.success .board-title::before { background: var(--red); }
.cra-scroll .kanban-board.good .board-title::before { background: var(--teal, #1d8f52); }

/* The icons the header ships are redundant next to the dot. */
.cra-scroll .kanban-board-header .fas,
.cra-scroll .kanban-board-header .fa { display: none !important; }

/* The drop area. Empty, it says so rather than sitting there as a grey slab. */
.cra-scroll .kanban-drag {
    min-height: 120px;
    margin: 0 !important;
    padding: 0 10px 10px !important;
    background: transparent !important;
}

.cra-scroll .kanban-drag:not(:has(.kanban-item)) {
    margin: 0 10px 10px !important;
    padding: 0 !important;
    border: 1px dashed var(--border);
    border-radius: 10px;
}

/* A card. */
.cra-scroll .kanban-item {
    margin: 0 0 8px !important;
    padding: 12px !important;
    border: 1px solid var(--border) !important;
    border-radius: 10px !important;
    background: var(--card) !important;
    box-shadow: var(--shadow) !important;
    color: var(--fg) !important;
    font-size: 13px;
    cursor: grab;
    transition: border-color .12s var(--ease), box-shadow .12s var(--ease);
}

.cra-scroll .kanban-item:last-child { margin-bottom: 0 !important; }
.cra-scroll .kanban-item:hover { border-color: var(--muted-fg) !important; }
.cra-scroll .kanban-item:active { cursor: grabbing; }

.cra-scroll .kanban-item a { color: inherit; text-decoration: none; }
.cra-scroll .kanban-item a:hover { text-decoration: underline; }
.cra-scroll .kanban-item small,
.cra-scroll .kanban-item .text-muted { color: var(--muted-fg) !important; font-size: 11.5px; }

/* jKanban's drag placeholder. */
.cra-scroll .kanban-item.is-moving,
.cra-scroll .gu-mirror.kanban-item {
    box-shadow: var(--shadow-pop) !important;
    opacity: .95;
}

.cra-scroll .gu-transit.kanban-item {
    border-style: dashed !important;
    background: var(--muted) !important;
    opacity: .5;
}

/* ── delivery channels ─────────────────────────────────────────────────
   Three screens: what is connected, what the platform's menu items mean
   here, and what has arrived. They reuse the card, chip and field styles
   above; what follows is only the parts those screens add — a tab strip,
   a plain table, and a monospaced treatment for the ids and URLs that get
   copied between this system and a platform's dashboard.
--------------------------------------------------------------------- */
.cra-field select {
    width: 100%;
    min-width: 0;
    height: 38px;
    padding: 0 34px 0 12px;
    border: 1px solid var(--border);
    border-radius: 9px;
    background: var(--bg) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%2371717a' stroke-width='2.5' stroke-linecap='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E") no-repeat right 12px center;
    color: var(--fg);
    font: inherit;
    font-size: 13px;
    -webkit-appearance: none;
    appearance: none;
    outline: none;
}

.cra-field select:focus { border-color: var(--ring); }

/* Ids, keys and webhook URLs. Read one character at a time when it is
   being checked against a platform's dashboard, so the digits need to be
   the same width and 0 must not read as O. */
.cra-mono {
    font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;
    font-size: 12px;
    letter-spacing: -0.01em;
}

input.cra-mono { cursor: text; }

.cra-tabs {
    display: flex;
    gap: 4px;
    padding: 3px;
    margin-bottom: 16px;
    border-radius: 9px;
    background: var(--muted);
    width: fit-content;
    max-width: 100%;
    overflow-x: auto;
}

.cra-tab {
    padding: 6px 14px;
    border-radius: 7px;
    color: var(--muted-fg);
    font-size: 12px;
    font-weight: 500;
    white-space: nowrap;
    text-decoration: none;
    transition: background .15s, color .15s;
}

.cra-tab:hover { color: var(--fg); text-decoration: none; }

.cra-tab.is-active {
    background: var(--card);
    color: var(--fg);
    box-shadow: 0 1px 2px rgba(0, 0, 0, .06);
}

/* The add-a-mapping row: four fields and a button, side by side while
   there is room and stacked once there is not. */
.cra-maprow {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
    gap: 12px;
    align-items: end;
}

.cra-maprow > .cra-btn { height: 38px; }

/* A plain table, measured like the list screens so the two do not read as
   coming from different products. */
.cra-tablewrap { overflow-x: auto; }

.cra-shell .cra-scroll table.cra-table {
    width: 100%;
    margin: 0;
    border: 0;
    border-collapse: collapse;
}

.cra-shell .cra-scroll table.cra-table > thead > tr > th {
    padding: 8px 14px;
    border: 0;
    border-bottom: 1px solid var(--border);
    background: var(--muted2);
    color: var(--muted-fg);
    font-size: 12px;
    font-weight: 500;
    text-transform: none;
    letter-spacing: normal;
    white-space: nowrap;
}

.cra-shell .cra-scroll table.cra-table > tbody > tr > td {
    padding: 14px;
    border: 0;
    border-top: 1px solid var(--border);
    color: var(--fg);
    font-size: 13px;
    vertical-align: middle;
}

.cra-shell .cra-scroll table.cra-table > tbody > tr:first-child > td { border-top: 0; }

.cra-table form { display: inline; margin: 0; }

.cra-btn--sm { height: 26px; padding: 0 10px; font-size: 11.5px; }

/* Why an order did not become a sale. Sits under its status chip, wraps,
   and stays quiet — it is a note, not an alarm. */
.cra-dcerr {
    margin-top: 4px;
    max-width: 320px;
    color: var(--muted-fg);
    font-size: 11.5px;
    line-height: 1.45;
}

.cra-steps {
    margin: 10px 0 0;
    padding-left: 18px;
    color: var(--muted-fg);
    font-size: 13px;
    line-height: 1.7;
}

.cra-steps li { margin-bottom: 2px; }

/* ── contact profile ───────────────────────────────────────────────────
   The top of a customer's or supplier's page. Identity and money on the
   left, what has been happening on the right; the tabs underneath keep
   the full ledger and lists they always had.
--------------------------------------------------------------------- */
.cra-prof {
    display: grid;
    grid-template-columns: minmax(0, 340px) minmax(0, 1fr);
    gap: 16px;
    align-items: start;
    margin-bottom: 20px;
}

@media (max-width: 991px) { .cra-prof { grid-template-columns: minmax(0, 1fr); } }

.cra-prof__side { display: grid; gap: 16px; align-content: start; }

.cra-prof__id { text-align: center; padding-bottom: 18px; }

/* No photographs on a contact, so initials — steadier than a stock avatar,
   and it tells two similarly named contacts apart at a glance. */
.cra-prof__av {
    width: 72px;
    height: 72px;
    margin: 0 auto 12px;
    display: grid;
    place-items: center;
    border-radius: 50%;
    background: var(--muted);
    color: var(--fg);
    font-size: 24px;
    font-weight: 600;
    letter-spacing: 0.02em;
}

.cra-prof__name { font-size: 17px; font-weight: 600; color: var(--fg); line-height: 1.3; }

.cra-prof__meta {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    margin-top: 7px;
    color: var(--muted-fg);
}

.cra-prof__biz { margin: 8px 0 0; font-size: 12.5px; color: var(--muted-fg); }

/* The three figures. Equal columns with hairline dividers, so the eye reads
   them as one set rather than three cards. */
.cra-prof__stats {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    border: 1px solid var(--border);
    border-radius: 11px;
    overflow: hidden;
    background: var(--muted2);
}

.cra-prof__stats > div {
    padding: 14px 8px;
    text-align: center;
    border-left: 1px solid var(--border);
    min-width: 0;
}

.cra-prof__stats > div:first-child { border-left: 0; }

/* Three amounts across a narrow card. Tabular figures keep the columns
   aligned, and the size steps down with the card rather than breaking a
   number across two lines — "₹11,28,382." above "00" reads as two
   numbers. */
.cra-prof__stat {
    font-size: clamp(12px, 3.4cqi, 15px);
    font-weight: 600;
    color: var(--fg);
    line-height: 1.3;
    white-space: nowrap;
    font-variant-numeric: tabular-nums;
}

.cra-prof__stats { container-type: inline-size; }

/* Money still owed is the one figure worth colouring; the rest stay plain
   so that colour keeps meaning something. */
.cra-prof__stat.is-due { color: var(--red, #dc2626); }

/* Labels wrap rather than run into the cell beside them: "Total purchase"
   and "Purchase due" are wider than a third of this card at some zoom
   levels, and a collision here reads as a broken layout. */
.cra-prof__statlabel {
    margin-top: 4px;
    font-size: 11.5px;
    line-height: 1.35;
    color: var(--muted-fg);
    overflow-wrap: break-word;
    hyphens: auto;
}

/* The stored address keeps its own line breaks. */
.cra-prof__addr { white-space: pre-line; }

.cra-prof__pair {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: 12px;
    padding: 9px 2px;
    border-bottom: 1px solid var(--border);
    font-size: 12.5px;
    color: var(--muted-fg);
}

.cra-prof__pair b { color: var(--fg); font-weight: 600; }

.cra-prof__rows { margin-top: 18px; display: grid; gap: 11px; }

.cra-prof__row {
    display: grid;
    grid-template-columns: 16px minmax(0, 1fr);
    gap: 10px;
    align-items: start;
    font-size: 13px;
    color: var(--fg);
    line-height: 1.5;
    word-break: break-word;
}

.cra-prof__row i { color: var(--muted-fg); font-size: 12px; margin-top: 3px; }
.cra-prof__row a { color: var(--fg); }
.cra-prof__row a:hover { text-decoration: underline; }

.cra-prof__acts { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 18px; }

/* Activity: a rail of dots down the left, the way a history reads. */
.cra-prof__act {
    display: grid;
    grid-template-columns: 8px minmax(0, 1fr);
    gap: 12px;
    padding: 10px 0;
    border-bottom: 1px solid var(--border);
}

.cra-prof__act:last-child { border-bottom: 0; padding-bottom: 0; }

.cra-prof__actdot {
    width: 8px;
    height: 8px;
    margin-top: 6px;
    border-radius: 50%;
    background: var(--border);
}

.cra-prof__act:first-child .cra-prof__actdot { background: var(--primary); }

.cra-prof__actmain { font-size: 13px; color: var(--fg); line-height: 1.5; }
.cra-prof__actmain span { color: var(--muted-fg); }
.cra-prof__actwhen { margin-top: 2px; font-size: 11.5px; color: var(--muted-fg); }

.cra-prof__more { font-size: 12px; color: var(--muted-fg); }
.cra-prof__more:hover { color: var(--fg); }

/* The jump-to-another-contact select, sized to the header rather than to
   the twelve-column grid it used to sit in. */
.cra-prof__jump { min-width: 240px; }
.cra-prof__jump .select2-container { min-width: 240px; }

/* ── hotel dashboard ───────────────────────────────────────────────────
   Rooms beside the booking trend, then the day's arrivals and departures
   underneath. The ring and the chart share a row because they answer the
   same question at two timescales — how full are we now, and where is
   that heading.
--------------------------------------------------------------------- */
.cra-hms__grid {
    display: grid;
    grid-template-columns: minmax(0, 360px) minmax(0, 1fr);
    gap: 16px;
    align-items: start;
    margin-bottom: 16px;
}

@media (max-width: 991px) { .cra-hms__grid { grid-template-columns: minmax(0, 1fr); } }

/* Both ranges reserve the same height, so switching between them does not
   move the cards underneath. */
.cra-hms__chart { min-height: 280px; margin-top: 14px; }
.cra-hms__chart > div { width: 100% !important; }

.cra-hms__types { margin-top: 18px; }
.cra-hms__types .cra-prof__pair:last-child { border-bottom: 0; }

/* ── trendline ─────────────────────────────────────────────────────────
   The small line chart drawn as plain SVG. Sized by its container, so it
   works inside a card that starts hidden — which is the whole reason it
   exists rather than a chart library instance.
--------------------------------------------------------------------- */
.cra-trend { margin-top: 14px; }

.cra-trend svg { display: block; width: 100%; height: 200px; overflow: visible; }

.cra-trend__grid { stroke: var(--border); stroke-width: 1; }

.cra-trend__ytick {
    fill: var(--muted-fg);
    font-size: 10px;
    font-family: inherit;
}

/* vector-effect keeps the stroke one pixel wide however the viewBox is
   stretched; without it a wide card draws a hairline and a narrow one a
   slab. */
.cra-trend__line {
    fill: none;
    stroke: var(--primary);
    stroke-width: 2;
    stroke-linecap: round;
    stroke-linejoin: round;
    vector-effect: non-scaling-stroke;
}

.cra-trend__dot {
    fill: var(--card);
    stroke: var(--primary);
    stroke-width: 2;
    vector-effect: non-scaling-stroke;
}

.cra-trend__x {
    display: flex;
    justify-content: space-between;
    gap: 4px;
    margin-top: 8px;
    padding-left: 34px;
    font-size: 11px;
    color: var(--muted-fg);
}

.cra-trend__x span {
    flex: 1 1 0;
    min-width: 0;
    text-align: center;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* ── booking calendar ──────────────────────────────────────────────────
   Rooms down the side, the week across the top, a stay drawn as one block
   however many nights it runs. The room column stays put while the week
   scrolls sideways, because a booking is meaningless without knowing which
   room it is in.
--------------------------------------------------------------------- */
.cra-cal__nav { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }

.cra-cal__range {
    padding: 0 8px;
    font-size: 13px;
    font-weight: 500;
    color: var(--fg);
    white-space: nowrap;
}

/* Stepping the week and jumping to a date are different intentions, so they
   sit at opposite ends of the strip rather than crowding each other. */
.cra-cal__jump { min-width: 190px; margin-inline-start: auto; }

/* A full-width select pushed the button onto its own line. The filter needs
   room to show a room type name and no more. */
.cra-cal__type { width: 190px; }
.cra-cal__type select { width: 100%; }

.cra-shell .cra-scroll table.cra-cal {
    width: 100%;
    margin: 0;
    border-collapse: separate;
    border-spacing: 0;
    table-layout: fixed;
}

.cra-shell .cra-scroll table.cra-cal th,
.cra-shell .cra-scroll table.cra-cal td {
    border: 0;
    border-inline-start: 1px solid var(--border);
    border-bottom: 1px solid var(--border);
    padding: 0;
    vertical-align: top;
}

.cra-shell .cra-scroll table.cra-cal thead th {
    padding: 10px 8px;
    background: var(--muted2);
    text-align: center;
    font-weight: 500;
    white-space: nowrap;
}

.cra-cal__dayname { display: block; font-size: 11px; color: var(--muted-fg); }
.cra-cal__daynum { display: block; font-size: 15px; font-weight: 600; color: var(--fg); margin-top: 2px; }

.cra-shell .cra-scroll table.cra-cal thead th.is-today { background: var(--muted); }
.cra-shell .cra-scroll table.cra-cal thead th.is-today .cra-cal__daynum { color: var(--primary); }

/* The room column is sticky, and opaque — a transparent sticky column lets
   the cells it is meant to cover show straight through it. */
.cra-shell .cra-scroll table.cra-cal .cra-cal__roomhead,
.cra-shell .cra-scroll table.cra-cal .cra-cal__room {
    position: sticky;
    inset-inline-start: 0;
    z-index: 2;
    width: 150px;
    padding: 12px 14px;
    background: var(--card);
    border-inline-start: 0;
    text-align: start;
}

.cra-shell .cra-scroll table.cra-cal .cra-cal__roomhead { background: var(--muted2); z-index: 3; }

.cra-cal__roomno { display: block; font-size: 13px; font-weight: 600; color: var(--fg); }
.cra-cal__roomtype { display: block; font-size: 11.5px; color: var(--muted-fg); margin-top: 2px; }

.cra-cal__cell { height: 74px; }

/* A stay, drawn as one block across every night it covers. */
.cra-cal__bk {
    display: block;
    height: 100%;
    margin: 5px;
    padding: 8px 10px;
    border-radius: 8px;
    border-inline-start: 3px solid var(--primary);
    background: var(--muted);
    color: var(--fg);
    text-decoration: none;
    overflow: hidden;
}

.cra-cal__bk:hover { background: var(--muted2); color: var(--fg); text-decoration: none; }

.cra-cal__bkid {
    display: block;
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-size: 10.5px;
    color: var(--muted-fg);
}

.cra-cal__bkname {
    display: block;
    margin-top: 2px;
    font-size: 13px;
    font-weight: 600;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.cra-cal__bkmeta { display: block; margin-top: 2px; font-size: 11px; color: var(--muted-fg); }

/* A free night is where a booking gets made, so the whole cell is the
   target. It stays quiet until pointed at. */
.cra-cal__add {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 5px;
    height: 100%;
    font-size: 11.5px;
    color: transparent;
    text-decoration: none;
    transition: color .12s var(--ease), background .12s var(--ease);
}

.cra-cal__cell--free:hover .cra-cal__add { color: var(--muted-fg); background: var(--muted2); }
.cra-cal__add:hover { color: var(--fg); text-decoration: none; }

/* ── catalogue summary ─────────────────────────────────────────────────
   The strip above the product list. Two ways of showing a proportion: a
   split bar where the ratio is the point, and a run of blocks where the
   figure is a count of things and should read as one.
--------------------------------------------------------------------- */
.cra-stockbar { margin-bottom: 16px; }

.cra-meterbar {
    display: flex;
    height: 8px;
    margin-top: 12px;
    border-radius: 999px;
    overflow: hidden;
    background: var(--cra-slice-1, var(--muted));
}

.cra-meterbar > span { display: block; background: var(--cra-slice-0, var(--primary)); }

.cra-meterbar__keys {
    display: flex;
    flex-wrap: wrap;
    gap: 12px;
    margin-top: 9px;
    font-size: 11.5px;
    color: var(--muted-fg);
}

.cra-meterbar__keys i {
    display: inline-block;
    width: 8px;
    height: 8px;
    margin-inline-end: 5px;
    border-radius: 2px;
    vertical-align: middle;
}

.cra-meterbar__keys i.is-a { background: var(--cra-slice-0, var(--primary)); }
.cra-meterbar__keys i.is-b { background: var(--cra-slice-1, var(--muted)); }

/* A run of blocks. The count of lit blocks is the proportion, but read as
   a quantity — which is what a stock figure is. */
.cra-blocks {
    display: flex;
    gap: 3px;
    margin-top: 12px;
}

.cra-blocks i {
    flex: 1 1 0;
    min-width: 0;
    height: 16px;
    border-radius: 2px;
    background: var(--muted);
}

.cra-blocks i.is-on { background: var(--cra-slice-0, var(--primary)); }

/* ── my profile ────────────────────────────────────────────────────────
   The person, above the forms for changing them. A cover strip with the
   avatar sitting across its lower edge, the way a profile reads.
--------------------------------------------------------------------- */
.cra-me {
    margin-bottom: 20px;
    border: 1px solid var(--border);
    border-radius: 14px;
    background: var(--card);
    overflow: hidden;
}

/* No cover images anywhere in this system, so the strip is a gradient built
   from the theme rather than a stock photograph that would date badly and
   look the same on every account. */
.cra-me__cover {
    height: 132px;
    background:
        radial-gradient(120% 140% at 12% 0%, color-mix(in srgb, var(--primary) 28%, transparent) 0%, transparent 60%),
        radial-gradient(100% 120% at 88% 10%, color-mix(in srgb, var(--primary) 16%, transparent) 0%, transparent 55%),
        var(--muted);
}

.cra-me__id { padding: 0 24px 22px; text-align: center; }

.cra-me__av {
    display: block;
    width: 96px;
    height: 96px;
    margin: -48px auto 12px;
    border-radius: 50%;
    border: 4px solid var(--card);
    background: var(--muted2);
    object-fit: cover;
}

.cra-me__av--initials {
    display: grid;
    place-items: center;
    font-size: 30px;
    font-weight: 600;
    color: var(--fg);
}

.cra-me__name { margin: 0; font-size: 20px; font-weight: 600; color: var(--fg); }

.cra-me__meta {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 8px 20px;
    margin-top: 10px;
    font-size: 12.5px;
    color: var(--muted-fg);
}

.cra-me__meta i { margin-inline-end: 6px; opacity: .8; }

/* ── sales dashboard ───────────────────────────────────────────────────
   The twelve-month line beside how much has been collected, then who is
   buying, who is selling, and what came in last.
--------------------------------------------------------------------- */
.cra-sd__grid {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 380px);
    gap: 16px;
    align-items: start;
    margin-bottom: 16px;
}

.cra-sd__grid--3 { grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); }

@media (max-width: 991px) { .cra-sd__grid { grid-template-columns: minmax(0, 1fr); } }

.cra-sd__filters { display: flex; gap: 8px; margin: 0; }
.cra-sd__range { width: 210px; }
.cra-sd__loc { width: 180px; }

/* Three segments in one track. Each carries its own colour inline because
   which segments are present depends on the data. */
.cra-meterbar--3 > span:first-child { border-start-start-radius: 999px; border-end-start-radius: 999px; }
.cra-meterbar--3 > span:last-child { border-start-end-radius: 999px; border-end-end-radius: 999px; }

.cra-sd__statuses { margin-top: 16px; }
.cra-sd__statuses .cra-prof__pair:last-child { border-bottom: 0; }

/* Its own class: .cra-bar__row is a flex row of name-and-value elsewhere, so
   nesting a label, a track and a note inside one laid all three side by
   side. */
.cra-sd__staff { padding: 10px 0; border-bottom: 1px solid var(--border); }
.cra-sd__staff:last-child { border-bottom: 0; padding-bottom: 0; }

.cra-sd__stafftop {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: 12px;
    font-size: 13px;
    color: var(--fg);
}

.cra-sd__staffname { font-weight: 500; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cra-sd__staffval { font-weight: 600; white-space: nowrap; }

.cra-sd__stafftrack {
    height: 6px;
    margin-top: 8px;
    border-radius: 999px;
    background: var(--muted);
    overflow: hidden;
}

.cra-sd__stafftrack > div { height: 100%; border-radius: 999px; background: var(--primary); }

.cra-sd__staffnote { margin-top: 5px; font-size: 11px; color: var(--muted-fg); }

.cra-sd__key {
    display: inline-block;
    width: 8px;
    height: 8px;
    margin-inline-end: 7px;
    border-radius: 2px;
    vertical-align: middle;
}

/* ── GSTIN lookup ──────────────────────────────────────────────────────
   The captcha panel, inline under the GSTIN field. The contact form is
   itself a modal on the contacts list, and Bootstrap 3 stacks a modal
   inside a modal badly — so this stays in the form.
--------------------------------------------------------------------- */
.cra-gst {
    margin-top: 10px;
    padding: 12px;
    border: 1px solid var(--border);
    border-radius: 10px;
    background: var(--muted2);
}

.cra-gst__cap { display: flex; align-items: center; gap: 8px; }

/* The portal's captcha comes back at its own size; a white plate behind it
   keeps it legible in dark mode, where the image's own background is not. */
.cra-gst__img {
    height: 44px;
    padding: 2px 6px;
    border-radius: 6px;
    background: #fff;
    flex: 0 0 auto;
}

/* The code goes on its own line. This panel lives inside a third-width form
   column, and an input sharing a row with two buttons there left room for
   about four characters of placeholder. */
.cra-gst__input { width: 100%; margin-top: 10px; }

.cra-gst__row { display: flex; gap: 8px; margin-top: 8px; }
.cra-gst__row .cra-btn { flex: 1 1 auto; }

.cra-gst__msg { margin-top: 9px; font-size: 12px; color: var(--muted-fg); line-height: 1.45; }
.cra-gst__msg.is-bad { color: var(--red, #dc2626); }

/* What came back. A cancelled registration is the one result worth
   colouring: billing against it costs the customer their input tax credit,
   and nothing else on the form would say so. */
.cra-gst__status {
    margin-top: 8px;
    font-size: 12px;
    color: var(--muted-fg);
}

.cra-gst__status.is-bad { color: var(--red, #dc2626); font-weight: 500; }

/* ── contact form ──────────────────────────────────────────────────────
   The add/edit contact dialog.

   Its fields were laid out in a mix of three-, four-, six- and
   twelve-column Bootstrap widths, so every row broke at a different place
   and nothing lined up with the row above it. The widths are ignored here
   and the whole form is put on one even track instead: each field takes a
   column, a full-width field spans them all, and the columns are the same
   width all the way down whatever fields the contact type reveals.

   Doing it this way rather than by rewriting the markup means the forty-odd
   conditional fields keep working exactly as they did — nothing is moved,
   only measured differently.
--------------------------------------------------------------------- */
/* Every group of fields lays out on the same track — the outer row, and the
   two blocks the form keeps collapsed. #more_div is a grid item itself, so
   without this its own fields were dividing one 288px column between three
   floated thirds and coming out 96px wide. */
.cra-cform .row,
.cra-cform #more_div:not(.hide),
.cra-cform .shipping_addr_div:not(.hide) {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(215px, 1fr));
    gap: 0 18px;
    margin: 0;
}

.cra-cform #more_div:not(.hide) { grid-column: 1 / -1; }

/* The Bootstrap widths are ignored throughout the dialog: they were a mix of
   three-, four-, six- and twelve-column spans, so every row broke at a
   different place and nothing lined up with the row above it. */
.cra-cform [class*="col-md-"],
.cra-cform [class*="col-sm-"],
.cra-cform [class*="col-xs-"] {
    float: none;
    width: auto;
    max-width: none;
    padding: 0;
    min-width: 0;
}

/* Full-width items — dividers, headings, wide notes — span the whole row
   rather than sitting in one column of it. */
.cra-cform .col-md-12,
.cra-cform .col-sm-12,
.cra-cform .cra-cform__sep,
.cra-cform .clearfix { grid-column: 1 / -1; }

/* Bootstrap clears its float rows with a ::before and an ::after carrying
   display:table. A grid container turns both of those into real grid items,
   so the first cell of the form was being eaten by an invisible one — which
   is why every field sat one column to the right of where it belonged. */
.cra-cform .row::before,
.cra-cform .row::after,
.cra-cform #more_div::before,
.cra-cform #more_div::after { content: none; display: none; }

/* Same for the clearfix divs between float rows: nothing to see, but a whole
   cell each. */
.cra-cform .clearfix { display: none !important; }

.cra-cform .form-group { margin-bottom: 16px; }

.cra-cform label {
    display: block;
    margin-bottom: 6px;
    font-size: 12.5px;
    font-weight: 500;
    color: var(--fg);
}

/* Labels of differing lengths wrapped onto two lines for some fields and
   one for others, which set every input in the row at a different height.
   A fixed label height keeps the inputs on a line. */
.cra-cform .form-group > label {
    min-height: 19px;
    line-height: 19px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.cra-cform .form-control,
.cra-cform .select2-container .select2-selection--single { height: 38px; }

/* A named break between groups of fields, in place of a bare rule that
   said only "something changes here". */
.cra-cform__sep {
    display: flex;
    align-items: center;
    gap: 12px;
    margin: 10px 0 18px;
}

.cra-cform__sep > span {
    flex: 0 0 auto;
    font-size: 12px;
    font-weight: 600;
    letter-spacing: .02em;
    text-transform: uppercase;
    color: var(--muted-fg);
}

.cra-cform__sep::after {
    content: "";
    flex: 1 1 auto;
    height: 1px;
    background: var(--border);
}

/* Three fields across needs the room for three fields. The dialog was sized
   for a two-column form and squeezed everything into 215px columns. */
.modal-dialog:has(.cra-cform) { width: 940px; max-width: calc(100vw - 32px); }

/* The two collapsed groups the form hides behind toggles. Buttons the width
   of the dialog, so they read as sections rather than as stray controls. */
.cra-cform .btn-modal-toggle,
.cra-cform [data-toggle="collapse"].btn { width: 100%; }

/* ── mail ──────────────────────────────────────────────────────────────
   Folders, a list, and what you are reading — three panes side by side,
   stacking down to one on a narrow screen. The panes scroll on their own
   so the page itself never does; a mailbox that moved the whole page every
   time you opened a message would be unusable.
--------------------------------------------------------------------- */
.cra-mail {
    display: grid;
    grid-template-columns: 230px minmax(280px, 380px) minmax(0, 1fr);
    gap: 16px;
    align-items: stretch;
    /* The header above is about 120px; the rest of the viewport is the app. */
    height: calc(100vh - 210px);
    min-height: 460px;
}

@media (max-width: 1100px) {
    .cra-mail { grid-template-columns: 200px minmax(0, 1fr); height: auto; }
    .cra-mail__reader { grid-column: 1 / -1; min-height: 420px; }
}

@media (max-width: 700px) {
    .cra-mail { grid-template-columns: minmax(0, 1fr); }
}

.cra-mail__folders,
.cra-mail__list-pane,
.cra-mail__reader {
    display: flex;
    flex-direction: column;
    min-height: 0;
    overflow: hidden;
}

.cra-mail__me {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 14px;
    border-bottom: 1px solid var(--border);
}

.cra-mail__av {
    flex: 0 0 auto;
    width: 30px;
    height: 30px;
    display: grid;
    place-items: center;
    border-radius: 50%;
    background: var(--muted);
    font-size: 13px;
    font-weight: 600;
    color: var(--fg);
}

.cra-mail__addr {
    min-width: 0;
    font-size: 12.5px;
    color: var(--fg);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.cra-mail__list { padding: 8px; overflow-y: auto; }

.cra-mail__folder {
    display: block;
    padding: 8px 10px;
    border-radius: 8px;
    color: var(--muted-fg);
    font-size: 13px;
    text-decoration: none;
}

.cra-mail__folder:hover { background: var(--muted2); color: var(--fg); text-decoration: none; }
.cra-mail__folder.is-active { background: var(--muted); color: var(--fg); font-weight: 500; }

.cra-mail__toolbar {
    display: flex;
    gap: 8px;
    padding: 12px;
    border-bottom: 1px solid var(--border);
}

.cra-mail__toolbar .form-control { height: 34px; }

.cra-mail__msgs { flex: 1 1 auto; overflow-y: auto; min-height: 0; }

.cra-mail__msg {
    display: block;
    width: 100%;
    padding: 12px 14px;
    border: 0;
    border-bottom: 1px solid var(--border);
    border-inline-start: 3px solid transparent;
    background: transparent;
    text-align: start;
    font: inherit;
    cursor: pointer;
}

.cra-mail__msg:hover { background: var(--muted2); }
.cra-mail__msg.is-open { background: var(--muted); border-inline-start-color: var(--primary); }

.cra-mail__msgtop { display: flex; justify-content: space-between; gap: 10px; align-items: baseline; }

.cra-mail__msgfrom {
    min-width: 0;
    font-size: 13px;
    color: var(--fg);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* Unread is carried by weight and a dot, not by colour alone. */
.cra-mail__msg.is-unread .cra-mail__msgfrom { font-weight: 600; }

.cra-mail__msg.is-unread .cra-mail__msgfrom::before {
    content: "";
    display: inline-block;
    width: 6px;
    height: 6px;
    margin-inline-end: 7px;
    border-radius: 50%;
    background: var(--primary);
    vertical-align: middle;
}

.cra-mail__msgwhen { flex: 0 0 auto; font-size: 11px; color: var(--muted-fg); }

.cra-mail__msgsub,
.cra-mail__msgaddr {
    display: block;
    margin-top: 3px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.cra-mail__msgsub { font-size: 12.5px; color: var(--fg); }
.cra-mail__msgaddr { font-size: 11.5px; color: var(--muted-fg); }

.cra-mail__pager {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 10px;
    padding: 10px;
    border-top: 1px solid var(--border);
    font-size: 12px;
    color: var(--muted-fg);
}

.cra-mail__msgview { display: flex; flex-direction: column; min-height: 0; height: 100%; }

.cra-mail__head { padding: 16px 18px 12px; border-bottom: 1px solid var(--border); }
.cra-mail__subject { font-size: 16px; font-weight: 600; color: var(--fg); line-height: 1.4; }
.cra-mail__meta { margin-top: 5px; font-size: 12px; color: var(--muted-fg); }

.cra-mail__acts { display: flex; gap: 8px; padding: 10px 18px; border-bottom: 1px solid var(--border); }

/* The message body renders inside a sandboxed frame — a message is written
   by whoever sent it, and their markup must not run in a signed-in session. */
.cra-mail__body {
    flex: 1 1 auto;
    width: 100%;
    min-height: 260px;
    border: 0;
    background: #fff;
}

.cra-mail__none { margin: auto; }

.cra-mail__pair { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }

.cra-mail__testmsg { align-self: center; font-size: 12.5px; color: var(--muted-fg); }
.cra-mail__testmsg.is-ok { color: var(--grn, #16a34a); }
.cra-mail__testmsg.is-bad { color: var(--red, #dc2626); }

/* ── invoice preview ───────────────────────────────────────────────────
   The invoice renders in a frame, on a plate the width of a sheet of
   paper. An invoice template carries its own stylesheet written for a
   blank page; in this document it would both inherit the app's styles and
   overwrite them, and what you looked at would be neither.
--------------------------------------------------------------------- */
.cra-preview {
    margin-top: 16px;
    padding: 20px;
    border-radius: 14px;
    background: var(--muted);
    display: flex;
    justify-content: center;
}

.cra-preview iframe {
    width: 100%;
    max-width: 820px;
    min-height: 700px;
    border: 0;
    border-radius: 8px;
    /* White whatever the app's theme is: paper is white. */
    background: #fff;
    box-shadow: 0 2px 16px rgba(0, 0, 0, .12);
}

/* ── legacy page headers ───────────────────────────────────────────────
   Most of this application still opens a page with

       <section class="content-header">
           <h1 class="tw-text-xl md:tw-text-3xl tw-font-bold">Title
               <small>subtitle</small></h1>
           <ol class="breadcrumb">…</ol>
       </section>

   while the pages rebuilt so far use .cra-head. Both are readable — the
   theme already redefines tw-text-black to a variable, so nothing is
   invisible — but they are set at different sizes with different spacing,
   so moving between two screens feels like moving between two products.

   Measuring the old header the same way as the new one settles that for
   every page at once, without touching a hundred and fourteen files. The
   markup keeps working; only the numbers change.
--------------------------------------------------------------------- */
.cra-shell .cra-scroll .content-header {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 20px;
    flex-wrap: wrap;
    padding: 0;
    margin: 0 0 20px;
    min-height: 0;
}

/* The heading, at the size the rebuilt pages use. The Tailwind classes on
   these elements carry !important, so this has to as well — the point is
   one measure across the application, not a race between stylesheets. */
.cra-shell .cra-scroll .content-header > h1 {
    margin: 0 !important;
    padding: 0;
    font-size: 26px !important;
    font-weight: 600 !important;
    line-height: 1.25;
    letter-spacing: -.02em;
    color: var(--fg) !important;
}

/* A subtitle sits under the title rather than trailing after it. Inline, at
   a third of the size, it reads as an afterthought; the rebuilt pages put
   it on its own line and so does this. */
.cra-shell .cra-scroll .content-header > h1 > small {
    display: block;
    margin-top: 6px;
    font-size: 13px !important;
    font-weight: 400 !important;
    line-height: 1.5;
    color: var(--muted-fg) !important;
}

/* The breadcrumb goes to the other end of the row, where the rebuilt pages
   keep their actions. */
.cra-shell .cra-scroll .content-header > .breadcrumb {
    position: static;
    margin: 0;
    padding: 0;
    background: transparent;
    font-size: 12px;
}

.cra-shell .cra-scroll .content-header > .breadcrumb > li > a { color: var(--muted-fg); }
.cra-shell .cra-scroll .content-header > .breadcrumb > .active { color: var(--fg); }

/* Some headers carry more than a title and a breadcrumb — the settings page
   puts a search box in there. A flex row shrank it to nothing beside the
   heading; anything that arrived as its own row takes its own line. */
.cra-shell .cra-scroll .content-header > .row {
    flex: 1 0 100%;
    margin: 4px 0 0;
}

/* The band between the header and the first card, so every page starts at
   the same place whichever markup it was written with. */
.cra-shell .cra-scroll > .content,
.cra-shell .cra-scroll > section.content { padding: 0; }

/* ── business settings ─────────────────────────────────────────────────
   Nineteen tabs whose fields were written at four-, three-, six- and
   twelve-column widths in no particular pattern, so each tab breaks at a
   different place and the page reads as nineteen pages by nineteen hands.

   Same treatment as the contact dialog: the declared widths are ignored
   and every field takes one column of one even track, so a tab looks the
   same as the tab before it. The markup is untouched — a hundred and
   seventy fields across nineteen partials keep working exactly as they
   did, and are only measured differently.
--------------------------------------------------------------------- */
/* Three columns, not as many as fit. auto-fit gave five on a wide screen,
   which packs a settings form tighter than anyone reads it — the eye has to
   travel too far between a label and the next one that relates to it. */
.cra-bset .row {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 0 20px;
    margin: 0;
}

@media (max-width: 1200px) { .cra-bset .row { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 760px) { .cra-bset .row { grid-template-columns: minmax(0, 1fr); } }

.cra-bset .row > [class*="col-md-"],
.cra-bset .row > [class*="col-sm-"],
.cra-bset .row > [class*="col-xs-"] {
    float: none;
    width: auto;
    max-width: none;
    padding: 0;
    min-width: 0;
}

/* Wide things span the row: headings, notes, tables, and the twelve-column
   blocks that were already meant to be full width. */
.cra-bset .row > .col-md-12,
.cra-bset .row > .col-sm-12,
.cra-bset .row > .col-xs-12,
.cra-bset .row > .clearfix { grid-column: 1 / -1; }

.cra-bset .row > .clearfix { display: none !important; }

/* Bootstrap clears its float rows with a ::before and an ::after carrying
   display:table. In a grid container both become real grid items and eat a
   cell each, which pushes every field one column to the right. */
.cra-bset .row::before,
.cra-bset .row::after { content: none; display: none; }

.cra-bset .form-group { margin-bottom: 16px; }

/* Labels of different lengths wrapped onto two lines for some fields and
   one for others, which set the inputs beside them at different heights. */
.cra-bset .form-group > label {
    display: block;
    min-height: 19px;
    line-height: 19px;
    margin-bottom: 6px;
    font-size: 12.5px;
    font-weight: 500;
    color: var(--fg);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.cra-bset .form-control,
.cra-bset .select2-container .select2-selection--single { height: 38px; }

/* A checkbox is not a field with a label above it; it is a line you read. */
.cra-bset .checkbox { margin: 0 0 12px; }
.cra-bset .checkbox label { white-space: normal; font-weight: 400; }

/* ── settings, as a page rather than a panel ───────────────────────────
   Seventeen sections behind a rail of centred bold links, all of it inside
   one flat box, with the save button floating in red underneath. The rail
   is now a list you read down, the section sits on a card, and saving
   happens on a bar that stays with you instead of at the bottom of
   whichever section happens to be longest.
--------------------------------------------------------------------- */
/* The rail and the section are not children of .pos-tab-container — the
   widget component wraps them in a body of its own, so the grid has to go
   on that. Put on the container it laid out a single child and left the
   two halves stacked underneath. */
.cra-bset .pos-tab-container {
    padding: 0 !important;
    border: 0 !important;
    background: transparent !important;
    box-shadow: none !important;
}

.cra-bset .pos-tab-container > .cr-card__body,
.cra-bset .pos-tab-container > .box-body {
    display: grid !important;
    grid-template-columns: 232px minmax(0, 1fr);
    gap: 18px;
    align-items: start;
    padding: 0 !important;
    /* The container is a flex row in the legacy theme, so its body sizes to
       its contents and stopped at 900px in a 1600px space. */
    width: 100%;
    flex: 1 1 100%;
}

.cra-bset .pos-tab-container > .cr-card__body::before,
.cra-bset .pos-tab-container > .cr-card__body::after { content: none; display: none; }

@media (max-width: 900px) {
    .cra-bset .pos-tab-container > .cr-card__body,
    .cra-bset .pos-tab-container > .box-body { grid-template-columns: minmax(0, 1fr); }
}

/* Both halves are laid out by the grid, so the Bootstrap widths on them
   would only fight it. */
.cra-bset .pos-tab-menu,
.cra-bset .pos-tab {
    float: none;
    width: auto;
    max-width: none;
    padding: 0;
}

/* ── the rail ── */
.cra-bset .pos-tab-menu {
    position: sticky;
    top: 8px;
    border: 1px solid var(--border);
    border-radius: 12px;
    background: var(--card);
    overflow: hidden;
}

.cra-bset .pos-tab-menu .list-group { margin: 0; padding: 6px; }

.cra-bset .pos-tab-menu .list-group-item {
    display: block;
    padding: 9px 12px !important;
    margin: 0 0 2px;
    border: 0 !important;
    border-radius: 8px;
    background: transparent !important;
    /* Centred bold text reads as a heading, not as something to click. */
    text-align: left !important;
    font-size: 13px !important;
    font-weight: 500 !important;
    color: var(--muted-fg) !important;
    transition: background .12s var(--ease), color .12s var(--ease);
}

.cra-bset .pos-tab-menu .list-group-item:hover {
    background: var(--muted2) !important;
    color: var(--fg) !important;
}

.cra-bset .pos-tab-menu .list-group-item.active {
    background: var(--muted) !important;
    color: var(--fg) !important;
    font-weight: 600 !important;
}

/* ── the section ── */
.cra-bset .pos-tab {
    border: 1px solid var(--border);
    border-radius: 14px;
    background: var(--card);
    padding: 22px 24px;
    min-height: 420px;
}

/* Sections inside carry their own headings; give them room to breathe and
   a rule to sit above, the way the rebuilt screens do. */
.cra-bset .pos-tab h4,
.cra-bset .pos-tab legend {
    margin: 0 0 18px;
    padding-bottom: 12px;
    border-bottom: 1px solid var(--border);
    font-size: 15px;
    font-weight: 600;
    color: var(--fg);
}

.cra-bset .pos-tab .tab-pane + .tab-pane { margin-top: 8px; }

/* ── saving ──
   The button was centred under a section that might be four screens long,
   coloured as a destructive action. It now rides along the bottom, and
   looks like the primary thing to do on the page, because it is. */
.cra-bset .row:has(> .text-center > .tw-dw-btn-lg[type="submit"]) {
    position: sticky;
    bottom: 0;
    z-index: 3;
    margin-top: 18px;
    padding: 14px 0;
    background: linear-gradient(to top, var(--bg) 62%, transparent);
}

/* The submit button, and only that one. Matching every submit in the form
   caught the file-upload button first and dressed that up instead — the
   upload widget ships its own, and it is not the primary action here.

   Every property carries !important because daisyUI's own button classes
   do: setting height against a class that sets min-height and padding
   left the button fourteen pixels tall. Stated in full rather than
   half-overriding a stylesheet that will not yield. */
.cra-bset .tw-dw-btn-lg[type="submit"] {
    display: inline-flex !important;
    align-items: center !important;
    justify-content: center !important;
    height: auto !important;
    min-height: 44px !important;
    padding: 11px 30px !important;
    border: 0 !important;
    border-radius: 10px !important;
    background: var(--primary) !important;
    background-image: none !important;
    color: var(--primary-fg) !important;
    font-size: 14px !important;
    font-weight: 600 !important;
    line-height: 1.2 !important;
    text-transform: none !important;
    box-shadow: 0 2px 12px rgba(0, 0, 0, .2) !important;
}

.cra-bset .tw-dw-btn-lg[type="submit"]:hover { filter: brightness(1.08); }

/* The settings search, which sits above everything and jumps to a field. */
.cra-shell .cra-scroll .content-header #search_settings + .select2-container { width: 100% !important; }

/* ── the GST set-up preview ────────────────────────────────────────────
   Grouped by slab, because that is how the choice is actually made: a sale
   is within the state or it is not. A flat list of sixteen names hides
   that the four in a row belong together.
--------------------------------------------------------------------- */
.cra-gst-plan { margin-top: 14px; }

.cra-gst-slab {
    border: 1px solid var(--border);
    border-radius: 10px;
    padding: 12px 14px;
    margin-bottom: 10px;
}

.cra-gst-slab__head { font-size: 14px; font-weight: 600; color: var(--fg); margin-bottom: 10px; }

.cra-gst-slab__cols { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }

@media (max-width: 560px) { .cra-gst-slab__cols { grid-template-columns: 1fr; } }

.cra-gst-slab__label {
    display: block;
    margin-bottom: 6px;
    font-size: 11px;
    text-transform: uppercase;
    letter-spacing: .03em;
    color: var(--muted-fg);
}

.cra-gst-row {
    display: flex;
    justify-content: space-between;
    gap: 10px;
    padding: 5px 0;
    font-size: 12.5px;
    color: var(--fg);
}

.cra-gst-row b { font-weight: 600; white-space: nowrap; }

/* What is already there is shown, not hidden — so it is clear the import
   is leaving it alone rather than silently missing it. */
.cra-gst-row.is-skip { color: var(--muted-fg); }
.cra-gst-row.is-skip b { font-weight: 400; font-size: 11.5px; }

/* ── Calculator popover ─────────────────────────────────────────────
   Bootstrap paints every popover white and the calculator's digits
   inherit the page's text colour, so in dark they were light-on-white:
   only AC, CE and = (which carry their own fill) were visible. The
   popover, its arrow and every key now take the shell's tokens. The
   title strip is the button's tooltip text leaking into the popover,
   so it is hidden. */
.popover:has(#calculator) {
    max-width: none; padding: 0;
    background: var(--card); color: var(--fg);
    border: 1px solid var(--border); border-radius: 12px;
    box-shadow: var(--shadow-pop);
}
.popover:has(#calculator) > .popover-title { display: none; }
.popover:has(#calculator) > .popover-content { padding: 10px; }
.popover.bottom:has(#calculator) > .arrow { border-bottom-color: var(--border); }
.popover.bottom:has(#calculator) > .arrow::after { border-bottom-color: var(--card); }

#calculator { width: 216px; }
#calculator #calc { display: block; margin: 0; }
#calculator #calc::before, #calculator #calc::after { display: none; }
#calculator .calcBG { margin: 0; padding: 0; width: 100%; float: none; }
#calculator .calcBG > .row { display: grid; grid-template-columns: repeat(4, 1fr); gap: 6px; margin: 0 0 6px; }
#calculator .calcBG > .row::before, #calculator .calcBG > .row::after { display: none; }
#calculator .calcBG > .row#result { display: block; margin: 0 0 8px; }
#calculator .calcBG .screen {
    display: block; margin: 0; box-sizing: border-box;
    width: 100%; height: 40px; padding: 0 10px;
    background: var(--muted2); color: var(--fg);
    border: 1px solid var(--border); border-radius: 8px;
    font: 500 18px/1 var(--cra-mono, ui-monospace, SFMono-Regular, Menlo, monospace);
    font-variant-numeric: tabular-nums; box-shadow: none; outline: none;
}
#calculator .calcBG .btn {
    width: auto; height: 38px; margin: 0; padding: 0;
    background: var(--muted); color: var(--fg);
    border: 1px solid transparent; border-radius: 8px;
    font-size: 14px; font-weight: 500; box-shadow: none;
    transition: background-color .12s var(--ease);
}
#calculator .calcBG .btn:hover { background: var(--g1); color: var(--fg); }
#calculator .btn:focus-visible { outline: 2px solid var(--ring); outline-offset: 1px; }
#calculator .btn:active { transform: translateY(1px); }
#calculator .btn-danger  { background: var(--redbg) !important; color: var(--red) !important; }
#calculator .btn-warning { background: var(--ambbg) !important; color: var(--amb) !important; }
#calculator .btn-success { background: var(--primary) !important; color: var(--primary-fg) !important; }
#calculator #blank { visibility: hidden; }

/* ── Superadmin: plan pricing ───────────────────────────────────────
   Three groups of rows, because what everyone gets, how big a business
   is, and what it adds are not the same kind of thing. The name a buyer
   reads is editable here: it arrives spelled the way each module named
   itself, which is a starting point rather than a shop window. */
.cra-planprice__group { margin-bottom: 28px; }
.cra-planprice__group:last-of-type { margin-bottom: 20px; }
.cra-planprice__title {
    margin: 0; font-size: 13px; font-weight: 600; letter-spacing: .06em;
    text-transform: uppercase; color: var(--fg);
}
.cra-planprice__note { margin: 4px 0 10px; font-size: 12.5px; color: var(--muted-fg); }
.cra-planprice__table { margin-bottom: 0; }
.cra-planprice__table > thead > tr > th {
    font-size: 11px; letter-spacing: .05em; text-transform: uppercase;
    color: var(--muted-fg); font-weight: 600; border-bottom: 1px solid var(--border);
}
.cra-planprice__table > tbody > tr > td { vertical-align: top; padding: 10px 8px; }
/* The name and its one line are short things; a box the width of the table
   invites neither. */
.cra-planprice__name,
.cra-planprice__desc { max-width: 420px; }
.cra-planprice__name { font-weight: 600; }
.cra-planprice__desc { margin-top: 5px; }
.cra-planprice__key {
    display: inline-block; margin-top: 6px; font-size: 11px;
    background: var(--muted); color: var(--muted-fg); border: 0;
}
