@font-face {
    font-family: "Century Gothic";
    src: url("/assets/fonts/CenturyGothicPaneuropeanLight.ttf") format("truetype");
    font-weight: 300;
    font-style: normal;
    font-display: swap;
}
@font-face {
    font-family: "Century Gothic";
    src: url("/assets/fonts/CenturyGothicPaneuropeanLightItalic.ttf") format("truetype");
    font-weight: 300;
    font-style: italic;
    font-display: swap;
}
@font-face {
    font-family: "Century Gothic";
    src: url("/assets/fonts/CenturyGothicPaneuropeanRegular.ttf") format("truetype");
    font-weight: 400;
    font-style: normal;
    font-display: swap;
}
@font-face {
    font-family: "Century Gothic";
    src: url("/assets/fonts/CenturyGothicPaneuropeanItalic.ttf") format("truetype");
    font-weight: 400;
    font-style: italic;
    font-display: swap;
}
@font-face {
    font-family: "Century Gothic";
    src: url("/assets/fonts/CenturyGothicPaneuropeanSemiBold.ttf") format("truetype");
    font-weight: 600;
    font-style: normal;
    font-display: swap;
}
@font-face {
    font-family: "Century Gothic";
    src: url("/assets/fonts/CenturyGothicPaneuropeanSemiBoldItalic.ttf") format("truetype");
    font-weight: 600;
    font-style: italic;
    font-display: swap;
}
@font-face {
    font-family: "Century Gothic";
    src: url("/assets/fonts/CenturyGothicPaneuropeanBold.ttf") format("truetype");
    font-weight: 700;
    font-style: normal;
    font-display: swap;
}
@font-face {
    font-family: "Century Gothic";
    src: url("/assets/fonts/CenturyGothicPaneuropeanBoldItalic.ttf") format("truetype");
    font-weight: 700;
    font-style: italic;
    font-display: swap;
}
@font-face {
    font-family: "Century Gothic";
    src: url("/assets/fonts/CenturyGothicPaneuropeanExtraBold.ttf") format("truetype");
    font-weight: 800;
    font-style: normal;
    font-display: swap;
}
@font-face {
    font-family: "Century Gothic";
    src: url("/assets/fonts/CenturyGothicPaneuropeanBlack.ttf") format("truetype");
    font-weight: 900;
    font-style: normal;
    font-display: swap;
}

:root {
    --gr-blue: #0c60a2;
    --gr-blue-dark: #054171;
    --gr-green: #4caf50;
    --gr-red: #e0483f;
    --gr-yellow: #f0ad4e;
    --gr-border: #e5e8ec;
    --gr-text-muted: #8a94a3;
    --gr-bg: #f4f6f8;

    /* ---- Shape/elevation system (colors are unchanged on purpose - only shape/depth here) ---- */
    --gr-radius-sm: 10px;
    --gr-radius: 16px;
    --gr-radius-lg: 22px;
    --gr-radius-pill: 999px;
    --gr-shadow-xs: 0 1px 2px rgba(15, 23, 42, 0.05);
    --gr-shadow-sm: 0 2px 6px rgba(15, 23, 42, 0.06), 0 1px 2px rgba(15, 23, 42, 0.04);
    --gr-shadow-md: 0 10px 28px rgba(15, 23, 42, 0.09), 0 2px 8px rgba(15, 23, 42, 0.05);
    --gr-shadow-lg: 0 24px 56px rgba(15, 23, 42, 0.18);
    --gr-ease: cubic-bezier(0.22, 0.61, 0.36, 1);
}

html {
    font-size: 18px;
}

html, body {
    overflow-x: hidden;
    max-width: 100%;
}

body {
    background-color: var(--gr-bg);
    color: #2b2f36;
    font-family: "Century Gothic", "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
    font-size: 0.9rem;
    overflow-wrap: break-word;
    letter-spacing: 0.001em;
}
h1, h2, h3, h4, h5, h6,
.fw-bold, .fw-semibold,
.btn, .small-caps-label {
    font-family: "Century Gothic", "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
}
/* Century Gothic has no true semibold face bundled - fake it by leaning on the SemiBold
   @font-face weight (600) wherever Bootstrap's .fw-semibold (weight 600) is used, and let
   .fw-bold ride the Bold face (700) as normal. */
.fw-semibold {
    font-weight: 600;
}

/* Flex children with text content (names, emails, descriptions...) default to
   min-width: auto, which refuses to shrink below the text's natural width and silently
   pushes flex rows wider than the viewport on mobile. This is the single most common
   cause of horizontal overflow in a flexbox-heavy layout like this one. */
.flex-grow-1 {
    min-width: 0;
}
.d-flex {
    min-width: 0;
}

img {
    max-width: 100%;
}

a {
    color: var(--gr-blue);
    text-decoration: none;
    transition: color 0.15s var(--gr-ease);
}
a:hover {
    color: var(--gr-blue-dark);
    text-decoration: underline;
}

::selection {
    background: var(--gr-blue);
    color: #fff;
}

/* ---------- Scrollbars (a small but very visible "this isn't the stock look" touch) ---------- */
* {
    scrollbar-width: thin;
    scrollbar-color: #c7cfd8 transparent;
}
*::-webkit-scrollbar {
    width: 8px;
    height: 8px;
}
*::-webkit-scrollbar-thumb {
    background: #c7cfd8;
    border-radius: var(--gr-radius-pill);
}
*::-webkit-scrollbar-track {
    background: transparent;
}

/* ---------- Logo ---------- */
.gr-logo {
    display: inline-flex;
    align-items: center;
}
.gr-logo img {
    display: block;
    height: 54px;
    width: auto;
}
.gr-logo:hover {
    text-decoration: none;
}
@media (max-width: 575.98px) {
    .gr-logo img { height: 40px; }
}

/* ---------- Top navbar ---------- */
.gr-navbar {
    border-bottom: none;
    background: #fff;
    box-shadow: 0 1px 0 var(--gr-border), 0 6px 18px rgba(15, 23, 42, 0.04);
    position: relative;
    z-index: 10;
}
.gr-navbar::after {
    content: '';
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    height: 2px;
    background: linear-gradient(90deg, var(--gr-blue) 0%, rgba(12, 96, 162, 0.15) 45%, rgba(12, 96, 162, 0) 70%);
}
.gr-navbar-inner {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    row-gap: 0.5rem;
    max-width: 1800px;
    margin: 0 auto;
    padding: 0.7rem 1.25rem;
}
/* Guide portal header carries almost nothing (logo, "Agenda Portal", avatar), so it stays on a
   single line at every width instead of wrapping the avatar onto its own row on a phone. */
.gr-navbar-guide .gr-navbar-inner {
    flex-wrap: nowrap;
}
.gr-navbar-guide .gr-section-toggle {
    white-space: nowrap;
}

.gr-section-toggle {
    background: var(--gr-bg);
    border: none;
    border-radius: var(--gr-radius-pill);
    color: #495057;
    font-weight: 600;
    display: flex;
    align-items: center;
    gap: 0.35rem;
    padding: 0.4rem 0.9rem;
    transition: background 0.15s var(--gr-ease);
}
.gr-section-toggle:hover {
    background: #eaeef2;
}
@media (max-width: 575.98px) {
    /* Client header: on mobile the section dropdown moves to the icon row as a hamburger icon
       (see client/_header.php) instead of living here next to the logo, so this group is back to
       just the logo. */
    .gr-client-navbar-left {
        gap: 0.5rem;
    }
    /* Family details modal: gap-5 (3rem) is meant as horizontal spacing between the three
       side-by-side columns (Spouse/Children/Pets) on desktop - once they wrap to a vertical
       stack on mobile, that same 48px reads as a big dead gap between each section instead. */
    .gr-family-toggles {
        flex-direction: column;
        align-items: center !important;
        gap: 1.5rem !important;
    }
    /* The dog/cat groups sit side by side with no flex-wrap, so their combined un-shrinkable
       width (each has a stepper with fixed +/- buttons and a count input) forces the whole modal
       wider than the screen - that's what drags the rest of the modal into horizontal scroll
       along with it. Stack them instead. */
    .gr-family-pets-row {
        flex-direction: column;
        align-items: center !important;
        gap: 0.75rem !important;
    }
}

.gr-navbar-icon {
    color: #495057;
    font-size: 1.15rem;
    position: relative;
    padding: 0.4rem 0.55rem;
    border-radius: var(--gr-radius-pill);
    transition: background 0.15s var(--gr-ease), color 0.15s var(--gr-ease);
}
.gr-navbar-icon:hover {
    background: var(--gr-bg);
    color: var(--gr-blue);
}
.gr-navbar-icon .dot {
    position: absolute;
    top: 4px;
    right: 4px;
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: var(--gr-blue);
    border: 2px solid #fff;
    box-shadow: var(--gr-shadow-xs);
}

.gr-user-avatar {
    width: 32px;
    height: 32px;
    border-radius: 50%;
    background: #d7dde5;
    object-fit: cover;
    box-shadow: 0 0 0 2px #fff, var(--gr-shadow-xs);
}

/* ---------- Tabs (rendered as a floating segmented pill control, not underline tabs) ---------- */
.gr-tabs {
    border-bottom: none;
    padding: 0.7rem 1.25rem;
    max-width: 1800px;
    margin: 0 auto;
    display: flex;
    column-gap: 0.4rem;
    row-gap: 0.4rem;
    flex-wrap: wrap;
    background: #fff;
}
.gr-tabs a:not(.dropdown-item) {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    line-height: 1;
    padding: 0.8rem 1.15rem;
    color: var(--gr-text-muted);
    font-weight: 600;
    font-size: 0.74rem;
    letter-spacing: 0.03em;
    text-transform: uppercase;
    background: var(--gr-bg);
    border-radius: var(--gr-radius-pill);
    white-space: nowrap;
    transition: background 0.15s var(--gr-ease), color 0.15s var(--gr-ease), box-shadow 0.15s var(--gr-ease);
}
.gr-tabs a.active:not(.dropdown-item), .gr-tabs .gr-tab-dropdown.active > a {
    color: #fff;
    background: var(--gr-blue);
    text-decoration: none;
    box-shadow: var(--gr-shadow-sm);
}
.gr-tabs a:not(.dropdown-item):hover {
    text-decoration: none;
    color: var(--gr-blue-dark);
    background: #e9edf2;
}
.gr-tabs a.disabled-tab {
    color: var(--gr-text-muted);
    opacity: 0.5;
    cursor: not-allowed;
}
.gr-tabs a.disabled-tab:hover {
    background: var(--gr-bg);
    color: var(--gr-text-muted);
}
.gr-tabs a.active:not(.dropdown-item):hover {
    color: #fff;
    background: var(--gr-blue-dark);
}

/* ---------- Relocation Progress & Activity layout ----------
   Deliberately not the reference's side-by-side "timeline+activity | next" split: one full-width
   column, top to bottom - the status/timeline card leads, then What's next/Generate document/
   Service team (three cards in their own row, since "next" now has the full row to itself instead
   of being squeezed into a narrow sidebar), then the activity feed last, as a log to check rather
   than the thing competing for attention with actionable items. Reordered purely via grid-area
   naming - the three blocks' actual position in the PHP source is unchanged. */
.gr-progress-layout {
    display: grid;
    gap: 1.5rem;
    grid-template-columns: 1fr;
    grid-template-areas: "timeline" "next" "activity";
}
.gr-progress-timeline { grid-area: timeline; min-width: 0; }
.gr-progress-activity { grid-area: activity; min-width: 0; }
.gr-progress-next { grid-area: next; min-width: 0; }

/* ---------- Cards / panels ---------- */
.gr-card {
    background: #fff;
    border: 1px solid var(--gr-border);
    border-radius: var(--gr-radius);
    box-shadow: var(--gr-shadow-sm);
    transition: box-shadow 0.2s var(--gr-ease);
}
.gr-card-header {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
    padding: 1.1rem 1.4rem;
    border-bottom: 1px solid var(--gr-border);
}
.gr-card-header h2, .gr-card-header h3 {
    font-size: 1rem;
    font-weight: 700;
    margin: 0;
}
.gr-chip-option {
    cursor: pointer;
    user-select: none;
    margin-bottom: 0;
}
/* Pill toggle for a single yes/no flag (VIP, Has a disability, ...) - a real checkbox underneath
   (so existing change-event JS, form submission, and keyboard use all keep working exactly as
   before), just skinned as a pill instead of a plain checkbox + label. */
.gr-wizard-toggle {
    display: inline-flex;
    align-items: center;
    cursor: pointer;
    user-select: none;
}
.gr-wizard-toggle input {
    position: absolute;
    opacity: 0;
    width: 0;
    height: 0;
}
.gr-wizard-toggle span {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    padding: 0.5rem 0.9rem;
    border-radius: var(--gr-radius-pill);
    border: 1px solid var(--gr-border);
    color: var(--gr-text-muted);
    font-size: 0.85rem;
    font-weight: 600;
    transition: background 0.15s var(--gr-ease), color 0.15s var(--gr-ease), border-color 0.15s var(--gr-ease);
}
.gr-wizard-toggle input:checked + span {
    background: var(--gr-blue);
    border-color: var(--gr-blue);
    color: #fff;
}
.gr-wizard-toggle input:focus-visible + span {
    box-shadow: 0 0 0 3px rgba(12, 96, 162, 0.25);
}
.prop-gallery-thumb {
    cursor: pointer;
    opacity: 0.7;
    border: 2px solid transparent;
    transition: opacity 0.15s ease, border-color 0.15s ease;
}
.prop-gallery-thumb:hover {
    opacity: 1;
}
.prop-gallery-thumb-active {
    opacity: 1;
    border-color: var(--gr-blue);
}
.prop-lightbox {
    position: fixed;
    inset: 0;
    z-index: 2000;
    background: rgba(0, 0, 0, 0.92);
    align-items: center;
    justify-content: center;
}
.prop-lightbox-body {
    max-width: 92vw;
    max-height: 92vh;
    text-align: center;
}
.prop-lightbox-body img {
    max-width: 92vw;
    max-height: 80vh;
    object-fit: contain;
}
.prop-lightbox-caption {
    color: #fff;
    margin-top: 0.75rem;
    font-size: 0.9rem;
}
.prop-lightbox-counter {
    color: rgba(255, 255, 255, 0.7);
    margin-top: 0.25rem;
    font-size: 0.8rem;
}
.prop-lightbox-close {
    position: absolute;
    top: 1rem;
    right: 1.25rem;
    background: transparent;
    border: none;
    color: #fff;
    font-size: 1.5rem;
    cursor: pointer;
}
.prop-lightbox-nav {
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
    background: rgba(255, 255, 255, 0.15);
    border: none;
    color: #fff;
    width: 48px;
    height: 48px;
    border-radius: 50%;
    font-size: 1.4rem;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
}
.prop-lightbox-nav:hover {
    background: rgba(255, 255, 255, 0.3);
}
.prop-lightbox-prev {
    left: 1rem;
}
.prop-lightbox-next {
    right: 1rem;
}
.icon-btn {
    width: 38px;
    height: 38px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border: 1px solid var(--gr-border);
    border-radius: 50%;
    background: #fff;
    color: var(--gr-blue);
    transition: background 0.15s var(--gr-ease), border-color 0.15s var(--gr-ease), transform 0.15s var(--gr-ease), box-shadow 0.15s var(--gr-ease);
}
.icon-btn:hover {
    background: var(--gr-blue);
    border-color: var(--gr-blue);
    color: #fff;
    transform: translateY(-1px);
    box-shadow: var(--gr-shadow-sm);
}
.gr-chevron-toggle i {
    transition: transform 0.2s ease;
}
.gr-chevron-toggle:not(.collapsed) i {
    transform: rotate(180deg);
}

/* ---------- Badges ---------- */
.badge-status-active { background: var(--gr-blue); color: #fff; }
.badge-status-completed { background: var(--gr-green); color: #fff; }
.badge-status-cancelled { background: var(--gr-red); color: #fff; }
.badge-status-onhold { background: var(--gr-yellow); color: #4b3a05; }
.badge-pill-status {
    font-size: 0.7rem;
    font-weight: 700;
    padding: 0.4rem 1rem;
    border-radius: var(--gr-radius-pill);
    letter-spacing: 0.05em;
    box-shadow: var(--gr-shadow-xs);
}

.dot-active, .dot-idle {
    display: inline-block;
    width: 10px;
    height: 10px;
    border-radius: 50%;
}
.dot-active { background: #48c774; box-shadow: 0 0 0 3px rgba(72, 199, 116, 0.18); }
.dot-idle { background: #fff; border: 1px solid #c6ccd4; }

/* Relocations list only (not .gr-filter-panel generally - that class is shared by Educate/Stay/
   Consultants' own toolbars, which have no reason to match this page's 1300px column). Keeps the
   filter panel aligned with the toolbar and list below it once those are centered on a wide
   screen instead of sitting flush left. */
#relocFilterPanel {
    max-width: 1300px;
    margin-left: auto;
    margin-right: auto;
}

/* ---------- Filter panel (toggled by the sliders icon) ---------- */
.gr-filter-panel {
    display: none;
    position: relative;
    background: #fff;
    border: none;
    border-radius: var(--gr-radius);
    padding: 1.6rem;
    box-shadow: var(--gr-shadow-md);
}
.gr-filter-panel.show { display: block; }
.gr-filter-panel::before {
    content: '';
    position: absolute;
    top: -7px;
    right: 34px;
    width: 14px;
    height: 14px;
    background: #fff;
    border-radius: 3px 0 0 0;
    box-shadow: -2px -2px 4px rgba(15, 23, 42, 0.03);
    transform: rotate(45deg);
}

/* ---------- Filter chips ---------- */
.gr-filter-chip {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    background: var(--gr-bg);
    border: 1px solid var(--gr-border);
    border-radius: var(--gr-radius-pill);
    padding: 0.35rem 0.9rem;
    font-size: 0.8rem;
    color: #495057;
}
.gr-filter-chip .remove {
    color: #8a94a3;
    font-weight: 700;
    cursor: pointer;
}

/* ---------- List rows (relocations, leases, immigration) ---------- */
.gr-list-row {
    position: relative;
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.75rem 1.1rem;
    padding: 1.15rem 1.4rem 1.15rem 1.7rem;
    border-bottom: 1px solid var(--gr-border);
    transition: background 0.2s var(--gr-ease), box-shadow 0.2s var(--gr-ease);
}
.gr-list-row::before {
    content: '';
    position: absolute;
    left: 0;
    top: 10%;
    bottom: 10%;
    width: 3px;
    border-radius: var(--gr-radius-pill);
    background: var(--gr-blue);
    opacity: 0;
    transform: scaleY(0.4);
    transition: opacity 0.2s var(--gr-ease), transform 0.2s var(--gr-ease);
}
.gr-list-row:hover {
    background: var(--gr-bg);
    box-shadow: inset 0 0 0 9999px rgba(12, 96, 162, 0.02);
}
.gr-list-row:hover::before {
    opacity: 1;
    transform: scaleY(1);
}

/* Immigration procedure header (client + staff): title / dates / status badge / (staff-only)
   action icons wrap independently via flex-wrap on a normal card, which on a phone-width screen
   packs each one wherever it fits rather than keeping them in a readable order. Force a clean
   top-to-bottom stack instead, and drop the dates block's right-alignment (it only made sense
   sitting to the right of the title on the same line). */
@media (max-width: 767.98px) {
    .imm-proc-header {
        flex-direction: column;
        align-items: stretch !important;
        gap: 0.5rem;
    }
    .imm-proc-header > * {
        min-width: 0 !important;
        text-align: left !important;
    }
    .imm-proc-header .badge-pill-status {
        align-self: flex-start;
    }
}

/* ---------- Relocation list rows ----------
   Deliberately not the reference's multi-column table row: the avatar carries its own progress
   ring (completion at a glance, no separate ring+status block further along), name+status+flags
   read as one heading, company/destination/consultants/activity collapse into two quiet lines
   underneath instead of four rigid columns, and the module breakdown becomes a chip strip.
   Supports two layouts from the same markup - a horizontal row (default) and a card grid
   (.gr-view-cards on the list container) - toggled via relocations/_filters.php's ?view= param. */
.gr-relocation-item {
    position: relative;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 1.1rem;
    padding: 1.15rem 1.7rem;
    border-bottom: 1px solid var(--gr-border);
    transition: background 0.2s var(--gr-ease);
}
.gr-relocation-item:hover {
    background: var(--gr-bg);
}
.gr-ri-avatar-ring {
    --size: 52px;
    display: block;
    flex-shrink: 0;
    width: var(--size);
    height: var(--size);
    border-radius: 50%;
    padding: 3px;
    background: conic-gradient(var(--gr-blue) calc(var(--pct, 0) * 1%), #e7ebf0 0);
}
.gr-ri-avatar-ring.is-complete {
    background: conic-gradient(var(--gr-green) calc(var(--pct, 0) * 1%), #e7ebf0 0);
}
.gr-ri-avatar-ring img,
.gr-ri-avatar-fallback {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    height: 100%;
    border-radius: 50%;
    object-fit: cover;
    background: #fff;
    color: #9aa4b2;
    font-size: 1.2rem;
}
.gr-ri-main {
    flex: 0 1 480px;
    min-width: 0;
}
/* "..." always anchored to the row's top-right corner - same corner-actions pattern used
   elsewhere - rather than sitting inline where it could drift away from the module chips once
   they wrap. .gr-relocation-item is already position: relative. */
.gr-ri-more {
    position: absolute;
    top: 1.15rem;
    right: 1.7rem;
    margin-left: 0;
}
.gr-ri-main a {
    text-decoration: none;
}
.gr-ri-main .dot-active,
.gr-ri-main .dot-idle {
    margin-right: 0.3rem;
    vertical-align: -1px;
}
/* Key dates - real fields the sort dropdown already treats as important (Arrival date, Work
   start date, Next appointment) but that had nowhere to show in the row itself. Fills the row's
   width with information instead of just capping the row narrower. */
.gr-ri-stats {
    display: flex;
    gap: 1.5rem;
    flex: 0 0 auto;
}
.gr-ri-stat {
    min-width: 84px;
    text-align: center;
}
@media (max-width: 1149.98px) {
    .gr-ri-stats {
        display: none;
    }
}

/* Module chip strip: dropped first (before resorting to stacking) below the width where the
   name/meta block still needs the room - the same relief valve .gr-row-module-icons used to be. */
@media (max-width: 1149.98px) {
    .gr-ri-module-strip {
        display: none;
    }
}
/* Two-column grid rather than a wrapped row - 4 enabled modules read as a tidy 2x2 block, 3 as
   two-then-one, instead of a ragged line that breaks wherever it runs out of width. */
.gr-ri-module-strip {
    display: grid;
    grid-template-columns: repeat(2, auto);
    gap: 0.4rem;
    flex: 0 0 auto;
    margin-left: auto;
    /* Clears the "..." menu, which is absolutely positioned at right: 1.7rem and would otherwise
       sit on top of this grid's own right column once the grid is pushed flush to the row edge. */
    margin-right: 2.5rem;
}
.gr-ri-module-chip {
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
    padding: 0.25rem 0.55rem;
    border-radius: var(--gr-radius-pill);
    background: var(--gr-bg);
    color: var(--gr-text-muted);
    font-size: 0.72rem;
    white-space: nowrap;
}
.gr-ri-module-chip.is-complete {
    background: rgba(76, 175, 80, 0.12);
    color: var(--gr-green);
}

/* Now that nothing in the row grows to fill leftover width (see .gr-ri-main above), a very wide
   screen left a huge blank void after the content instead of a mid-row gap - capping the
   container so it only takes the width its content actually needs, rather than stretching the
   navbar's full 1800px. Centered (not flush with the page's own left padding) so that on a very
   wide screen the leftover space splits evenly on both sides instead of piling up entirely on the
   right as one lopsided gap - .gr-reloc-toolbar and #relocFilterPanel above/below it match this
   same width and centering so the whole column (search bar, filters, list) stays aligned as one
   unit instead of the list drifting out of line with the toolbar above it. */
.gr-relocation-panel {
    max-width: 1300px;
    margin-left: auto;
    margin-right: auto;
}

/* Below md, the relocation list has exactly one layout - the card grid, whichever view the URL
   asks for. List mode's row layout (built for a wide screen) never actually reads well stacked
   into a phone-width column, so instead of continuing to patch it, mobile always renders the card
   treatment - literally reusing .gr-view-cards' own rules against .gr-relocation-panel, the
   shared marker class both index.php and all-relocations/index.php's wrapper carries regardless
   of $relocView. The view toggle itself is hidden below md - see .gr-view-toggle. */
@media (max-width: 767.98px) {
    .gr-relocation-panel {
        display: grid;
        grid-template-columns: 1fr;
        gap: 1.1rem;
        background: transparent;
        border: none;
        box-shadow: none;
        padding: 0;
    }
    .gr-relocation-panel .gr-relocation-item {
        flex-direction: column;
        align-items: center;
        text-align: center;
        gap: 0.6rem;
        background: #fff;
        border: 1px solid var(--gr-border);
        border-radius: var(--gr-radius);
        box-shadow: var(--gr-shadow-sm);
        padding: 1.35rem 1.25rem 1.1rem;
    }
    .gr-relocation-panel .gr-relocation-item::before {
        display: none;
    }
    .gr-relocation-panel .gr-ri-avatar-ring {
        --size: 64px;
    }
    .gr-relocation-panel .gr-ri-main .d-flex {
        justify-content: center;
    }
    .gr-relocation-panel .gr-ri-module-strip {
        display: flex;
        justify-content: center;
        max-width: 100%;
        margin: 0 auto;
    }
    .gr-relocation-panel .gr-ri-stats {
        display: flex;
        justify-content: center;
        gap: 1.25rem;
    }
}

.gr-view-cards {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
    gap: 1.1rem;
}
.gr-view-cards .gr-relocation-item {
    flex-direction: column;
    align-items: center;
    text-align: center;
    gap: 0.6rem;
    background: #fff;
    border: 1px solid var(--gr-border);
    border-radius: var(--gr-radius);
    box-shadow: var(--gr-shadow-sm);
    padding: 1.35rem 1.25rem 1.1rem;
}
.gr-view-cards .gr-relocation-item:hover {
    box-shadow: var(--gr-shadow-md);
}
.gr-view-cards .gr-relocation-item::before {
    display: none;
}
.gr-view-cards .gr-ri-avatar-ring {
    --size: 64px;
}
.gr-view-cards .gr-ri-main {
    flex: 0 0 auto;
    width: 100%;
}
.gr-view-cards .gr-ri-main .d-flex {
    justify-content: center;
}
.gr-view-cards .gr-ri-module-strip {
    /* The base rule's margin-left: auto is meant to push the grid to the row's right edge in
       list mode - inside this column-direction card, that same auto margin instead shoves the
       whole grid to the card's right edge (fighting align-items: center on the card), which is
       what was colliding with the "..." menu and the stats block above it. */
    margin: 0 auto;
    justify-content: center;
    max-width: 100%;
}
.gr-view-cards .gr-ri-stats {
    justify-content: center;
    flex-wrap: wrap;
    width: 100%;
    padding-top: 0.4rem;
    border-top: 1px solid var(--gr-border);
}
.gr-view-cards .gr-ri-more {
    position: absolute;
    top: 1rem;
    right: 1rem;
    margin-left: 0;
}
/* Wrap the two view-toggle buttons in a pill so they read as one control (two states of the
   same setting) instead of two unrelated floating icon buttons. */
.gr-view-toggle {
    display: flex;
    align-items: center;
    border: 1px solid var(--gr-border);
    border-radius: 999px;
    background: #fff;
    padding: 2px;
    gap: 0;
}
/* 32px inner button + 2px padding + 1px border on each side = 38px overall, matching the
   standalone .icon-btn (now 38x38, bumped to match the toolbar's search input/select height). */
.gr-view-toggle .icon-btn {
    width: 32px;
    height: 32px;
    border: none;
    border-radius: 999px;
    background: transparent;
}
.gr-view-toggle .icon-btn:hover {
    background: var(--gr-bg);
    border-color: transparent;
    color: var(--gr-blue);
}
.gr-view-toggle .icon-btn.active {
    background: var(--gr-blue);
    border-color: var(--gr-blue);
    color: #fff;
}
.gr-view-toggle .icon-btn.active:hover {
    background: var(--gr-blue);
    color: #fff;
}
.gr-reloc-toolbar {
    justify-content: flex-end;
    max-width: 1300px;
    margin: 0 auto;
}
/* Generic version of the same fix, reused by every other search/filter toolbar built on this
   identical shape (Educate search, Stay search, Consultants) - Bootstrap's justify-content-end
   utility carries !important, so it can never be overridden by a later, more specific media-query
   rule; the fix has to skip that utility entirely and own the property itself instead. */
.gr-toolbar-row {
    justify-content: flex-end;
}
@media (max-width: 767.98px) {
    .gr-toolbar-row {
        justify-content: flex-start;
    }
    .gr-toolbar-search {
        flex: 1 1 100%;
        width: auto !important;
    }
    /* Generic version of the relocations-list sort fix - the select grows to fill the leftover
       width in its row instead of sitting narrow next to the icon buttons around it. */
    .gr-toolbar-sort {
        flex: 1 1 auto;
        min-width: 0;
    }
    .gr-toolbar-sort select {
        width: 100% !important;
    }
    /* Each consultant becomes its own bordered card instead of a row inside one shared list box -
       .gr-list-row's own mobile stacking (flex-direction: column etc., defined above) still
       applies inside each card unchanged, this just wraps it in the card visual. */
    .gr-consultant-list {
        background: transparent;
        border: none;
        box-shadow: none;
        display: grid;
        gap: 1.1rem;
    }
    .gr-consultant-list .gr-list-row {
        background: #fff;
        border: 1px solid var(--gr-border);
        border-radius: var(--gr-radius);
        box-shadow: var(--gr-shadow-sm);
        padding: 1.15rem 1.4rem;
        align-items: center;
        text-align: center;
    }
    .gr-consultant-list .gr-list-row::before {
        display: none;
    }
    .gr-consultant-list .gr-list-row > :first-child {
        align-self: center;
    }
    /* The stats block (Active/Completed/Cancelled) and the admin-actions row (key/activate icons)
       are each their own internal flex row, still end/start-aligned from the desktop layout -
       .justify-content-end carries Bootstrap's !important, so this needs its own to win. */
    .gr-consultant-list .gr-list-row .justify-content-end {
        justify-content: center !important;
    }
    .gr-consultant-list .gr-list-row .d-flex.gap-2 {
        justify-content: center;
    }
}
/* Cards are the only mobile layout now (see .gr-relocation-panel above) - a toggle offering a
   choice that no longer exists would just be confusing. This has to come after the base
   .gr-view-toggle rule above, not before it - same specificity, so source order decides, and an
   earlier display:none was losing to the later unconditional display:flex. */
@media (max-width: 767.98px) {
    .gr-view-toggle {
        display: none;
    }
    /* justify-content-end right-aligns each wrapped line independently, so once Search (220px)
       and the sort select (200px) land on separate lines, their very different total widths give
       each line a different LEFT edge - a staggered look, even though both stay flush right.
       Left-align instead, and let Search claim its own full-width row rather than share a
       leftover sliver with just the filter icon. */
    .gr-reloc-toolbar {
        justify-content: flex-start;
    }
    .gr-reloc-search {
        flex: 1 1 100%;
        width: auto !important;
    }
    /* The sort select + the two icon buttons around it are all content-sized, leaving that whole
       row narrower than Search above it - let the select itself grow to soak up the leftover
       width instead of the two fixed-width icons floating in a too-wide row. */
    .gr-reloc-sort {
        flex: 1 1 auto;
        min-width: 0;
    }
    .gr-reloc-sort select {
        width: 100% !important;
    }
}

@media (max-width: 767.98px) {
    /* Fixed pixel column widths (set inline per-row) don't make sense once rows wrap, and letting
       them wrap via flex-wrap packs a leftover column onto its own line wherever it happens to
       fit - detached from the content above it (the "Public" school-type column doing exactly
       that was the bug report). Stack every column full-width top to bottom instead. The thumb/
       avatar (always the row's first child across every .gr-list-row template) keeps its fixed
       square size - align-self stops it stretching to the row's full width, and flex: 0 0 auto
       !important overrides the flex-basis every other column gets further down (needed because a
       flex-basis in px, meant as a width hint, gets reinterpreted as a HEIGHT once the container
       is flex-direction: column - the bug that produced the huge gaps between rows). */
    .gr-list-row {
        flex-direction: column;
        align-items: stretch;
    }
    .gr-list-row > * {
        width: auto !important;
    }
    .gr-list-row > :first-child {
        align-self: flex-start;
        flex: 0 0 auto !important;
    }
    .gr-list-row > .text-end {
        text-align: left !important;
    }
    /* .gr-list-row > * above forces width: auto on every direct child, including a .gr-avatar
       first child - its own width: 44px gets clobbered while height: 44px doesn't, stretching the
       circle into an ellipse (the source photo's aspect ratio takes over once width is free to
       shrink-wrap). More specific than the universal selector, so this wins regardless of order. */
    .gr-list-row > .gr-avatar {
        width: 44px !important;
        height: 44px !important;
    }
    /* Opt-in: a row's message/archive icons can float in the top-right corner instead of taking
       their own stacked line at the bottom - lifted out of the column flow, layered over the row
       next to the thumbnail instead of trailing after every other stacked field. */
    .gr-list-row-corner-actions {
        position: absolute;
        top: 1.15rem;
        right: 1.4rem;
    }
}
.gr-avatar {
    width: 44px;
    height: 44px;
    border-radius: 50%;
    background: #e7ebf0;
    display: flex;
    align-items: center;
    justify-content: center;
    color: #9aa4b2;
    font-size: 1.4rem;
    flex-shrink: 0;
    overflow: hidden;
    box-shadow: 0 0 0 3px #fff, 0 0 0 4px var(--gr-border);
    transition: box-shadow 0.2s var(--gr-ease);
}
.gr-list-row:hover .gr-avatar {
    box-shadow: 0 0 0 3px #fff, 0 0 0 4px rgba(12, 96, 162, 0.35);
}
.gr-avatar img { width: 100%; height: 100%; object-fit: cover; }
.gr-progress-thin {
    height: 6px;
    border-radius: var(--gr-radius-pill);
    background: #e7ebf0;
    overflow: hidden;
    width: 120px;
}
.gr-progress-thin > span {
    display: block;
    height: 100%;
    border-radius: var(--gr-radius-pill);
    background: var(--gr-blue);
    transition: width 0.3s var(--gr-ease);
}

/* ---------- Dashboard module summary cards (Service initiation / Depart / Move / ...) ---------- */
.border.rounded.p-3.h-100 {
    position: relative;
    overflow: hidden;
    border-color: var(--gr-border) !important;
    border-radius: var(--gr-radius) !important;
    padding: 1.2rem !important;
    transition: box-shadow 0.2s var(--gr-ease), transform 0.2s var(--gr-ease), border-color 0.2s var(--gr-ease);
}
.gr-timeline-completion {
    position: relative;
    overflow: hidden;
    transition: box-shadow 0.2s var(--gr-ease), transform 0.2s var(--gr-ease), border-color 0.2s var(--gr-ease);
}
.border.rounded.p-3.h-100::before,
.gr-timeline-completion::before {
    content: '';
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    height: 3px;
    background: var(--gr-blue);
    opacity: 0;
    transform: translateY(-3px);
    transition: opacity 0.2s var(--gr-ease), transform 0.2s var(--gr-ease);
}
a.border.rounded.p-3.h-100:hover,
button.border.rounded.p-3.h-100:hover,
.gr-timeline-completion:hover {
    box-shadow: var(--gr-shadow-md);
    transform: translateY(-3px);
    border-color: var(--gr-blue) !important;
}
a.border.rounded.p-3.h-100:hover::before,
button.border.rounded.p-3.h-100:hover::before,
.gr-timeline-completion:hover::before {
    opacity: 1;
    transform: translateY(0);
}
.border.rounded.p-3.h-100 .fw-semibold {
    font-size: 0.95rem;
}

/* Progress ring: a conic-gradient donut standing in for the module's icon, replacing the old
   icon + separate horizontal bar layout - the fill angle is read from --pct (0-100), set inline
   per card from PHP. The module icon sits in the punched-out center. */
.gr-progress-ring {
    --size: 46px;
    width: var(--size);
    height: var(--size);
    border-radius: 50%;
    flex-shrink: 0;
    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;
    background: conic-gradient(var(--gr-blue) calc(var(--pct, 0) * 1%), #e7ebf0 0);
}
.gr-progress-ring::before {
    content: '';
    position: absolute;
    inset: 5px;
    border-radius: 50%;
    background: #fff;
}
.gr-progress-ring > i.bi {
    position: relative;
    z-index: 1;
    color: var(--gr-blue);
    font-size: 1.05rem;
}
.gr-progress-ring.is-complete {
    background: conic-gradient(var(--gr-green) calc(var(--pct, 0) * 1%), #e7ebf0 0);
}
.gr-progress-ring.is-complete > i.bi {
    color: var(--gr-green);
}
.gr-module-card-complete {
    border-color: rgba(76, 175, 80, 0.4) !important;
    background: rgba(76, 175, 80, 0.05);
}

/* Service initiation/completion are process milestones, not real service modules and not a task
   list - they're a fixed sequence of dated checkpoints, so a horizontal stepper reads faster and
   takes less vertical space than the label/value box layout used for the real service modules
   above. Initiation sits above the module grid, completion below it (start -> work -> finish). */
.gr-timeline {
    border: 1px solid var(--gr-border);
    border-radius: var(--gr-radius);
    background: #fff;
    padding: 1.1rem 1.5rem;
}
button.gr-timeline-completion {
    cursor: pointer;
    color: inherit;
}
.gr-timeline.is-complete {
    border-color: rgba(76, 175, 80, 0.4);
    background: rgba(76, 175, 80, 0.05);
}
.gr-timeline-icon {
    width: 32px;
    height: 32px;
    border-radius: 50%;
    background: rgba(12, 96, 162, 0.1);
    color: var(--gr-blue);
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    font-size: 1rem;
}
.gr-timeline.is-complete .gr-timeline-icon {
    background: rgba(76, 175, 80, 0.15);
    color: var(--gr-green);
}
.gr-timeline-track {
    display: flex;
    position: relative;
}
/* Base rail: a single unbroken bar from the first dot's center to the last dot's center (each
   dot sits at the midpoint of its 1/steps-wide column, so the rail is inset by half a column on
   each side) - avoids stitching per-segment half-lines together, which left visible gaps where
   they were supposed to meet under each dot. */
.gr-timeline-track::before {
    content: '';
    position: absolute;
    top: 6px;
    left: calc(50% / var(--steps));
    right: calc(50% / var(--steps));
    height: 2px;
    background: #e7ebf0;
    z-index: 1;
}
/* Fill: same left edge as the rail, width set inline from PHP as (doneCount - 1) / steps * 100%,
   which lands exactly on each dot's center in turn - one continuous colored bar, not per-segment
   pieces, so there's nothing for a rounding gap to hide in. */
.gr-timeline-fill {
    position: absolute;
    top: 6px;
    left: calc(50% / var(--steps));
    height: 2px;
    background: var(--gr-blue);
    z-index: 1;
}
.gr-timeline.is-complete .gr-timeline-fill {
    background: var(--gr-green);
}
.gr-timeline-step {
    flex: 1;
    position: relative;
    z-index: 2;
    text-align: center;
    min-width: 0;
}
.gr-timeline-dot {
    display: block;
    width: 14px;
    height: 14px;
    margin: 0 auto;
    border-radius: 50%;
    background: #fff;
    border: 2px solid #c8d0d8;
}
.gr-timeline-step.is-done .gr-timeline-dot {
    background: var(--gr-blue);
    border-color: var(--gr-blue);
}
.gr-timeline.is-complete .gr-timeline-step.is-done .gr-timeline-dot {
    background: var(--gr-green);
    border-color: var(--gr-green);
}
.gr-timeline-label {
    margin-top: 0.5rem;
}
.gr-timeline-value {
    font-weight: 500;
}
.gr-timeline-step form {
    margin-top: 0.15rem;
}

/* ---------- Task list rows (rent/educate/settle/stay/depart/move/immigrate): the next pending
   task gets a stronger highlight than the rest, and completed/cancelled tasks fade back ---------- */
.task-row-next {
    background: rgba(240, 173, 78, 0.18);
    border-radius: var(--gr-radius-sm);
}
/* The row sits flush against its scroll-column's edge with no gap, and that column is itself
   flush against the outer .gr-card's rounded corner - so when the highlighted row lands first or
   last, its own (smaller) corner radius doesn't reach as far as the card's, and the tinted
   background pokes past the card's border arc. Matching the card's own radius on just that
   corner fixes it without touching .gr-card generally (which needs to stay overflow:visible for
   dropdowns elsewhere). */
.task-row-next:first-child {
    border-top-left-radius: var(--gr-radius);
}
.task-row-next:last-child {
    border-bottom-left-radius: var(--gr-radius);
}
.task-row-next-label {
    font-weight: 700;
    color: #8a5a00;
}

/* ---------- Task timeline (client Rent/Educate/Settle "Tasks" subtab): a single vertical
   accordion - task name + status dot on a connecting line, click to expand its description right
   there - instead of the reference's static two-column list-with-a-side-panel. The next-pending
   highlight above (.task-row-next / .task-row-next-label) is untouched; it's just applied to this
   different shape of row now. ---------- */
.gr-task-timeline-header-row {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    padding: 0.9rem 1.5rem;
    border-bottom: 1px solid var(--gr-border);
    color: var(--gr-blue);
}
.gr-task-timeline-header-row i {
    font-size: 1.05rem;
}
.gr-task-timeline {
    padding: 0.5rem 1.5rem;
}
.gr-task-timeline-item {
    position: relative;
    padding: 0.75rem 0.5rem 1.5rem 3.25rem;
    border-radius: var(--gr-radius-sm);
    cursor: pointer;
}
.gr-task-timeline-item:last-child {
    padding-bottom: 0.75rem;
}
.gr-task-timeline-item:not(:last-child)::before {
    content: '';
    position: absolute;
    left: 1.94rem;
    top: 2.6rem;
    bottom: 0;
    width: 2px;
    background: var(--gr-border);
}
.gr-task-timeline-dot {
    position: absolute;
    left: 1rem;
    top: 0.75rem;
    width: 30px;
    height: 30px;
    display: flex;
    align-items: center;
    justify-content: center;
    background: #fff;
    border-radius: 50%;
    font-size: 1.2rem;
    z-index: 1;
}
.gr-task-timeline-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
}
.gr-task-timeline-label {
    font-size: 0.98rem;
    font-weight: 600;
    color: #2b2f36;
}
.gr-task-timeline-actions {
    flex-shrink: 0;
}
.gr-task-timeline-actions .icon-btn {
    width: 32px;
    height: 32px;
}
.gr-task-timeline-body {
    margin-top: 0.85rem;
    padding: 1rem 1.1rem;
    background: #fff;
    border: 1px solid var(--gr-border);
    border-radius: var(--gr-radius-sm);
    font-size: 0.92rem;
    line-height: 1.7;
    color: #4a5568;
    cursor: default;
}

/* Client-only trial of a lighter "next task" treatment (client/rent.php, client/educate.php,
   client/settle.php Tasks tabs): a filled blue dot + small "NEXT" badge instead of painting the
   whole row's background. Scoped through .gr-task-timeline-item, which only exists in these 3
   files, so the shared .task-row-next/.task-row-next-label rules above are untouched everywhere
   else (staff Progress tab, client Immigrate/Depart/Move, every other task list in the app) -
   deliberately side-by-side for comparison before deciding whether to roll this out further. It
   also makes "is next" a real label (the badge), not just a color, so it stays legible once the
   client opens a *different* task and the dot/badge are the only things still marking which one
   is "up next" - the highlight no longer needs to double as an "is this open" signal. */
.gr-task-timeline-item.task-row-next {
    background: none;
}
.gr-task-timeline-item.task-row-next .gr-task-timeline-dot {
    background: var(--gr-blue);
    box-shadow: 0 0 0 4px rgba(12, 96, 162, 0.15);
}
.gr-task-timeline-item.task-row-next .gr-task-timeline-dot i {
    color: #fff;
}
.gr-task-timeline-item.task-row-next .task-row-next-label {
    color: var(--gr-blue-dark);
}
.gr-task-next-badge {
    display: inline-flex;
    align-items: center;
    font-size: 0.62rem;
    font-weight: 700;
    letter-spacing: 0.04em;
    padding: 0.2rem 0.55rem;
    border-radius: var(--gr-radius-pill);
    background: var(--gr-blue);
    color: #fff;
}
.gr-task-next-badge-completed {
    background: var(--gr-green);
}
.gr-task-next-badge-cancelled {
    background: var(--gr-text-muted);
}
/* Client Immigrate's task list (client/immigrate.php) is a much tighter layout (a narrow
   scrolling column nested inside a procedure card) than rent/educate/settle's timeline, so it
   gets the same spirit - no flat background, blue accent, NEXT badge - without the big dot; just
   recolors the existing small icon. .gr-imm-task-row is a marker unique to this client file, so
   the staff equivalent (relocations/tabs/immigrate.php), which shares the bare .task-row/
   .task-row-next classes, is untouched. */
.gr-imm-task-row.task-row-next {
    background: none;
}
.gr-imm-task-row.task-row-next > i {
    color: var(--gr-blue);
}
.gr-imm-task-row.task-row-next .task-row-next-label {
    color: var(--gr-blue-dark);
}

/* ---------- Latest activity feed (dashboard) ---------- */
.gr-activity-feed {
    position: relative;
    padding-left: 1.6rem;
}
.gr-activity-feed::before {
    content: '';
    position: absolute;
    left: 4px;
    top: 6px;
    bottom: 6px;
    width: 2px;
    background: var(--gr-border);
}
.gr-activity-row {
    position: relative;
    padding: 0.85rem 0 0.85rem 0.6rem;
}
.gr-activity-row::before {
    content: '';
    position: absolute;
    left: -1.6rem;
    top: 1.15rem;
    width: 9px;
    height: 9px;
    border-radius: 50%;
    background: #fff;
    border: 2px solid var(--gr-blue);
}
.gr-activity-row:not(:last-child) {
    border-bottom: 1px solid var(--gr-border);
}

/* ---------- Stay dashboard stage cards ---------- */
.gr-stage-card {
    border: 1px solid var(--gr-border);
    border-radius: var(--gr-radius);
    padding: 1.1rem 1.25rem;
    display: flex;
    align-items: center;
    justify-content: space-between;
    color: #c6ccd4;
    font-weight: 600;
    box-shadow: var(--gr-shadow-xs);
    transition: box-shadow 0.2s var(--gr-ease), transform 0.2s var(--gr-ease);
}
.gr-stage-card.has-items { color: #2b2f36; box-shadow: var(--gr-shadow-sm); }
.gr-stage-card.has-items:hover { transform: translateY(-2px); box-shadow: var(--gr-shadow-md); }
.gr-stage-card .count { font-size: 1.4rem; font-weight: 700; }
.gr-stage-card.active-stage {
    border-color: var(--gr-blue);
    background: #eef5fc;
    color: var(--gr-blue);
    box-shadow: var(--gr-shadow-sm);
}
.gr-stage-card.active-stage .count { color: var(--gr-blue); }

/* ---------- Engagement badge ---------- */
.engagement-badge {
    display: inline-block;
    background: #48c774;
    color: #fff;
    font-weight: 700;
    font-size: 0.72rem;
    letter-spacing: 0.04em;
    padding: 0.4rem 0.9rem;
    border-radius: var(--gr-radius-pill);
    box-shadow: var(--gr-shadow-xs);
}

/* ---------- Relocation detail top mini-nav ---------- */
.gr-subnav {
    border-bottom: none;
    background: #fff;
    box-shadow: 0 1px 0 var(--gr-border), 0 6px 18px rgba(15, 23, 42, 0.04);
    position: relative;
    z-index: 10;
}
.gr-subnav::after {
    content: '';
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    height: 2px;
    background: linear-gradient(90deg, var(--gr-blue) 0%, rgba(12, 96, 162, 0.15) 45%, rgba(12, 96, 162, 0) 70%);
}
.gr-subnav-inner {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.75rem;
    row-gap: 0.5rem;
    max-width: 1800px;
    margin: 0 auto;
    padding: 0.7rem 1.25rem;
}
.gr-subnav-person {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    color: #495057;
    font-weight: 600;
    padding: 0.3rem 0.7rem;
    border-radius: var(--gr-radius-pill);
    transition: background 0.15s var(--gr-ease);
}
.gr-subnav-person:hover {
    background: var(--gr-bg);
    text-decoration: none;
}
.gr-subnav-icons { display: flex; align-items: center; gap: 0.25rem; flex-wrap: wrap; margin-left: auto; }
@media (max-width: 575.98px) {
    /* Forced onto its own full-width row, always - not left to wrap wherever it happens to run
       out of space, which put a different split of icons on line 1 vs line 2 depending on what
       else was in the bar. */
    .gr-subnav-icons { flex-basis: 100%; margin-left: 0; }
    /* Row 1: logo stays left, the Dashboard/module dropdown (the only other visible item once
       gr-subnav-person is hidden) pushes to the right edge. Row 2: the icon cluster stays left,
       the staff avatar pushes to the right edge of that row. */
    .gr-subnav-section { margin-left: auto; }
    .gr-subnav-avatar { margin-left: auto; }
    /* includes/navbar.php wraps its logo+dropdown in an extra container (relocations/_subnav.php
       doesn't - logo and dropdown sit as direct siblings there) - margin-left: auto on the
       dropdown has no effect unless this wrapper itself spans the row's full width first. */
    .gr-navbar-left {
        width: 100%;
    }
    /* Immigration procedures toolbar: once the sort select + "+" button wrap below the heading,
       spread them across the full row (select left, button right) instead of leaving them
       clustered together on the left. */
    .imm-proc-toolbar-actions { width: 100%; justify-content: space-between; }
}

/* ---------- Side panel (documents/messages/schedule/profile summary) ---------- */
.gr-side-panel {
    position: fixed;
    top: 0;
    right: -420px;
    width: 400px;
    max-width: 92vw;
    height: 100vh;
    /* Dynamic viewport height: on tablets/phones, 100vh is measured against the layout viewport
       and doesn't shrink when the on-screen keyboard opens, so a form pinned to the bottom of a
       fixed 100vh panel (the message composer below) ends up hidden behind the keyboard. dvh
       tracks the actual visible viewport instead - falls back to the line above where unsupported. */
    height: 100dvh;
    background: #fff;
    border-radius: var(--gr-radius-lg) 0 0 var(--gr-radius-lg);
    z-index: 1050;
    transition: right 0.3s var(--gr-ease);
    display: flex;
    flex-direction: column;
}
/* The shadow only applies once open - it's set here rather than unconditionally above because
   box-shadow isn't clipped by the panel sitting just off-screen (its blur radius bled back into
   the visible page as a permanent dark strip along the right edge even while "closed"). */
.gr-side-panel.open { right: 0; box-shadow: var(--gr-shadow-lg); }
.gr-side-panel-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 1.35rem 1.5rem;
    border-bottom: 1px solid var(--gr-border);
    font-weight: 700;
    font-size: 1.05rem;
    border-radius: var(--gr-radius-lg) 0 0 0;
    background: linear-gradient(135deg, rgba(12, 96, 162, 0.07), rgba(12, 96, 162, 0) 60%);
}
.gr-side-panel-body {
    padding: 1.4rem;
    overflow-y: auto;
    flex: 1;
    position: relative;
}
/* Filling this via percentage height (height:100%) depends on the ancestor chain having a
   definite height at every step, which some tablet browsers don't resolve reliably through a
   flex:1 parent - the composer form (the last flex child, pinned to the bottom) would then
   collapse out of view instead of just staying put. Absolute positioning against the now-relative
   .gr-side-panel-body sidesteps that entirely - it doesn't depend on percentage-height resolution. */
.thread-detail-block {
    position: absolute;
    inset: 0;
    flex-direction: column;
}
.gr-side-panel-backdrop {
    position: fixed;
    inset: 0;
    background: rgba(15, 23, 42, 0.32);
    backdrop-filter: blur(1px);
    z-index: 1040;
    display: none;
}
.gr-side-panel-backdrop.open { display: block; }

.gr-summary-row {
    display: flex;
    gap: 0.9rem;
    padding: 1rem 0;
    border-bottom: 1px solid var(--gr-border);
}
.gr-summary-row i { color: #8a94a3; width: 20px; }
.gr-summary-row .label { color: #8a94a3; font-size: 0.78rem; }

/* ---------- Relocation Profile tab ---------- */
.gr-profile-section { display: flex; gap: 0.9rem; padding: 1.1rem 0; position: relative; }
.gr-profile-section:not(:last-child)::before {
    content: '';
    position: absolute;
    left: 9px;
    top: 2.1rem;
    bottom: -1rem;
    width: 1px;
    background: var(--gr-border);
}
.gr-profile-section .gr-profile-icon { width: 20px; flex-shrink: 0; color: #8a94a3; text-align: center; }
.gr-profile-section .gr-profile-content { flex: 1; min-width: 0; }
.gr-profile-section .gr-profile-content .title { font-weight: 700; margin-bottom: 0.5rem; }
.gr-profile-section .gr-profile-content .row-line { color: var(--gr-text-muted); margin-bottom: 0.25rem; }
.gr-profile-section .gr-profile-content .row-line strong { color: inherit; font-weight: 700; }
.gr-profile-section .gr-profile-edit { flex-shrink: 0; color: #c6ccd4; }
.gr-profile-section.gr-profile-muted { background: var(--gr-bg); border-radius: var(--gr-radius); padding: 1.1rem 1.25rem; }
/* "Coming up" preview badge (staff Progress tab) - Immigrate's "where" label can list several
   family members on one procedure, so it's capped and truncated with an ellipsis (full text in
   the title tooltip) instead of pushing the task name into a near-zero-width column. */
.gr-next-task-badge {
    /* Fixed px, not a %: this badge now sits inside .gr-coming-up-meta (an auto/shrink-to-fit
       flex item on the "Coming up" list pages), and a percentage max-width there resolves against
       that container's own not-yet-determined width - which made the badge truncate unpredictably
       (and always) instead of only when genuinely needed. */
    flex-shrink: 0;
    max-width: 160px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
/* "Coming up" full list (client/next.php, relocations/next.php): on a narrow phone there's simply
   not room for icon(s) + task name + badge + action buttons on one line - forcing them to share
   it is what squeezed the name down to breaking mid-word. Below this width the task name gets its
   own full-width line, and every badge/button after it (grouped in .gr-coming-up-meta) wraps to
   the line under that instead. */
@media (max-width: 576px) {
    .gr-coming-up-row {
        flex-wrap: wrap;
        row-gap: 0.5rem;
    }
    .gr-coming-up-row > .flex-grow-1 {
        flex-basis: 100%;
    }
    .gr-coming-up-meta {
        flex-basis: 100%;
        flex-wrap: wrap;
        justify-content: flex-end;
    }
}

/* Client "Coming up" page: tasks grouped per service, service filter chips, and the next pending
   task of each group highlighted (client/next.php only - staff's relocations/next.php doesn't use
   these classes). */
.gr-coming-up-filters {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
}
.gr-coming-up-chip {
    border: 1px solid var(--gr-border);
    background: #fff;
    color: inherit;
    border-radius: var(--gr-radius-pill);
    padding: 0.3rem 0.9rem;
    font-size: 0.85rem;
    cursor: pointer;
    transition: background 0.15s var(--gr-ease), color 0.15s var(--gr-ease), border-color 0.15s var(--gr-ease);
}
.gr-coming-up-chip:hover {
    border-color: var(--gr-blue);
}
.gr-coming-up-chip.active {
    background: var(--gr-blue);
    border-color: var(--gr-blue);
    color: #fff;
}
.gr-coming-up-next .gr-coming-up-name {
    font-weight: 600;
    color: var(--gr-blue-dark);
}
.gr-coming-up-next .gr-coming-up-status-icon {
    color: var(--gr-blue);
}

.gr-nationality-pill, .gr-task-pill {
    display: inline-block;
    padding: 0.3rem 0.85rem;
    border-radius: var(--gr-radius-pill);
    background: var(--gr-blue);
    color: #fff;
    font-size: 0.78rem;
    margin: 0.15rem 0.3rem 0.15rem 0;
    box-shadow: var(--gr-shadow-xs);
}

/* Small dark tooltip-style hint shown on demand (e.g. "mark at least one service as billable") -
   not a native title attribute since it needs to stay open (click-triggered, not hover) and wrap
   onto multiple lines. */
.gr-inline-tip {
    position: absolute;
    top: 100%;
    right: 0;
    margin-top: 0.5rem;
    width: 220px;
    background: #33383d;
    color: #fff;
    font-size: 0.75rem;
    font-weight: 400;
    text-transform: none;
    line-height: 1.4;
    padding: 0.6rem 0.8rem;
    border-radius: var(--gr-radius-sm);
    box-shadow: var(--gr-shadow-md);
    z-index: 20;
}

.gr-remove-service-label {
    cursor: pointer;
    color: var(--gr-muted-light, #8a939c);
    font-size: 1rem;
    margin: 0;
}
.gr-remove-service-label:hover {
    color: #dc3545;
}
.gr-remove-service-checkbox:checked ~ i {
    color: #dc3545;
}
.gr-service-row-removing input:not(.gr-remove-service-checkbox) {
    text-decoration: line-through;
    opacity: 0.55;
}

/* ---------- Login ---------- */
.gr-login-wrap {
    min-height: 100vh;
    background-size: cover;
    background-position: center;
    display: flex;
    align-items: center;
    justify-content: center;
}
.gr-login-card {
    background: #fff;
    border-radius: var(--gr-radius-lg);
    box-shadow: var(--gr-shadow-lg);
    padding: 2.75rem;
    width: 380px;
    max-width: 92vw;
    text-align: center;
}
.gr-login-card .gr-logo {
    display: inline-flex;
    margin: 0 auto 1.5rem;
}
.gr-login-card .gr-logo img {
    height: 96px;
}
@media (max-width: 400px) {
    .gr-login-card { padding: 1.75rem; }
    .gr-login-card .gr-logo img { height: 76px; }
}

/* ---------- Misc ---------- */
.text-muted-light { color: var(--gr-text-muted); }
.small-caps-label {
    font-size: 0.72rem;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--gr-text-muted);
    font-weight: 700;
}
.btn-primary-gr {
    background: var(--gr-blue);
    border-color: var(--gr-blue);
    color: #fff;
    border-radius: var(--gr-radius-pill);
    font-weight: 600;
    padding-left: 1.3rem;
    padding-right: 1.3rem;
    box-shadow: var(--gr-shadow-xs);
    transition: background 0.15s var(--gr-ease), border-color 0.15s var(--gr-ease), transform 0.15s var(--gr-ease), box-shadow 0.15s var(--gr-ease);
}
.btn-primary-gr:hover {
    background: var(--gr-blue-dark);
    border-color: var(--gr-blue-dark);
    color: #fff;
    transform: translateY(-1px);
    box-shadow: var(--gr-shadow-sm);
}
/* Rounder, pill-shaped buttons app-wide (Bootstrap's plain outline variants, not just our
   custom -gr classes) - a small but pervasive touch away from the stock squared-off look. */
.btn-outline-secondary,
.btn-outline-danger {
    border-radius: var(--gr-radius-pill);
}
.btn-outline-secondary,
.btn-outline-danger {
    font-weight: 600;
}

.property-thumb {
    width: 64px;
    height: 64px;
    border-radius: var(--gr-radius-sm);
    object-fit: cover;
    background: #e7ebf0;
    box-shadow: var(--gr-shadow-xs);
}

/* ---------- School & property cards (client Schools/Archived and Rent Considering/Archived
   subtabs): a responsive card grid, photo on top, floating corner actions over it, pill tags -
   instead of the reference's flush list with fixed-width columns in a fixed order. .gr-property-*
   shares every rule with .gr-school-* (same visual language, just a different data set) rather
   than duplicating the block. Cards intentionally get no hover transform/overflow:hidden
   together: some of these cards hold a Bootstrap modal and/or dropdown-menu (position:fixed /
   position:absolute), and a transformed ancestor would turn into its containing block and clip
   them against overflow - same trap already hit and fixed elsewhere in this app. */
.gr-school-grid,
.gr-property-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(270px, 1fr));
    gap: 1.1rem;
}
.gr-school-card,
.gr-property-card {
    position: relative;
    background: #fff;
    border: 1px solid var(--gr-border);
    border-radius: var(--gr-radius);
    box-shadow: var(--gr-shadow-sm);
    display: flex;
    flex-direction: column;
    transition: box-shadow 0.2s var(--gr-ease);
}
.gr-school-card:hover,
.gr-property-card:hover {
    box-shadow: var(--gr-shadow-md);
}
.gr-school-card-media,
.gr-property-card-media {
    position: relative;
    height: 128px;
    background: var(--gr-bg);
    border-top-left-radius: var(--gr-radius);
    border-top-right-radius: var(--gr-radius);
    overflow: hidden;
}
.gr-school-card-media img,
.gr-property-card-media img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}
.gr-school-card-media > .bi,
.gr-property-card-media > .bi {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    font-size: 2rem;
    color: #c6ccd4;
}
.gr-property-new-badge {
    position: absolute;
    top: 0.6rem;
    left: 0.6rem;
    font-size: 0.65rem;
    letter-spacing: 0.03em;
    padding: 0.2rem 0.5rem;
}
/* .gr-property-card-actions sits outside .gr-property-card-media (a sibling, positioned against
   the card itself) even though it visually floats over the photo - so the status dropdown-menu
   and archive modal it contains are never clipped by the media block's own overflow:hidden. */
.gr-school-card-actions,
.gr-property-card-actions {
    position: absolute;
    top: 0.6rem;
    right: 0.6rem;
    display: flex;
    gap: 0.4rem;
    z-index: 1;
}
.gr-school-card-actions a,
.gr-school-card-actions button,
.gr-property-card-actions a,
.gr-property-card-actions .gr-card-action-btn {
    width: 32px;
    height: 32px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: 50%;
    background: rgba(255, 255, 255, 0.92);
    color: var(--gr-text-muted);
    border: none;
    box-shadow: var(--gr-shadow-xs);
    transition: background 0.15s var(--gr-ease), color 0.15s var(--gr-ease);
}
.gr-school-card-actions a:hover,
.gr-school-card-actions button:hover,
.gr-property-card-actions a:hover,
.gr-property-card-actions .gr-card-action-btn:hover {
    background: var(--gr-blue);
    color: #fff;
}
.gr-property-card-actions .dropdown-menu {
    width: max-content;
}
.gr-school-card-body,
.gr-property-card-body {
    padding: 1rem 1.1rem 1.1rem;
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    flex-grow: 1;
}
.gr-school-card-name,
.gr-property-card-name {
    font-weight: 700;
    font-size: 0.98rem;
    color: var(--gr-blue);
}
.gr-school-card-meta,
.gr-property-card-meta {
    color: var(--gr-text-muted);
    font-size: 0.82rem;
    display: flex;
    align-items: center;
    gap: 0.35rem;
}
.gr-school-card-tags,
.gr-property-card-tags {
    display: flex;
    flex-wrap: wrap;
    gap: 0.4rem;
    margin-top: auto;
    padding-top: 0.4rem;
}
.gr-school-type-pill,
.gr-property-info-pill {
    display: inline-flex;
    align-items: center;
    gap: 0.25rem;
    padding: 0.25rem 0.65rem;
    border-radius: var(--gr-radius-pill);
    background: var(--gr-bg);
    border: 1px solid var(--gr-border);
    font-size: 0.74rem;
    color: #4a5568;
}
.gr-school-selected-pill,
.gr-property-selected-pill {
    display: inline-flex;
    align-items: center;
    gap: 0.25rem;
    padding: 0.25rem 0.65rem;
    border-radius: var(--gr-radius-pill);
    background: var(--gr-blue);
    color: #fff;
    font-size: 0.74rem;
}
.gr-school-card-archive-note,
.gr-property-card-archive-note {
    font-size: 0.8rem;
    color: var(--gr-text-muted);
    border-top: 1px solid var(--gr-border);
    padding-top: 0.5rem;
    margin-top: 0.2rem;
    display: flex;
    flex-direction: column;
    gap: 0.2rem;
}
.gr-school-card-archive-note .small-caps-label,
.gr-property-card-archive-note .small-caps-label {
    margin-right: 0.3rem;
}

/* ---------- Detail-page hero (client School and Property pages): the photo with name/address
   (and, on Property, the price) overlaid and floating actions on it - instead of the reference's
   flat photo plus a duplicate name/address/price card stacked next to or under it. .gr-school-*
   names are kept as aliases so the school page needs no change. No transform on hover here
   (nothing to hover), so no modal-clipping trap to guard. */
/* The wrap is a non-clipping positioned parent: the hero photo itself is overflow:hidden (rounded
   corners), but the floating actions - which include a Bootstrap dropdown menu - live in the wrap
   as a sibling of the photo so the menu is never clipped by that overflow. */
.gr-detail-hero-wrap {
    position: relative;
}
.gr-school-hero,
.gr-detail-hero {
    position: relative;
    border-radius: var(--gr-radius);
    overflow: hidden;
    height: 420px;
    background: var(--gr-bg);
}
/* The property hero (client property page, and property stops in the client tour viewer) is taller
   than the school one - listing photos are wide and were being cropped hard at 420px. Scales with
   the width so it stays proportionate on narrower screens. */
.gr-detail-hero {
    height: clamp(380px, 40vw, 560px);
}
.gr-school-hero img,
.gr-detail-hero > img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}
.gr-school-hero > .bi-building,
.gr-detail-hero > .bi {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    font-size: 3rem;
    color: #c6ccd4;
}
.gr-school-hero-actions,
.gr-detail-hero-actions {
    position: absolute;
    top: 1rem;
    right: 1rem;
    display: flex;
    gap: 0.5rem;
    z-index: 2;
}
.gr-school-hero-actions .icon-btn,
.gr-detail-hero-actions .icon-btn {
    background: rgba(255, 255, 255, 0.92);
}
.gr-school-hero-overlay,
.gr-detail-hero-overlay {
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    padding: 2.75rem 1.5rem 1.25rem;
    background: linear-gradient(to top, rgba(15, 23, 42, 0.72), rgba(15, 23, 42, 0));
    color: #fff;
    /* text-only, so let clicks fall through to the photo (opens the lightbox on the property page) */
    pointer-events: none;
}
.gr-school-hero-name,
.gr-detail-hero-name {
    font-size: 1.35rem;
    font-weight: 700;
}
.gr-school-hero-address,
.gr-detail-hero-address {
    font-size: 0.85rem;
    opacity: 0.9;
}
.gr-detail-hero-price {
    font-size: 1.15rem;
    font-weight: 700;
    margin-top: 0.5rem;
}
.gr-detail-hero-price span {
    font-size: 0.8rem;
    font-weight: 400;
    opacity: 0.85;
}
/* Clicking the hero photo opens the lightbox - make that affordance obvious. */
.gr-detail-hero-zoom {
    position: absolute;
    bottom: 1rem;
    right: 1rem;
    z-index: 2;
    width: 34px;
    height: 34px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: 50%;
    background: rgba(255, 255, 255, 0.92);
    color: #2b2f36;
    box-shadow: var(--gr-shadow-xs);
    pointer-events: none;
}
.gr-fact-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
    gap: 1.1rem 1rem;
}
.gr-fact-item {
    display: flex;
    align-items: flex-start;
    gap: 0.6rem;
}
/* Long free-text values (e.g. a school's "Other programs" list) get two grid columns instead of
   wrapping word-by-word in one narrow track. Only from 576px up - below that the grid can be a
   single column, where spanning two would create an overflowing implicit track. */
@media (min-width: 576px) {
    .gr-fact-item-wide {
        grid-column: span 2;
    }
}
.gr-fact-item > .bi {
    font-size: 1.1rem;
    color: var(--gr-blue);
    margin-top: 0.2rem;
    flex-shrink: 0;
}
.gr-fact-label {
    font-size: 0.7rem;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--gr-text-muted);
}
.gr-fact-value {
    font-weight: 600;
    font-size: 0.9rem;
}
.gr-tuition-grid {
    display: grid;
    grid-template-columns: 1fr auto;
    row-gap: 0.65rem;
    column-gap: 1.5rem;
    align-items: baseline;
}
.gr-tuition-value {
    font-variant-numeric: tabular-nums;
    font-weight: 600;
}
.gr-contact-line {
    display: flex;
    align-items: center;
    gap: 0.55rem;
    font-size: 0.85rem;
}
.gr-contact-icon {
    width: 26px;
    height: 26px;
    border-radius: 50%;
    background: var(--gr-bg);
    color: var(--gr-blue);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    font-size: 0.8rem;
}

/* ---------- "My Home" page (client Rent > My Home): icon-rail section nav instead of a plain
   Bootstrap list-group, a hero photo (property_details) with the address overlaid instead of a
   duplicate text block beside it, and label/value definition grids instead of Bootstrap's
   row/col-md-N grid of muted-label-over-value pairs used throughout the reference. */
.gr-myhome-nav {
    display: flex;
    flex-direction: column;
    gap: 0.35rem;
}
.gr-myhome-nav-item {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    padding: 0.75rem 0.9rem;
    border-radius: var(--gr-radius-sm);
    border: 1px solid transparent;
    color: inherit;
    text-decoration: none;
    transition: background 0.15s var(--gr-ease), border-color 0.15s var(--gr-ease);
}
.gr-myhome-nav-item:hover {
    background: var(--gr-bg);
    text-decoration: none;
    color: inherit;
}
.gr-myhome-nav-item.active {
    background: #fff;
    border-color: var(--gr-border);
    box-shadow: var(--gr-shadow-sm);
    color: var(--gr-blue);
}
.gr-myhome-nav-icon {
    width: 32px;
    height: 32px;
    border-radius: 50%;
    background: var(--gr-bg);
    color: var(--gr-blue);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    font-size: 0.9rem;
}
.gr-myhome-nav-item.active .gr-myhome-nav-icon {
    background: var(--gr-blue);
    color: #fff;
}
.gr-myhome-nav-label {
    flex-grow: 1;
    font-weight: 600;
    font-size: 0.88rem;
}
.gr-myhome-nav-chevron {
    color: var(--gr-text-muted);
    font-size: 0.75rem;
}

.gr-myhome-hero {
    position: relative;
    border-radius: var(--gr-radius);
    overflow: hidden;
    height: 260px;
    background: var(--gr-bg);
}
.gr-myhome-hero img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}
.gr-myhome-hero > .bi-house {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    font-size: 3rem;
    color: #c6ccd4;
}
.gr-myhome-hero-doc-btn {
    position: absolute;
    top: 1rem;
    right: 1rem;
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    padding: 0.5rem 0.9rem;
    border-radius: var(--gr-radius-pill);
    background: rgba(255, 255, 255, 0.94);
    border: none;
    font-size: 0.82rem;
    font-weight: 600;
    color: #2b2f36;
    box-shadow: var(--gr-shadow-xs);
    transition: background 0.15s var(--gr-ease), color 0.15s var(--gr-ease);
}
.gr-myhome-hero-doc-btn:hover {
    background: var(--gr-blue);
    color: #fff;
}
.gr-myhome-hero-overlay {
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    padding: 2.75rem 1.5rem 1.25rem;
    background: linear-gradient(to top, rgba(15, 23, 42, 0.72), rgba(15, 23, 42, 0));
    color: #fff;
}
.gr-myhome-hero-title {
    font-size: 1.3rem;
    font-weight: 700;
}
.gr-myhome-hero-address {
    font-size: 0.85rem;
    opacity: 0.9;
}

.gr-myhome-compact {
    display: flex;
    align-items: center;
    gap: 1rem;
    background: #fff;
    border: 1px solid var(--gr-border);
    border-radius: var(--gr-radius);
    box-shadow: var(--gr-shadow-sm);
    padding: 0.9rem 1.1rem;
}
.gr-myhome-compact img,
.gr-myhome-compact-noimg {
    width: 72px;
    height: 72px;
    border-radius: var(--gr-radius-sm);
    object-fit: cover;
    flex-shrink: 0;
    background: var(--gr-bg);
}
.gr-myhome-compact-noimg {
    display: flex;
    align-items: center;
    justify-content: center;
    color: #c6ccd4;
    font-size: 1.4rem;
}

.gr-definition-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
    gap: 1rem 1.25rem;
}
.gr-definition-item {
    display: flex;
    flex-direction: column;
    gap: 0.2rem;
    font-size: 0.9rem;
}
.gr-definition-item-wide {
    grid-column: span 2;
}
.gr-definition-item-full {
    grid-column: 1 / -1;
}

/* ---------- "My profile" page (client only): a card grid instead of the reference's single
   vertical connected-line list (relocations/tabs/profile.php keeps that list style for staff -
   .gr-profile-section there is untouched, these are new classes so nothing shared breaks). Each
   section is its own card with an icon-badge header and a corner-pinned edit pencil; two sections
   (Leasing, Temporary accommodation) have no edit modal in this file, same as before - their
   pencil stays a plain non-interactive icon, not a button. */
.gr-profile-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
    gap: 1rem;
}
.gr-profile-card-wide {
    grid-column: 1 / -1;
}
.gr-profile-row-split {
    grid-column: 1 / -1;
    display: flex;
    flex-wrap: wrap;
    gap: 1rem;
}
.gr-profile-card-split-wide {
    flex: 3 1 320px;
}
.gr-profile-card-split-narrow {
    flex: 1 1 200px;
}
.gr-profile-card-security {
    display: flex;
    align-items: center;
}
.gr-profile-2x2 {
    grid-column: 1 / -1;
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 1rem;
}
@media (max-width: 640px) {
    .gr-profile-2x2 {
        grid-template-columns: 1fr;
    }
}
.gr-profile-card {
    position: relative;
    background: #fff;
    border: 1px solid var(--gr-border);
    border-radius: var(--gr-radius);
    box-shadow: var(--gr-shadow-sm);
    padding: 1.1rem 1.25rem;
}
.gr-profile-card-photo {
    display: flex;
    align-items: center;
    gap: 1rem;
    grid-column: 1 / -1;
}
.gr-profile-card-header {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    margin-bottom: 0.6rem;
}
.gr-profile-card-icon {
    width: 32px;
    height: 32px;
    border-radius: 50%;
    background: var(--gr-bg);
    color: var(--gr-blue);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    font-size: 0.9rem;
}
.gr-profile-card-title {
    font-weight: 700;
    font-size: 0.95rem;
}
.gr-profile-card-edit {
    position: absolute;
    top: 1rem;
    right: 1.1rem;
    width: 30px;
    height: 30px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: 50%;
    background: transparent;
    border: none;
    color: #c6ccd4;
    transition: background 0.15s var(--gr-ease), color 0.15s var(--gr-ease);
}
button.gr-profile-card-edit:hover {
    background: var(--gr-bg);
    color: var(--gr-blue);
}
.gr-profile-card .row-line {
    color: var(--gr-text-muted);
    font-size: 0.88rem;
    margin-bottom: 0.25rem;
}
.gr-profile-card .row-line strong {
    color: #2b2f36;
    font-weight: 700;
}

/* Give every plain form control the same rounder, softer treatment site-wide. */
.form-control, .form-select {
    border-radius: var(--gr-radius-sm);
    border-color: var(--gr-border);
    transition: border-color 0.15s var(--gr-ease), box-shadow 0.15s var(--gr-ease);
}
.form-control:focus, .form-select:focus {
    border-color: var(--gr-blue);
    box-shadow: 0 0 0 3px rgba(12, 96, 162, 0.14);
}
.btn {
    border-radius: var(--gr-radius-pill);
}
.modal-content {
    border: none;
    border-radius: var(--gr-radius);
    box-shadow: var(--gr-shadow-lg);
}
.modal-header {
    background: linear-gradient(135deg, rgba(12, 96, 162, 0.07), rgba(12, 96, 162, 0) 60%);
    border-top-left-radius: var(--gr-radius);
    border-top-right-radius: var(--gr-radius);
}
.dropdown-menu {
    border: none;
    border-radius: var(--gr-radius);
    box-shadow: var(--gr-shadow-md);
    padding: 0.5rem;
}
.dropdown-item {
    border-radius: var(--gr-radius-sm);
    padding: 0.5rem 0.75rem;
}
.dropdown-item:hover, .dropdown-item.active {
    background: var(--gr-bg);
    color: var(--gr-blue-dark);
}

/* ---------- New relocation wizard ---------- */
.btn-outline-primary-gr {
    background: #fff;
    border-color: var(--gr-blue);
    color: var(--gr-blue);
    border-radius: var(--gr-radius-pill);
    transition: background 0.15s var(--gr-ease), transform 0.15s var(--gr-ease);
}
.btn-outline-primary-gr:hover {
    background: #eaf1f8;
    border-color: var(--gr-blue);
    color: var(--gr-blue-dark);
    transform: translateY(-1px);
}
.btn-check:checked + .btn-outline-primary-gr {
    background: var(--gr-blue);
    border-color: var(--gr-blue);
    color: #fff;
    box-shadow: var(--gr-shadow-xs);
}
.gr-toggle-btn {
    width: 50px;
    height: 50px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: 1.3rem;
    border: 1px solid var(--gr-border);
    border-radius: var(--gr-radius);
    background: var(--gr-bg);
    color: var(--gr-text-muted);
    cursor: pointer;
    transition: background 0.15s var(--gr-ease), transform 0.15s var(--gr-ease), box-shadow 0.15s var(--gr-ease);
}
.gr-toggle-btn:hover {
    transform: translateY(-1px);
    box-shadow: var(--gr-shadow-sm);
}
.gr-toggle-btn.active {
    background: var(--gr-blue);
    border-color: var(--gr-blue);
    color: #fff;
    box-shadow: var(--gr-shadow-sm);
}
.gr-stepper {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
}
.gr-stepper button {
    width: 28px;
    height: 28px;
    border: 1px solid var(--gr-border);
    border-radius: var(--gr-radius-sm);
    background: #fff;
    line-height: 1;
}
.gr-stepper button:disabled {
    color: var(--gr-text-muted);
    background: var(--gr-bg);
}
.gr-stepper input {
    width: 48px;
    text-align: center;
    border-radius: var(--gr-radius-sm);
}
.gr-family-card {
    border: 1px solid var(--gr-border);
    border-radius: var(--gr-radius);
    padding: 1.1rem 1.25rem;
    margin-bottom: 1rem;
    box-shadow: var(--gr-shadow-xs);
}
.type-btn {
    background: #fff;
    border: 1px solid #ced4da;
    color: #2b2f36;
    border-radius: var(--gr-radius-pill);
    padding: 0.4rem 1.1rem;
    transition: border-color 0.15s var(--gr-ease), color 0.15s var(--gr-ease);
}
.type-btn.active {
    border-color: var(--gr-blue);
    color: var(--gr-blue);
    box-shadow: 0 0 0 2px rgba(12, 96, 162, 0.14);
}
.step-card-interactive {
    cursor: pointer;
    transition: box-shadow 0.2s var(--gr-ease), transform 0.2s var(--gr-ease);
}
.step-card-interactive:hover {
    box-shadow: var(--gr-shadow-md);
    transform: translateY(-2px);
}
.step-card-active {
    border-color: var(--gr-blue) !important;
    box-shadow: var(--gr-shadow-sm);
}
.task-row:hover {
    background: var(--gr-bg);
}

/* A footer <button> styled to read exactly like the plain footer links beside it: Bootstrap's .btn
   sets its own font-size/line-height/underline, which made "Cookie settings" larger than
   "Privacy Policy". */
.gr-footer-link-btn {
    font-size: inherit;
    line-height: inherit;
    font-family: inherit;
    text-decoration: none;
    vertical-align: baseline;
}

/* ---------- Bulk-select rows (consultants/relocations.php): a checkbox pinned into the row's left
   padding, so the shared relocation row layout doesn't change for anyone else. ---------- */
.gr-relocation-panel-selectable .gr-relocation-item {
    padding-left: 3.1rem;
}
.gr-ri-select {
    position: absolute;
    left: 1.1rem;
    top: 50%;
    transform: translateY(-50%);
    margin: 0;
    display: flex;
    z-index: 2;
}
@media (max-width: 767.98px) {
    .gr-relocation-panel-selectable .gr-relocation-item {
        padding-left: 1.25rem;
    }
    .gr-ri-select {
        top: 1rem;
        left: 1rem;
        transform: none;
    }
}

/* ---------- Client cookie banner (client/_footer.php). Sits below Bootstrap's modal layer (1050+)
   so opening "Customize" puts the settings modal on top of it. ---------- */
.gr-cookie-banner {
    position: fixed;
    left: 1rem;
    right: 1rem;
    bottom: 1rem;
    max-width: 640px;
    margin: 0 auto;
    padding: 1.1rem 1.25rem;
    background: #fff;
    border: 1px solid var(--gr-border);
    border-radius: var(--gr-radius);
    box-shadow: var(--gr-shadow-md);
    z-index: 1040;
}
.gr-cookie-banner[hidden] {
    display: none;
}
.gr-cookie-banner-actions {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem;
}
@media (max-width: 576px) {
    .gr-cookie-banner-actions .btn-primary-gr {
        flex: 1 1 100%;
    }
}

/* ---------- Tour: clickable stop rows (staff tour builder relocations/tour.php, and the client
   read-only viewer client/tour_view.php - shared class, since the click-to-preview behavior and
   hover/selected affordance are identical on both sides). ---------- */
.gr-tour-stop-row {
    cursor: pointer;
    transition: box-shadow 0.2s var(--gr-ease), border-color 0.2s var(--gr-ease);
}
.gr-tour-stop-row:hover {
    box-shadow: var(--gr-shadow-md);
}
.gr-tour-stop-row.active {
    border-color: var(--gr-blue) !important;
    box-shadow: var(--gr-shadow-sm);
}
/* Client-only stop number: an outlined pill instead of staff's solid filled circle, so the
   client's tour viewer doesn't read as a plain reskin of the staff builder. */
.gr-tour-stop-num {
    width: 26px;
    height: 26px;
    border-radius: 50%;
    border: 1.5px solid var(--gr-blue);
    color: var(--gr-blue);
    font-weight: 700;
    font-size: 0.8rem;
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
}
.gr-tour-stop-row.active .gr-tour-stop-num {
    background: var(--gr-blue);
    color: #fff;
}

/* ---------- Move: stage cards ---------- */
.move-stage-card {
    cursor: pointer;
    border-color: var(--gr-border);
    transition: box-shadow 0.2s var(--gr-ease), transform 0.2s var(--gr-ease), border-color 0.2s var(--gr-ease);
}
.move-stage-card:hover {
    box-shadow: var(--gr-shadow-md);
    transform: translateY(-2px);
}
.move-stage-card-open {
    border-color: var(--gr-blue);
    box-shadow: var(--gr-shadow-sm);
}
.move-stage-card .badge.rounded-pill {
    font-weight: 600;
    font-size: 0.68rem;
}
.move-stage-panel {
    animation: gr-fade-in 0.15s var(--gr-ease);
}
/* Each point (dot + label + date) is one self-contained column, so the label always centers
   under its own dot no matter how long the text is. The connecting line is drawn as two half-
   width pseudo-elements per column (left half + right half) that meet exactly at the shared
   boundary between adjacent columns, instead of trying to keep a separate row of dots/bars in
   sync with a separate row of labels underneath. */
.gr-move-timeline {
    display: flex;
    align-items: flex-start;
}
.gr-move-timeline-point {
    position: relative;
    flex: 1 1 0;
    min-width: 0;
    text-align: center;
    padding-top: 18px;
}
.gr-move-timeline-point:not(:first-child)::before,
.gr-move-timeline-point:not(:last-child)::after {
    content: '';
    position: absolute;
    top: 4px;
    width: 50%;
    height: 2px;
    background: var(--gr-border);
}
.gr-move-timeline-point:not(:first-child)::before {
    left: 0;
}
.gr-move-timeline-point:not(:last-child)::after {
    right: 0;
}
.gr-move-timeline-dot {
    position: absolute;
    top: 0;
    left: 50%;
    transform: translateX(-50%);
    width: 10px;
    height: 10px;
    border-radius: 50%;
    background: var(--gr-blue);
    z-index: 1;
}
.gr-move-timeline-point-label {
    padding: 0 4px;
}
@keyframes gr-fade-in {
    from { opacity: 0; transform: translateY(-4px); }
    to { opacity: 1; transform: translateY(0); }
}
.task-row-label.fw-bold {
    color: #2b2f36;
}
.dropdown-menu-fit {
    min-width: auto;
}
.imm-steps-row {
    display: flex;
    align-items: stretch;
    flex-wrap: wrap;
}
.imm-step-card {
    width: 170px;
}
.imm-step-connector {
    align-self: center;
    flex-shrink: 0;
    width: 40px;
    height: 2px;
    margin: 1.2rem 0.5rem 0;
}
/* Connectors only make visual sense as a straight line between two horizontally-adjacent cards
   in a single unbroken row - once flex-wrap actually breaks the row (5 fixed-170px cards don't
   fit at tablet widths), a connector can land stranded at the wrap seam, floating between a card
   at the end of one row and one at the start of the next with no visible relationship to either.
   Tablet widths get a 2-column grid instead (connectors dropped entirely, a grid has no linear
   "next card" to draw one to); phone widths keep the existing single-column stack. */
@media (min-width: 576px) and (max-width: 991.98px) {
    .imm-steps-row {
        display: grid;
        grid-template-columns: repeat(2, 1fr);
        gap: 0.75rem;
    }
    .imm-step-card {
        width: auto;
    }
    .imm-step-connector {
        display: none;
    }
}
@media (max-width: 575.98px) {
    .imm-steps-row {
        flex-direction: column;
        align-items: stretch;
    }
    .imm-step-card {
        width: 100%;
    }
    .imm-step-connector {
        align-self: center;
        width: 2px;
        height: 20px;
        margin: 0.25rem 0;
    }
}

/* ---------- Immigrate "next action first" layout (client/immigrate.php only -
   relocations/tabs/immigrate.php keeps the card-stepper above, untouched). The step rail replaces
   the 5 large cards - a compact numbered/checked dot per step, connected by a line, with the
   current step highlighted - so the vertical space those cards used to take goes to the thing the
   client actually needs to read and act on (.imm-task-highlight) instead. */
.imm-rail {
    display: flex;
    align-items: flex-start;
}
.imm-rail-step {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.4rem;
    background: none;
    border: none;
    padding: 0;
    flex: 1 1 0;
    min-width: 0;
}
.imm-rail-dot {
    width: 28px;
    height: 28px;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 0.75rem;
    font-weight: 700;
    color: var(--gr-text-muted);
    background: var(--gr-bg);
    border: 2px solid var(--gr-border);
    flex-shrink: 0;
}
.imm-rail-dot-done {
    color: #fff;
    background: var(--gr-blue);
    border-color: var(--gr-blue);
}
.imm-rail-step-active .imm-rail-dot {
    border-color: var(--gr-blue);
    color: var(--gr-blue);
}
.imm-rail-step-active .imm-rail-dot-done {
    color: #fff;
}
.imm-rail-label {
    font-size: 0.68rem;
    color: var(--gr-text-muted);
    text-align: center;
    line-height: 1.2;
}
.imm-rail-step-active .imm-rail-label {
    color: var(--gr-blue-dark);
    font-weight: 700;
}
.imm-rail-connector {
    flex: 0 1 60px;
    height: 2px;
    background: var(--gr-border);
    margin-top: 13px;
}
.imm-rail-connector-done {
    background: var(--gr-blue);
}
@media (max-width: 575.98px) {
    .imm-rail-label {
        display: none;
    }
    .imm-rail-connector {
        flex: 1 1 auto;
    }
}
.imm-task-highlight {
    border: 1px solid var(--gr-border);
    border-left: 4px solid var(--gr-blue);
    border-radius: var(--gr-radius);
    padding: 1rem 1rem 1rem calc(1rem - 3px);
    background: #fff;
}

/* ---------- Discover redesign (client/discover.php AND relocations/tabs/discover.php) ----------
   Originally client-only, now shared by the staff Discover tab too: a compact gradient hero
   instead of a full-bleed photo banner, and horizontal pill/chip navigation instead of a right-hand
   sidebar list with click-to-switch sections. Everything here is scoped under .gr-discover-view,
   which both pages' markup wrap themselves in. --gr-blue/--gr-blue-dark themselves are untouched
   per the brand color rule; --gr-discover-accent reuses the brand blue rather than introducing a
   new color. */
/* Client dashboard destination cover photo - same discover_cities.hero_image_path as the
   .gr-discover-hero below, built on the same side-by-side idea (photo in a fixed-ratio box next to
   the text, not a full-bleed banner) since that's what keeps background-size: cover from having to
   crop a normal landscape photo hard just to fill an ultra-wide strip. */
.gr-dest-hero {
    display: flex;
    align-items: stretch;
    border-radius: var(--gr-radius-lg);
    overflow: hidden;
    box-shadow: var(--gr-shadow-md);
}
.gr-dest-hero-photo {
    position: relative;
    width: 42%;
    max-width: 480px;
    min-height: 260px;
    flex-shrink: 0;
}
.gr-dest-hero-img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}
/* City name lives on the photo itself (not the blue card next to it) - same bottom-gradient
   treatment as .gr-discover-hero-img's caption would use, so it's always legible regardless of
   what's in that part of the photo. */
.gr-dest-hero-photo-overlay {
    position: absolute;
    inset: 0;
    display: flex;
    flex-direction: column;
    justify-content: flex-start;
    padding: 1.25rem 1.5rem;
    background: linear-gradient(180deg, rgba(5, 16, 30, 0.78) 0%, rgba(5, 16, 30, 0) 55%);
    color: #fff;
}
.gr-dest-hero-content {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 1.5rem;
    padding: 1.5rem 2rem;
    flex: 1 1 auto;
    background: #fff;
}
.gr-dest-hero-eyebrow {
    text-transform: uppercase;
    letter-spacing: 0.14em;
    font-size: 0.68rem;
    opacity: 0.85;
}
.gr-dest-hero-title {
    font-size: 1.6rem;
    font-weight: 700;
}
@media (max-width: 576px) {
    .gr-dest-hero {
        flex-direction: column;
    }
    .gr-dest-hero-photo {
        width: 100%;
        max-width: none;
        height: 160px;
        min-height: 0;
    }
}

.gr-discover-view {
    --gr-discover-accent: var(--gr-blue);
}
.gr-discover-hero {
    display: flex;
    align-items: center;
    gap: 1.25rem;
    margin: 1.25rem 1.25rem 1.5rem;
    padding: 1.5rem;
    background: linear-gradient(135deg, var(--gr-blue-dark), var(--gr-blue));
    border-radius: var(--gr-radius-lg);
    color: #fff;
    box-shadow: var(--gr-shadow-md);
}
.gr-discover-view .gr-tabs {
    margin-top: 0.5rem;
}
.gr-discover-hero-img {
    width: 220px;
    height: 128px;
    border-radius: var(--gr-radius);
    object-fit: cover;
    flex-shrink: 0;
    border: 3px solid rgba(255, 255, 255, 0.35);
    box-shadow: var(--gr-shadow-sm);
}
.gr-discover-eyebrow {
    text-transform: uppercase;
    letter-spacing: 0.14em;
    font-size: 0.68rem;
    font-weight: 700;
    color: rgba(255, 255, 255, 0.72);
    margin-bottom: 0.3rem;
}
.gr-discover-title {
    font-size: 1.85rem;
    font-weight: 700;
    margin: 0;
    line-height: 1.15;
}
.gr-discover-tagline {
    margin: 0.35rem 0 0;
    color: rgba(255, 255, 255, 0.85);
}
/* Every group now renders in one continuous scroll instead of one-at-a-time (sidebar links jump
   to an item instead of swapping which block is visible) - a heading + divider per group keeps
   "which section am I in" legible without that switcher. */
.discover-content-block {
    padding-bottom: 2rem;
    margin-bottom: 2rem;
    border-bottom: 1px solid var(--gr-border);
}
.discover-content-block:last-child {
    border-bottom: none;
    margin-bottom: 0;
    padding-bottom: 0;
}
.gr-discover-group-heading {
    font-size: 1.1rem;
    font-weight: 700;
    color: var(--gr-discover-accent, var(--gr-blue));
    margin-bottom: 1.25rem;
}

.gr-discover-sidebar-group {
    border-bottom: 1px solid var(--gr-border);
}
.gr-discover-sidebar-toggle {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 0.85rem 0.1rem;
    font-weight: 600;
    color: #1c2733;
    cursor: pointer;
}
.gr-discover-sidebar-caret {
    color: var(--gr-text-muted);
    font-size: 0.8rem;
}
.gr-discover-sidebar-items {
    display: flex;
    flex-direction: column;
    padding: 0 0 0.75rem 0.1rem;
}
.gr-discover-sidebar-link {
    padding: 0.35rem 0 0.35rem 0.75rem;
    border-left: 2px solid transparent;
    color: #495057 !important;
    font-size: 0.9rem;
    text-decoration: none !important;
    transition: color 0.15s var(--gr-ease), border-color 0.15s var(--gr-ease);
}
.gr-discover-sidebar-link:hover {
    color: var(--gr-blue-dark) !important;
}
.gr-discover-sidebar-link.active {
    color: var(--gr-discover-accent) !important;
    font-weight: 600;
    border-left-color: var(--gr-discover-accent);
}

.gr-discover-content p {
    text-align: justify;
}
.gr-discover-content h2 {
    position: relative;
    padding-left: 1rem;
    color: #1c2733;
}
.gr-discover-content h2::before {
    content: '';
    position: absolute;
    left: 0;
    top: 0.15em;
    bottom: 0.15em;
    width: 4px;
    border-radius: 2px;
    background: var(--gr-discover-accent);
}

@media (max-width: 767.98px) {
    .gr-discover-hero {
        flex-direction: column;
        text-align: center;
        margin: 1rem 1rem 0;
    }
}
