/* =============================================================================
   GrowthCG design layer
   -----------------------------------------------------------------------------
   Loaded after the WowDash theme so it wins ties on equal specificity.
   Everything here is driven from the tokens in the first block — add a token
   rather than a one-off value, so the system stays consistent.

   The theme already ships Inter and a neutral scale that matches our palette
   (--neutral-900 #111827, --neutral-700 #374151, --neutral-500 #6B7280), so we
   build on it instead of replacing it.
   ========================================================================== */

/* -----------------------------------------------------------------------------
   1. Tokens
   -------------------------------------------------------------------------- */
:root {
    /* Type scale — hierarchy comes from size, spacing and colour, not weight. */
    --gcg-fs-page-title: 1.5rem;      /* 24 / 32 */
    --gcg-lh-page-title: 2rem;
    --gcg-fs-card-title: 1.25rem;     /* 20 / 28 */
    --gcg-lh-card-title: 1.75rem;
    --gcg-fs-body: 0.9375rem;         /* 15 / 24 */
    --gcg-lh-body: 1.5rem;
    --gcg-fs-nav: 0.875rem;           /* 14 / 20 */
    --gcg-lh-nav: 1.25rem;
    --gcg-fs-label: 0.75rem;          /* 12 / 16 */
    --gcg-lh-label: 1rem;
    --gcg-fs-crumb: 0.8125rem;        /* 13 / 20 */
    --gcg-fs-btn: 0.875rem;
    --gcg-fs-footer: 0.8125rem;
    --gcg-fs-table: 0.875rem;

    --gcg-fw-regular: 400;
    --gcg-fw-medium: 500;
    --gcg-fw-semibold: 600;

    --gcg-tracking-tight: -0.02em;

    /* Colour — restrained neutrals; brand blue is the theme's own. */
    --gcg-text: #111827;
    --gcg-text-body: #374151;
    --gcg-text-muted: #6b7280;
    --gcg-border: #e5e7eb;
    --gcg-border-subtle: #eef0f3;
    --gcg-surface: #ffffff;
    --gcg-surface-sunken: #f9fafb;
    --gcg-app-bg: #f6f7f9;
    --gcg-brand: var(--primary-600, #487fff);
    --gcg-brand-soft: rgba(72, 127, 255, 0.08);
    --gcg-brand-ring: rgba(72, 127, 255, 0.28);

    /* The race palette. One colour per group, fixed: a reader who learns that
       magenta is African must not find it means White on the next screen. Here
       rather than in the chart script so the HTML legend and the donut cannot
       drift apart. */
    --gcg-race-african: #c2185b;
    --gcg-race-coloured: #00838f;
    --gcg-race-indian: #f9a825;
    --gcg-race-white: #d32f2f;
    --gcg-race-foreign: #1565c0;

    /* Target-vs-actual tints. Deliberately faint: a grid of 130 figures shaded
       at full strength reads as an alarm, not as information. */
    --gcg-tint-met: rgba(22, 163, 74, 0.10);
    --gcg-tint-near: rgba(217, 119, 6, 0.13);
    --gcg-tint-short: rgba(220, 38, 38, 0.10);
    --gcg-tint-rule-met: rgba(22, 163, 74, 0.55);
    --gcg-tint-rule-near: rgba(217, 119, 6, 0.60);
    --gcg-tint-rule-short: rgba(220, 38, 38, 0.55);

    /* Spacing — 8px based. */
    --gcg-1: 4px;
    --gcg-2: 8px;
    --gcg-3: 12px;
    --gcg-4: 16px;
    --gcg-6: 24px;
    --gcg-8: 32px;
    --gcg-10: 40px;
    --gcg-12: 48px;

    /* Geometry */
    --gcg-radius-sm: 6px;
    --gcg-radius: 8px;
    --gcg-radius-lg: 12px;
    --gcg-control: 40px;
    --gcg-btn-h: 40px;
    --gcg-icon-nav: 18px;
    --gcg-icon-util: 20px;
    --gcg-shadow-card: 0 1px 2px rgba(16, 24, 40, 0.04);

    /* Logo block: the theme pins this at 72px and derives the sidebar menu
       height from the same number, so both are driven from here. */
    --gcg-logo-width: 152px;
    --gcg-logo-block: 104px;
    --gcg-sidebar-w: 248px;
}

/* -----------------------------------------------------------------------------
   1b. Retune the theme's own type scale
   -----------------------------------------------------------------------------
   The theme's `.text-sm/.text-md/.text-lg` utilities are
   `font-size: var(--font-*) !important`, and our views use them ~230 times, so
   overriding them per-selector is unwinnable. Redefining the variables retunes
   every usage at once, with no specificity fight.

   Headings were `clamp()` expressions that scale with the viewport — --h6 alone
   reached 24px on a wide screen, which is why the UI read large. Fixed sizes
   suit a dense admin UI: hierarchy should not move as the window resizes.
   -------------------------------------------------------------------------- */
:root {
    --font-xxs: 0.625rem;   /* 10 */
    --font-xs: 0.75rem;     /* 12 — labels, table headers */
    --font-sm: 0.875rem;    /* 14 — nav, table cells, buttons */
    --font-md: 0.9375rem;   /* 15 — body (was 16) */
    --font-lg: 1rem;        /* 16 — card and section titles (was 18) */
    --font-xl: 1.125rem;    /* 18 (was 20) */
    --font-xxl: 1.25rem;    /* 20 (was 24) */
    --font-2xl: 1.5rem;     /* 24 (was 28) */
    --font-2xxl: 1.75rem;   /* 28 (was 32) */

    --h1: 1.5rem;           /* 24 — page titles */
    --h2: 1.375rem;         /* 22 */
    --h3: 1.25rem;          /* 20 */
    --h4: 1.125rem;         /* 18 */
    --h5: 1rem;             /* 16 */
    --h6: 0.9375rem;        /* 15 — card headers */
}

[data-theme="dark"] {
    --gcg-text: #f5f6fa;
    --gcg-text-body: #d1d5db;
    --gcg-text-muted: #9ca3af;
    --gcg-border: #323d4e;
    --gcg-border-subtle: #273142;
    --gcg-surface: #273142;
    --gcg-surface-sunken: #1b2431;
    --gcg-app-bg: #1b2431;

    /* A dark surface swallows a 10% tint, so lift them. */
    --gcg-tint-met: rgba(34, 197, 94, 0.18);
    --gcg-tint-near: rgba(245, 158, 11, 0.20);
    --gcg-tint-short: rgba(248, 113, 113, 0.18);
}

/* -----------------------------------------------------------------------------
   2. Base typography
   -------------------------------------------------------------------------- */
body {
    font-family: Inter, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
    font-size: var(--gcg-fs-body);
    line-height: var(--gcg-lh-body);
    font-weight: var(--gcg-fw-regular);
    color: var(--gcg-text-body);
    background-color: var(--gcg-app-bg);
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
}

h1, h2, h3, h4, h5, h6 {
    color: var(--gcg-text);
    font-weight: var(--gcg-fw-semibold);
    letter-spacing: var(--gcg-tracking-tight);
}

/* Bold is reserved; 700 across a dense admin UI reads as shouting. */
.fw-bold,
.fw-semibold,
b, strong {
    font-weight: var(--gcg-fw-semibold);
}

.fw-medium {
    font-weight: var(--gcg-fw-medium);
}

/* The theme's muted helpers, unified onto our two secondary tones. */
.text-secondary-light {
    color: var(--gcg-text-muted);
}

code {
    font-size: 0.8125rem;
    color: var(--gcg-text-muted);
}

/* -----------------------------------------------------------------------------
   3. Page header & breadcrumb
   -------------------------------------------------------------------------- */
.gcg-page-head {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    justify-content: space-between;
    gap: var(--gcg-3) var(--gcg-6);
    margin-block-end: var(--gcg-6);
}

/* The theme sets `h1..h6 { font-size: ... !important }`, so overriding a
   semantic heading requires !important here. Used only for that reason. */
.gcg-page-head-main {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--gcg-3);
    min-width: 0;
}

.gcg-page-actions {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--gcg-2);
}

.gcg-page-title {
    margin: 0;
    font-size: var(--gcg-fs-page-title) !important;
    line-height: var(--gcg-lh-page-title);
    font-weight: var(--gcg-fw-semibold);
    letter-spacing: var(--gcg-tracking-tight);
    color: var(--gcg-text);
}

.gcg-breadcrumb {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: var(--gcg-2);
    margin: 0;
    padding: 0;
    list-style: none;
    font-size: var(--gcg-fs-crumb);
    line-height: 1.25rem;
    font-weight: var(--gcg-fw-medium);
    color: var(--gcg-text-muted);
}

.gcg-breadcrumb a {
    color: var(--gcg-text-muted);
    text-decoration: none;
}

.gcg-breadcrumb a:hover {
    color: var(--gcg-brand);
}

/* A hairline slash reads as secondary; the theme's dash did not. */
.gcg-breadcrumb .gcg-crumb-sep {
    color: var(--gcg-border);
    user-select: none;
}

.gcg-breadcrumb .gcg-crumb-current {
    color: var(--gcg-text-body);
}

/* -----------------------------------------------------------------------------
   4. Surfaces
   -------------------------------------------------------------------------- */
.dashboard-main-body {
    padding: var(--gcg-6);
}

.card {
    background-color: var(--gcg-surface);
    border: 1px solid var(--gcg-border);
    border-radius: var(--gcg-radius-lg);
    box-shadow: var(--gcg-shadow-card);
}

/* The theme layers heavier shadow utilities onto cards; hold them back. */
.card.shadow-2,
.card.shadow-none {
    box-shadow: var(--gcg-shadow-card);
}

.card-header {
    background-color: var(--gcg-surface);
    border-block-end: 1px solid var(--gcg-border);
    padding: var(--gcg-4) var(--gcg-6);
    border-start-start-radius: var(--gcg-radius-lg);
    border-start-end-radius: var(--gcg-radius-lg);
}

.card-header h6,
.card-header .text-lg {
    font-size: 0.9375rem !important;
    line-height: 1.5rem;
    font-weight: var(--gcg-fw-semibold);
    letter-spacing: 0;
}

.card-body {
    padding: var(--gcg-6);
}

/* -----------------------------------------------------------------------------
   5. Sidebar
   -------------------------------------------------------------------------- */
.sidebar {
    background-color: var(--gcg-surface);
}

/* The theme steps the sidebar up to 275/312px on wide screens, which starved the
   data tables of width. One deliberate width instead. */
@media (min-width: 1200px) {
    .sidebar,
    .sidebar.active:hover {
        width: var(--gcg-sidebar-w);
    }

    .dashboard-main {
        margin-inline-start: var(--gcg-sidebar-w);
    }

    .sidebar.active {
        width: 78px;
    }

    .sidebar.active ~ .dashboard-main,
    .dashboard-main.active {
        margin-inline-start: 78px;
    }
}

.sidebar-logo {
    height: var(--gcg-logo-block);
    padding: var(--gcg-6) var(--gcg-4) var(--gcg-4);
    /* The theme left-aligns this (justify-content: flex-start). */
    justify-content: center;
    border-block-end: 1px solid var(--gcg-border-subtle);
    border-inline-end: 1px solid var(--gcg-border-subtle);
}

.sidebar-logo img {
    max-height: none;
}

.sidebar-logo img.light-logo,
.sidebar-logo img.dark-logo {
    width: 100%;
    max-width: var(--gcg-logo-width);
    height: auto;
}

.sidebar-logo img.logo-icon {
    width: 42px;
    max-width: none;
    height: auto;
}

.sidebar.active:not(:hover) .sidebar-logo {
    padding-inline: var(--gcg-2);
}

.sidebar-menu-area {
    height: calc(100vh - var(--gcg-logo-block));
    padding: var(--gcg-4) var(--gcg-3);
    border-inline-end: 1px solid var(--gcg-border-subtle);
}

/* Section labels: quiet, and spaced as group separators rather than items. */
.sidebar-menu .sidebar-menu-group-title {
    margin-block: var(--gcg-6) var(--gcg-2);
    padding-inline: var(--gcg-3);
    font-size: var(--gcg-fs-label);
    line-height: var(--gcg-lh-label);
    font-weight: var(--gcg-fw-semibold);
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--gcg-text-muted);
}

.sidebar-menu .sidebar-menu-group-title:first-child {
    margin-block-start: 0;
}

.sidebar-menu li a {
    gap: var(--gcg-3);
    padding: var(--gcg-2) var(--gcg-3);
    border-radius: var(--gcg-radius);
    font-size: var(--gcg-fs-nav);
    line-height: var(--gcg-lh-nav);
    font-weight: var(--gcg-fw-medium);
    color: var(--gcg-text-body);
}

.sidebar-menu > li + li {
    margin-block-start: 2px;
}

/* The chevron is an absolutely positioned ::after at inset-inline-end .75rem,
   so the label needs padding reserved or the two collide. */
.sidebar-menu li.dropdown > a {
    padding-inline-end: var(--gcg-8);
}

.sidebar-menu li.dropdown > a::after {
    font-size: 1rem;
    color: var(--gcg-text-muted);
    inset-inline-end: var(--gcg-3);
}

.sidebar-menu li.dropdown > a.active-page::after {
    color: #fff;
}

/* Labels take the remaining width and wrap tidily rather than overrunning. */
.sidebar-menu li a > span {
    min-width: 0;
    flex: 1 1 auto;
}

.sidebar-menu li a:hover {
    background-color: var(--gcg-surface-sunken);
    color: var(--gcg-text);
}

/* One icon size and one stroke weight everywhere in the nav. */
.sidebar-menu li a .menu-icon,
.sidebar-menu li a iconify-icon {
    width: var(--gcg-icon-nav);
    height: var(--gcg-icon-nav);
    font-size: var(--gcg-icon-nav);
    flex-shrink: 0;
    margin: 0;
    color: var(--gcg-text-muted);
}

.sidebar-menu li a:hover .menu-icon,
.sidebar-menu li a.active-page .menu-icon {
    color: currentColor;
}

/* Active parent: brand blue, but not oversized. */
.sidebar-menu li a.active-page {
    background-color: var(--gcg-brand);
    color: #fff;
    font-weight: var(--gcg-fw-medium);
}

.sidebar-menu li a.active-page iconify-icon {
    color: #fff;
}

/* Child items sit on a rail, with a light blue active state. */
.sidebar-submenu {
    margin-block: var(--gcg-1) var(--gcg-2);
    padding-inline-start: var(--gcg-4);
    margin-inline-start: var(--gcg-4);
    border-inline-start: 1px solid var(--gcg-border);
}

.sidebar-submenu li a {
    padding: 6px var(--gcg-3);
    font-size: var(--gcg-fs-nav);
    font-weight: var(--gcg-fw-regular);
    color: var(--gcg-text-muted);
}

.sidebar-submenu li a:hover {
    color: var(--gcg-text);
    background-color: var(--gcg-surface-sunken);
}

.sidebar-submenu li a.active-page {
    background-color: var(--gcg-brand-soft);
    color: var(--gcg-brand);
    font-weight: var(--gcg-fw-medium);
}

/* The theme's bullet dots are decoration; shrink them to a quiet indicator. */
.sidebar-submenu li a .circle-icon {
    width: 5px !important;
    height: 5px;
    font-size: 5px;
    margin-inline-end: var(--gcg-2);
    color: var(--gcg-border);
}

.sidebar-submenu li a.active-page .circle-icon,
.sidebar-submenu li a:hover .circle-icon {
    color: var(--gcg-brand);
}

/* -----------------------------------------------------------------------------
   6. Header
   -------------------------------------------------------------------------- */
.navbar-header {
    padding: var(--gcg-3) var(--gcg-6);
    background-color: var(--gcg-surface);
    border-block-end: 1px solid var(--gcg-border-subtle);
}

.navbar-header .row {
    align-items: center;
}

/* Utility controls to one size, quiet until needed. */
.navbar-header .sidebar-toggle,
.navbar-header .sidebar-mobile-toggle,
.navbar-header [data-theme-toggle],
.navbar-header .dropdown > button {
    width: var(--gcg-control);
    height: var(--gcg-control);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: var(--gcg-radius);
    background-color: transparent;
    color: var(--gcg-text-muted);
    border: 0;
}

.navbar-header .sidebar-toggle:hover,
.navbar-header .sidebar-mobile-toggle:hover,
.navbar-header [data-theme-toggle]:hover {
    background-color: var(--gcg-surface-sunken);
    color: var(--gcg-text);
}

.navbar-header iconify-icon {
    font-size: var(--gcg-icon-util);
}

/* Setting `display` above re-enabled the mobile toggle on desktop, because the
   theme hides it in a media query of equal specificity that we now outrank.
   Re-assert the hide at the same breakpoint. */
@media (min-width: 1200px) {
    .navbar-header .sidebar-mobile-toggle {
        display: none;
    }
}

/* The avatar keeps its fill; it is the one deliberate accent up here. */
.navbar-header .dropdown > button > span,
.navbar-header .dropdown > button > img {
    width: 36px;
    height: 36px;
    font-size: 0.8125rem;
    font-weight: var(--gcg-fw-semibold);
}

/* -----------------------------------------------------------------------------
   7. Buttons
   -------------------------------------------------------------------------- */
.btn {
    min-height: var(--gcg-btn-h);
    padding: var(--gcg-2) var(--gcg-6);
    border-radius: var(--gcg-radius);
    font-size: var(--gcg-fs-btn);
    line-height: var(--gcg-lh-nav);
    font-weight: var(--gcg-fw-semibold);
    letter-spacing: 0;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--gcg-2);
    transition: background-color .15s ease, border-color .15s ease, color .15s ease;
}

.btn-sm {
    min-height: 36px;
    padding: 6px var(--gcg-4);
}

.btn:focus-visible,
.form-control:focus-visible,
.form-select:focus-visible,
.sidebar-menu li a:focus-visible {
    outline: 2px solid var(--gcg-brand);
    outline-offset: 2px;
    box-shadow: none;
}

.btn-primary {
    background-color: var(--gcg-brand);
    border-color: var(--gcg-brand);
    color: #fff;
}

.btn-primary:hover {
    background-color: var(--primary-700, #3f6fe0);
    border-color: var(--primary-700, #3f6fe0);
}

.btn-primary:active {
    background-color: var(--primary-800, #355cba);
}

.btn:disabled,
.btn.disabled {
    opacity: .55;
    cursor: not-allowed;
}

.btn-outline-primary {
    border-color: var(--gcg-border);
    color: var(--gcg-brand);
    background-color: transparent;
}

.btn-outline-primary:hover {
    background-color: var(--gcg-brand-soft);
    border-color: var(--gcg-brand);
    color: var(--gcg-brand);
}

/* -----------------------------------------------------------------------------
   8. Forms
   -------------------------------------------------------------------------- */
.form-control,
.form-select {
    min-height: var(--gcg-control);
    border-radius: var(--gcg-radius);
    border-color: var(--gcg-border);
    font-size: var(--gcg-fs-nav);
    color: var(--gcg-text-body);
    background-color: var(--gcg-surface);
}

.form-control-sm,
.form-select-sm {
    min-height: 36px;
    font-size: var(--gcg-fs-nav);
}

.form-control::placeholder {
    color: var(--gcg-text-muted);
}

/* Filter toolbars: the theme's `w-auto` sizes a select to its longest option,
   so a long industry name pushed the row into wrapping. Cap them instead. */
.card-header form .form-select,
.card-header form .form-control {
    max-width: 180px;
}

.card-header form .form-select-sm {
    max-width: 148px;
}

.card-header form .form-control-sm {
    max-width: 180px;
}

/* Not every card-header select is a filter. One that names what a figure is
   measured against has to read in full once chosen: a clipped "Feb 2025 — from
   01/02…" is exactly the detail the reader opened it for.

   Listed both scoped and bare so the class means the same thing wherever the
   select sits. Outside a card header there is no cap to lift, but a select is
   still a flex item, and a flex item shrinks below the width of its own
   options. */
.form-select.gcg-select-wide,
.card-header form .form-select.gcg-select-wide,
.card-header form .form-select-sm.gcg-select-wide {
    max-width: none;
    min-width: max-content;
    flex-shrink: 0;
}

.card-header form {
    row-gap: var(--gcg-2);
    flex: 1 1 auto;
}

/* When the toolbar does wrap, the trailing action goes to the right so it reads
   as deliberate rather than orphaned under the filters. */
.card-header > form + * {
    margin-inline-start: auto;
}

.form-label {
    font-size: var(--gcg-fs-nav);
    line-height: var(--gcg-lh-nav);
    font-weight: var(--gcg-fw-medium);
    color: var(--gcg-text-body);
    margin-block-end: var(--gcg-2);
}

/* -----------------------------------------------------------------------------
   9. Tables
   -------------------------------------------------------------------------- */
/* The theme sets `.bordered-table { min-width: max-content }`, which forces the
   table to its widest possible size — cells can never wrap and the last columns
   fall off the right edge into the horizontal scroller. Releasing it lets
   Bootstrap's `width: 100%` constrain the table and long cells wrap instead.
   .table-responsive still scrolls on genuinely narrow screens. */
.bordered-table {
    min-width: 0;
}

/* Density: the theme pins cell padding with !important on both .sm-table and
   .bordered-table, so matching it is the only way to tighten the rows. */
.sm-table thead tr th,
.sm-table thead tr td,
.sm-table tbody tr th,
.sm-table tbody tr td,
.bordered-table thead tr th,
.bordered-table tbody tr td {
    padding: var(--gcg-2) var(--gcg-3) !important;
}

.table > thead > tr > th {
    font-size: var(--gcg-fs-label);
    line-height: var(--gcg-lh-label);
    font-weight: var(--gcg-fw-semibold);
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--gcg-text-muted);
    background-color: var(--gcg-surface-sunken);
    border-block-end: 1px solid var(--gcg-border);
    padding: var(--gcg-2) var(--gcg-3);
    /* Deliberately NOT nowrap: it forced the table past its container and
       pushed the Action column off-screen. */
    white-space: normal;
}

.table > tbody > tr > td {
    font-size: var(--gcg-fs-table);
    color: var(--gcg-text-body);
    border-block-end: 1px solid var(--gcg-border-subtle);
    padding: var(--gcg-2) var(--gcg-3);
    vertical-align: middle;
}

.table > tbody > tr:last-child > td {
    border-block-end: 0;
}

.table a {
    color: var(--gcg-text);
    text-decoration: none;
}

.table a:hover {
    color: var(--gcg-brand);
}

/* Action clusters: the theme's gap-10 made the column needlessly wide. */
.table td .d-flex.gap-10 {
    gap: var(--gcg-1) !important;
}

.table td .w-32-px {
    width: 30px !important;
    height: 30px !important;
}

/* Secondary line under a primary cell value (trading name, email). 14px under a
   15px primary is barely a hierarchy; .text-sm is !important so match it. */
.table td .text-secondary-light,
.table td .text-sm {
    font-size: 0.8125rem !important;
    line-height: 1.125rem;
}

/* Status pills: readable, not loud. */
.table .radius-4 {
    border-radius: var(--gcg-radius-sm) !important;
    font-size: var(--gcg-fs-label);
    font-weight: var(--gcg-fw-medium);
    padding: var(--gcg-1) var(--gcg-2) !important;
}

/* -----------------------------------------------------------------------------
   9a. Statutory grids
   --------------------------------------------------------------------------
   Every EEA grid is the same shape: a row label, then the ten reporting cells
   in the form's own order, then a total. Left to auto layout the columns size
   themselves by content, so "Foreign Nationals / Male" came out three times the
   width of "A", and a header centred over a right-aligned figure sat visibly off
   to one side of it.

   Fixed layout with one sized label column makes the remaining columns divide
   the space equally, so all ten figure columns match whatever they contain. The
   header and the figure are then centred on the same axis, which is the only way
   a reader can scan a column of ten single digits and know which group it is. */
.gcg-grid {
    table-layout: fixed;
    width: 100%;
}

/* A fixed-layout grid does not scroll when it runs out of room — it keeps the
   container's width and clips every figure instead. Releasing the theme's
   `min-width: max-content` (see .bordered-table above) lets a *text* cell wrap,
   which is right for prose and useless for a column of numbers. So the dense
   grids carry a floor: below it the .table-responsive wrapper scrolls, which is
   legible, where a clipped figure is not.

   990px is where the widest of these — twelve columns of two-decimal figures
   beside a label column holding "4. Skilled/Junior Management" — stops clipping.
   Below roughly an 1100px viewport these grids therefore scroll sideways. That
   is the deliberate trade: on a compliance document a figure that reads is worth
   more than a page with no scrollbar. */
.gcg-grid-dense {
    min-width: 990px;
}

/* A grid of only a few columns still has a total column pinned at 9%, which at
   tablet width is too narrow for "89.40%". It needs a floor too, just a lower
   one — and the floor has to sit *above* the tablet container width (~700px) or
   it never engages at all. */
.gcg-grid-dense-sm {
    min-width: 740px;
}

/* The label needs room for "Professionally qualified and experienced
   specialists and mid-management"; the figures need almost none. */
/* text-align carries !important throughout this block, and only here.
   Bootstrap's .text-end utility is itself !important and the views use it on
   individual grid cells; without matching it, a single stray utility class
   knocks one column out of alignment with its own header. Alignment inside a
   statutory grid is a property of the grid, not of each cell, so it is settled
   in one place. */
/* The label column, and only it. Scoped to the first header row on purpose:
   `thead th:first-child` also matched the "A" that opens the second row, which
   left one column's header aligned differently from the other nine. */
.gcg-grid > thead > tr:first-child > th:first-child,
.gcg-grid > tbody > tr > td:first-child {
    width: 22%;
    text-align: start !important;
}

.gcg-grid > thead > tr > th {
    text-align: center !important;
    vertical-align: middle;
}

.gcg-grid > tbody > tr > td {
    text-align: center !important;
}

/* A figure is one token: "22.49%" must never be split across lines. The theme
   sets overflow-wrap: break-word, so in a twelve-column grid a four-pixel
   shortfall put the "%" on a second line and took the row from 41px to 65px.
   Denying the mid-token break is most of the fix; the rest is buying those
   pixels back from the padding, which the figures do not need. Long prose in a
   cell still wraps, because it breaks at spaces. */
.gcg-grid > thead > tr > th,
.gcg-grid > tbody > tr > td {
    overflow-wrap: normal;
    word-break: normal;
}

.gcg-grid > thead > tr > th:not(:first-child),
.gcg-grid > tbody > tr > td:not(:first-child) {
    padding-inline: var(--gcg-2);
}

/* The actual row, banded so it reads as a pair with the target above it. */
.gcg-grid > tbody > tr.gcg-row-actual > td {
    background-color: var(--gcg-surface-sunken);
}

/* How the actual compares with the target it sits under. Scoped past
   `.bordered-table td`, which sets its own background. A cell tint wins over
   the row band above. */
.gcg-grid > tbody > tr > td.gcg-cell-met {
    background-color: var(--gcg-tint-met);
    box-shadow: inset 2px 0 0 var(--gcg-tint-rule-met);
}

.gcg-grid > tbody > tr > td.gcg-cell-near {
    background-color: var(--gcg-tint-near);
    box-shadow: inset 2px 0 0 var(--gcg-tint-rule-near);
}

.gcg-grid > tbody > tr > td.gcg-cell-short {
    background-color: var(--gcg-tint-short);
    box-shadow: inset 2px 0 0 var(--gcg-tint-rule-short);
}

/* A multiple select.
   `height`, not `min-height`: the theme leaves the height to the content, so a
   roster of sixty grew the box to sixty rows and spilled it over the Save button
   and the meeting history beneath. A fixed height makes it a scrollable box,
   which is what a long pick-list should be. */
.gcg-multi-select {
    height: 220px;
    overflow-y: auto;
    padding-right: var(--gcg-3);
    /* No arrow: a multiple select has no closed state for one to point at. */
    background-image: none;
}

.gcg-multi-select optgroup {
    font-weight: var(--gcg-fw-semibold);
    color: var(--gcg-text-muted);
}

.gcg-multi-select option {
    padding: 4px var(--gcg-2);
    color: var(--gcg-text-body);
}

/* A staff row taken out of the list. Kept visible so the headcount can be
   reconciled against the imported file, and muted so it is plainly not counted —
   struck through on the identifying columns only, since striking a whole row of
   figures makes them hard to read for no gain. */
.gcg-row-removed > td {
    color: var(--gcg-text-muted);
    background-color: var(--gcg-surface-sunken);
}

.gcg-row-removed > td:nth-child(2) .fw-semibold {
    text-decoration: line-through;
}

/* The gaps table reads as blocks, not a flat list: one statutory designated
   total, then the races inside it that miss their own benchmark. Without the
   grouping the detail rows read as more levels, and the table doubles in
   apparent length. */
.gcg-row-group > td {
    border-block-start: 1px solid var(--gcg-border);
}

.gcg-row-detail > td {
    border-block-end: 0;
    padding-block: var(--gcg-1);
}

/* The row number and the control that edits that row, on one line.

   The theme ships no working .text-nowrap, so a table cell this narrow drops
   the pencil onto a second line under the number — where it reads as another
   row rather than as the control for this one. Flex items do not wrap, which
   also lets the column size itself to both. */
.gcg-row-handle {
    display: inline-flex;
    align-items: center;
    gap: var(--gcg-1);
    white-space: nowrap;
}

/* A date field in a dense inline form: wide enough for dd/mm/yyyy and the
   picker's own icon, and no wider. */
.gcg-date-narrow {
    max-width: 160px;
}

/* The representation widget: a donut with its own legend beneath it.
   Apex's built-in legend wrapped four items and then one, and its tooltip
   escaped the card. An HTML legend wraps evenly, carries the headcount the
   percentages are of, and cannot overflow anything. */
.gcg-chart-widget {
    display: flex;
    flex-direction: column;
    gap: var(--gcg-3);
}

.gcg-chart-legend {
    display: grid;
    /* One column in a sidebar-width card, two if the widget is ever given more
       room. The floor is 220px because a row is a label and a right-aligned
       "87 · 59.6%": at 140px those two wrapped onto separate lines and doubled
       the row height. */
    grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
    gap: var(--gcg-1) var(--gcg-3);
    margin: 0;
    font-size: var(--gcg-fs-nav);
}

.gcg-chart-legend > div {
    display: flex;
    align-items: baseline;
    gap: var(--gcg-2);
    /* Baseline-aligned so the swatch, the label and the figure sit on one line
       rather than the swatch riding above the text. */
}

.gcg-chart-legend .gcg-swatch {
    flex: 0 0 auto;
    width: 10px;
    height: 10px;
    border-radius: 50%;
    /* Nudged onto the text baseline: a round swatch centred on the line box
       reads as sitting too high. */
    transform: translateY(-1px);
}

.gcg-chart-legend dt {
    color: var(--gcg-text-body);
}

.gcg-chart-legend dd {
    margin: 0 0 0 auto;
    color: var(--gcg-text-muted);
    font-variant-numeric: tabular-nums;
}

/* Reserve the height before the chart draws, so the card does not jump when
   ApexCharts renders into it. */
.gcg-chart {
    min-height: 300px;
}

/* The legend's swatches: the same tints at a readable size. */
.gcg-key {
    display: inline-block;
    width: 14px;
    height: 14px;
    border: 1px solid var(--gcg-border);
    border-radius: 3px;
    vertical-align: -2px;
}

/* The tint rules below are scoped to grid cells so they beat the theme's own
   `td` background, which leaves the swatches unpainted. Restate them here. */
.gcg-key.gcg-cell-met {
    background-color: var(--gcg-tint-met);
    box-shadow: inset 2px 0 0 var(--gcg-tint-rule-met);
}

.gcg-key.gcg-cell-near {
    background-color: var(--gcg-tint-near);
    box-shadow: inset 2px 0 0 var(--gcg-tint-rule-near);
}

.gcg-key.gcg-cell-short {
    background-color: var(--gcg-tint-short);
    box-shadow: inset 2px 0 0 var(--gcg-tint-rule-short);
}

/* The swatch hatches in the muted text colour, not the border colour: on the
   dark surface a border-coloured stripe is near-invisible at 14px square. */
.gcg-key.gcg-grid-na {
    background-image: repeating-linear-gradient(
        135deg,
        transparent 0 3px,
        var(--gcg-text-muted) 3px 4px
    );
}

/* A column that can never hold a figure. The workbook leaves it empty too —
   White Male has no share of a designated-male target — but an empty cell under
   a "Designated male" heading reads as missing data, so it is hatched to say
   "not applicable" rather than "not filled in". */
.gcg-grid > tbody > tr > td.gcg-grid-na,
.gcg-grid > thead > tr > th.gcg-grid-na {
    background-image: repeating-linear-gradient(
        135deg,
        transparent 0 5px,
        var(--gcg-border-subtle) 5px 6px
    );
    color: var(--gcg-text-muted);
}

/* A grid carrying a "value"/"%" marker beside the label: narrow, and left
   aligned so it reads as part of the label rather than as a figure. */
.gcg-grid > tbody > tr > td.gcg-grid-marker,
.gcg-grid > thead > tr > th.gcg-grid-marker {
    width: 7%;
    text-align: start !important;
    color: var(--gcg-text-muted);
}

/* The total is excluded from the equal-width rule deliberately: it holds the
   largest number in the row and is the one column worth making stand out. */
.gcg-grid > thead > tr > th.gcg-grid-total,
.gcg-grid > tbody > tr > td.gcg-grid-total {
    width: 9%;
    font-weight: var(--gcg-fw-semibold);
}

/* Inputs inside a grid: centred on the column's axis like the figures they
   replace, and free of the browser's spinner, which stole half the width. */
.gcg-grid input[type="number"],
.gcg-grid input[type="text"] {
    text-align: center !important;
    padding-inline: var(--gcg-1) !important;
    -moz-appearance: textfield;
    appearance: textfield;
}

.gcg-grid input[type="number"]::-webkit-outer-spin-button,
.gcg-grid input[type="number"]::-webkit-inner-spin-button {
    -webkit-appearance: none;
    margin: 0;
}

/* Editable cells in a statutory grid.
   The complaint that prompted this was fair: a grid of sixty boxes gave no clue
   which of them you were meant to type into, and the figures below them looked
   just as editable. A tint and a border say "this one", and the recomputed rows
   are left plain. */
.gcg-grid td.gcg-editable {
    background-color: var(--gcg-surface-sunken);
}

.gcg-grid td.gcg-editable input {
    border-color: var(--gcg-border) !important;
    background-color: var(--gcg-surface);
}

.gcg-grid td.gcg-editable input:focus {
    border-color: var(--gcg-brand) !important;
    box-shadow: 0 0 0 2px color-mix(in srgb, var(--gcg-brand) 20%, transparent);
}

/* While a recalculation is in flight. Deliberately faint: the figures on screen
   are still the last correct ones, so this says "catching up", not "wrong". */
.gcg-recalculating [data-year-total],
.gcg-recalculating [data-new-total],
.gcg-recalculating [data-new-share],
.gcg-recalculating [data-variance],
.gcg-recalculating [data-year-cell],
.gcg-recalculating [data-designated] {
    opacity: 0.55;
    transition: opacity 120ms ease-out;
}

/* -----------------------------------------------------------------------------
   9b. Pagination
   -------------------------------------------------------------------------- */
.gcg-pagination {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: var(--gcg-3);
    margin-block-start: var(--gcg-4);
    padding-block-start: var(--gcg-4);
    border-block-start: 1px solid var(--gcg-border-subtle);
}

.gcg-pagination-summary {
    margin: 0;
    font-size: var(--gcg-fs-crumb);
    color: var(--gcg-text-muted);
}

.gcg-pagination nav {
    margin-inline-start: auto;
}

.gcg-pagination .pagination {
    margin: 0;
    gap: var(--gcg-1);
}

.gcg-pagination .page-link {
    min-width: 32px;
    height: 32px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 0 var(--gcg-2);
    border: 1px solid var(--gcg-border);
    border-radius: var(--gcg-radius-sm);
    font-size: var(--gcg-fs-nav);
    color: var(--gcg-text-body);
    background-color: var(--gcg-surface);
}

.gcg-pagination .page-link:hover {
    background-color: var(--gcg-surface-sunken);
    color: var(--gcg-text);
}

.gcg-pagination .page-item.active .page-link {
    background-color: var(--gcg-brand);
    border-color: var(--gcg-brand);
    color: #fff;
}

.gcg-pagination .page-item.disabled .page-link {
    color: var(--gcg-border);
    background-color: var(--gcg-surface);
}

/* Laravel's bootstrap-5 paginator prints its own "Showing 1 to 25 of 38 results"
   nested inside the nav. Ours is more specific about what is being counted, so
   suppress theirs rather than show both. Descendant, not child: it is nested. */
.gcg-pagination nav p {
    display: none !important;
}

/* -----------------------------------------------------------------------------
   10. Empty state
   -------------------------------------------------------------------------- */
.gcg-empty {
    max-width: 420px;
    margin-inline: auto;
    padding-block: var(--gcg-10);
    text-align: center;
}

.gcg-empty-icon {
    width: 48px;
    height: 48px;
    margin-inline: auto;
    margin-block-end: var(--gcg-6);
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: var(--gcg-radius-lg);
    background-color: var(--gcg-brand-soft);
    color: var(--gcg-brand);
}

.gcg-empty-icon iconify-icon {
    font-size: 22px;
}

.gcg-empty-title {
    margin: 0 0 var(--gcg-2);
    font-size: var(--gcg-fs-card-title) !important;
    line-height: var(--gcg-lh-card-title);
    font-weight: var(--gcg-fw-semibold);
    letter-spacing: var(--gcg-tracking-tight);
    color: var(--gcg-text);
}

.gcg-empty-body {
    margin: 0 0 var(--gcg-6);
    font-size: var(--gcg-fs-body);
    line-height: var(--gcg-lh-body);
    color: var(--gcg-text-muted);
}

.gcg-empty-status {
    margin: 0 0 var(--gcg-4);
    font-size: var(--gcg-fs-nav);
    color: var(--gcg-text-muted);
}

.gcg-empty-actions {
    display: flex;
    flex-wrap: wrap;
    gap: var(--gcg-2);
    justify-content: center;
}

/* -----------------------------------------------------------------------------
   11. Footer
   -------------------------------------------------------------------------- */
.d-footer {
    padding: var(--gcg-4) var(--gcg-6);
    background-color: transparent;
    border-block-start: 1px solid var(--gcg-border-subtle);
    font-size: var(--gcg-fs-footer);
    color: var(--gcg-text-muted);
}

.d-footer p {
    font-size: var(--gcg-fs-footer);
    color: var(--gcg-text-muted);
}

.footer-attribution a {
    color: var(--gcg-text-muted);
    font-weight: var(--gcg-fw-medium);
    text-decoration: none;
}

.footer-attribution a:hover {
    color: var(--gcg-brand);
    text-decoration: underline;
}

/* -----------------------------------------------------------------------------
   12. Dashboard stat tiles
   -------------------------------------------------------------------------- */
.gcg-stat {
    display: block;
    text-decoration: none;
    /* The theme's gradient utility fought the flat surface; keep it white. */
    background-image: none;
    background-color: var(--gcg-surface);
}

.gcg-stat-body {
    display: flex;
    align-items: center;
    gap: var(--gcg-3);
    padding: var(--gcg-4);
}

.gcg-stat-icon {
    width: 36px;
    height: 36px;
    flex-shrink: 0;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: var(--gcg-radius);
    font-size: var(--gcg-icon-nav);
}

/* Tinted chips rather than saturated fills; colour only where it means
   something (warning = needs attention). */
.gcg-stat-icon--brand {
    background-color: var(--gcg-brand-soft);
    color: var(--gcg-brand);
}

.gcg-stat-icon--neutral {
    background-color: var(--gcg-surface-sunken);
    color: var(--gcg-text-muted);
}

.gcg-stat-icon--warning {
    background-color: rgba(180, 83, 9, .09);
    color: #b45309;
}

.gcg-stat-text {
    display: flex;
    flex-direction: column;
    gap: 2px;
    min-width: 0;
}

.gcg-stat-label {
    font-size: var(--gcg-fs-crumb);
    line-height: 1.25rem;
    font-weight: var(--gcg-fw-medium);
    color: var(--gcg-text-muted);
}

.gcg-stat-value {
    font-size: 1.375rem;
    line-height: 1.75rem;
    font-weight: var(--gcg-fw-semibold);
    letter-spacing: var(--gcg-tracking-tight);
    color: var(--gcg-text);
}

.gcg-stat .stat-tile-arrow {
    margin-inline-start: auto;
    color: var(--gcg-border);
}

.stat-tile {
    color: inherit;
    transition: border-color .15s ease, box-shadow .15s ease;
}

.stat-tile:hover {
    border-color: var(--gcg-brand) !important;
    box-shadow: 0 1px 2px rgba(16, 24, 40, .06), 0 0 0 3px var(--gcg-brand-soft);
}

.stat-tile:hover .stat-tile-arrow {
    color: var(--gcg-brand) !important;
}

.stat-tile-arrow {
    transition: color .15s ease;
    font-size: var(--gcg-icon-nav);
}

/* -----------------------------------------------------------------------------
   13. Auth screens
   -------------------------------------------------------------------------- */
.auth-logo {
    display: block;
    /* Centred on its own, so the heading beside it stays left-aligned. */
    margin-inline: auto;
    width: 100%;
    max-width: 216px;
    height: auto;
    max-height: none;
}

/* -----------------------------------------------------------------------------
   14. Impersonation banner
   -------------------------------------------------------------------------- */
.impersonation-banner {
    position: sticky;
    top: 0;
    z-index: 10;
    background: #b45309;
    color: #fff;
    text-align: center;
    font-size: var(--gcg-fs-crumb);
}

.impersonation-banner-btn {
    border: 1px solid rgba(255, 255, 255, .5);
    background: rgba(255, 255, 255, .12);
    color: #fff;
    border-radius: var(--gcg-radius-sm);
    padding: var(--gcg-1) var(--gcg-3);
    font-weight: var(--gcg-fw-semibold);
    font-size: var(--gcg-fs-crumb);
}

.impersonation-banner-btn:hover {
    background: rgba(255, 255, 255, .22);
}

body:has(.impersonation-banner) .sidebar {
    top: 40px;
    height: calc(100vh - 40px);
}


/* ---------------------------------------------------------------------------
   Dismissible explainers

   An explainer that reappears on every page load stops explaining and starts
   nagging, so these can be closed and stay closed. The close button is
   positioned rather than floated so it never reflows the text beside it.
   --------------------------------------------------------------------------- */
.gcg-dismissible {
    position: relative;
}

.gcg-dismissible .gcg-dismiss-btn {
    position: absolute;
    top: 0.75rem;
    inset-inline-end: 0.75rem;
    cursor: pointer;
    line-height: 1;
    opacity: 0.6;
    transition: opacity 0.15s ease;
}

.gcg-dismissible .gcg-dismiss-btn:hover,
.gcg-dismissible .gcg-dismiss-btn:focus-visible {
    opacity: 1;
}

/* Leave room for the button so a long heading cannot run underneath it. */
.gcg-dismissible > .d-flex:first-of-type {
    padding-inline-end: 1.5rem;
}

.gcg-dismissed-hint a {
    text-decoration: none;
}

.gcg-dismissed-hint iconify-icon {
    vertical-align: -0.125em;
}
