/********** Portal Theme **********/
/*
 * Design language ported from recruiter-portal.html.
 *
 * Loaded AFTER css/style.css and css/bootstrap.min.css, so every rule here is
 * an override that wins on load order. css/style.css is intentionally NOT
 * edited: removing the <link> to this file in resources/views/common/header.blade.php
 * reverts the entire redesign in one step.
 *
 * Section order and comment style mirror recruiter-portal.html so the two files
 * stay easy to diff when the reference design is updated.
 *
 * Class naming follows the reference (.admin-card, .data-table, .btn--primary,
 * .badge--active ...) so the same vocabulary can be reused by other pages
 * (Applications, Category, Specialty ...) without writing new CSS.
 */


/*** Design tokens ***/
:root {
    --navy: #192638;
    --green: #B5D334;
    --blue: #0096D7;
    --bg: #EEF3F7;
    --paper: #FFFFFF;
    --line: #D4DDE6;
    --muted: #5A6A7A;
    --grad: linear-gradient(135deg, #2C5BA9 0%, #8FC73E 100%);

    --r-sm: 10px;
    --r: 16px;
    --r-lg: 24px;

    --shadow-sm: 0 1px 3px rgba(25, 38, 56, .07), 0 1px 2px rgba(25, 38, 56, .04);
    --shadow: 0 4px 20px rgba(25, 38, 56, .10), 0 1px 4px rgba(25, 38, 56, .06);
    --shadow-lg: 0 16px 48px rgba(25, 38, 56, .14), 0 4px 12px rgba(25, 38, 56, .08);
    --shadow-accent: 0 8px 28px rgba(44, 91, 169, .28), 0 2px 8px rgba(143, 199, 62, .12);

    /* Single source of truth for the sidebar width. The reference uses 240px;
       style.css ships 250px, so every rule that depended on 250px is
       re-declared below. Media queries cannot read custom properties, so the
       literal 240px also appears in the @media blocks at the end of this file. */
    --sidebar-w: 240px;

    /* Shared height for form controls that sit on one row (filter bars, search
       bars), so inputs, selects and buttons line up exactly. */
    --control-h: 46px;
}


/*** Base ***/
body {
    font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
    background: var(--bg);
    color: var(--navy);
    font-size: 15px;
}

/* bootstrap.min.css hard-codes "Heebo" on body, .tooltip and .popover. body is
   overridden above; these two are appended to body, so inherit resolves to
   Inter and the now-unused Heebo webfont no longer has to be downloaded. */
.tooltip,
.popover {
    font-family: inherit;
}

/* Full-bleed shell. Replaces the .container-xxl max-width that used to cap the
   layout at 1320px, so the sidebar + content span the viewport as they do in
   the reference. */
.admin-shell {
    width: 100%;
    min-height: 100vh;
    background: var(--bg);
}


/*** Layout ***/
/*
 * style.css makes .sidebar a single scrolling block (height:100vh;
 * overflow-y:auto). That scrolls the signed-in user row along with everything
 * else, so it ends up sitting directly under the last nav item instead of at
 * the foot of the panel — obvious once the Settings dropdown is open and the
 * content is taller than the viewport.
 *
 * The sidebar itself is therefore a non-scrolling flex column: the nav list
 * takes the free space and scrolls internally, and .admin-user stays pinned to
 * the bottom, as in the reference.
 */
.sidebar {
    display: flex;
    flex-direction: column;
    width: var(--sidebar-w);
    height: 100vh;
    overflow: hidden;
    background: var(--navy);
    padding: 0;
}

.content {
    margin-left: var(--sidebar-w);
    background: var(--bg);
    min-height: 100vh;
}

/* The sidebar is a <nav> wrapper; make it a full-height column so the
   signed-in user block can be pushed to the bottom edge. */
.sidebar .navbar {
    flex: 1;
    flex-direction: column;
    /* Bootstrap sets flex-wrap:wrap. In a column container with a bounded
       height that spills the overflow into a second column instead of
       scrolling, which breaks the layout outright. */
    flex-wrap: nowrap;
    align-items: stretch;
    justify-content: flex-start;
    /* min-height:0 lets the nav list below actually shrink and scroll; without
       it a flex child refuses to go below its content height. */
    min-height: 0;
    padding: 0;
    background: transparent;
}


/*** Sidebar — brand ***/
.admin-brand {
    display: block;
    padding: 24px 24px 20px;
    margin: 0;
    border-bottom: 1px solid rgba(255, 255, 255, .1);
}

.admin-brand__name {
    display: block;
    font-size: 16px;
    font-weight: 800;
    letter-spacing: -.02em;
    color: #FFFFFF;
}

.admin-brand__tag {
    display: block;
    margin-top: 2px;
    font-size: 11.5px;
    color: rgba(255, 255, 255, .45);
}

/* Retained so the logo lockup can be restored by swapping the markup back. */
.admin-brand__logo {
    display: block;
    width: 140px;
    height: auto;
}


/*** Sidebar — navigation ***/
/* flex-grow is 0 so the list takes only the height of its items — that keeps the
   signed-in user row directly beneath the last nav item rather than pushed to
   the foot of the panel. (The reference uses flex:1 here, which pins the user
   row to the bottom instead.)

   flex-shrink and the min-height/overflow pair are kept so a long menu still
   scrolls inside the list rather than spilling out of the sidebar. */
.sidebar .navbar .navbar-nav {
    flex: 0 1 auto;
    min-height: 0;
    overflow-y: auto;
    padding: 16px 0;
}

.sidebar .navbar .navbar-nav .nav-link {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 12px 24px;
    color: rgba(255, 255, 255, .65);
    font-weight: 600;
    font-size: 14px;
    border-left: 3px solid transparent;
    border-radius: 0;
    transition: .18s;
}

.sidebar .navbar .navbar-nav .nav-link:hover {
    background: rgba(255, 255, 255, .05);
    color: #FFFFFF;
    border-color: transparent;
}

.sidebar .navbar .navbar-nav .nav-link.active {
    background: rgba(255, 255, 255, .08);
    color: #FFFFFF;
    border-left-color: var(--green);
}

/* style.css renders nav icons as 40px white circles. The reference uses plain
   inline icons, so the circle treatment is unwound here. */
.sidebar .navbar .navbar-nav .nav-link i,
.sidebar .navbar .navbar-nav .nav-link:hover i,
.sidebar .navbar .navbar-nav .nav-link.active i {
    width: 18px;
    height: auto;
    display: inline-flex;
    justify-content: center;
    background: transparent;
    border-radius: 0;
    font-size: 14px;
}

/* Inline SVG nav icons, as the reference uses. Font Awesome <i> icons and these
   sit in the same 10px flex gap, so the two can coexist. */
.sidebar .navbar .navbar-nav .nav-link svg {
    flex-shrink: 0;
    opacity: .8;
}

/* Anchor the dropdown caret to its own nav item. Without this it resolves
   against the fixed .sidebar, stacking every caret in the same corner. */
.sidebar .navbar .nav-item {
    position: relative;
}

.sidebar .navbar .dropdown-toggle::after {
    top: 16px;
    right: 18px;
    color: rgba(255, 255, 255, .45);
}

/* Bootstrap renders .navbar-nav .dropdown-menu as position:static, so these
   expand inline beneath their parent rather than floating. */
.sidebar .navbar .dropdown-menu {
    padding: 2px 0 6px;
    background: transparent;
}

.sidebar .navbar .dropdown-item {
    padding: 9px 24px 9px 52px;
    color: rgba(255, 255, 255, .55);
    font-size: 13.5px;
    font-weight: 500;
    border-radius: 0;
    transition: .18s;
}

.sidebar .navbar .dropdown-item:hover,
.sidebar .navbar .dropdown-item:focus,
.sidebar .navbar .dropdown-item.active {
    background: rgba(255, 255, 255, .05);
    color: #FFFFFF;
}


/*** Sidebar — signed-in user ***/
/* Sits directly under the last nav item. flex-shrink:0 stops it being squeezed
   when the nav list above is long enough to scroll. */
.admin-user {
    display: flex;
    align-items: center;
    gap: 10px;
    flex-shrink: 0;
    padding: 18px 24px;
    border-top: 1px solid rgba(255, 255, 255, .1);
}

.admin-user__avatar {
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    width: 32px;
    height: 32px;
    border-radius: 50%;
    background: var(--grad);
    color: #FFFFFF;
    font-size: 13px;
    font-weight: 700;
    text-transform: uppercase;
}

.admin-user__meta {
    min-width: 0;
    flex: 1;
}

.admin-user__name {
    font-size: 13px;
    font-weight: 600;
    color: #FFFFFF;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.admin-user__role {
    font-size: 11.5px;
    color: rgba(255, 255, 255, .45);
}

.admin-user__logout {
    margin: 0;
    line-height: 0;
}

.admin-user__logout-btn {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 32px;
    height: 32px;
    padding: 0;
    background: rgba(255, 255, 255, .06);
    border: none;
    border-radius: 8px;
    color: rgba(255, 255, 255, .6);
    font-size: 14px;
    cursor: pointer;
    transition: .18s;
}

.admin-user__logout-btn:hover {
    background: rgba(255, 255, 255, .14);
    color: #FFFFFF;
}


/*** Topbar (below 992px only — holds the sidebar toggler) ***/
.admin-topbar {
    display: flex;
    align-items: center;
    gap: 14px;
    padding: 10px 16px;
    background: var(--paper);
    border-bottom: 1px solid var(--line);
}

.content .navbar.admin-topbar .sidebar-toggler {
    width: 38px;
    height: 38px;
    background: var(--bg);
    border-radius: 8px;
    color: var(--navy);
}

.admin-topbar__title {
    font-size: 15px;
    font-weight: 700;
    color: var(--navy);
    letter-spacing: -.01em;
}


/*** Breadcrumb ***/
/*
 * The reference's #applicants-breadcrumb, shown above the page header when a
 * list has been narrowed to one record.
 *
 * Bootstrap styles .breadcrumb too, as a list with its own padding and a 1rem
 * bottom margin; both are reset here. portal-theme.css is linked after
 * bootstrap.min.css, so these equal-specificity rules win on order.
 */
.breadcrumb {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 6px;
    margin: 0 0 10px;
    padding: 0;
    background: none;
    font-size: 13px;
    color: var(--muted);
    list-style: none;
}

.breadcrumb a {
    font-weight: 600;
    color: var(--blue);
    text-decoration: none;
    cursor: pointer;
}

.breadcrumb a:hover {
    text-decoration: underline;
}


/*** Page header ***/
.admin-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 16px;
    flex-wrap: wrap;
    margin-bottom: 28px;
}

.admin-header h2 {
    font-size: 26px;
    font-weight: 800;
    letter-spacing: -.02em;
    margin: 0;
}

.admin-header p {
    color: var(--muted);
    font-size: 14.5px;
    margin: 4px 0 0;
}

/* Right-hand cluster of the page header (search, primary action). The reference
   header carries a single button; this wraps so extra controls stay aligned. */
.admin-header__actions {
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
}

.search-form {
    display: flex;
    align-items: center;
    gap: 8px;
    margin: 0;
}

.search-form .input {
    width: 260px;
}

/* Same shared height as the filter bar, so the search box and every button in
   the header row match on the careers page too. */
.search-form .input,
.admin-header__actions .btn {
    height: var(--control-h);
}


/*** Filter bar ***/
/* Filters and the page's primary action on one row. Filters flow from the left
   and wrap as needed; the action stays pinned right on wide screens. */
.filter-bar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    flex-wrap: wrap;
    margin-bottom: 20px;
}

.filter-bar__filters {
    display: flex;
    align-items: center;
    gap: 10px;
    flex: 1;
    flex-wrap: wrap;
    margin: 0;
    min-width: 0;
}

/* Right-hand slot of the filter row. __export is the Applications export form;
   __action is the generic equivalent used by the Add buttons elsewhere. */
.filter-bar__export,
.filter-bar__action {
    margin: 0;
    flex-shrink: 0;
}

/*
 * Applicant Inbox filter bar, per the reference: a card holding a wide search
 * plus three selects on a 2fr + 3×1fr grid.
 *
 * Scoped with a modifier rather than changing .filter-bar itself, because the
 * eight lookup screens use .filter-bar for a search-plus-Add row and would
 * break under a four-column grid.
 */
.filter-bar--grid {
    display: grid;
    grid-template-columns: 1fr;
    gap: 14px;
    padding: 18px 20px;
    background: var(--paper);
    border: 1px solid var(--line);
    border-radius: var(--r);
    box-shadow: var(--shadow-sm);
}

@media (min-width: 992px) {
    .filter-bar--grid {
        grid-template-columns: 2fr repeat(3, 1fr);
    }
}

/* background-color, never the shorthand: the shorthand would drop the custom
   select chevron drawn further down this file. */
.filter-bar--grid .input {
    width: 100%;
    height: 46px;
    padding: 0 14px;
    background-color: var(--bg);
    border: 1.5px solid var(--line);
    border-radius: var(--r-sm);
    font-family: inherit;
    font-size: 14px;
    color: var(--navy);
}

/* Restores the room the chevron needs, which the padding above would remove. */
.filter-bar--grid select.input {
    cursor: pointer;
    padding-right: 38px;
}

/* Two-class selectors on purpose: these controls also carry .input, which is
   declared later in this file with width:100%. Equal specificity would let it
   win, so the parent class is included to raise it. */
.filter-bar .filter-bar__select {
    width: auto;
    min-width: 170px;
}

.filter-bar .filter-bar__search {
    flex: 1;
    min-width: 240px;
}

/* Every control on the row shares one height so the Export button lines up
   exactly with the search box and the selects. box-sizing:border-box is already
   global, so padding stays inside this height. */
.filter-bar .filter-bar__select,
.filter-bar .filter-bar__search,
.filter-bar__filters .btn,
.filter-bar__export .btn,
.filter-bar__action .btn {
    height: var(--control-h);
}


/*** Buttons ***/
/*
 * Declaration order matters here. The Bootstrap bridges (.btn, .btn-sm,
 * .btn-primary) come FIRST so the reference modifiers below, which share their
 * single-class specificity, win the cascade on markup like
 * class="btn btn--secondary btn--sm".
 */

/* Bridge: shared geometry for every Bootstrap button across the untouched pages. */
.btn {
    padding: 10px 18px;
    font-size: 14px;
    font-weight: 600;
    border-radius: var(--r-sm);
    transition: all .22s cubic-bezier(.22, 1, .36, 1);
}

.btn-sm {
    padding: 8px 14px;
    font-size: 13px;
    border-radius: 8px;
}

/* Bridge: Bootstrap's primary button takes the reference gradient, so existing
   class="btn btn-primary" markup is restyled with no view edits. */
.btn-primary {
    background: var(--grad);
    border: none;
    color: #FFFFFF;
    box-shadow: var(--shadow-accent);
}

.btn-primary:hover,
.btn-primary:focus,
.btn-primary:active {
    background: var(--grad);
    border: none;
    color: #FFFFFF;
    transform: translateY(-1px);
    box-shadow: 0 10px 32px rgba(44, 91, 169, .36), 0 3px 10px rgba(143, 199, 62, .16);
}

/* Shared geometry for the reference's button modifiers. They are used together
   with Bootstrap's .btn (class="btn btn--primary"), so only the properties the
   reference changes are declared. */
.btn--primary,
.btn--secondary,
.btn--ghost,
.btn--destructive {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    padding: 12px 22px;
    font-family: inherit;
    font-size: 14px;
    font-weight: 600;
    line-height: 1.2;
    border: none;
    border-radius: var(--r-sm);
    text-decoration: none;
    white-space: nowrap;
    cursor: pointer;
    transition: all .22s cubic-bezier(.22, 1, .36, 1);
}

.btn--primary {
    background: var(--grad);
    color: #FFFFFF;
    box-shadow: var(--shadow-accent);
}

.btn--primary:hover,
.btn--primary:focus {
    color: #FFFFFF;
    transform: translateY(-1px);
    box-shadow: 0 10px 32px rgba(44, 91, 169, .36), 0 3px 10px rgba(143, 199, 62, .16);
}

.btn--secondary {
    background: #FFFFFF;
    color: var(--blue);
    border: 1.5px solid var(--blue);
}

.btn--secondary:hover,
.btn--secondary:focus {
    background: var(--navy);
    border-color: var(--navy);
    color: #FFFFFF;
}

.btn--ghost {
    background: #FFFFFF;
    color: var(--navy);
    border: 1.5px solid var(--line);
}

.btn--ghost:hover,
.btn--ghost:focus {
    border-color: var(--blue);
    color: var(--blue);
}

.btn--destructive {
    background: #FDF2F2;
    color: #B42318;
    border: 1.5px solid #F3C6C2;
}

.btn--destructive:hover,
.btn--destructive:focus {
    background: #B42318;
    border-color: #B42318;
    color: #FFFFFF;
}

.btn--sm {
    padding: 8px 14px;
    font-size: 13px;
    border-radius: 8px;
}

/* Square, icon-only variant. Declared after .btn--sm so it wins on padding.
   Always pair with title + aria-label, since there is no visible text. */
.btn--icon {
    width: 34px;
    height: 34px;
    padding: 0;
    gap: 0;
    justify-content: center;
}


/*** Cards ***/
.admin-card {
    background: var(--paper);
    border: 1px solid var(--line);
    border-radius: var(--r);
    box-shadow: var(--shadow-sm);
    overflow: hidden;
}

/* A card nested inside a .panel, as the reference has it around the dashboard's
   Recent applications table. The panel already carries the shadow, so the inner
   card drops its own and softens its border to the pale --bg. */
.admin-card--inset {
    box-shadow: none;
    border-color: var(--bg);
}

/* Wide tables scroll inside their own card so the page itself never gains a
   horizontal scrollbar on small screens. The reference has no equivalent. */
.table-scroll {
    width: 100%;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
}


/*** Dashboard ***/
/*
 * Mirrors the reference's dashboard panel. The reference pins .stat-grid to
 * four columns and .dash-grid to 1.6fr/1fr with no breakpoints at all; both are
 * given a single-column base here so they reflow on a phone rather than
 * overflowing.
 */
.stat-grid {
    display: grid;
    grid-template-columns: 1fr;
    gap: 18px;
    margin-bottom: 28px;
}

@media (min-width: 768px) {
    .stat-grid {
        grid-template-columns: repeat(2, 1fr);
    }
}

@media (min-width: 1200px) {
    .stat-grid {
        grid-template-columns: repeat(4, 1fr);
    }
}

/* Anchors rather than divs — the cards deep-link into filtered lists, so they
   need to be real links. The text colour is reset because .content a inherits
   the link colour. */
.stat-card {
    display: block;
    padding: 22px 24px;
    background: var(--paper);
    border: 1px solid var(--line);
    border-radius: var(--r);
    box-shadow: var(--shadow-sm);
    color: var(--navy);
    text-decoration: none;
    transition: transform .18s, box-shadow .18s;
}

.stat-card:hover {
    transform: translateY(-1px);
    box-shadow: var(--shadow);
    color: var(--navy);
    text-decoration: none;
}

.stat-card__top {
    display: flex;
    justify-content: space-between;
    align-items: flex-start;
    margin-bottom: 14px;
}

.stat-card__icon {
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    width: 40px;
    height: 40px;
    border-radius: 11px;
    background: var(--grad);
    box-shadow: var(--shadow-accent);
    color: #FFFFFF;
}

.stat-card__num {
    margin-bottom: 6px;
    font-size: 32px;
    font-weight: 800;
    line-height: 1;
    letter-spacing: -.02em;
    color: var(--navy);
}

.stat-card__label {
    font-size: 13.5px;
    font-weight: 500;
    color: var(--muted);
}

/* Summary panels: stacked by default, side by side once there is room. An
   explicit breakpoint is used rather than auto-fit + minmax, because a minmax
   floor wider than a phone viewport would force the grid to overflow.

   align-items is deliberately left at its `stretch` default, as the reference
   has it: "Recently posted roles" and "Applicant pipeline" then share a row
   height and their cards end level, however few funnel stages there are. */
.dash-grid {
    display: grid;
    grid-template-columns: 1fr;
    gap: 20px;
}

@media (min-width: 1200px) {
    .dash-grid {
        grid-template-columns: 1.6fr 1fr;
    }
}

/* Recent applications sits directly beneath the two summary panels, 20px down,
   the gap the reference uses. Expressed as an adjacency rule so the view does
   not have to carry a spacing utility class. */
.dash-grid + .panel {
    margin-top: 20px;
}

.panel {
    padding: 24px;
    background: var(--paper);
    border: 1px solid var(--line);
    border-radius: var(--r);
    box-shadow: var(--shadow-sm);
}

.panel h3 {
    margin: 0 0 18px;
    font-size: 16px;
    font-weight: 700;
    color: var(--navy);
}

.panel__empty {
    margin: 0;
    font-size: 13.5px;
    color: var(--muted);
}

/* A table inside a panel already has the panel's border and shadow. */
.panel .data-table {
    border: 0;
}

/* Recently posted roles */
.recent-row {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 16px;
    padding: 12px 0;
    border-bottom: 1px solid var(--bg);
}

.recent-row:last-child {
    border-bottom: none;
}

.recent-row__job {
    font-size: 14px;
    font-weight: 600;
    color: var(--navy);
}

.recent-row__meta {
    margin-top: 2px;
    font-size: 12.5px;
    color: var(--muted);
}

/* A link to that job's applicants, so it needs a hover affordance the
   reference's static markup did not. */
.recent-row__link {
    flex-shrink: 0;
    font-size: 13px;
    font-weight: 700;
    color: var(--blue);
    text-decoration: none;
    white-space: nowrap;
}

.recent-row__link:hover {
    color: var(--blue);
    text-decoration: underline;
}

/* Applicant pipeline funnel */
.funnel-row {
    display: flex;
    align-items: center;
    gap: 12px;
    margin-bottom: 14px;
}

.funnel-row:last-child {
    margin-bottom: 0;
}

.funnel-row__label {
    flex-shrink: 0;
    width: 92px;
    font-size: 13px;
    font-weight: 600;
    color: var(--muted);
}

.funnel-row__bar-wrap {
    flex: 1;
    height: 10px;
    overflow: hidden;
    background: var(--bg);
    border-radius: 100px;
}

.funnel-row__bar {
    height: 100%;
    background: var(--grad);
    border-radius: 100px;
}

.funnel-row__num {
    flex-shrink: 0;
    width: 28px;
    font-size: 13px;
    font-weight: 700;
    text-align: right;
    color: var(--navy);
}


/* Card title row, used above a table inside .admin-card. */
.card-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    padding: 16px 22px;
    border-bottom: 1px solid var(--line);
}

.card-head h3 {
    margin: 0;
    font-size: 16px;
    font-weight: 700;
    letter-spacing: -.01em;
    color: var(--navy);
}


/*** Data table ***/
.data-table {
    width: 100%;
    margin: 0;
    border-collapse: collapse;
}

.data-table th {
    padding: 14px 20px;
    text-align: left;
    font-size: 12px;
    font-weight: 700;
    letter-spacing: .04em;
    text-transform: uppercase;
    color: var(--muted);
    background: var(--bg);
    border-bottom: 1px solid var(--line);
    white-space: nowrap;
}

.data-table td {
    padding: 15px 20px;
    text-align: left;
    font-size: 14.5px;
    vertical-align: middle;
    border-bottom: 1px solid var(--line);
}

.data-table tr:last-child td {
    border-bottom: none;
}

.data-table tbody tr:hover td {
    background: rgba(0, 150, 215, .03);
}

.data-table__title {
    font-weight: 600;
}

.data-table__actions {
    display: flex;
    align-items: center;
    gap: 6px;
}

/* Stacked rather than side by side. A modifier, not a change to the base: the
   row layout above is what the other eleven listings' Actions columns use.
   stretch, so the two buttons match each other's width instead of each sizing
   to its own label. */
.data-table__actions--stack {
    flex-direction: column;
    align-items: stretch;
}

.data-table__actions form {
    margin: 0;
}

.data-table__empty {
    padding: 40px 22px;
    text-align: center;
    color: var(--muted);
    font-size: 14.5px;
}

/* Row-selection column: keep it tight so it does not steal width from the data. */
.data-table__check {
    width: 44px;
    text-align: center;
}

.data-table__check input[type="checkbox"] {
    width: 16px;
    height: 16px;
    accent-color: var(--blue);
    cursor: pointer;
    vertical-align: middle;
}

/*
 * Bulk action bar — sits between the filters and the table, and is hidden until
 * at least one row is ticked, so the page looks exactly as it did before when
 * nothing is selected.
 *
 * [hidden] is used rather than a modifier class because the attribute already
 * carries the meaning and needs no JS to stay in step; display:flex on the base
 * rule would otherwise override the browser's own [hidden] {display:none}, which
 * is why the attribute selector is repeated here.
 */
.bulk-bar {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 12px;
    margin-bottom: 14px;
    padding: 12px 16px;
    border: 1px solid var(--line);
    border-radius: var(--r-sm);
    background: var(--paper);
}

.bulk-bar[hidden] {
    display: none;
}

.bulk-bar__count {
    margin: 0;
    font-weight: 700;
    font-size: 14px;
    color: var(--navy);
}

/* Pushes the destructive action to the far end, away from the routine one. */
.bulk-bar__spacer {
    flex: 1 1 auto;
}

.bulk-bar select.input {
    width: auto;
    min-width: 170px;
}

/* Date column: reserve enough width for "01 Sep 2026" and keep it on one line,
   so the value never wraps to "01 Sep" / "2026". */
.data-table__date {
    width: 120px;
    white-space: nowrap;
}

/* Stacked contact cell — email above, phone muted beneath, per the reference.
   A long address wraps rather than forcing the column wide enough to push the
   whole table into horizontal scrolling. */
.contact-email {
    display: block;
    color: var(--blue);
    font-weight: 600;
    text-decoration: none;
    overflow-wrap: anywhere;
}

.contact-email:hover {
    text-decoration: underline;
}

.contact-phone {
    display: block;
    margin-top: 2px;
    color: var(--muted);
    font-size: 13px;
}

/* Placeholder for a cell with no value yet. */
.text-empty {
    color: var(--muted);
    opacity: .6;
}


/*** Recruiter notes thread ***/
/*
 * Shown editable inside the Edit Application modal and read-only on the full
 * View Application page, from the one partial.
 *
 * The list is capped and scrolls internally: an application worked for months
 * could carry a long history, and without this the modal would grow past the
 * viewport and push Save out of reach.
 */
.note-thread {
    margin-top: 4px;
    padding-top: 16px;
    border-top: 1px solid var(--line);
}

.note-thread__title {
    margin: 0 0 12px;
    font-size: 14px;
    font-weight: 700;
    color: var(--navy);
}

.note-thread__empty {
    margin: 0 0 12px;
    font-size: 13.5px;
    color: var(--muted);
}

.note {
    margin-bottom: 12px;
    padding: 10px 12px;
    border-radius: var(--r-sm);
    background: var(--bg);
}

/* Changes the panel recorded itself, rather than a typed comment: quieter, and
   marked down the edge so the two are never mistaken for each other. */
.note--system {
    background: transparent;
    border-left: 2px solid var(--line);
    border-radius: 0;
    padding-left: 10px;
}

.note__meta {
    margin: 0 0 3px;
    font-size: 12px;
    color: var(--muted);
}

.note__author {
    font-weight: 700;
    color: var(--navy);
}

.note__dot {
    margin: 0 5px;
}

.note__body {
    margin: 0;
    font-size: 14px;
    line-height: 1.5;
    color: var(--navy);
    /* Candidate notes can carry long unbroken strings, e.g. a pasted URL. */
    overflow-wrap: anywhere;
    white-space: pre-line;
}

.note--system .note__body {
    color: var(--muted);
    font-size: 13.5px;
}

/* Only the entries scroll — the "Add a note" box below stays put, so Save is
   always reachable however long the history gets. */
.note-thread__list {
    max-height: 220px;
    overflow-y: auto;
}

/* The Activity Log is reference material rather than the thing being written,
   so it is capped shorter and sits quieter than the notes above it. */
.note-thread__list--log {
    max-height: 150px;
}

.note-thread--log {
    margin-top: 16px;
}

.note-thread--log .note-thread__title {
    font-size: 13px;
    color: var(--muted);
}

.note-thread__input {
    margin-top: 6px;
    resize: vertical;
}


/*** Badges ***/
/*
 * The pill shape lives on .badge itself, as in the reference, so every modifier
 * inherits it. Declaring it only on the modifiers left the applicant-status
 * badges falling back to Bootstrap's own .badge — white text on a 4px radius,
 * which is why they read as unstyled next to the job badges.
 *
 * Bootstrap's .badge is the same single-class specificity, so this wins on load
 * order; portal-theme.css is linked after bootstrap.min.css.
 */
.badge {
    display: inline-block;
    padding: 5px 12px;
    border-radius: 100px;
    font-size: 12px;
    font-weight: 700;
    letter-spacing: .01em;
    line-height: normal;
    text-align: left;
    white-space: nowrap;
    color: var(--navy);
}

/* Job posting statuses — the reference's jobStatusClass(). */
.badge--active {
    background: rgba(0, 150, 215, .12);
    color: #0077AB;
}

/*
 * Amber, not grey. Draft previously sat on the same muted grey wash as Active's
 * pale blue, and at pill size the two read as the same "quiet" colour — a Draft
 * could be mistaken for something already live on the public careers site. Amber
 * is the conventional "not published yet" signal and separates cleanly from both
 * the blue of Active and the red of Closed at a glance down the column.
 */
.badge--draft {
    background: rgba(245, 158, 11, .16);
    color: #92400E;
}

.badge--closed {
    background: #FDF2F2;
    color: #B42318;
}

/* Applicant statuses — the reference's appStatusClass(). */
.badge--applied {
    background: rgba(0, 150, 215, .12);
    color: #0077AB;
}

.badge--shortlisted {
    background: rgba(90, 106, 122, .12);
    color: var(--muted);
}

.badge--interviewing {
    background: rgba(181, 211, 52, .2);
    color: #5C7314;
}

.badge--hired {
    background: rgba(181, 211, 52, .28);
    color: #45590F;
}

.badge--rejected {
    background: #FDF2F2;
    color: #B42318;
}


/*** Form fields ***/
.field-label {
    display: block;
    margin-bottom: 7px;
    font-size: 13.5px;
    font-weight: 600;
    color: var(--navy);
}

/* background-color, never the `background` shorthand: the shorthand would reset
   background-image and wipe the custom select arrow below, including on focus. */
.field-input,
.input {
    width: 100%;
    padding: 12px 14px;
    background-color: var(--bg);
    border: 1.5px solid var(--line);
    border-radius: var(--r-sm);
    font-family: inherit;
    font-size: 14.5px;
    color: var(--navy);
}

.field-input:focus,
.input:focus {
    outline: none;
    background-color: var(--paper);
    border-color: var(--blue);
    box-shadow: 0 0 0 3px rgba(0, 150, 215, .12);
}

/* Native select arrows sit hard against the border and each browser insets them
   differently. Suppressing the native control and drawing our own chevron gives
   identical spacing in Chrome, Firefox, Safari and Edge. The 38px right padding
   reserves room for it so long option text never runs underneath. */
select.field-input,
select.input,
select.form-control {
    -webkit-appearance: none;
    -moz-appearance: none;
    appearance: none;
    padding-right: 38px;
    background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%235A6A7A' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M2 5l6 6 6-6'/%3e%3c/svg%3e");
    background-repeat: no-repeat;
    background-position: right 14px center;
    background-size: 12px 9px;
}

/* Firefox keeps a focus ring inside the control; remove it so only our own
   focus treatment shows. */
select.field-input:-moz-focusring,
select.input:-moz-focusring,
select.form-control:-moz-focusring {
    color: transparent;
    text-shadow: 0 0 0 var(--navy);
}

/* An on/off setting as a toggle switch. A checkbox underneath rather than a
   scripted button, so it posts with the form, is reachable by keyboard and
   announces its state without any JS of its own. The whole thing is a <label>,
   so the track and the wording beside it are both part of the hit area. */
.field-toggle {
    display: inline-flex;
    align-items: center;
    gap: 10px;
    margin: 0;
    cursor: pointer;
}

/* Visually hidden rather than display:none — a display:none input drops out of
   the tab order and stops being announced, which would leave the switch
   unreachable by keyboard and silent to a screen reader. */
.field-toggle input[type="checkbox"] {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    border: 0;
    overflow: hidden;
    clip: rect(0 0 0 0);
    clip-path: inset(50%);
    white-space: nowrap;
}

.field-toggle__track {
    position: relative;
    flex: none;
    width: 44px;
    height: 24px;
    background-color: var(--line);
    border-radius: 999px;
    transition: background-color .15s ease;
}

.field-toggle__track::after {
    content: "";
    position: absolute;
    top: 3px;
    left: 3px;
    width: 18px;
    height: 18px;
    background-color: var(--paper);
    border-radius: 50%;
    box-shadow: 0 1px 2px rgba(25, 38, 56, .25);
    transition: transform .15s ease;
}

/* The hidden 0-value input sits before the checkbox, so the checkbox's next
   sibling is the track. */
.field-toggle input[type="checkbox"]:checked + .field-toggle__track {
    background-color: var(--blue);
}

.field-toggle input[type="checkbox"]:checked + .field-toggle__track::after {
    transform: translateX(20px);
}

/* Focus lands on the hidden checkbox, so the ring has to be drawn on the track
   beside it — otherwise tabbing through the form shows nothing at all here. */
.field-toggle input[type="checkbox"]:focus-visible + .field-toggle__track {
    box-shadow: 0 0 0 3px rgba(0, 150, 215, .12);
}

.field-toggle__state {
    font-size: 14px;
    font-weight: 600;
    color: var(--navy);
}

/* Both wordings are in the markup and CSS shows the one matching the state, so
   the label stays correct with no script involved. */
.field-toggle__state .is-on {
    display: none;
}

.field-toggle input[type="checkbox"]:checked ~ .field-toggle__state .is-on {
    display: inline;
}

.field-toggle input[type="checkbox"]:checked ~ .field-toggle__state .is-off {
    display: none;
}

/* Keeps a switch the same overall height as a text input beside it in
   .form-grid, so the two columns stay level. */
.field-toggle-row {
    display: flex;
    align-items: center;
    min-height: 48px;
}

@media (prefers-reduced-motion: reduce) {
    .field-toggle__track,
    .field-toggle__track::after {
        transition: none;
    }
}

.field-hint {
    display: block;
    margin-top: 6px;
    font-size: 12.5px;
    color: var(--muted);
}


/*** Summary view ***/
/*
 * The dashboard's applicant summary as a full screen: the whole application
 * record, so around thirty columns. It scrolls sideways inside its own
 * container — the page body never scrolls horizontally.
 */
/*
 * Everywhere else a .data-table sits directly inside an .admin-card, which is
 * what draws the frame around it — the table itself only rules between rows.
 * The Summary dialog has no card to sit in, so without this its table would
 * float in the modal body with ruled rows and no edge. This gives it the card's
 * own border, radius and clipping, so the table is framed the same in the
 * dialog as it is on every screen.
 */
.table-frame {
    border: 1px solid var(--line);
    border-radius: var(--r);
    overflow: hidden;
}

/* Inside a card the frame would double the card's own border. */
.admin-card > .table-frame {
    border: 0;
    border-radius: 0;
}

/* A job posting's reference — USA01. Tabular figures and a mono-ish weight so a
   column of them lines up and reads as an identifier rather than as prose. */
.job-code {
    font-variant-numeric: tabular-nums;
    font-weight: 600;
    letter-spacing: .02em;
    color: var(--muted);
    white-space: nowrap;
}


/*** Rich text editor ***/
/*
 * The Detailed Job Description field, matching the reference's .rich-text-*
 * block (recruiter-portal.html → #job-modal). The reference drives it with
 * document.execCommand; here it is a Tiptap editor — public/js/tiptap.bundle.js,
 * source in resources/js/rich-text.js — so the markup it produces is limited to
 * the editor's own schema rather than whatever the browser emits.
 *
 * .rich-text-content is applied to the ProseMirror element by the editor, so it
 * is the editable surface itself, not a wrapper.
 */
.rich-text-editor {
    overflow: hidden;
    background: #FFFFFF;
    border: 1.5px solid var(--line);
    border-radius: var(--r-sm);
}

/* The whole control lights up on focus, the way .field-input does — the border
   is on the wrapper, so the inner element cannot show it. */
.rich-text-editor:focus-within {
    border-color: var(--blue);
    box-shadow: 0 0 0 3px rgba(0, 150, 215, .12);
}

.rich-text-toolbar {
    display: flex;
    gap: 4px;
    padding: 8px;
    background: var(--bg);
    border-bottom: 1px solid var(--line);
}

.rich-text-toolbar button {
    padding: 7px 13px;
    background: transparent;
    border: 1px solid transparent;
    border-radius: 6px;
    font-family: inherit;
    font-size: 13.5px;
    line-height: 1;
    color: var(--navy);
    cursor: pointer;
}

.rich-text-toolbar button:hover {
    background: #FFFFFF;
    border-color: var(--line);
}

/* Set by the editor while the cursor sits inside that format. */
.rich-text-toolbar button.is-active {
    background: #FFFFFF;
    border-color: var(--blue);
    color: var(--blue);
}

.rich-text-content {
    min-height: 180px;
    max-height: 320px;
    overflow-y: auto;
    padding: 16px;
    outline: none;
    font-size: 14.5px;
    line-height: 1.6;
    color: var(--navy);
}

/* The editable area holds real block elements, so it needs its own typography —
   nothing else in the panel styles free-form content. */
.rich-text-content > :first-child {
    margin-top: 0;
}

.rich-text-content > :last-child {
    margin-bottom: 0;
}

.rich-text-content p {
    margin: 0 0 10px;
}

.rich-text-content h1,
.rich-text-content h2,
.rich-text-content h3 {
    margin: 18px 0 8px;
    font-size: 15.5px;
    font-weight: 700;
}

.rich-text-content ul,
.rich-text-content ol {
    margin: 0 0 10px;
    padding-left: 22px;
}

.rich-text-content li {
    margin-bottom: 4px;
}

.rich-text-content blockquote {
    margin: 0 0 10px;
    padding-left: 14px;
    border-left: 3px solid var(--line);
    color: var(--muted);
}


/*** Forms inside a card ***/
/* Padding lives here rather than on .admin-card, which is otherwise flush so a
   table can meet its edges. */
.form-card {
    padding: 26px 28px;
}

/* Two columns of fields on desktop, one on narrow screens. */
.form-grid {
    display: grid;
    grid-template-columns: 1fr;
    gap: 18px 20px;
}

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

.form-actions {
    display: flex;
    gap: 10px;
    margin-top: 26px;
}


/*** Bootstrap bridges ***/
/*
 * The pages not being rewritten (Dashboard, Applications, Category, Specialty,
 * Experience, State, Hub, Add/Edit Career) keep their Bootstrap markup. These
 * rules re-skin the Bootstrap components they use so those pages remain
 * coherent on the new canvas without touching a single view file.
 */

/* Page surface: .bg-light.rounded wrappers become the reference's white card. */
.content .bg-light {
    background-color: var(--paper) !important;
}

.content .bg-light.rounded,
.content .bg-light.rounded-top {
    border: 1px solid var(--line);
    border-radius: var(--r) !important;
    box-shadow: var(--shadow-sm);
}

/* Buttons are bridged in the Buttons section above, where declaration order
   relative to the .btn--* modifiers is load-bearing. */

/* Inputs and selects pick up the .field-input treatment. Only background-color
   is set (never the `background` shorthand) so .form-select keeps the caret SVG
   Bootstrap paints as a background-image. */
.form-control,
.form-select {
    padding: 12px 14px;
    background-color: var(--bg);
    border: 1.5px solid var(--line);
    border-radius: var(--r-sm);
    font-size: 14.5px;
    color: var(--navy);
}

/* Keep Bootstrap's right-hand gutter so the value never runs under the caret. */
.form-select {
    padding-right: 2.25rem;
}

.form-control:focus,
.form-select:focus {
    background-color: var(--paper);
    border-color: var(--blue);
    box-shadow: 0 0 0 3px rgba(0, 150, 215, .12);
}

/* Plain Bootstrap tables inherit the .data-table look. The selectors clear
   Bootstrap's inset box-shadow, which is how it paints striping and hover. */
.content .table {
    margin: 0;
    border-collapse: collapse;
}

.content .table > thead > tr > th {
    padding: 14px 22px;
    font-size: 12px;
    font-weight: 700;
    letter-spacing: .04em;
    text-transform: uppercase;
    color: var(--muted);
    background: var(--bg);
    border-bottom: 1px solid var(--line);
    box-shadow: none;
}

.content .table > tbody > tr > td {
    padding: 16px 22px;
    font-size: 14.5px;
    vertical-align: middle;
    border-bottom: 1px solid var(--line);
    box-shadow: none;
}

.content .table > tbody > tr:last-child > td {
    border-bottom: none;
}

/* Pagination */
.content .pagination {
    margin: 20px 0 0;
    gap: 6px;
}

.content .pagination .page-link {
    min-width: 38px;
    padding: 8px 12px;
    background: var(--paper);
    border: 1px solid var(--line);
    border-radius: 8px;
    color: var(--navy);
    font-size: 13.5px;
    font-weight: 600;
    text-align: center;
}

.content .pagination .page-link:hover {
    border-color: var(--blue);
    color: var(--blue);
}

.content .pagination .page-item.active .page-link {
    background: var(--grad);
    border-color: transparent;
    color: #FFFFFF;
}

.content .pagination .page-item.disabled .page-link {
    background: var(--bg);
    color: var(--muted);
    opacity: .65;
}

/* Row count on the left, page links on the right. Wraps to two lines on a
   narrow viewport rather than squeezing the links. */
.pagination-bar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: 12px 16px;
    margin-top: 16px;
}

.pagination-bar__summary {
    margin: 0;
    font-size: 13.5px;
    color: var(--muted);
}

/* The list carries a top margin for when it stands alone; inside the bar that
   would knock it out of line with the summary. Three classes so this wins over
   `.content .pagination` regardless of where the two sit in the file. */
.content .pagination-bar .pagination {
    margin: 0;
}

/* Alerts */
.content .alert {
    border-radius: var(--r-sm);
    border: 1px solid transparent;
    font-size: 14.5px;
}


/*** Application view form ***/
/*
 * resources/views/application/edit.blade.php — the read-only record opened by
 * the eye icon on the Applications table. Every control is readonly/disabled.
 *
 * Its markup uses generic class names (.form-row, .form-group, .notice ...)
 * that were meant to come from css/jobform.css, which does not exist in the
 * project. Everything here is therefore scoped under .application-container,
 * which appears in that one file only, so these names cannot leak into any
 * other screen.
 */
.application-container {
    max-width: 1000px;
}

/* Page header */
.application-container > header {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 16px;
    flex-wrap: wrap;
    margin-bottom: 24px;
}

.application-container > header h1 {
    margin: 0;
    font-size: 26px;
    font-weight: 800;
    letter-spacing: -.02em;
    color: var(--navy);
}

.application-container > header p {
    margin: 4px 0 0;
    font-size: 14.5px;
    color: var(--muted);
}

/* Section panels */
.application-container .form-section {
    padding: 24px 26px;
    margin-bottom: 20px;
    background: var(--paper);
    border: 1px solid var(--line);
    border-radius: var(--r);
    box-shadow: var(--shadow-sm);
}

/* A nested .form-section is already inside a panel — unwrap it. */
.application-container .form-section .form-section {
    padding: 0;
    margin: 0;
    background: none;
    border: 0;
    border-radius: 0;
    box-shadow: none;
}

.application-container .form-section > h2 {
    margin: 0 0 20px;
    padding-bottom: 14px;
    font-size: 17px;
    font-weight: 700;
    letter-spacing: -.01em;
    color: var(--navy);
    border-bottom: 1px solid var(--line);
}

/* Field rows: two per row on desktop, one when marked .full or on mobile. */
.application-container .form-row {
    display: grid;
    grid-template-columns: 1fr;
    gap: 18px 20px;
    margin-bottom: 18px;
}

.application-container .form-row:last-child {
    margin-bottom: 0;
}

.application-container .form-group {
    min-width: 0;
}

.application-container label {
    display: block;
    margin-bottom: 7px;
    font-size: 13.5px;
    font-weight: 600;
    color: var(--navy);
}

.application-container .required {
    margin-left: 2px;
    color: #B42318;
}

.application-container .form-group > p {
    margin: 6px 0 10px;
    font-size: 12.5px;
    color: var(--muted);
}

/* Controls */
.application-container input[type="text"],
.application-container input[type="email"],
.application-container input[type="tel"],
.application-container input[type="number"],
.application-container input[type="date"],
.application-container input[type="url"],
.application-container select,
.application-container textarea {
    width: 100%;
    padding: 12px 14px;
    background-color: var(--bg);
    border: 1.5px solid var(--line);
    border-radius: var(--r-sm);
    font-family: inherit;
    font-size: 14.5px;
    color: var(--navy);
}

.application-container textarea {
    min-height: 96px;
    line-height: 1.55;
    resize: vertical;
}

.application-container select {
    -webkit-appearance: none;
    -moz-appearance: none;
    appearance: none;
    padding-right: 38px;
    background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%235A6A7A' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M2 5l6 6 6-6'/%3e%3c/svg%3e");
    background-repeat: no-repeat;
    background-position: right 14px center;
    background-size: 12px 9px;
}

/* This is a view, not an edit screen: keep disabled values at full contrast
   rather than letting the browser grey them out. */
.application-container [readonly],
.application-container [disabled] {
    opacity: 1;
    color: var(--navy);
    cursor: default;
}

/* Radios and checkboxes */
.application-container .radio-group,
.application-container .checkbox-group {
    display: flex;
    flex-wrap: wrap;
    gap: 10px 18px;
}

.application-container .radio-item,
.application-container .checkbox-item {
    display: inline-flex;
    align-items: center;
    gap: 8px;
}

.application-container .radio-item label,
.application-container .checkbox-item label {
    margin: 0;
    font-size: 14px;
    font-weight: 500;
}

.application-container input[type="radio"],
.application-container input[type="checkbox"] {
    width: 16px;
    height: 16px;
    margin: 0;
    accent-color: var(--blue);
}

/* Required agreements */
.application-container .required-checkbox-group {
    display: flex;
    flex-direction: column;
    gap: 12px;
}

.application-container .required-checkbox-item {
    display: flex;
    align-items: flex-start;
    gap: 10px;
}

.application-container .required-checkbox-item input {
    margin-top: 3px;
    flex-shrink: 0;
}

.application-container .required-checkbox-label {
    margin: 0;
    font-size: 13.5px;
    font-weight: 500;
    line-height: 1.55;
    color: var(--muted);
}

/* Repeating skill and hub rows */
.application-container .skills-container {
    display: flex;
    flex-direction: column;
    gap: 14px;
}

.application-container .skill-row,
.application-container .hub-row {
    display: grid;
    grid-template-columns: 1fr;
    gap: 14px;
    padding: 16px;
    background: var(--bg);
    border: 1px solid var(--line);
    border-radius: var(--r-sm);
}

/* Lift nested controls to white so they read against the tinted row. */
.application-container .skill-row select,
.application-container .hub-row select,
.application-container .skill-row input,
.application-container .hub-row input {
    background-color: var(--paper);
}

/* Notices — amber callouts, the one place the palette needs a warning tone. */
.application-container .notice {
    padding: 18px 20px;
    margin-bottom: 20px;
    background: #FFFAEB;
    border: 1px solid #FEDF89;
    border-left: 4px solid #F79009;
    border-radius: var(--r-sm);
}

.application-container .notice h3 {
    margin: 0 0 8px;
    font-size: 14.5px;
    font-weight: 700;
    color: #B54708;
}

.application-container .notice p,
.application-container .notice li {
    margin: 0 0 8px;
    font-size: 13.5px;
    line-height: 1.6;
    color: #7A5A2E;
}

.application-container .notice ul {
    margin: 8px 0 0;
    padding-left: 20px;
}

.application-container .notice a {
    color: #B54708;
    font-weight: 600;
}

/* Privacy policy blocks */
.application-container .policy-section {
    padding: 16px 0;
    border-top: 1px solid var(--line);
}

.application-container .policy-section:first-of-type {
    padding-top: 0;
    border-top: 0;
}

.application-container .policy-section h3 {
    margin: 0 0 8px;
    font-size: 14.5px;
    font-weight: 700;
    color: var(--navy);
}

.application-container .policy-section p,
.application-container .policy-section li {
    margin: 0 0 8px;
    font-size: 13.5px;
    line-height: 1.65;
    color: var(--muted);
}

.application-container .policy-section ul {
    margin: 8px 0;
    padding-left: 20px;
}

/* Add / remove row buttons. Commented out in the markup today, styled here so
   they are correct if the repeat-row scripts are ever switched back on. */
.application-container .add-skill-btn,
.application-container .add-Hub-btn {
    padding: 8px 14px;
    background: #FFFFFF;
    border: 1.5px solid var(--line);
    border-radius: 8px;
    color: var(--navy);
    font-family: inherit;
    font-size: 13px;
    font-weight: 600;
    cursor: pointer;
}

.application-container .add-skill-btn:hover,
.application-container .add-Hub-btn:hover {
    border-color: var(--blue);
    color: var(--blue);
}

.application-container .delete-skill-btn,
.application-container .delete-hub-btn {
    padding: 8px 14px;
    background: #FDF2F2;
    border: 1.5px solid #F3C6C2;
    border-radius: 8px;
    color: #B42318;
    font-family: inherit;
    font-size: 13px;
    font-weight: 600;
    cursor: pointer;
}

.application-container .button-group {
    display: flex;
    gap: 10px;
    margin-top: 24px;
}

/*
 * Carried over from the public-facing application form. Nothing on this admin
 * screen ever adds .show, and with jobform.css missing they were rendering
 * permanently — the success banner and both "required" errors showed on every
 * record. Hidden by default; the .show rules keep the original contract.
 */
.application-container .success-message,
.application-container .error-message {
    display: none;
}

.application-container .success-message.show,
.application-container .error-message.show {
    display: block;
}

.application-container .error-message {
    margin-top: 6px;
    font-size: 13px;
    font-weight: 500;
    color: #B42318;
}

.application-container .success-message {
    padding: 14px 16px;
    margin-bottom: 20px;
    background: rgba(0, 150, 215, .10);
    border: 1px solid rgba(0, 150, 215, .25);
    border-radius: var(--r-sm);
    font-size: 13.5px;
    font-weight: 500;
    color: #0077AB;
}

/* ── Application view: the two apply-form variants ────────────────────────────
 *
 * .app-view reproduces the apply panel on the careers site as a full-page admin
 * screen: navy gradient header, then one white sheet whose sections are divided
 * by hairlines under small blue uppercase legends.
 *
 * The field controls themselves reuse .form-row / .form-group / .radio-group /
 * .skills-container / .hub-row / .skill-row declared above, so only the shell
 * and the few controls the careers site adds are defined here.
 */
.app-view {
    overflow: hidden;
    background: var(--paper);
    border: 1px solid var(--line);
    border-radius: var(--r);
    box-shadow: var(--shadow-sm);
}

/* Header — same navy ramp and green kicker the careers site uses. */
.app-view__header {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 20px;
    flex-wrap: wrap;
    padding: 24px 28px;
    background: linear-gradient(160deg, #0D1A28, var(--navy));
}

.app-view__head-text {
    min-width: 0;
}

.app-view__kicker {
    margin-bottom: 8px;
    font-size: 11px;
    font-weight: 700;
    letter-spacing: .08em;
    text-transform: uppercase;
    color: var(--green);
}

.app-view__title {
    margin: 0;
    font-size: 22px;
    font-weight: 800;
    letter-spacing: -.02em;
    color: #fff;
}

.app-view__meta {
    margin-top: 6px;
    font-size: 13px;
    color: rgba(255, 255, 255, .6);
}

.app-view__back {
    flex-shrink: 0;
    padding: 8px 16px;
    background: rgba(255, 255, 255, .12);
    border: 1px solid rgba(255, 255, 255, .18);
    border-radius: 999px;
    font-size: 13px;
    font-weight: 600;
    color: #fff;
    text-decoration: none;
    transition: background .15s ease;
}

.app-view__back:hover,
.app-view__back:focus {
    background: rgba(255, 255, 255, .22);
    color: #fff;
}

.app-view__body {
    padding: 0 28px;
}

/* Sections: hairline-separated bands rather than separate cards. */
.app-view__section {
    padding: 26px 0;
}

.app-view__section + .app-view__section {
    border-top: 1px solid var(--line);
}

.app-view__legend {
    margin: 0 0 20px;
    font-size: 12px;
    font-weight: 700;
    letter-spacing: .08em;
    text-transform: uppercase;
    color: var(--blue);
}

/* Job description, shown above the standard variant's fields. */
.app-view__lede {
    margin: 0 0 22px;
    font-size: 15px;
    line-height: 1.6;
    color: var(--muted);
}

.app-view__empty {
    margin: 0;
    font-size: 13.5px;
    color: var(--muted);
}

/* Currency-prefixed control, e.g. the freelance rate. */
.app-view__prefixed {
    display: flex;
    align-items: stretch;
    overflow: hidden;
    border: 1px solid var(--line);
    border-radius: var(--r-sm);
    background: var(--paper);
}

.app-view__prefix {
    display: flex;
    align-items: center;
    padding: 0 14px;
    background: var(--bg);
    border-right: 1px solid var(--line);
    font-size: 14px;
    font-weight: 600;
    color: var(--muted);
}

/* The inner control already carries a border from the shared rules; drop it so
   the wrapper provides the single outline. */
.app-view__prefixed input {
    flex: 1;
    min-width: 0;
    border: 0 !important;
    border-radius: 0 !important;
}

/* Uploaded CV. */
.app-view__file {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    flex-wrap: wrap;
    padding: 16px 18px;
    background: var(--bg);
    border: 1px dashed var(--line);
    border-radius: var(--r-sm);
}

.app-view__file-name {
    min-width: 0;
    font-size: 13.5px;
    font-weight: 600;
    color: var(--navy);
    word-break: break-all;
}

/* Confirmations the applicant ticked. */
.app-view__agreements {
    display: flex;
    flex-direction: column;
    gap: 14px;
    margin-top: 22px;
}

.app-view__agreement {
    display: flex;
    align-items: flex-start;
    gap: 12px;
}

.app-view__agreement input[type="checkbox"] {
    flex-shrink: 0;
    margin-top: 2px;
}

/* Lighter than the field labels — this is prose, not a field name. */
.app-view__agreement label {
    margin: 0;
    font-size: 13.5px;
    font-weight: 400;
    line-height: 1.55;
    color: var(--muted);
}

.app-view__actions {
    padding: 22px 0 26px;
    border-top: 1px solid var(--line);
}

@media (max-width: 575.98px) {
    .app-view__header,
    .app-view__body {
        padding-left: 18px;
        padding-right: 18px;
    }
}

@media (min-width: 768px) {
    .application-container .form-row {
        grid-template-columns: 1fr 1fr;
    }

    .application-container .form-row.full {
        grid-template-columns: 1fr;
    }

    .application-container .skill-row {
        grid-template-columns: repeat(3, 1fr);
    }

    .application-container .hub-row {
        grid-template-columns: repeat(2, 1fr);
    }
}

@media (max-width: 575.98px) {
    .application-container .form-section {
        padding: 20px 18px;
    }
}


/*** Modals ***/
/*
 * Reproduces the reference dialog (recruiter-portal.html → .modal-overlay /
 * .modal-content) on top of Bootstrap 5's modal.
 *
 * The reference puts a single 36px/40px pad on the whole white card, with the
 * title row and the buttons sitting inside it — there is no tinted header bar
 * and no footer rule. Bootstrap pads header, body and footer separately, so
 * those are zeroed and the padding is moved onto .modal-content.
 *
 * Only presentation changes here. The .modal / .modal-dialog machinery and the
 * data-bs-toggle / data-bs-dismiss contract are Bootstrap's and are untouched.
 */

/* Reference overlay is rgba(13,39,64,.5); Bootstrap's backdrop is black. */
.modal-backdrop {
    background-color: #0D2740;
}

.modal-backdrop.show {
    opacity: .5;
}

/* 820px in the reference. Two classes so this beats Bootstrap's .modal-lg
   (max-width 800px) on specificity rather than on source order. */
.modal .modal-dialog {
    max-width: 820px;
}

.modal-content {
    max-height: 88vh;
    overflow-y: auto;
    padding: 36px 40px;
    background: var(--paper);
    border: 0;
    border-radius: var(--r-lg);
    box-shadow: var(--shadow-lg);
}

/* Reference popIn: .22s cubic-bezier(.22,1,.36,1), rising and scaling in. */
.modal.fade .modal-dialog {
    transform: translateY(12px) scale(.98);
    transition: transform .22s cubic-bezier(.22, 1, .36, 1);
}

.modal.show .modal-dialog {
    transform: translateY(0) scale(1);
}

.modal-header {
    align-items: center;
    padding: 0;
    margin-bottom: 24px;
    background: none;
    border-bottom: 0;
    border-radius: 0;
}

.modal-header .modal-title {
    font-size: 20px;
    font-weight: 800;
    letter-spacing: -.01em;
    color: var(--navy);
}

/*
 * Reference close control: a 32px grey disc holding a muted ×. Bootstrap's
 * .btn-close is a black SVG sized in em, so the glyph is replaced with one
 * already stroked in --muted rather than tinted with a filter — the same
 * approach used for the select chevron above.
 */
.modal-header .btn-close {
    box-sizing: border-box;
    width: 32px;
    height: 32px;
    padding: 0;
    margin: 0;
    background-color: var(--bg);
    background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%235A6A7A' stroke-linecap='round' stroke-width='2' d='M3 3l10 10M13 3L3 13'/%3e%3c/svg%3e");
    background-position: center;
    background-size: 12px 12px;
    background-repeat: no-repeat;
    border-radius: 50%;
    opacity: 1;
}

.modal-header .btn-close:hover {
    background-color: var(--line);
}

.modal-body {
    padding: 0;
}

/* Buttons sit flush right under the fields, with no rule above them. */
.modal-footer {
    gap: 10px;
    justify-content: flex-end;
    padding: 0;
    margin-top: 26px;
    background: none;
    border-top: 0;
    border-radius: 0;
}

/* Bootstrap spaces footer children with margins; the gap above handles it. */
.modal-footer > * {
    margin: 0;
}

@media (max-width: 575.98px) {
    .modal-content {
        padding: 24px 20px;
    }
}

/* Job posting modal — the reference's two-column field grid. */
.modal-grid {
    display: grid;
    grid-template-columns: 1fr;
    gap: 18px;
}

.modal-grid__full {
    grid-column: 1 / -1;
}

/* A read-only value shown under a .field-label, as in the reference's
   application modal — plain bold text rather than a disabled input. */
.field-value {
    font-size: 14px;
    font-weight: 600;
    color: var(--navy);
    overflow-wrap: anywhere;
}

@media (min-width: 768px) {
    .modal-grid {
        grid-template-columns: 1fr 1fr;
    }
}

/* Applicant count on the Job Postings table — the reference's
   .applicant-count-link, opening the Applicant Inbox filtered to that job. */
.job-applicants {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-size: 14.5px;
    font-weight: 700;
    color: var(--blue);
    text-decoration: none;
}

.job-applicants:hover {
    color: var(--blue);
    text-decoration: underline;
}

.job-applicants svg {
    flex-shrink: 0;
}


/*** System Settings ***/
/*
 * The reference's Settings panel: a grid of cards, each a list of values with a
 * × delete and an Add control. The reference pins the grid to two columns with
 * no breakpoints; a single-column base is added here so it reflows on a phone.
 */
.settings-grid {
    display: grid;
    grid-template-columns: 1fr;
    gap: 24px;
}

@media (min-width: 992px) {
    .settings-grid {
        grid-template-columns: 1fr 1fr;
    }
}

.settings-card {
    display: flex;
    flex-direction: column;
    padding: 24px;
    background: var(--paper);
    border: 1px solid var(--line);
    border-radius: var(--r);
    box-shadow: var(--shadow-sm);
}

.settings-card__head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    margin-bottom: 16px;
}

.settings-card h3 {
    margin: 0;
    font-size: 17px;
    font-weight: 700;
    color: var(--navy);
}

/* Filter box beside the title, on cards whose list scrolls. Compact so the
   head stays one line; it sits between the title and the count, which the
   head's space-between already positions. */
.settings-search {
    flex: 1 1 auto;
    min-width: 0;
    max-width: 180px;
    padding: 7px 12px;
    background-color: var(--bg);
    border: 1.5px solid var(--line);
    border-radius: var(--r-sm);
    font-family: inherit;
    font-size: 13px;
    color: var(--navy);
}

.settings-search:focus {
    outline: none;
    background-color: var(--paper);
    border-color: var(--blue);
    box-shadow: 0 0 0 3px rgba(0, 150, 215, .12);
}

.settings-card__count {
    flex-shrink: 0;
    padding: 3px 10px;
    background: var(--bg);
    border-radius: 100px;
    font-size: 12px;
    font-weight: 700;
    color: var(--muted);
}

/* Capped and scrollable: Hub alone runs to 93 rows, which would otherwise make
   one card many times taller than the rest of the grid. */
.settings-list {
    list-style: none;
    max-height: 320px;
    overflow-y: auto;
    margin: 0 0 16px;
    padding: 0;
}

.settings-list li {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    padding: 10px 0;
    border-bottom: 1px solid var(--bg);
    font-size: 14px;
    font-weight: 500;
}

.settings-list li:last-child {
    border-bottom: none;
}

/* The value itself is the edit trigger, so it is a button styled back down to
   plain text. */
.settings-list__item {
    display: flex;
    align-items: center;
    gap: 8px;
    flex: 1;
    min-width: 0;
    padding: 0;
    background: none;
    border: 0;
    font: inherit;
    color: var(--navy);
    text-align: left;
    cursor: pointer;
}

.settings-list__item:hover {
    color: var(--blue);
}

.settings-list__delete {
    flex-shrink: 0;
    padding: 0;
    background: none;
    border: none;
    color: #B42318;
    font-size: 18px;
    line-height: 1;
    cursor: pointer;
}

.settings-list__empty {
    color: var(--muted);
    font-weight: 400;
}

.settings-add {
    display: flex;
    gap: 8px;
    margin-top: auto;
}

/* .input is width:100% elsewhere; in this row it needs to share the space. */
.settings-add .input {
    flex: 1;
    min-width: 0;
}


/*** Login ***/
/*
 * The login screen renders outside the .content shell (header.blade.php gates
 * that behind @auth), so these styles are standalone rather than scoped.
 */
.login-page {
    display: grid;
    grid-template-columns: 1fr;
    min-height: 100vh;
}

/* Brand panel — the navy of the admin sidebar, so signing in already looks like
   the product you are signing in to. */
.login-aside {
    position: relative;
    display: flex;
    align-items: center;
    padding: 48px 40px;
    background: var(--navy);
    overflow: hidden;
}

/* Two soft brand-gradient discs. Plain opacity, no blur filter, so large-area
   compositing stays cheap. */
.login-aside::before,
.login-aside::after {
    content: "";
    position: absolute;
    border-radius: 50%;
    background: var(--grad);
    pointer-events: none;
}

.login-aside::before {
    top: -140px;
    right: -110px;
    width: 380px;
    height: 380px;
    opacity: .22;
}

.login-aside::after {
    bottom: -170px;
    left: -90px;
    width: 300px;
    height: 300px;
    opacity: .12;
}

.login-aside__inner {
    position: relative;
    z-index: 1;
    display: flex;
    flex-direction: column;
    gap: 30px;
    width: 100%;
    max-width: 440px;
    margin: 0 auto;
}

.login-brand__logo {
    display: block;
    width: 150px;
    height: auto;
}

.login-brand__tag {
    display: block;
    margin-top: 8px;
    font-size: 11.5px;
    font-weight: 500;
    letter-spacing: .02em;
    color: rgba(255, 255, 255, .45);
}

.login-aside__copy h1 {
    margin: 0;
    font-size: 34px;
    font-weight: 800;
    line-height: 1.15;
    letter-spacing: -.02em;
    color: #FFFFFF;
}

/* Short gradient rule under the heading, picking up the brand blue-to-green. */
.login-aside__copy h1::after {
    content: "";
    display: block;
    width: 56px;
    height: 4px;
    margin-top: 18px;
    border-radius: 4px;
    background: var(--grad);
}

.login-aside__copy p {
    margin: 16px 0 0;
    font-size: 15px;
    line-height: 1.6;
    color: rgba(255, 255, 255, .62);
}

.login-aside__foot {
    font-size: 12.5px;
    color: rgba(255, 255, 255, .35);
}

/* Form panel */
.login-main {
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 48px 20px;
    background: var(--bg);
}

.login-card {
    width: 100%;
    max-width: 420px;
    padding: 36px 32px;
    background: var(--paper);
    border: 1px solid var(--line);
    border-radius: var(--r-lg);
    box-shadow: var(--shadow);
}

.login-card__title {
    margin: 0;
    font-size: 24px;
    font-weight: 800;
    letter-spacing: -.02em;
    color: var(--navy);
}

.login-card__sub {
    margin: 6px 0 26px;
    font-size: 14px;
    color: var(--muted);
}

.login-field {
    margin-bottom: 18px;
}

.login-form .field-input {
    height: var(--control-h);
}

.req {
    margin-left: 2px;
    color: #B42318;
}

.field-error {
    display: block;
    margin-top: 6px;
    font-size: 13px;
    font-weight: 500;
    color: #B42318;
}

.login-submit {
    width: 100%;
    height: var(--control-h);
    margin-top: 6px;
}

/* Flash message (e.g. "Logged out successfully."). */
.login-note {
    margin-bottom: 20px;
    padding: 12px 14px;
    border-radius: var(--r-sm);
    font-size: 13.5px;
    font-weight: 500;
}

.login-note--ok {
    background: rgba(0, 150, 215, .10);
    border: 1px solid rgba(0, 150, 215, .25);
    color: #0077AB;
}

@media (min-width: 992px) {
    .login-page {
        grid-template-columns: 1.05fr 1fr;
    }
}

/* Below the split breakpoint the brand panel becomes a compact band: the
   supporting copy and footer are dropped so the form stays above the fold. */
@media (max-width: 991.98px) {
    .login-aside {
        padding: 28px 20px;
    }

    .login-aside__inner {
        gap: 18px;
    }

    .login-aside__copy h1 {
        font-size: 24px;
    }

    .login-aside__copy h1::after {
        margin-top: 14px;
    }

    .login-aside__copy p,
    .login-aside__foot {
        display: none;
    }

    .login-main {
        padding: 32px 20px 48px;
    }
}

@media (max-width: 575.98px) {
    .login-card {
        padding: 28px 22px;
    }
}


/*** Footer ***/
.admin-footer {
    padding: 22px 0 26px;
    border-top: 1px solid var(--line);
    color: var(--muted);
    font-size: 13.5px;
}

.admin-footer a {
    color: var(--blue);
    font-weight: 600;
    text-decoration: none;
}

.admin-footer a:hover {
    text-decoration: underline;
}


/*** Responsive ***/
/*
 * Added by us — recruiter-portal.html ships no media queries at all. The .open
 * class contract from style.css is preserved exactly so the existing toggler in
 * public/js/main.js keeps working untouched.
 */
@media (min-width: 992px) {
    .sidebar {
        margin-left: 0;
    }

    .sidebar.open {
        margin-left: -240px;
    }

    .content {
        width: calc(100% - 240px);
    }

    .content.open {
        width: 100%;
        margin-left: 0;
    }

    /* Match the reference's 40px / 44px page gutter. Bootstrap's spacing
       utilities carry !important, so these must too.
       Two selectors on purpose: layouts/app.blade.php wraps @yield in <main>,
       so page content is a grandchild of .content while the footer container is
       a direct child. */
    .content > .container-fluid,
    .content > main > .container-fluid {
        padding-top: 40px !important;
        padding-right: 44px !important;
        padding-left: 44px !important;
    }
}

@media (max-width: 991.98px) {
    .sidebar {
        margin-left: -240px;
    }

    .sidebar.open {
        margin-left: 0;
    }

    .content {
        width: 100%;
        margin-left: 0;
    }
}

@media (max-width: 575.98px) {
    .content > .container-fluid,
    .content > main > .container-fluid {
        padding-right: 16px !important;
        padding-left: 16px !important;
    }

    .admin-header {
        align-items: flex-start;
        flex-direction: column;
    }

    .admin-header h2 {
        font-size: 22px;
    }

    /* Search and the primary action go full width and share one row so the
       header never overflows a phone viewport. */
    .admin-header__actions,
    .search-form {
        width: 100%;
    }

    .search-form .input {
        width: auto;
        flex: 1;
        min-width: 0;
    }

    /* Filter bar goes one control per row; Export spans the full width so it
       stays an easy tap target. The .filter-bar prefix on the two control
       selectors matches the specificity used above, which a media query alone
       would not beat. */
    .filter-bar__filters,
    .filter-bar__export,
    .filter-bar__action,
    .filter-bar .filter-bar__select,
    .filter-bar .filter-bar__search {
        width: 100%;
        min-width: 0;
    }

    .filter-bar__export .btn,
    .filter-bar__action .btn {
        width: 100%;
    }

    .data-table th,
    .data-table td {
        padding-right: 14px;
        padding-left: 14px;
    }
}


/*** Dashboard board ***/
/*
 * The dashboard rebuilt to follow resources/views_old/"blupace-hiring (4) 1.html".
 *
 * The reference ships its own palette, type scale and radii. None of that is
 * carried over: every colour below is one of this file's existing tokens, the
 * controls are the same .input the rest of the portal uses, and the cards are
 * .admin-card. Only the structures the reference adds — the pipeline stage
 * cards, the list toolbars, the sortable headers and the group headers — are
 * new, and they are built from those tokens so the board reads as part of this
 * portal rather than as a second design.
 *
 * The stage ramp is the one exception worth naming: the reference runs its five
 * stages along a blue-to-green gradient. This portal already has that gradient
 * in --grad, so the four ramp stops below are that gradient's own endpoints
 * (#2C5BA9 → #8FC73E) sampled at even intervals, and the tints are those four
 * at 12% over white. Nothing new enters the palette.
 */
:root {
    /* Five stops now, not four: Offer joined the pipeline between Interviewing
       and Hired, so the gradient is resampled at quarters rather than thirds. */
    --stage-1: #2C5BA9;
    --stage-2: #45768E;
    --stage-3: #5E9174;
    --stage-4: #76AC59;
    --stage-5: #8FC73E;

    --stage-1-tint: #E6EBF5;
    --stage-2-tint: #E9EFF1;
    --stage-3-tint: #ECF2EE;
    --stage-4-tint: #EFF5EB;
    --stage-5-tint: #F2F8E8;

    /* Rejected is off the ramp: an outcome, not a step along it, which is why
       the badge is grey too. */
    --stage-0: var(--muted);
    --stage-0-tint: #F1F3F6;

    /* "No movement" — a warning, but a quieter one than a destructive action. */
    --warn-bg: rgba(234, 88, 12, .13);
    --warn-fg: #9A3412;
}


/*** Dashboard — recruiter chip (page header, top right) ***/
/*
 * Whose board this is, kept out of the filter bar below: it changes whose work
 * you are looking at, where the others narrow what is shown.
 *
 * Styled as a chip rather than a labelled select so it does not read as a fourth
 * filter — the same distinction the reference draws by putting it in the header
 * beside the page title. The select inside is deliberately borderless and sits on
 * the chip's own surface; the chip carries the border.
 */
.header-scope {
    display: flex;
    align-items: center;
    gap: 11px;
    margin: 0;
    padding: 8px 14px 9px 10px;
    background: var(--paper);
    border: 1px solid var(--line);
    border-radius: var(--r);
    box-shadow: var(--shadow-sm);
}

/* No hover state on purpose. The chip is not itself a control — the select inside
   it is, and that already shows a pointer cursor. Tinting the border on hover
   made the whole chip look clickable and read as a stray blue outline. */

.header-scope__av {
    display: grid;
    place-items: center;
    flex-shrink: 0;
    width: 34px;
    height: 34px;
    border-radius: 50%;
    background: var(--grad);
    color: #FFFFFF;
    font-size: 11.5px;
    font-weight: 800;
    letter-spacing: .02em;
    text-transform: uppercase;
}

.header-scope__body {
    display: flex;
    flex-direction: column;
    min-width: 0;
    line-height: 1.3;
}

.header-scope__cap {
    font-size: 10px;
    font-weight: 700;
    letter-spacing: .09em;
    text-transform: uppercase;
    color: var(--muted);
}

/* Not .input: this one is transparent and unbordered, so the chip reads as one
   control. The chevron is the same data URI .input uses, drawn hard right rather
   than inset 14px, because there is no border to sit inside. */
.header-scope__select {
    -webkit-appearance: none;
    -moz-appearance: none;
    appearance: none;
    max-width: 190px;
    padding: 1px 18px 0 0;
    border: 0;
    background-color: transparent;
    background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%235A6A7A' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M2 5l6 6 6-6'/%3e%3c/svg%3e");
    background-repeat: no-repeat;
    background-position: right center;
    background-size: 11px 8px;
    font-family: inherit;
    font-size: 14.5px;
    font-weight: 700;
    color: var(--navy);
    text-overflow: ellipsis;
    cursor: pointer;
}

/*
 * No ring on this one, by request.
 *
 * :focus-visible was tried first and did not help: a <select> takes keyboard
 * input, so browsers match :focus-visible on a plain mouse click too, and the
 * blue outline still appeared the instant the chip was touched. Both states are
 * therefore cleared outright.
 *
 * The cost is that there is now no visible indication when this control holds
 * focus, so a keyboard user tabbing through the header cannot see where they are.
 * Every other control in the portal keeps its focus treatment; this is the one
 * exception.
 */
.header-scope__select:focus,
.header-scope__select:focus-visible {
    outline: none;
    box-shadow: none;
}


/*** Dashboard — scope bar ***/
/*
 * Recruiter, location, period and the no-movement threshold: what the whole
 * board is looking at. Same card treatment as .filter-bar--grid on the Applicant
 * Inbox, but auto-fitting rather than a fixed 2fr + 3×1fr, because the two date
 * inputs appear only for a custom period and a fixed grid would leave a hole.
 */
.dash-scope {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(170px, 1fr));
    align-items: end;
    gap: 14px 16px;
    margin-bottom: 20px;
    padding: 18px 20px;
    background: var(--paper);
    border: 1px solid var(--line);
    border-radius: var(--r);
    box-shadow: var(--shadow-sm);
}

.dash-scope__field {
    display: block;
    min-width: 0;
    margin: 0;
}

/* The caption is not decoration: "USA" and "Last 90 days" are unreadable as
   filters without it, and the reference labels every control for the same
   reason. */
.dash-scope__cap {
    display: block;
    margin-bottom: 6px;
    font-size: 11px;
    font-weight: 700;
    letter-spacing: .07em;
    text-transform: uppercase;
    color: var(--muted);
}

/* Shared height with the rest of the portal's filter rows. */
.dash-scope .input {
    height: var(--control-h);
    padding-top: 0;
    padding-bottom: 0;
    font-size: 14px;
}

/* A date whose range is backwards. background-color, never the shorthand — the
   shorthand would wipe the select chevron on the controls beside it. */
.dash-scope .input.is-bad {
    border-color: #B42318;
    background-color: #FDF2F2;
}

.dash-scope__warn {
    grid-column: 1 / -1;
    margin: 0;
    padding: 10px 14px;
    border-radius: var(--r-sm);
    background: #FDF2F2;
    color: #B42318;
    font-size: 13px;
    font-weight: 600;
}

/* Clears filters rather than gathering them, so it is a link and not a submit.
   Bottom-aligned with the controls beside it by the grid's align-items:end. */
.dash-scope__reset {
    align-self: end;
    height: var(--control-h);
    display: inline-flex;
    align-items: center;
    font-size: 14px;
    font-weight: 600;
    color: var(--muted);
    text-decoration: none;
}

.dash-scope__reset:hover {
    color: var(--navy);
    text-decoration: underline;
}


/*** Dashboard — banner ***/
/* One banner, one action: it only sets the Status control on the Postings list,
   so the two can never disagree about what is being shown. */
.dash-note {
    display: flex;
    align-items: center;
    gap: 12px;
    flex-wrap: wrap;
    margin-bottom: 20px;
    padding: 13px 18px;
    border: 1px solid rgba(234, 88, 12, .25);
    border-radius: var(--r);
    background: var(--warn-bg);
    color: var(--warn-fg);
    font-size: 14px;
}

.dash-note b {
    font-weight: 700;
}

.dash-note__text {
    flex: 1 1 auto;
    min-width: 0;
}

.dash-note__action {
    flex-shrink: 0;
    padding: 7px 14px;
    border: 1px solid rgba(234, 88, 12, .3);
    border-radius: var(--r-sm);
    background: rgba(255, 255, 255, .65);
    color: var(--warn-fg);
    font-size: 13px;
    font-weight: 700;
    text-decoration: none;
}

.dash-note__action:hover {
    background: var(--paper);
    color: var(--warn-fg);
    text-decoration: none;
}


/*** Dashboard — headline numbers ***/
/* Three cards rather than the four the previous dashboard had, so the grid needs
   its own column count. .stat-card itself is unchanged. */
.stat-grid--3 {
    margin-bottom: 20px;
}

@media (min-width: 768px) {
    .stat-grid--3 {
        grid-template-columns: repeat(3, 1fr);
    }
}

@media (min-width: 1200px) {
    .stat-grid--3 {
        grid-template-columns: repeat(3, 1fr);
    }
}

/* The sub-line under a headline number: what the number is made of. */
.stat-card__note {
    margin-top: 8px;
    font-size: 12.5px;
    color: var(--muted);
}

.stat-card__note b {
    font-weight: 700;
    color: var(--navy);
}


/*** Dashboard — cards ***/
/* Pipeline, Postings and Applicants each sit in their own .admin-card, stacked
   with the same 20px the rest of the page uses. */
.dash-block {
    margin-bottom: 20px;
}

/* The right-hand half of a .card-head: what the card is currently showing, or
   what selecting a row in it will do. */
.card-head__hint {
    font-size: 13px;
    color: var(--muted);
    text-align: right;
}


/*** Dashboard — pipeline ***/
.stage-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
    gap: 12px;
    padding: 20px;
}

/* Each card is a link that toggles the stage filter, so it needs no JS to work
   and can be opened in a new tab like anything else. The 3px top rule is the
   stage's own ramp colour — the only place the stage colour appears at full
   strength, which is what keeps five tinted cards from shouting. */
.stage-card {
    position: relative;
    display: block;
    overflow: hidden;
    padding: 16px 16px 15px;
    border: 1.5px solid transparent;
    border-radius: var(--r-sm);
    background: var(--stage-tint, var(--bg));
    color: var(--navy);
    text-decoration: none;
    transition: border-color .18s, opacity .18s, transform .18s;
}

.stage-card::before {
    content: "";
    position: absolute;
    top: 0;
    right: 0;
    left: 0;
    height: 3px;
    background: var(--stage, var(--muted));
}

.stage-card:hover {
    border-color: var(--stage, var(--line));
    color: var(--navy);
    text-decoration: none;
    transform: translateY(-1px);
}

.stage-card__name {
    display: block;
    font-size: 13px;
    font-weight: 600;
    color: var(--muted);
}

.stage-card__num {
    display: block;
    margin-top: 4px;
    font-size: 28px;
    font-weight: 800;
    line-height: 1.15;
    letter-spacing: -.02em;
    color: var(--navy);
}

/* The picked stage keeps full contrast and the others drop back, so the pick
   reads as a choice made rather than as five numbers that happen to differ. */
.stage-card.is-on {
    border-color: var(--stage, var(--line));
    box-shadow: inset 0 0 0 1px var(--stage, var(--line));
}

.stage-grid.is-picked .stage-card:not(.is-on) {
    opacity: .45;
}

.stage-card--r0 { --stage: var(--stage-0); --stage-tint: var(--stage-0-tint); }
.stage-card--r1 { --stage: var(--stage-1); --stage-tint: var(--stage-1-tint); }
.stage-card--r2 { --stage: var(--stage-2); --stage-tint: var(--stage-2-tint); }
.stage-card--r3 { --stage: var(--stage-3); --stage-tint: var(--stage-3-tint); }
.stage-card--r4 { --stage: var(--stage-4); --stage-tint: var(--stage-4-tint); }
.stage-card--r5 { --stage: var(--stage-5); --stage-tint: var(--stage-5-tint); }

/* Needs attention is not a step along the ramp — it is a warning about one — so
   it takes the same amber the Postings list uses for "No movement". Same idea,
   one level down, so the same colour. */
.stage-card--rwarn { --stage: var(--warn-fg); --stage-tint: var(--warn-bg); }


/*** Dashboard — list toolbars ***/
/*
 * A list's own filters, inside its card and above its table. Distinct from
 * .dash-scope on purpose: the scope narrows the whole board, a toolbar narrows
 * one list, and the two would be indistinguishable if they looked the same.
 */
.card-tools {
    display: flex;
    align-items: flex-end;
    gap: 12px;
    flex-wrap: wrap;
    margin: 0;
    padding: 16px 20px 18px;
    border-bottom: 1px solid var(--line);
}

.card-tools .input {
    width: auto;
    min-width: 165px;
    max-width: 230px;
    height: 40px;
    padding-top: 0;
    padding-bottom: 0;
    background-color: var(--paper);
    font-size: 13.5px;
}

/* Pushes the count and the clear link to the far end of the row. */
.card-tools__spacer {
    flex: 1 1 auto;
}

.card-tools__count {
    padding-bottom: 10px;
    font-size: 12.5px;
    color: var(--muted);
    white-space: nowrap;
}

.card-tools__count b {
    font-weight: 700;
    color: var(--navy);
}

.card-tools__clear {
    padding-bottom: 10px;
    font-size: 13px;
    font-weight: 700;
    color: var(--blue);
    text-decoration: none;
    white-space: nowrap;
}

.card-tools__clear:hover {
    color: var(--blue);
    text-decoration: underline;
}


/*** Dashboard — table extras ***/
/* Sortable header. The <a> carries the whole cell so the hit area is the header,
   not just its text. */
/*
 * The link fills the cell, so the cell gives up its own padding — otherwise the
 * two stack and the heading sits 20px right of the values beneath it.
 *
 * `.data-table th.data-table__sort`, not `.data-table__sort` alone: the base
 * rule is `.data-table th`, which carries a type selector and therefore outranks
 * a lone class. Written the short way this declaration simply never applied, and
 * every sortable heading was indented by exactly its own padding.
 */
.data-table th.data-table__sort {
    padding: 0;
}

.data-table__sort a {
    display: block;
    padding: 14px 20px;
    color: inherit;
    text-decoration: none;
}

.data-table__sort a:hover {
    color: var(--navy);
    text-decoration: none;
}

.data-table__sort.is-on {
    color: var(--navy);
}

/* Hidden until the column is the one being sorted on, so four idle arrows do
   not compete with the one that means something. */
.data-table__arrow {
    margin-left: 6px;
    font-size: 9px;
    vertical-align: 1px;
    opacity: 0;
}

.data-table__sort.is-on .data-table__arrow {
    opacity: .9;
}

/*
 * The applicant count reads tabular and a little heavier than the rest of the
 * row, but left-aligned like every other column — no right-aligned exception
 * for a glance down the heading row to trip over. Both the class on the <th>
 * and the text-align rule that used to right-align this column are gone with
 * it; the heading now falls through to .data-table th's own left alignment,
 * same as the rest.
 */
.data-table td.data-table__num {
    font-variant-numeric: tabular-nums;
    font-weight: 600;
}

/* Secondary line inside a cell: the posting's category and location, the date an
   application came in. */
.cell-sub {
    display: block;
    margin-top: 3px;
    font-size: 12px;
    font-weight: 400;
    color: var(--muted);
}

.cell-link {
    color: var(--navy);
    font-weight: 600;
    text-decoration: none;
}

.cell-link:hover {
    color: var(--blue);
    text-decoration: none;
}

/* Marks a record touched since it was submitted. A dot rather than a word, so
   the column width is unchanged whether or not any row carries one. */
.cell-dot {
    display: inline-block;
    width: 7px;
    height: 7px;
    margin-left: 6px;
    border-radius: 50%;
    background: var(--blue);
    box-shadow: 0 0 0 3px rgba(0, 150, 215, .14);
    vertical-align: 2px;
}

/* Selecting a posting row focuses the applicant list on it. The whole row is a
   target, so it takes the pointer the title link already had. */
.data-table--pick tbody tr {
    cursor: pointer;
}

.data-table--pick tbody tr.is-selected td {
    background: var(--stage-1-tint);
}

.data-table--pick tbody tr.is-selected td:first-child {
    box-shadow: inset 3px 0 0 var(--stage-1);
}

/* Recruiter cell: initials beside the name, as the reference has it. Built from
   the name because created_by holds a name, not a user id — there is no avatar
   to load. */
.owner-chip {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    font-size: 14px;
    white-space: nowrap;
}

.owner-chip__av {
    display: grid;
    place-items: center;
    flex-shrink: 0;
    width: 26px;
    height: 26px;
    border-radius: 50%;
    background: var(--grad);
    color: #FFFFFF;
    font-size: 10px;
    font-weight: 800;
    letter-spacing: .02em;
    text-transform: uppercase;
}


/*** Dashboard — grouped postings ***/
/*
 * Group by puts each bucket in its own <tbody>, so collapsing one hides a single
 * element and the columns keep their widths when it opens again.
 */
.data-table__group td {
    padding: 0;
    background: var(--bg);
    border-top: 1px solid var(--line);
}

/* The header of the first group needs no rule above it — the table head is
   already there. :nth-of-type, not :first-child: the <thead> is the table's
   first child, so :first-child on a <tbody> never matches. */
.data-table__group:nth-of-type(1) td {
    border-top: 0;
}

.group-head {
    display: flex;
    align-items: center;
    gap: 12px;
    width: 100%;
    padding: 10px 20px;
    border: 0;
    background: none;
    text-align: left;
    cursor: pointer;
}

.group-head:hover {
    background: rgba(0, 150, 215, .06);
}

.group-head__chev {
    flex-shrink: 0;
    color: var(--muted);
    transition: transform .18s;
}

.group-head.is-closed .group-head__chev {
    transform: rotate(-90deg);
}

.group-head__name {
    font-size: 13px;
    font-weight: 800;
    color: var(--navy);
}

.group-head__meta {
    font-size: 12px;
    color: var(--muted);
}

/* Relative to the busiest group, so the bars compare with each other rather
   than against an absolute scale. */
.group-head__bar {
    flex: 1 1 auto;
    max-width: 120px;
    height: 5px;
    overflow: hidden;
    border-radius: 100px;
    background: var(--line);
}

.group-head__bar i {
    display: block;
    height: 100%;
    border-radius: 100px;
    background: var(--grad);
}

/* .data-table drops the border on the last row of a tbody, which with one tbody
   per group would erase the line between the last row of a group and the next
   group's header. Restored here, then dropped again on the final group only. */
.data-table--pick tbody tr:last-child td {
    border-bottom: 1px solid var(--line);
}

.data-table--pick tbody:last-child tr:last-child td {
    border-bottom: none;
}


/*** Dashboard — long lists ***/
/*
 * Five rows, then the list scrolls inside its own card instead of pushing the
 * cards below it off the screen. The row count is HomeController::
 * ROWS_BEFORE_SCROLL, which decides which lists get this class; the height below
 * has to agree with it.
 *
 * Both dashboard tables put a title over a .cell-sub in their first column, so a
 * row is the 30px of td padding plus two lines at the inherited 1.5 line-height
 * — 14.5px and 12px, with the sub's 3px margin. That is ~73px, and the header is
 * ~46px on the same arithmetic. Held in custom properties rather than inlined so
 * the sum stays legible and a padding change here has one place to be corrected.
 *
 * The height is a slight over-estimate on purpose: too small clips the fifth row,
 * too large shows a sliver of the sixth, and a sliver reads as "there is more"
 * rather than as a mistake.
 *
 * The header is pinned as it scrolls. .data-table th already carries the pale
 * --bg fill, so the rows do not show through it; the bottom rule is redrawn as
 * an inset shadow because a collapsed border is painted with the table, not with
 * the sticky cell, and would be left behind.
 */
/*
 * The height here is only a fallback. The dashboard measures the real rows on
 * load and sets an exact max-height, because a row is not a fixed height: a
 * posting's second line wraps or does not depending on how wide its column ends
 * up, a flagged row carries an extra line under its badge, and everything shifts
 * again when the webfont replaces the fallback face.
 *
 * So --row-h is deliberately generous rather than accurate. Too small clips the
 * last row, which reads as a bug; too large shows a sliver of the next one for
 * the moment before the measurement lands, which reads as "there is more" — and
 * is what the scroll is saying anyway.
 */
.table-scroll--tall {
    --row-h: 92px;
    --head-h: 46px;
    --rows: 5;

    max-height: calc(var(--head-h) + var(--row-h) * var(--rows));
    overflow: auto;
}

/* Postings shows one row fewer. It sits above the pipeline and the applicant
   list, so every row it shows pushes both further down the page.

   This has to agree with HomeController::POSTING_ROWS_BEFORE_SCROLL, which
   decides when the list starts scrolling at all: a height for five rows on a
   list that scrolls past four would leave a permanently empty strip under the
   last row. */
.table-scroll--rows-4 {
    --rows: 4;
}

.table-scroll--tall thead th {
    position: sticky;
    top: 0;
    z-index: 2;
    box-shadow: inset 0 -1px 0 var(--line);
}


/*** Dashboard — empty lists ***/
/* Says which filter emptied the list and offers the way back out of it, rather
   than leaving a blank card. */
.table-empty {
    padding: 44px 22px;
    text-align: center;
}

.table-empty b {
    display: block;
    margin-bottom: 6px;
    font-size: 15px;
    font-weight: 700;
    color: var(--navy);
}

.table-empty p {
    margin: 0 0 16px;
    font-size: 13.5px;
    color: var(--muted);
}


/*** Dashboard — "No movement" badge ***/
/*
 * A fourth posting status, derived rather than stored: an Active posting nothing
 * has moved on for the threshold set in the scope bar.
 *
 * Deliberately not amber — .badge--draft already owns amber, and at pill size a
 * second amber would read as the same state. This is the warmer, deeper orange
 * one step along, so the Status column separates Open / No movement / Draft /
 * Closed at a glance.
 */
.badge--stalled {
    background: var(--warn-bg);
    color: var(--warn-fg);
}


/*** Dashboard — the two new applicant statuses ***/
/*
 * Offer is a real stage, added to job_applicant_statuses between Interviewing
 * and Hired. It sits on the ramp's fourth stop, so the badge colour matches the
 * pipeline card above it.
 */
.badge--offer {
    background: rgba(118, 172, 89, .20);
    color: #4A6E33;
}

/*
 * Needs attention is derived, never stored: an application still in Applied that
 * nothing has moved for the threshold set in the scope bar.
 *
 * Same amber as .badge--stalled, because it is the same idea one level down — a
 * posting nobody has worked, and an applicant nobody has answered. Reusing the
 * colour is what makes the two read as one concept rather than as two unrelated
 * warnings that happen to share a screen.
 */
.badge--attention {
    background: var(--warn-bg);
    color: var(--warn-fg);
}


/*** Dashboard — responsive ***/
@media (max-width: 767.98px) {
    /* Both toolbars go one control per row; the count and the clear link share
       the row below them. */
    .card-tools {
        align-items: stretch;
        flex-direction: column;
    }

    .card-tools .input {
        width: 100%;
        min-width: 0;
        max-width: none;
    }

    .card-tools__count,
    .card-tools__clear {
        padding-bottom: 0;
    }

    .card-head {
        align-items: flex-start;
        flex-direction: column;
        gap: 4px;
    }

    .card-head__hint {
        text-align: left;
    }
}

@media (max-width: 575.98px) {
    /* .admin-header__actions already goes full width at this breakpoint, so the
       chip fills it rather than sitting as a stub under the title. */
    .header-scope {
        width: 100%;
    }

    .header-scope__body {
        flex: 1 1 auto;
    }

    .header-scope__select {
        max-width: none;
        width: 100%;
    }

    .dash-scope {
        grid-template-columns: 1fr;
    }

    .stage-grid {
        grid-template-columns: repeat(2, minmax(0, 1fr));
        padding: 16px;
    }

    .dash-note__action {
        width: 100%;
        text-align: center;
    }
}


/*** Applicant drawer ***/
/*
 * One applicant, in a panel sliding in from the right — the reference's
 * applicant window (resources/views_old/"blupace-hiring (4) 1.html" → #drawer).
 *
 * Unlike everything above, this block follows the reference's own design rather
 * than the portal's: its palette, its type, its radii and its spacing. The rest
 * of the portal is deliberately untouched, so the drawer is the one place the
 * two visual languages meet.
 *
 * Every token is namespaced --rf-* and scoped to the drawer. Scoping the
 * reference's own names (--navy, --line, --muted …) here instead would have
 * silently re-coloured any portal component that happened to be used inside the
 * panel, since those names carry different values eight hundred lines up. The
 * drawer therefore brings its own controls (.rf-inp, .rf-btn, .rf-tag) rather
 * than borrowing .input and .btn.
 *
 * The ramp: one blue-to-green run cut into five stops, one per stage, exactly as
 * the reference has it.
 */
.drawer,
.drawer-scrim {
    --rf-navy: #1E2636;
    --rf-lime: #BBD155;

    --rf-s1: #425CA3;
    --rf-s2: #577490;
    --rf-s3: #6C8D7E;
    --rf-s4: #82A66B;
    --rf-s5: #97BE58;

    --rf-t1: #EDF0F7;
    --rf-t3: #F1F5F3;

    --rf-page: #F3F6FA;
    --rf-surface: #FFFFFF;
    --rf-line: #E7EDF4;
    --rf-line-2: #F0F4F8;
    --rf-ink: #171C26;
    --rf-text: #2C3543;
    --rf-muted: #6E7A8A;
    --rf-faint: #9AA6B4;

    --rf-stop-bg: #FAF1F0;
    --rf-stop-fg: #96453A;
    --rf-calm-bg: #F1F3F6;

    --rf-ui: "Plus Jakarta Sans", system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
    --rf-display: "Fraunces", Georgia, "Times New Roman", serif;

    --rf-r-lg: 16px;
    --rf-r: 12px;
    --rf-r-sm: 9px;

    /* The reference's own chevron, drawn in its --muted rather than the
       portal's, so the selects inside the panel match the panel. */
    --rf-chev: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'><path d='M2.6 4.6 6 8l3.4-3.4' fill='none' stroke='%236E7A8A' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/></svg>");
}

.drawer-scrim {
    position: fixed;
    inset: 0;
    z-index: 1040;
    background: rgba(23, 28, 38, .34);
}

.drawer-scrim[hidden] {
    display: none;
}

.drawer {
    position: fixed;
    top: 0;
    right: 0;
    bottom: 0;
    z-index: 1041;
    display: none;
    flex-direction: column;
    width: min(700px, 100%);
    margin: 0;
    background: var(--rf-surface);
    box-shadow: -40px 0 70px -40px rgba(23, 28, 38, .45);
    font-family: var(--rf-ui);
    font-size: 14px;
    line-height: 1.55;
    color: var(--rf-text);
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
}

.drawer.is-open {
    display: flex;
}

@media (prefers-reduced-motion: no-preference) {
    .drawer.is-open {
        animation: drawer-in .3s cubic-bezier(.32, .72, 0, 1) both;
    }
}

@keyframes drawer-in {
    from { transform: translateX(102%); }
    to   { transform: none; }
}

/*
 * Fraunces has a SOFT axis, and turning it up literally rounds the terminals —
 * the whole reason it is here rather than a default serif. font-synthesis is off
 * so a missing weight is never faked into a smeared bold.
 */
.drawer .rf-display {
    font-family: var(--rf-display);
    font-variation-settings: 'SOFT' 40, 'WONK' 0;
    font-optical-sizing: auto;
    font-synthesis-weight: none;
    letter-spacing: -.015em;
}

/* Header and footer hold still; only the body scrolls, so who you are looking at
   and the Save button are never scrolled away from. */
.dw-top {
    flex: none;
    padding: 20px 26px 0;
    border-bottom: 1px solid var(--rf-line);
}

.dw-nav {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    margin-bottom: 14px;
}

.dw-pos {
    display: flex;
    align-items: center;
    gap: 6px;
}

.dw-count {
    padding-right: 4px;
    font-size: 12px;
    color: var(--rf-faint);
}

.dw-icon {
    display: grid;
    place-items: center;
    width: 32px;
    height: 32px;
    padding: 0;
    border: 1px solid var(--rf-line);
    border-radius: var(--rf-r-sm);
    background: var(--rf-surface);
    color: var(--rf-muted);
    cursor: pointer;
}

.dw-icon:hover:not(:disabled) {
    border-color: #D3DCE6;
    background: #FAFCFE;
    color: var(--rf-ink);
}

.dw-icon:disabled {
    opacity: .35;
    cursor: default;
}

.dw-icon svg {
    width: 15px;
    height: 15px;
}

.dw-id {
    display: flex;
    align-items: flex-start;
    gap: 14px;
}

/* The avatar carries the stage colour, which is the reference's one flash of
   full-strength ramp in the header. */
.dw-av {
    display: grid;
    place-items: center;
    flex: none;
    width: 48px;
    height: 48px;
    border-radius: 50%;
    background: var(--rf-stage, var(--rf-s3));
    color: #FFFFFF;
    font-size: 15px;
    font-weight: 700;
    letter-spacing: .02em;
    text-transform: uppercase;
}

.dw-name {
    margin: 0;
    font-size: 21px;
    font-weight: 500;
    color: var(--rf-ink);
}

.dw-meta {
    margin: 3px 0 0;
    font-size: 13px;
    color: var(--rf-muted);
}

.dw-actionrow {
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
    margin-top: 14px;
}

.dw-owner {
    font-size: 12.5px;
    color: var(--rf-muted);
}

/* The stage, as the reference draws it: a tinted pill with a full-strength dot,
   rather than the portal's solid badge. */
.rf-tag {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    padding: 4px 12px;
    border-radius: 999px;
    background: var(--rf-tint, var(--rf-calm-bg));
    color: var(--rf-text);
    font-size: 12.5px;
    font-weight: 600;
    white-space: nowrap;
}

.rf-tag__dot {
    flex: none;
    width: 7px;
    height: 7px;
    border-radius: 50%;
    background: var(--rf-stage, var(--rf-muted));
}

/* Stage colours. Applied through to Hired run the ramp; Rejected is an outcome
   rather than a step, and Needs Attention is a warning about one, so both sit
   off it. */
.rf-stage-1 { --rf-stage: var(--rf-s1); --rf-tint: var(--rf-t1); }
.rf-stage-2 { --rf-stage: var(--rf-s2); --rf-tint: #EFF3F6; }
.rf-stage-3 { --rf-stage: var(--rf-s3); --rf-tint: var(--rf-t3); }
.rf-stage-6 { --rf-stage: var(--rf-s4); --rf-tint: #F3F7EF; }
.rf-stage-4 { --rf-stage: var(--rf-s5); --rf-tint: #F6F9ED; }
.rf-stage-5 { --rf-stage: #96453A;      --rf-tint: var(--rf-stop-bg); }
.rf-stage-7 { --rf-stage: #8B6220;      --rf-tint: #FBF5E9; }

.dw-tabs {
    display: flex;
    gap: 22px;
    margin-top: 16px;
}

.dw-tabs button {
    margin-bottom: -1px;
    padding: 0 0 11px;
    border: 0;
    border-bottom: 2px solid transparent;
    background: none;
    color: var(--rf-muted);
    font-family: inherit;
    font-size: 13.5px;
    font-weight: 500;
    cursor: pointer;
}

.dw-tabs button:hover {
    color: var(--rf-ink);
}

.dw-tabs button[aria-selected="true"] {
    border-bottom-color: var(--rf-s3);
    color: var(--rf-ink);
    font-weight: 600;
}

.dw-tabs__n {
    color: var(--rf-faint);
    font-weight: 500;
}

.dw-body {
    flex: 1;
    overflow-y: auto;
    padding: 4px 26px 26px;
}

.dw-foot {
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
    flex: none;
    padding: 14px 26px;
    border-top: 1px solid var(--rf-line);
    background: var(--rf-surface);
}

.dw-foot__spacer {
    flex: 1 1 auto;
}

/* The drawer's own buttons. Not .btn: the portal's are 46px tall with a gradient
   primary, which would tower over a panel built on 9px radii. */
.rf-btn {
    padding: 9px 16px;
    border: 1px solid var(--rf-line);
    border-radius: var(--rf-r-sm);
    background: var(--rf-surface);
    color: var(--rf-text);
    font-family: inherit;
    font-size: 13.5px;
    font-weight: 600;
    cursor: pointer;
}

.rf-btn:hover {
    border-color: #D3DCE6;
    background: #FAFCFE;
    color: var(--rf-text);
    text-decoration: none;
}

.rf-btn--go {
    border-color: var(--rf-navy);
    background: var(--rf-navy);
    color: #FFFFFF;
}

.rf-btn--go:hover {
    border-color: #151C29;
    background: #151C29;
    color: #FFFFFF;
}

.rf-btn--quiet {
    border-color: transparent;
    color: var(--rf-muted);
}

.rf-btn--quiet:hover {
    border-color: transparent;
    background: var(--rf-page);
    color: var(--rf-ink);
}

/* A section heading in the body: a signpost, not a title competing with the
   applicant's name above. */
.dw-sec {
    padding: 22px 0 4px;
    font-size: 10.5px;
    font-weight: 700;
    letter-spacing: .09em;
    text-transform: uppercase;
    color: var(--rf-faint);
}

/* The job applied for, on the reference's navy with its lime eyebrow — the one
   deliberately loud block, because it is the context everything else is read
   against. */
.dw-postcard {
    margin-top: 4px;
    padding: 15px 17px;
    border-radius: var(--rf-r);
    background: var(--rf-navy);
}

.dw-postcard__eyebrow {
    display: block;
    font-size: 9.5px;
    font-weight: 700;
    letter-spacing: .12em;
    text-transform: uppercase;
    color: var(--rf-lime);
}

.dw-postcard h3 {
    margin: 5px 0 0;
    font-size: 16px;
    font-weight: 600;
    color: #FFFFFF;
}

.dw-postcard__meta {
    margin: 4px 0 0;
    font-size: 12px;
    color: #9AA3B2;
}

/* Label beside value, on the reference's 170px column, so values line up down
   the panel and read as a column rather than being hunted for. */
.dw-row {
    display: grid;
    grid-template-columns: 170px minmax(0, 1fr);
    gap: 14px;
    align-items: center;
    padding: 11px 0;
    border-bottom: 1px solid var(--rf-line-2);
}

.dw-row:last-child {
    border-bottom: 0;
}

.dw-key {
    font-size: 12.5px;
    color: var(--rf-muted);
}

.dw-val {
    font-size: 13.5px;
    font-weight: 500;
    color: var(--rf-text);
    word-break: break-word;
}

.dw-val a {
    color: var(--rf-s1);
    text-decoration: none;
}

.dw-val a:hover {
    text-decoration: underline;
}

.dw-val--none {
    color: var(--rf-faint);
    font-weight: 400;
}

/*
 * Read and write states of the same field. Both are rendered and only one shows,
 * so the input keeps what was typed when the tab changes, and a rejected save
 * comes back with the values still in place.
 */
.dw-edit {
    display: none;
}

.drawer.is-editing .dw-row [data-drawer-read] {
    display: none;
}

.drawer.is-editing .dw-edit {
    display: block;
}

/* Tighter rows while editing, and no rules between them: the inputs already
   separate one field from the next. */
.drawer.is-editing .dw-row {
    padding: 7px 0;
    border-bottom-color: transparent;
}

.rf-inp {
    width: 100%;
    padding: 8px 11px;
    border: 1px solid var(--rf-line);
    border-radius: var(--rf-r-sm);
    background: var(--rf-surface);
    color: var(--rf-text);
    font-family: inherit;
    font-size: 13.5px;
}

.rf-inp:hover {
    border-color: #D3DCE6;
}

.rf-inp:focus {
    outline: 2px solid var(--rf-s1);
    outline-offset: 2px;
    border-radius: 6px;
}

.rf-inp.is-bad {
    border-color: #C08578;
    background: #FEFAF9;
}

.rf-inp--area {
    min-height: 82px;
    line-height: 1.55;
    resize: vertical;
}


/* The select draws the reference's chevron. background-color, never the
   shorthand, or the chevron would be wiped on hover and focus. */
select.rf-inp {
    -webkit-appearance: none;
    -moz-appearance: none;
    appearance: none;
    padding-right: 32px;
    background-image: var(--rf-chev);
    background-repeat: no-repeat;
    background-position: right 11px center;
    font-weight: 500;
    cursor: pointer;
}

.dw-err {
    display: block;
    margin-top: 5px;
    font-size: 11.5px;
    color: var(--rf-stop-fg);
}

/* The CV, as a file rather than as a link in a sentence. */
.dw-file {
    display: flex;
    align-items: center;
    gap: 12px;
    margin-top: 12px;
    padding: 12px 14px;
    border: 1px solid var(--rf-line);
    border-radius: var(--rf-r);
    background: var(--rf-page);
}

.dw-file__icon {
    display: grid;
    place-items: center;
    flex: none;
    width: 32px;
    height: 32px;
    border-radius: var(--rf-r-sm);
    background: #EFF3F6;
    color: var(--rf-s2);
}

.dw-file__icon svg {
    width: 15px;
    height: 15px;
}

.dw-file__text {
    flex: 1 1 auto;
    min-width: 0;
}

.dw-file__name {
    display: block;
    font-size: 13px;
    font-weight: 600;
    color: var(--rf-ink);
    overflow-wrap: anywhere;
}

.dw-file__sub {
    display: block;
    font-size: 11.5px;
    color: var(--rf-faint);
}

/* Activity tab */
.dw-composer {
    margin: 18px 0 6px;
    padding: 12px;
    border: 1px solid var(--rf-line);
    border-radius: var(--rf-r);
    background: var(--rf-page);
}

.dw-composer label {
    display: block;
    margin-bottom: 7px;
    font-size: 12.5px;
    font-weight: 600;
    color: var(--rf-text);
}

.dw-composer__hint {
    margin: 9px 0 0;
    font-size: 11.5px;
    color: var(--rf-faint);
}

.dw-event {
    padding: 12px 0;
    border-bottom: 1px solid var(--rf-line-2);
}

.dw-event:last-child {
    border-bottom: 0;
}

.dw-event__when {
    margin: 0;
    font-size: 11.5px;
    color: var(--rf-faint);
}

.dw-event__body {
    margin: 4px 0 0;
    font-size: 13.5px;
    color: var(--rf-text);
    white-space: pre-wrap;
}

/* A typed note is somebody's words, so it gets the reference's green-tinted
   card. Recorded changes are the machine's account and stay plain. */
.dw-event--note .dw-event__body {
    margin-top: 8px;
    padding: 11px 13px;
    border: 1px solid #E3ECE6;
    border-radius: var(--rf-r);
    background: var(--rf-t3);
}

.dw-event--system .dw-event__body {
    color: var(--rf-muted);
    font-size: 13px;
}

.dw-empty {
    margin: 10px 0 0;
    font-size: 13px;
    color: var(--rf-faint);
}

@media (max-width: 575.98px) {
    .dw-top,
    .dw-body,
    .dw-foot {
        padding-right: 16px;
        padding-left: 16px;
    }

    /* Label above value: two columns in a phone's width leaves the value too
       narrow to read. */
    .dw-row {
        grid-template-columns: minmax(0, 1fr);
        gap: 5px;
        align-items: start;
    }

    .dw-av {
        width: 40px;
        height: 40px;
        font-size: 13px;
    }

    .dw-name {
        font-size: 18px;
    }
}

/* Confirmation of a save, inside the drawer. The page's own alert is behind the
   panel, so without this a successful save from in here would look like nothing
   happened. */
.dw-saved {
    margin: 14px 0 0;
    padding: 10px 14px;
    border: 1px solid #E0EBD3;
    border-radius: var(--rf-r-sm);
    background: #F2F7EC;
    color: #527A26;
    font-size: 12.5px;
    font-weight: 600;
}

/* A sub-heading inside a section — the hub list's own title, with the note the
   careers form shows under it. */
.dw-sec--sub {
    padding-top: 16px;
}

.dw-note {
    display: block;
    margin-top: 3px;
    font-size: 11.5px;
    font-weight: 400;
    letter-spacing: 0;
    text-transform: none;
    color: var(--rf-faint);
}

/* Free text the candidate wrote, so it keeps the line breaks they typed. */
.dw-prose {
    display: block;
    font-weight: 400;
    white-space: pre-wrap;
}

/*
 * A consent box as it was submitted. Read-only on purpose: this records what the
 * applicant agreed to, and a recruiter agreeing on their behalf would make the
 * record worthless. A tick or a cross rather than a disabled checkbox, which
 * browsers grey out until it is hard to tell which way it is set.
 */
.dw-agree {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    margin: 10px 0 0;
    font-size: 12.5px;
    line-height: 1.5;
    color: var(--rf-muted);
}

.dw-agree__mark {
    display: grid;
    place-items: center;
    flex: none;
    width: 17px;
    height: 17px;
    margin-top: 1px;
    border-radius: 5px;
    background: var(--rf-calm-bg);
    color: var(--rf-faint);
    font-size: 11px;
    font-weight: 700;
}

.dw-agree.is-given .dw-agree__mark {
    background: var(--rf-s4);
    color: #FFFFFF;
}


/*** Applicant summary + resume preview modals ***/
/* Subtitle under the Applicant summary modal's title: the count and, when one
   posting is focused, which. */
.applicant-summary__count {
    display: block;
    margin-top: 4px;
    font-size: 13px;
    font-weight: 500;
    color: var(--muted);
}

/*
 * The resume preview modal is edge-to-edge — an iframe filling the whole card,
 * no padding for it to sit inside. .modal-content normally carries the
 * reference's 36px/40px pad for a field form; here that padding would just be
 * blank margin around the one thing the modal exists to show.
 */
.resume-preview .modal-content {
    max-height: 92vh;
    padding: 0;
}

.resume-preview .modal-header {
    padding: 18px 24px;
    margin-bottom: 0;
    border-bottom: 1px solid var(--line);
}

.resume-preview .modal-body {
    height: 78vh;
    padding: 0;
}

.resume-preview iframe {
    width: 100%;
    height: 100%;
    border: 0;
}


/*** Applicant drawer — Move to CV Bank ***/
/*
 * A switch in the drawer's top row that copies the candidate into the CV Bank.
 * One-way: once banked it renders on and disabled, because the entry is a
 * snapshot and taking it again would only duplicate.
 */
.dw-bank {
    display: inline-flex;
    align-items: center;
    gap: 9px;
    margin: 0 auto 0 4px;
    cursor: pointer;
    user-select: none;
}

/* Visually hidden rather than display:none, which would drop it out of the tab
   order and silence it for a screen reader. */
.dw-bank input[type="checkbox"] {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    border: 0;
    overflow: hidden;
    clip: rect(0 0 0 0);
    clip-path: inset(50%);
    white-space: nowrap;
}

.dw-bank__track {
    position: relative;
    flex: none;
    width: 38px;
    height: 21px;
    background-color: var(--rf-line, #D4DDE6);
    border-radius: 999px;
    transition: background-color .15s ease;
}

.dw-bank__track::after {
    content: "";
    position: absolute;
    top: 3px;
    left: 3px;
    width: 15px;
    height: 15px;
    background-color: #fff;
    border-radius: 50%;
    box-shadow: 0 1px 2px rgba(25, 38, 56, .3);
    transition: transform .15s ease;
}

.dw-bank input[type="checkbox"]:checked + .dw-bank__track {
    background-color: #2F7D5B;
}

.dw-bank input[type="checkbox"]:checked + .dw-bank__track::after {
    transform: translateX(17px);
}

.dw-bank input[type="checkbox"]:focus-visible + .dw-bank__track {
    box-shadow: 0 0 0 3px rgba(47, 125, 91, .18);
}

.dw-bank__text {
    font-size: 12.5px;
    font-weight: 600;
    color: var(--rf-muted, #5A6A7A);
    white-space: nowrap;
}

/* Banked already, or nothing to bank: the switch stays readable but stops
   inviting a click. */
.dw-bank input[type="checkbox"]:disabled ~ .dw-bank__text {
    color: var(--rf-muted, #5A6A7A);
}

.dw-bank input[type="checkbox"]:disabled {
    cursor: default;
}

.dw-bank:has(input:disabled) {
    cursor: default;
}

.dw-bank.is-banked .dw-bank__text {
    color: #2F7D5B;
}

/* The switch's companion form carries no controls of its own. */
.dw-bank__form {
    display: none;
}

@media (prefers-reduced-motion: reduce) {
    .dw-bank__track,
    .dw-bank__track::after {
        transition: none;
    }
}

/*** CV Bank ***/
/*
 * The listing's own furniture, per the CV Bank reference: a fuller page header,
 * a two-row filter panel, example searches beneath the box, and a table whose
 * cells stack a value over a quieter second line (city over country, date over
 * "4 days ago").
 *
 * Everything else on the page is the shared vocabulary — .stat-card, .btn--*,
 * .badge, .data-table — so this section only holds what had no equivalent.
 */

/*
 * Page header, per the reference: a larger title, the description held to a
 * readable measure so it breaks into two lines rather than running the width of
 * a wide screen, and two chunkier buttons.
 *
 * Scoped to a modifier rather than changed on .admin-header itself, which the
 * other twelve listings share and which the reference sizes differently.
 */
.admin-header--cvbank {
    align-items: flex-start;
    margin-bottom: 24px;
}

.admin-header--cvbank h2 {
    font-size: 32px;
}

.admin-header--cvbank p {
    max-width: 62ch;
    margin-top: 8px;
    font-size: 15.5px;
    line-height: 1.5;
}

.admin-header--cvbank .admin-header__actions {
    gap: 12px;
    /* Nudges the buttons down onto the title's baseline, the header now being
       top-aligned so the two-line description does not centre them. */
    padding-top: 4px;
}

/* Two-class selectors: the shared rule further up this file pins every header
   button to --control-h, and equal specificity would leave it winning. */
.admin-header--cvbank .btn--ghost,
.admin-header--cvbank .btn--primary {
    height: 50px;
    padding: 0 24px;
    font-size: 15px;
    border-radius: 12px;
}

/* Raised rather than outlined — in the reference this reads as a white card on
   the page's grey, with the border only just visible. */
.admin-header--cvbank .btn--ghost {
    border-color: rgba(212, 221, 230, .9);
    box-shadow: var(--shadow-sm);
}

.admin-header--cvbank .btn--ghost:hover,
.admin-header--cvbank .btn--ghost:focus {
    box-shadow: var(--shadow);
}

/* Search and sort on the first row, the four filters on the second. Declared as
   its own modifier rather than reusing .filter-bar--grid, whose 2fr+3×1fr is a
   single row and would put six controls on one line. */
.cv-filters {
    display: grid;
    gap: 14px;
    margin-bottom: 20px;
    padding: 18px 20px;
    background: var(--paper);
    border: 1px solid var(--line);
    border-radius: var(--r);
    box-shadow: var(--shadow-sm);
}

.cv-filters__row {
    display: grid;
    grid-template-columns: 1fr;
    gap: 12px;
}

@media (min-width: 992px) {
    /* Box, Search, then Sort. auto for the button so it takes only the width of
       its own label rather than a share of the row. */
    .cv-filters__row--search {
        grid-template-columns: 1fr auto 220px;
    }

    /* Sources, Countries, Any Time, then Check Duplicates. auto on the button so
       it takes the width of its own label rather than a quarter of the row —
       the three selects keep equal widths between them. */
    .cv-filters__row--selects {
        grid-template-columns: repeat(3, 1fr) auto;
    }
}

/* Matched to the height the box and the sort control share, so the three line
   up exactly. Full width below the breakpoint, where the row is stacked. */
.cv-filters__search {
    height: var(--control-h);
    padding: 0 22px;
    justify-content: center;
}

/* The search box and the X that clears it. The wrapper is what the X is
   positioned against, and it is the grid item the box used to be. */
.cv-search {
    position: relative;
}

/* Room for the button, so a long term does not run underneath it. Three classes
   to beat .cv-filters .input, which sets the padding for the whole row. */
.cv-filters .cv-search .input {
    padding-right: 42px;
}

.cv-search__clear {
    position: absolute;
    top: 50%;
    right: 7px;
    transform: translateY(-50%);
    display: flex;
    align-items: center;
    justify-content: center;
    width: 26px;
    height: 26px;
    padding: 0;
    background: none;
    border: 0;
    border-radius: 50%;
    color: var(--muted);
    cursor: pointer;
    transition: background .15s, color .15s;
}

.cv-search__clear:hover,
.cv-search__clear:focus-visible {
    background: rgba(25, 38, 56, .09);
    color: var(--navy);
}

/* display:flex above would otherwise beat the browser's own [hidden] rule and
   leave the X showing on an empty box. */
.cv-search__clear[hidden] {
    display: none;
}

/* The two ends of a custom period, shown only when that period is chosen. Two
   narrow fields rather than a share of the row: a date input has a fixed width
   of content and stretching it across a quarter of the panel looks like a
   mistake. The trailing 1fr is the empty remainder that holds them left. */
@media (min-width: 992px) {
    .cv-filters__row--dates {
        grid-template-columns: 200px 200px 1fr;
        align-items: end;
    }
}

.cv-dates__field .field-label {
    margin-bottom: 5px;
    font-size: 12.5px;
    color: var(--muted);
}

/* A date input sizes itself to its own text unless told otherwise, and its
   picker icon needs the room the shared padding would take. */
.cv-filters .cv-dates__field .input {
    width: 100%;
    padding-right: 10px;
}


/* background-color, never the shorthand: the shorthand would drop the custom
   select chevron declared earlier in this file. */
.cv-filters .input {
    width: 100%;
    height: var(--control-h);
    padding: 0 14px;
    background-color: var(--bg);
    border: 1.5px solid var(--line);
    border-radius: var(--r-sm);
    font-family: inherit;
    font-size: 14px;
    color: var(--navy);
}

/* Restores the room the chevron needs, which the padding above would remove. */
.cv-filters select.input {
    cursor: pointer;
    padding-right: 38px;
}

/* Example searches. Buttons, not links: they fill the box in place rather than
   navigating, so the caret stays where the next word would be typed. */
.cv-hints {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 8px;
    font-size: 13px;
    color: var(--muted);
}

.cv-hint {
    padding: 4px 10px;
    background: rgba(0, 150, 215, .07);
    border: 1px solid rgba(0, 150, 215, .22);
    border-radius: 7px;
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-size: 12.5px;
    color: #0077AB;
    cursor: pointer;
}

.cv-hint:hover,
.cv-hint:focus {
    background: rgba(0, 150, 215, .14);
    border-color: var(--blue);
}

.cv-hints__note {
    flex-basis: 100%;
    font-size: 12.5px;
    color: var(--muted);
}

/* Candidate cell: initials, then the name over the email.
 *
 * The floor matters. This cell carries three things where the other columns
 * carry one, and the browser will squeeze it to fit the rest until the name
 * breaks after its first word and the address wraps a few characters at a time.
 * The table already scrolls inside its own card once the total no longer fits,
 * so reserving the width here costs nothing. */
.cv-candidate {
    display: flex;
    align-items: center;
    gap: 12px;
    min-width: 232px;
}

.cv-candidate .cell-strong {
    white-space: nowrap;
}

/* .contact-email breaks mid-word, which is right in the Applicant Inbox's
   narrow contact column and wrong here, now the cell has room for a whole
   address on one line. */
.cv-candidate .contact-email {
    font-size: 13px;
    font-weight: 500;
    overflow-wrap: break-word;
}

.cv-avatar {
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    width: 38px;
    height: 38px;
    border-radius: 50%;
    background: var(--grad);
    color: #FFFFFF;
    font-size: 13px;
    font-weight: 700;
    letter-spacing: .02em;
}

.cv-candidate__body {
    min-width: 0;
}

/* The mobile number. E.164 has no spaces of its own, so the only thing to guard
   against is the browser breaking it across two lines. */
.cell-tel {
    white-space: nowrap;
}

.cell-tel a {
    color: var(--navy);
    text-decoration: none;
    font-variant-numeric: tabular-nums;
}

.cell-tel a:hover {
    color: var(--blue);
    text-decoration: underline;
}

/* Shared by the candidate, location, role and date columns: a value with a
   quieter line beneath it. */
.cell-strong {
    display: block;
    font-weight: 600;
    color: var(--navy);
}

.cell-sub {
    display: block;
    margin-top: 2px;
    font-size: 13px;
    color: var(--muted);
}

/* How many earlier applications sit behind the one named above, and the control
   that opens them. A <button> reset back to looking like the link it reads as —
   it belongs in the sentence it sits in, not as a control beside it. */
.cell-more {
    padding: 0;
    background: none;
    border: 0;
    font: inherit;
    color: var(--blue);
    font-weight: 600;
    cursor: pointer;
}

.cell-more:hover {
    text-decoration: underline;
}

.cell-more[aria-expanded="true"] {
    text-decoration: underline;
}

/* Every job the candidate has applied for, opened from the count.
 *
 * A table inside a table cell, so it is scoped tightly to .job-history and
 * given its own borders: .data-table's rules would otherwise apply to these
 * rows as well and give them the outer table's padding and 14.5px type. */
.job-history {
    margin: 10px 0 2px;
    overflow-x: auto;
    border: 1px solid var(--line);
    border-radius: 8px;
}

.job-history__table {
    width: 100%;
    margin: 0;
    border-collapse: collapse;
    font-size: 12.5px;
    white-space: nowrap;
}

.job-history__table th {
    padding: 7px 10px;
    text-align: left;
    font-size: 11px;
    font-weight: 700;
    letter-spacing: .03em;
    text-transform: uppercase;
    color: var(--muted);
    background: var(--bg);
    border-bottom: 1px solid var(--line);
}

.job-history__table td {
    padding: 7px 10px;
    text-align: left;
    color: var(--navy);
    border-bottom: 1px solid var(--line);
}

.job-history__table tr:last-child td {
    border-bottom: none;
}

.job-history__code {
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-size: 11.5px;
    font-weight: 700;
    color: var(--blue);
}

.job-history__title {
    font-weight: 600;
}

.job-history__date {
    color: var(--muted);
}

/*
 * Duplicate warning, at the head of the Upload CV dialog.
 *
 * Amber, not red: nothing has gone wrong and nothing has been lost — the save
 * is waiting on a decision only the recruiter can make. Red would read as a
 * rejection and push them to abandon a CV that may be perfectly wanted.
 */
.dup-warning {
    margin-bottom: 20px;
    padding: 16px 18px;
    background: rgba(245, 158, 11, .08);
    border: 1px solid rgba(245, 158, 11, .38);
    border-radius: var(--r-sm);
}

.dup-warning__title {
    margin: 0 0 4px;
    font-size: 14.5px;
    font-weight: 700;
    color: #92400E;
}

.dup-warning__lead {
    margin: 0 0 12px;
    font-size: 13.5px;
    color: var(--navy);
}

.dup-list {
    margin: 0 0 14px;
    padding: 0;
    list-style: none;
}

.dup {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    padding: 10px 12px;
    background: var(--paper);
    border: 1px solid var(--line);
    border-radius: 8px;
}

.dup + .dup {
    margin-top: 8px;
}

.dup__body {
    min-width: 0;
}

.dup__name {
    display: block;
    font-weight: 700;
    font-size: 14px;
    color: var(--navy);
}

.dup__meta {
    display: block;
    margin-top: 1px;
    font-size: 12.5px;
    color: var(--muted);
    overflow-wrap: anywhere;
}

/* Why this one was flagged. Carries the weight of the decision, so it is set
   apart from the contact details above it rather than run in with them. */
.dup__why {
    display: block;
    margin-top: 4px;
    font-size: 12px;
    font-weight: 600;
    color: #92400E;
}

/* The override. A real <label> around the box so the words are part of the
   target, not just something sitting beside it. */
.dup-confirm {
    display: flex;
    align-items: flex-start;
    gap: 9px;
    margin: 0;
    font-size: 13.5px;
    font-weight: 600;
    color: var(--navy);
    cursor: pointer;
}

.dup-confirm input[type="checkbox"] {
    width: 16px;
    height: 16px;
    margin-top: 1px;
    flex-shrink: 0;
    accent-color: var(--blue);
    cursor: pointer;
}

.dup-warning__note {
    margin: 10px 0 0;
    font-size: 12.5px;
    color: var(--muted);
}

/* The drawer warning's two answers, side by side. The override is a form of its
   own — the switch that raised it closed with the drawer — and Cancel is a plain
   link, so the row has to hold one of each. */
.dup-actions {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 10px;
    margin: 0;
}

.dup-actions__form {
    margin: 0;
}

/* Says the CV the recruiter already chose is still held. Green rather than the
   usual grey hint: it is reassurance, and it is answering the obvious worry
   that the attachment has been lost. */
.field-hint--held {
    color: #2F7D5B;
}

/*
 * Actions pinned to the right-hand edge, the rest of the row scrolling beneath
 * it — this table carries eight columns and the buttons would otherwise be the
 * first thing off the side of a laptop screen.
 *
 * Sticky resolves against the nearest scrolling ancestor, which is .table-scroll
 * around this table; .admin-card's own overflow:hidden sits outside that and so
 * clips the card's corners without breaking the pinning.
 *
 * A class rather than :last-child, deliberately: the "no CVs match" row is a
 * single cell spanning the whole table, and would otherwise be pinned to the
 * edge as though it were an Actions cell.
 */
.data-table__sticky {
    position: sticky;
    right: 0;
    z-index: 2;
    /* Opaque on purpose. The default cell has no background of its own, and the
       scrolled columns would show straight through it. */
    background: var(--paper);
}

.data-table th.data-table__sticky {
    z-index: 3;
    background: var(--bg);
}

/* The edge the rest of the row disappears behind — depth rather than a drawn
   line, so the pinned column reads as sitting above the row instead of as a
   ninth column divider.
 *
 * A gradient strip laid just outside the cell rather than a box-shadow on the
 * cell itself: this table collapses its borders, and browsers disagree about
 * where a shadow on a collapsed-border cell should paint. pointer-events stays
 * off so the strip never swallows a click meant for the column beneath it. */
.data-table__sticky::before {
    content: '';
    position: absolute;
    top: 0;
    bottom: 0;
    left: -16px;
    width: 16px;
    background: linear-gradient(to right, rgba(25, 38, 56, 0), rgba(25, 38, 56, .13));
    pointer-events: none;
}

/* The shared row hover is a 3% wash, which is transparent — under it the
   scrolled columns would reappear. This is the same colour already flattened
   against the card, so the cell stays opaque. */
.data-table tbody tr:hover td.data-table__sticky {
    background: #F7FCFE;
}

/*** Recruiter Comments — the posting's internal note ***/
/*
 * Amber rather than the panel's blue, and labelled on its face. This is the one
 * thing on either screen that must never be read out to a candidate, so it is
 * deliberately not styled like the fields around it — a note that looks like the
 * advert is a note that gets treated like the advert.
 */

/* The tag beside a field label on the posting form. */
.field-label__tag {
    margin-left: 8px;
    padding: 2px 7px;
    border-radius: 5px;
    background: rgba(245, 158, 11, .16);
    font-size: 10.5px;
    font-weight: 700;
    letter-spacing: .02em;
    text-transform: uppercase;
    color: #92400E;
    vertical-align: middle;
}

/* The same note shown read-only inside the applicant drawer's posting card. */
.dw-internal {
    margin-top: 12px;
    padding: 10px 12px;
    background: rgba(245, 158, 11, .09);
    border: 1px solid rgba(245, 158, 11, .34);
    border-radius: 8px;
}

.dw-internal__tag {
    display: block;
    margin-bottom: 5px;
    font-size: 10.5px;
    font-weight: 700;
    letter-spacing: .04em;
    text-transform: uppercase;
    color: #92400E;
}

/* white-space so a note typed as several lines stays that way. */
.dw-internal__body {
    margin: 0;
    font-size: 13px;
    line-height: 1.55;
    color: var(--navy);
    white-space: pre-wrap;
    overflow-wrap: anywhere;
}

/*** Consent box — Upload CV ***/
/*
 * A real <label> wrapping the box, so the sentence is part of the target rather
 * than something sitting beside it: a consent tick that is hard to hit is a
 * consent tick people get wrong.
 */
.consent {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    margin: 4px 0 0;
    padding: 12px 14px;
    background: var(--bg);
    border: 1px solid var(--line);
    border-radius: var(--r-sm);
    font-size: 13px;
    line-height: 1.55;
    color: var(--navy);
    cursor: pointer;
}

.consent input[type="checkbox"] {
    width: 16px;
    height: 16px;
    margin-top: 1px;
    flex-shrink: 0;
    accent-color: var(--blue);
    cursor: pointer;
}

/* Focus lands on the box itself, which is small; the ring is drawn round the
   whole statement so it is obvious what is about to be agreed to. */
.consent:has(input:focus-visible) {
    border-color: var(--blue);
    box-shadow: 0 0 0 3px rgba(0, 150, 215, .12);
}

/*** CV Bank — Check Duplicates ***/
/* The fourth control on the filter row, so it matches the height of the three
   selects beside it and reads as one of them rather than an action. */
.cv-dupes {
    height: var(--control-h);
    padding: 0 18px;
    gap: 7px;
    justify-content: center;
    white-space: nowrap;
}

/* How many were found, under the row that found them. Only rendered while the
   filter is on, so it never sits there saying nothing. */
.cv-filters__note {
    margin: -4px 0 0;
    font-size: 12.5px;
    color: var(--muted);
}

