/* ----------------------------------------------------------------------------------------------
CTMS stylesheet: design tokens and the site's own components.

Layered on top of Bootstrap 5, which supplies the grid, buttons and navbar. Bootstrap's own classes
are never redefined here; anything needing different behaviour carries a class of its own.

Breakpoints follow Bootstrap: sm 576, md 768, lg 992, xl 1200. Rules are mobile-first, so a plain
declaration applies to the smallest screen and min-width queries build upward.
---------------------------------------------------------------------------------------------- */

/* --- Design tokens ------------------------------------------------------------------------- */

:root {
    /* Brand */
    --ctms-primary: #0b4fd8;
    --ctms-primary-dark: #06308a;
    --ctms-primary-darker: #041a4d;
    --ctms-accent: #ff9800;
    --ctms-accent-hover: #ffb547;

    /* Status. Each clears WCAG AA both on its pill's tint and as a filled control in white. */
    --ctms-success: #0d7b48;
    --ctms-warning: #995400;
    --ctms-danger: #cc2535;

    /* Text */
    --ctms-text: #313437;
    /* Dark enough to clear WCAG AA against the tinted surfaces below, not only against white. */
    --ctms-text-muted: #656e76;
    --ctms-text-inverse: #ffffff;
    --ctms-text-inverse-muted: rgba(255, 255, 255, 0.72);

    /* Surfaces */
    --ctms-surface: #ffffff;
    --ctms-surface-alt: #eef4f7;
    --ctms-surface-muted: #f5f7fa;
    --ctms-surface-dark: #22272e;

    /* Provider branding, whose values belong to the provider rather than to this palette */
    --ctms-google-text: #3c4043;
    --ctms-google-border: #dadce0;

    /* Lines and shadows */
    --ctms-border: #e3e8ee;
    --ctms-shadow-sm: 0 1px 2px rgba(16, 24, 40, 0.06), 0 1px 3px rgba(16, 24, 40, 0.10);
    --ctms-shadow-md: 0 4px 8px -2px rgba(16, 24, 40, 0.10), 0 2px 4px -2px rgba(16, 24, 40, 0.06);
    --ctms-shadow-lg: 0 12px 16px -4px rgba(16, 24, 40, 0.08), 0 4px 6px -2px rgba(16, 24, 40, 0.03);

    /* Layout */
    --ctms-header-height: 4rem;
    --ctms-section-gap: 3.5rem;
    --ctms-radius: 0.5rem;
    --ctms-radius-lg: 0.875rem;

    /* Motion */
    --ctms-transition: 0.2s ease-in-out;
}

@media (min-width: 992px) {
    :root {
        --ctms-header-height: 4.75rem;
        --ctms-section-gap: 5rem;
    }
}

@media (prefers-reduced-motion: reduce) {
    *,
    *::before,
    *::after {
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.01ms !important;
        scroll-behavior: auto !important;
    }
}

/* --- Base ---------------------------------------------------------------------------------- */

/* The padding clears the fixed header; scroll-padding keeps anchor jumps clear of it as well. */
body {
    color: var(--ctms-text);
    background-color: var(--ctms-surface);
    padding-top: var(--ctms-header-height);
    scroll-padding-top: var(--ctms-header-height);
    -webkit-font-smoothing: antialiased;
}

/* The landing hero sits behind the translucent header, so it supplies its own offset. */
body.has-hero {
    padding-top: 0;
}

h1,
h2,
h3,
h4,
h5,
h6 {
    overflow-wrap: break-word;
}

a {
    transition: color var(--ctms-transition);
}

a:focus-visible,
button:focus-visible,
.btn:focus-visible {
    outline: 3px solid var(--ctms-accent);
    outline-offset: 2px;
}

img {
    max-width: 100%;
    height: auto;
}

/* ----------------------------------------------------------------------------------------------
Section rhythm

Shared vertical spacing and heading treatment for the content sections, so no section restates
its own padding.
---------------------------------------------------------------------------------------------- */

.section {
    padding-top: var(--ctms-section-gap);
    padding-bottom: var(--ctms-section-gap);
}

.section-light {
    background-color: var(--ctms-surface);
}

.section-alt {
    background-color: var(--ctms-surface-alt);
}

.section-muted {
    background-color: var(--ctms-surface-muted);
}

.section-intro {
    max-width: 40rem;
    margin: 0 auto 3rem;
    text-align: center;
}

.section-intro h2 {
    font-weight: 700;
    font-size: clamp(1.5rem, 1.15rem + 1.6vw, 2.25rem);
    margin-bottom: 0.75rem;
    color: inherit;
}

.section-intro p {
    color: var(--ctms-text-muted);
    margin-bottom: 0;
}

/* --- Buttons ------------------------------------------------------------------------------- */

/* One box for every variant, with a transparent border on the filled ones, so a row stays level. */
.btn-ctms,
.btn-ctms-accent,
.btn-ctms-outline,
.btn-ctms-danger,
.btn-google {
    border: 1px solid transparent;
    border-radius: var(--ctms-radius);
    font-weight: 600;
    padding: 0.6875rem 1.5rem;
    transition: background-color var(--ctms-transition), transform var(--ctms-transition), box-shadow var(--ctms-transition);
}

.btn-ctms {
    color: var(--ctms-text-inverse);
    background-color: var(--ctms-primary);
}

.btn-ctms:hover,
.btn-ctms:focus {
    color: var(--ctms-text-inverse);
    background-color: var(--ctms-primary-dark);
    box-shadow: var(--ctms-shadow-md);
}

.btn-ctms-accent {
    color: var(--ctms-primary-darker);
    background-color: var(--ctms-accent);
}

.btn-ctms-accent:hover,
.btn-ctms-accent:focus {
    color: var(--ctms-primary-darker);
    background-color: var(--ctms-accent-hover);
    box-shadow: var(--ctms-shadow-md);
}

.btn-ctms-outline {
    color: var(--ctms-text);
    background-color: transparent;
    border-color: var(--ctms-border);
}

.btn-ctms-outline:hover,
.btn-ctms-outline:focus {
    color: var(--ctms-text);
    background-color: var(--ctms-surface-muted);
    border-color: var(--ctms-text-muted);
}

.btn-ctms-danger {
    color: var(--ctms-danger);
    background-color: transparent;
    border-color: var(--ctms-danger);
}

.btn-ctms-danger:hover,
.btn-ctms-danger:focus {
    color: var(--ctms-text-inverse);
    background-color: var(--ctms-danger);
    border-color: var(--ctms-danger);
}

/* A provider button wears the provider's colours, and mark and wording stay on one line. */
.btn-google {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0.75rem;
    width: 100%;
    color: var(--ctms-google-text);
    background-color: var(--ctms-surface);
    border-color: var(--ctms-google-border);
}

.btn-google:hover,
.btn-google:focus {
    color: var(--ctms-google-text);
    background-color: var(--ctms-surface-muted);
    border-color: var(--ctms-text-muted);
    box-shadow: var(--ctms-shadow-md);
}

.btn-google img {
    flex-shrink: 0;
}

/* Bootstrap's .btn-sm never reaches these on source order, so each variant states its own size. */
.btn-ctms.btn-sm,
.btn-ctms-accent.btn-sm,
.btn-ctms-outline.btn-sm,
.btn-ctms-danger.btn-sm,
.btn-google.btn-sm {
    padding: 0.375rem 0.875rem;
}

.btn-ctms:active,
.btn-ctms-accent:active,
.btn-ctms-outline:active,
.btn-ctms-danger:active,
.btn-google:active {
    transform: translateY(1px);
}

/* ----------------------------------------------------------------------------------------------
Forms

Field wrappers, help text and validation messages. Bootstrap supplies the controls themselves, so
nothing here redefines .form-control, .form-label or .form-check.
---------------------------------------------------------------------------------------------- */

.form-field {
    margin-bottom: 1.125rem;
}

/* A shade lighter than the wording, so it identifies the field without competing with it. */
.form-label-icon {
    margin-right: 0.375rem;
    color: var(--ctms-text-muted);
}

.form-label {
    font-size: 0.875rem;
    font-weight: 600;
    margin-bottom: 0.375rem;
}

.form-field .form-control {
    padding: 0.625rem 0.875rem;
    border-color: var(--ctms-border);
}

.form-field .form-control:focus {
    border-color: var(--ctms-primary);
    box-shadow: 0 0 0 0.2rem rgba(11, 79, 216, 0.15);
}

.form-field-invalid .form-control,
.form-field-invalid .form-check-input {
    border-color: var(--ctms-danger);
}

.form-help {
    margin-top: 0.375rem;
    font-size: 0.8125rem;
    color: var(--ctms-text-muted);
}

/* The password validators publish their help as a list, whose bullets sit outside the field. */
.form-help ul {
    padding-left: 1.125rem;
    margin-bottom: 0;
}

.form-error {
    margin: 0.375rem 0 0;
    font-size: 0.8125rem;
    font-weight: 500;
    color: var(--ctms-danger);
}

.form-error-summary {
    padding: 0.625rem 0.875rem;
    margin: 0 0 1rem;
    background-color: rgba(220, 53, 69, 0.08);
    border-radius: var(--ctms-radius);
}

.password-toggle {
    color: var(--ctms-text-muted);
    border: 1px solid var(--ctms-border);
    border-left: none;
}

.password-toggle:hover,
.password-toggle:focus {
    color: var(--ctms-primary);
    background-color: var(--ctms-surface-muted);
}

/* ----------------------------------------------------------------------------------------------
Authentication pages

A form card beside a photograph. The photograph is decorative and appears from the lg breakpoint
only, so a phone never downloads it and the card keeps the full width of the screen.
---------------------------------------------------------------------------------------------- */

.auth-layout {
    display: grid;
    min-height: calc(100vh - var(--ctms-header-height));
    background: linear-gradient(155deg, var(--ctms-surface-alt) 0%, var(--ctms-surface) 60%);
}

.auth-panel {
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 2.5rem 1rem;
}

.auth-card {
    width: 100%;
    max-width: 30rem;
    padding: 1.75rem 1.25rem;
    background-color: var(--ctms-surface);
    border: 1px solid var(--ctms-border);
    border-radius: var(--ctms-radius-lg);
    box-shadow: var(--ctms-shadow-lg);
}

.auth-brand {
    display: flex;
    align-items: center;
    gap: 0.625rem;
    margin-bottom: 1.5rem;
    font-size: 0.6875rem;
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--ctms-primary);
    text-decoration: none;
}

.auth-brand img {
    flex-shrink: 0;
}

.auth-card-header {
    margin-bottom: 1.5rem;
}

.auth-icon {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 3rem;
    height: 3rem;
    margin: 0 auto 1rem;
    font-size: 1.5rem;
    border-radius: 50%;
}

.auth-icon-success {
    color: var(--ctms-success);
    background-color: rgba(25, 135, 84, 0.12);
}

.auth-icon-warning {
    color: var(--ctms-warning);
    background-color: rgba(255, 152, 0, 0.16);
}

.auth-icon-info {
    color: var(--ctms-primary);
    background-color: rgba(11, 79, 216, 0.1);
}

.auth-title {
    font-weight: 700;
    font-size: clamp(1.375rem, 1.2rem + 0.8vw, 1.75rem);
    margin-bottom: 0.5rem;
}

.auth-subtitle,
.auth-note {
    font-size: 0.9375rem;
    line-height: 1.65;
    color: var(--ctms-text-muted);
    margin-bottom: 0;
}

/* A note introducing a form takes the card header's gap; one closing a card does not. */
.auth-note + .auth-form {
    margin-top: 1.5rem;
}

.auth-submit {
    width: 100%;
    margin-top: 0.5rem;
}

.auth-links {
    display: flex;
    flex-wrap: wrap;
    justify-content: space-between;
    gap: 0.5rem 1.5rem;
    margin-top: 1.5rem;
    padding-top: 1.25rem;
    border-top: 1px solid var(--ctms-border);
    font-size: 0.875rem;
}

/* space-between would pin a single link to the left edge, where it reads as a stray fragment. */
.auth-links a:only-child {
    margin: 0 auto;
}

.auth-links a {
    font-weight: 600;
    color: var(--ctms-primary);
    text-decoration: none;
}

.auth-links a:hover,
.auth-links a:focus {
    color: var(--ctms-primary-dark);
    text-decoration: underline;
}

.auth-visual {
    display: none;
}

@media (min-width: 576px) {
    .auth-card {
        padding: 2.5rem;
    }
}

@media (min-width: 992px) {
    .auth-layout {
        grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    }

    .auth-panel {
        padding: 3rem 2rem;
    }

    .auth-visual {
        display: block;
        background-color: var(--ctms-primary-darker);
        background-position: center;
        background-repeat: no-repeat;
        background-size: cover;
    }

    /* Brand tint over the photograph, so each page reads as part of the same site. */
    .auth-visual::after {
        content: "";
        display: block;
        height: 100%;
        background: linear-gradient(200deg, rgba(4, 26, 77, 0.55) 0%, rgba(4, 26, 77, 0.12) 50%, rgba(11, 79, 216, 0.45) 100%);
    }

    .auth-visual-signin {
        background-image: url("../images/signin-bg.3d9ef3e87f4c.jpg");
    }

    .auth-visual-signup {
        background-image: url("../images/signup-bg.c50db311cac2.jpg");
    }

    .auth-visual-activation-failed {
        background-image: url("../images/activation-failed-bg.45f26c227475.jpg");
    }

    .auth-visual-password-reset {
        background-image: url("../images/password-reset-bg.838b6f106b45.jpg");
    }

    .auth-visual-password-reset-sent {
        background-image: url("../images/password-reset-done-bg.716250c73494.jpg");
    }

    .auth-visual-password-reset-confirm {
        background-image: url("../images/password-reset-confirm-bg.e5ee0dea50a5.jpg");
    }

    .auth-visual-password-reset-complete {
        background-image: url("../images/password-reset-complete-bg.b1a6be0ba692.jpg");
    }

    .auth-visual-password-change {
        background-image: url("../images/password-change-bg.4b250591f0fd.jpg");
    }

    .auth-visual-password-change-done {
        background-image: url("../images/password-change-done-bg.1333b6a2fb97.jpg");
    }

    .auth-visual-email-change {
        background-image: url("../images/change-email-bg.3286049cd017.jpg");
    }

    .auth-visual-username-change {
        background-image: url("../images/change-username-bg.3eae499ecc13.jpg");
    }

    .auth-visual-google-signin {
        background-image: url("../images/google-signin-bg.fe73c40fce37.jpg");
    }

    .auth-visual-social-signin {
        background-image: url("../images/social-signin-bg.992eb76af89d.jpg");
    }
}

/* ----------------------------------------------------------------------------------------------
Social sign-in and reCAPTCHA

The provider button sits above the credentials it is an alternative to, separated by a rule that
carries the word standing between the two ways in.
---------------------------------------------------------------------------------------------- */

.social-signin {
    margin-top: 1.5rem;
}

.auth-divider {
    display: flex;
    align-items: center;
    gap: 1rem;
    margin: 1.25rem 0 0;
    font-size: 0.8125rem;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: var(--ctms-text-muted);
}

/* The rules are drawn by the pseudo-elements either side, so the word keeps its own width. */
.auth-divider::before,
.auth-divider::after {
    content: "";
    flex: 1;
    height: 1px;
    background-color: var(--ctms-border);
}

.recaptcha-notice {
    margin: 1rem 0 0;
    font-size: 0.75rem;
    line-height: 1.5;
    text-align: center;
    color: var(--ctms-text-muted);
}

.recaptcha-notice a {
    color: var(--ctms-text-muted);
    text-decoration: underline;
}

.recaptcha-notice a:hover,
.recaptcha-notice a:focus {
    color: var(--ctms-primary);
}

/* Pinned opposite the scroll-to-top control, releasing the right edge the service sets. */
.grecaptcha-badge {
    left: 1rem !important;
    right: auto !important;
}

/* ----------------------------------------------------------------------------------------------
Header

Translucent and pinned to the top so the landing video shows through, yet dark enough that white
nav text keeps its contrast over the video and over plain white pages alike.
---------------------------------------------------------------------------------------------- */

.site-header {
    min-height: var(--ctms-header-height);
    padding-top: 0;
    padding-bottom: 0;
    background: linear-gradient(180deg, rgba(4, 26, 77, 0.94) 0%, rgba(4, 26, 77, 0.82) 100%);
    box-shadow: var(--ctms-shadow-md);
}

@supports ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
    .site-header {
        -webkit-backdrop-filter: blur(10px);
        backdrop-filter: blur(10px);
    }
}

.site-brand {
    display: flex;
    align-items: center;
    gap: 0.625rem;
    text-decoration: none;
    /* Leaves room for the toggler on narrow phones. */
    min-width: 0;
}

.site-brand-logo {
    width: 2.25rem;
    height: 2.25rem;
    flex-shrink: 0;
}

.site-brand-text {
    display: flex;
    flex-direction: column;
    line-height: 1.1;
    min-width: 0;
}

.site-brand-title,
.site-brand-subtitle {
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.site-brand-title {
    color: var(--ctms-text-inverse);
    font-weight: 700;
    font-size: 1rem;
}

.site-brand-subtitle {
    color: var(--ctms-text-inverse-muted);
    font-weight: 400;
    font-size: 0.6875rem;
    letter-spacing: 0.04em;
    text-transform: uppercase;
}

/* The narrowest phones cannot fit the full wordmark beside the toggler. */
@media (max-width: 359px) {
    .site-brand-subtitle {
        display: none;
    }

    .site-brand-title {
        font-size: 0.9375rem;
    }
}

.site-header .navbar-toggler {
    color: var(--ctms-text-inverse);
    border-color: rgba(255, 255, 255, 0.4);
    padding: 0.375rem 0.625rem;
}

.site-header .navbar-toggler:focus {
    box-shadow: 0 0 0 0.2rem rgba(255, 255, 255, 0.25);
}

.site-header .nav-link {
    color: var(--ctms-text-inverse-muted);
    font-weight: 500;
    padding: 0.5rem 0;
    transition: color var(--ctms-transition);
}

.site-header .nav-link:hover,
.site-header .nav-link:focus {
    color: var(--ctms-accent);
}

.site-header .nav-link[aria-current="page"] {
    color: var(--ctms-text-inverse);
    font-weight: 600;
}

@media (max-width: 991.98px) {
    .site-header .navbar-collapse {
        margin-top: 0.5rem;
        padding: 0.5rem 0 0.75rem;
        border-top: 1px solid rgba(255, 255, 255, 0.15);
    }

    .site-header .nav-link {
        padding: 0.625rem 0.25rem;
    }
}

@media (min-width: 992px) {
    .site-header .nav-link {
        position: relative;
        padding: 0.5rem 0;
        margin-left: 1.75rem;
    }

    .site-header .nav-link::after {
        content: "";
        position: absolute;
        left: 0;
        bottom: 0.125rem;
        width: 100%;
        height: 2px;
        background-color: var(--ctms-accent);
        transform: scaleX(0);
        transform-origin: left;
        transition: transform var(--ctms-transition);
    }

    .site-header .nav-link:hover::after,
    .site-header .nav-link:focus::after,
    .site-header .nav-link[aria-current="page"]::after {
        transform: scaleX(1);
    }
}

/* --- Account menu -------------------------------------------------------------------------- */

.site-account-toggle {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.375rem 0;
    font-weight: 500;
    color: var(--ctms-text-inverse);
    background: none;
    border: none;
}

.site-account-toggle:hover,
.site-account-toggle:focus {
    color: var(--ctms-accent);
}

.site-account-avatar {
    border-radius: 50%;
    background-color: rgba(255, 255, 255, 0.15);
    object-fit: cover;
}

/* Wide enough that an ordinary address fits on one line, since addresses have no natural break. */
.site-account-menu .dropdown-menu {
    min-width: 15rem;
}

.site-account-summary {
    display: flex;
    flex-direction: column;
    padding: 0.25rem 1rem 0.5rem;
}

.site-account-summary-name {
    font-weight: 600;
    font-size: 0.875rem;
}

.site-account-summary-email {
    font-size: 0.8125rem;
    color: var(--ctms-text-muted);
    overflow-wrap: anywhere;
}

.site-nav-action {
    margin-top: 0.75rem;
}

@media (min-width: 992px) {
    .site-account-menu {
        margin-left: 1.75rem;
    }

    .site-nav-action {
        margin-top: 0;
        margin-left: 1.5rem;
    }
}

/* ----------------------------------------------------------------------------------------------
Hero

Full-bleed video with a headline layered over it. The height is clamped so the video neither fills
an ultrawide monitor nor collapses to a strip on a phone.
---------------------------------------------------------------------------------------------- */

.hero {
    position: relative;
    display: flex;
    align-items: flex-end;
    min-height: 38rem;
    height: 100vh;
    max-height: 62rem;
    overflow: hidden;
    background-color: var(--ctms-primary-darker);
}

.hero-video {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

/* Darkens the video so the headline keeps contrast wherever the footage is bright. */
.hero-overlay {
    position: absolute;
    inset: 0;
    background: linear-gradient(180deg, rgba(4, 26, 77, 0.55) 0%, rgba(4, 26, 77, 0.35) 45%, rgba(4, 26, 77, 0.88) 100%);
}

.hero-content {
    position: relative;
    padding-bottom: 3.5rem;
    color: var(--ctms-text-inverse);
}

.hero-title {
    font-weight: 700;
    font-size: clamp(1.75rem, 1.15rem + 2.8vw, 3.25rem);
    line-height: 1.15;
    margin-bottom: 0.75rem;
    text-shadow: 0 2px 12px rgba(0, 0, 0, 0.35);
}

.hero-text {
    max-width: 34rem;
    font-size: clamp(0.9375rem, 0.9rem + 0.25vw, 1.125rem);
    color: rgba(255, 255, 255, 0.9);
    margin-bottom: 1.75rem;
}

.hero-actions {
    display: flex;
    flex-wrap: wrap;
    gap: 0.75rem;
}

@media (max-width: 575.98px) {
    .hero {
        height: 92vh;
        min-height: 32rem;
    }

    .hero-content {
        padding-bottom: 2.5rem;
    }

    .hero-actions .btn {
        flex: 1 1 100%;
    }
}

/* --- Highlight ----------------------------------------------------------------------------- */

.highlight-text h2 {
    font-weight: 700;
    font-size: clamp(1.5rem, 1.15rem + 1.6vw, 2.25rem);
    margin-bottom: 1rem;
}

.highlight-text p {
    color: var(--ctms-text-muted);
    font-size: 1.0625rem;
    line-height: 1.7;
    margin-bottom: 1.75rem;
}

/* ----------------------------------------------------------------------------------------------
Route card

Sample multi-leg journey. The connecting line is drawn with a pseudo-element on each leg, so it
stays sharp at any size and follows the text as it wraps.
---------------------------------------------------------------------------------------------- */

.route-card {
    padding: 1.5rem;
    background-color: var(--ctms-surface);
    border: 1px solid var(--ctms-border);
    border-radius: var(--ctms-radius-lg);
    box-shadow: var(--ctms-shadow-lg);
}

.route-card-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
    padding-bottom: 1rem;
    margin-bottom: 0.5rem;
    border-bottom: 1px solid var(--ctms-border);
}

.route-card-title {
    font-weight: 700;
    font-size: 0.9375rem;
}

.route-card-badge {
    padding: 0.1875rem 0.625rem;
    font-size: 0.75rem;
    font-weight: 600;
    color: var(--ctms-primary);
    background-color: rgba(11, 79, 216, 0.1);
    border-radius: 62.5rem;
}

.route-legs {
    padding: 0;
    margin: 0;
    list-style: none;
}

.route-leg {
    position: relative;
    padding: 0 0 1.75rem 1.75rem;
}

.route-leg:last-child {
    padding-bottom: 0;
}

.route-leg::before {
    content: "";
    position: absolute;
    top: 0.25rem;
    left: 0;
    width: 0.75rem;
    height: 0.75rem;
    background-color: var(--ctms-surface);
    border: 2px solid var(--ctms-primary);
    border-radius: 50%;
}

/* Connecting line, omitted on the final leg so the track ends at the destination. */
.route-leg:not(:last-child)::after {
    content: "";
    position: absolute;
    top: 1.25rem;
    left: 0.3125rem;
    width: 2px;
    height: calc(100% - 1.25rem);
    background-color: var(--ctms-border);
}

.route-leg-origin::before,
.route-leg-destination::before {
    background-color: var(--ctms-primary);
}

.route-leg-place {
    display: block;
    font-weight: 600;
    font-size: 0.9375rem;
    line-height: 1.3;
}

.route-leg-role {
    display: block;
    font-size: 0.75rem;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--ctms-text-muted);
}

.route-figures-inline {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(6rem, 1fr));
    gap: 0.75rem 1rem;
    margin: 1.25rem 0 0;
    padding-top: 1.25rem;
    border-top: 1px solid var(--ctms-border);
}

.route-figure-inline dt {
    font-size: 0.6875rem;
    font-weight: 700;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--ctms-text-muted);
}

.route-figure-inline dd {
    margin-bottom: 0;
    font-weight: 600;
}

.route-card-link {
    font-size: 0.8125rem;
    font-weight: 600;
    color: var(--ctms-primary);
    text-decoration: none;
    white-space: nowrap;
}

.route-card-link:hover,
.route-card-link:focus {
    text-decoration: underline;
}

.route-card-footer {
    display: flex;
    flex-wrap: wrap;
    gap: 0.25rem 1.5rem;
    padding-top: 1rem;
    margin-top: 1.25rem;
    border-top: 1px solid var(--ctms-border);
    font-size: 0.8125rem;
    color: var(--ctms-text-muted);
}

.route-total-value {
    font-weight: 700;
    color: var(--ctms-text);
}

/* --- Feature cards ------------------------------------------------------------------------- */

.feature-card {
    height: 100%;
    padding: 1.75rem;
    background-color: var(--ctms-surface);
    border: 1px solid var(--ctms-border);
    border-radius: var(--ctms-radius-lg);
    box-shadow: var(--ctms-shadow-sm);
    transition: transform var(--ctms-transition), box-shadow var(--ctms-transition);
}

.feature-card:hover {
    transform: translateY(-4px);
    box-shadow: var(--ctms-shadow-lg);
}

.feature-card-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 3rem;
    height: 3rem;
    margin-bottom: 1.125rem;
    font-size: 1.375rem;
    color: var(--ctms-primary);
    background-color: rgba(11, 79, 216, 0.1);
    border-radius: var(--ctms-radius);
}

.feature-card-title {
    font-size: 1.125rem;
    font-weight: 700;
    margin-bottom: 0.5rem;
}

.feature-card-text {
    font-size: 0.9375rem;
    color: var(--ctms-text-muted);
    margin-bottom: 0;
}

/* ----------------------------------------------------------------------------------------------
Service and role cards

A service card stacks its own rows and lets the rate table sit at a fixed place, so four cards in a
row line their figures up whatever length the description above them runs to.
---------------------------------------------------------------------------------------------- */

.service-card {
    display: flex;
    flex-direction: column;
    height: 100%;
    padding: 1.75rem;
    background-color: var(--ctms-surface);
    border: 1px solid var(--ctms-border);
    border-radius: var(--ctms-radius-lg);
    box-shadow: var(--ctms-shadow-sm);
    transition: transform var(--ctms-transition), box-shadow var(--ctms-transition);
}

.service-card:hover {
    transform: translateY(-4px);
    box-shadow: var(--ctms-shadow-lg);
}

.service-card-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 3rem;
    height: 3rem;
    margin-bottom: 1.125rem;
    font-size: 1.375rem;
    color: var(--ctms-primary);
    background-color: rgba(11, 79, 216, 0.1);
    border-radius: var(--ctms-radius);
}

.service-card-title {
    font-size: 1.125rem;
    font-weight: 700;
    margin-bottom: 0.125rem;
}

.service-card-carrier {
    font-size: 0.8125rem;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--ctms-text-muted);
    margin-bottom: 0.875rem;
}

.service-card-text {
    font-size: 0.9375rem;
    color: var(--ctms-text-muted);
    margin-bottom: 1.25rem;
}

/* Pushed to the foot, so rate tables align across unequal descriptions. */
.service-rates {
    margin-top: auto;
    margin-bottom: 1.25rem;
    padding: 0.875rem 1rem;
    background-color: var(--ctms-surface-muted);
    border-radius: var(--ctms-radius);
}

.service-rate {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 0.75rem;
    font-size: 0.875rem;
}

.service-rate:not(:last-child) {
    margin-bottom: 0.5rem;
}

.service-rate dt {
    font-weight: 400;
    color: var(--ctms-text-muted);
}

.service-rate dd {
    font-weight: 700;
    margin-bottom: 0;
}

.service-rate dd span {
    font-weight: 400;
    font-size: 0.8125rem;
    color: var(--ctms-text-muted);
    margin-left: 0.1875rem;
}

.service-suits-title {
    font-size: 0.8125rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--ctms-text-muted);
    margin-bottom: 0.5rem;
}

.service-suits {
    list-style: none;
    padding-left: 0;
    margin-bottom: 0;
    font-size: 0.875rem;
    color: var(--ctms-text-muted);
}

.service-suits li {
    position: relative;
    padding-left: 1.25rem;
}

.service-suits li:not(:last-child) {
    margin-bottom: 0.3125rem;
}

/* A drawn dot, so the marker needs no icon font and no non-ASCII character. */
.service-suits li::before {
    content: "";
    position: absolute;
    left: 0;
    top: 0.5rem;
    width: 0.375rem;
    height: 0.375rem;
    background-color: var(--ctms-primary);
    border-radius: 50%;
}

.role-list {
    list-style: none;
    padding-left: 0;
    margin-bottom: 0;
}

/* Split into text and action from sm, so the button never squeezes the summary. */
.role-card {
    display: flex;
    flex-direction: column;
    gap: 1.25rem;
    padding: 1.5rem;
    background-color: var(--ctms-surface);
    border: 1px solid var(--ctms-border);
    border-radius: var(--ctms-radius-lg);
    box-shadow: var(--ctms-shadow-sm);
    transition: box-shadow var(--ctms-transition);
}

.role-card:not(:last-child) {
    margin-bottom: 1rem;
}

.role-card:hover {
    box-shadow: var(--ctms-shadow-md);
}

.role-card-title {
    font-size: 1.125rem;
    font-weight: 700;
    margin-bottom: 0.625rem;
}

.role-card-meta {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem 1.25rem;
    list-style: none;
    padding-left: 0;
    margin-bottom: 0.75rem;
    font-size: 0.875rem;
    color: var(--ctms-text-muted);
}

.role-card-meta i {
    color: var(--ctms-primary);
}

.role-card-text {
    font-size: 0.9375rem;
    color: var(--ctms-text-muted);
    margin-bottom: 0;
}

.role-card-action .btn {
    width: 100%;
}

.page-cta {
    max-width: 40rem;
    margin: 0 auto;
    text-align: center;
}

.page-cta-title {
    font-weight: 700;
    font-size: clamp(1.375rem, 1.1rem + 1.2vw, 1.875rem);
    margin-bottom: 0.75rem;
}

.page-cta-text {
    color: var(--ctms-text-muted);
    margin-bottom: 1.75rem;
}

.page-cta-actions {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 0.75rem;
}

@media (min-width: 576px) {
    .role-card {
        flex-direction: row;
        align-items: center;
        justify-content: space-between;
    }

    /* Without this the summary cannot wrap and forces the row wider than its container. */
    .role-card-body {
        min-width: 0;
    }

    .role-card-action .btn {
        width: auto;
        white-space: nowrap;
    }
}

/* --- Statistics ---------------------------------------------------------------------------- */

.stat {
    text-align: center;
    padding: 1rem 0.5rem;
}

.stat-value {
    display: block;
    font-weight: 700;
    font-size: clamp(1.75rem, 1.3rem + 2vw, 2.75rem);
    line-height: 1.1;
    color: var(--ctms-primary);
}

.stat-label {
    display: block;
    margin-top: 0.375rem;
    font-size: 0.875rem;
    color: var(--ctms-text-muted);
}

/* ----------------------------------------------------------------------------------------------
Profile pages

An identity banner over cards of grouped detail. Each card is a grid row on wide screens and a
stacked pair on narrow ones, so a long value never squeezes its label into a column of letters.
---------------------------------------------------------------------------------------------- */

.profile-banner {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 1.25rem;
    padding: 1.75rem 1.25rem;
    margin-bottom: 1.75rem;
    text-align: center;
    background-color: var(--ctms-surface);
    border: 1px solid var(--ctms-border);
    border-radius: var(--ctms-radius-lg);
    box-shadow: var(--ctms-shadow-sm);
}

.profile-avatar {
    display: block;
    width: 7rem;
    height: 7rem;
    flex-shrink: 0;
    object-fit: cover;
    border-radius: 50%;
    background-color: rgba(11, 79, 216, 0.08);
    box-shadow: 0 0 0 4px var(--ctms-surface), 0 0 0 5px var(--ctms-border);
}

.profile-identity {
    min-width: 0;
}

.profile-name {
    font-weight: 700;
    font-size: clamp(1.375rem, 1.2rem + 0.8vw, 1.75rem);
    margin-bottom: 0.25rem;
    overflow-wrap: anywhere;
}

.profile-handle {
    font-size: 0.9375rem;
    color: var(--ctms-text-muted);
    margin-bottom: 1rem;
    overflow-wrap: anywhere;
}

.profile-actions {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    justify-content: center;
}

@media (min-width: 768px) {
    .profile-banner {
        flex-direction: row;
        gap: 1.75rem;
        padding: 2rem;
        text-align: left;
    }

    .profile-actions {
        justify-content: flex-start;
    }
}

.detail-card {
    height: 100%;
    padding: 1.5rem;
    background-color: var(--ctms-surface);
    border: 1px solid var(--ctms-border);
    border-radius: var(--ctms-radius-lg);
    box-shadow: var(--ctms-shadow-sm);
}

.detail-card-title {
    display: flex;
    align-items: center;
    gap: 0.625rem;
    float: none;
    width: auto;
    padding: 0 0 1rem;
    margin-bottom: 1.25rem;
    font-size: 1rem;
    font-weight: 700;
    border-bottom: 1px solid var(--ctms-border);
}

.detail-card-title i {
    color: var(--ctms-primary);
}

.detail-card-text {
    font-size: 0.875rem;
    color: var(--ctms-text-muted);
    margin-bottom: 1.25rem;
}

.detail-list {
    margin: 0;
}

.detail-row {
    display: grid;
    gap: 0.125rem;
    padding-bottom: 0.875rem;
}

.detail-row:last-child {
    padding-bottom: 0;
}

.detail-label {
    font-size: 0.8125rem;
    font-weight: 600;
    color: var(--ctms-text-muted);
}

.detail-value {
    margin-bottom: 0;
    overflow-wrap: anywhere;
}

.detail-value-empty {
    color: var(--ctms-text-muted);
    font-style: italic;
}

@media (min-width: 576px) {
    .detail-row {
        grid-template-columns: 11rem minmax(0, 1fr);
        gap: 0.75rem;
        align-items: baseline;
    }
}

/* Neutral by itself, so a badge with no colour of its own still reads as one. */
.detail-badge {
    display: inline-flex;
    align-items: center;
    gap: 0.375rem;
    padding: 0.1875rem 0.625rem;
    margin-right: 0.375rem;
    font-size: 0.75rem;
    font-weight: 600;
    color: var(--ctms-text-muted);
    background-color: var(--ctms-surface-alt);
    border-radius: 62.5rem;
}

.detail-badge-verified {
    color: var(--ctms-success);
    background-color: rgba(25, 135, 84, 0.12);
}

/* The colour rises with what the rank may do. */
.detail-badge-staff {
    color: var(--ctms-warning);
    background-color: rgba(255, 152, 0, 0.16);
}

.detail-badge-administrator {
    color: var(--ctms-primary);
    background-color: rgba(11, 79, 216, 0.1);
}

.detail-badge-superuser {
    color: var(--ctms-success);
    background-color: rgba(25, 135, 84, 0.12);
}

/* ----------------------------------------------------------------------------------------------
Profile editor

The picture uploader sits inside the banner, and the sign-in details sit beside the editable
fields so that changing an address or a username starts from the same page.
---------------------------------------------------------------------------------------------- */

.profile-picture-form {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.75rem;
}

.profile-picture-label {
    display: inline-flex;
    align-items: center;
    gap: 0.375rem;
    padding: 0.375rem 0.875rem;
    font-size: 0.8125rem;
    font-weight: 600;
    color: var(--ctms-primary);
    background-color: rgba(11, 79, 216, 0.08);
    border-radius: 62.5rem;
    cursor: pointer;
    transition: background-color var(--ctms-transition);
}

.profile-picture-label:hover,
.profile-picture-form input:focus-visible + .profile-picture-label {
    background-color: rgba(11, 79, 216, 0.16);
}

.profile-form-actions {
    display: flex;
    flex-wrap: wrap;
    gap: 0.75rem;
    margin-top: 1.75rem;
}

/* The row shares one height, so each label centres in it rather than in its own padding. */
.profile-form-actions .btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: 1 1 12rem;
}

@media (min-width: 576px) {
    .profile-form-actions .btn {
        flex: 0 0 auto;
        min-width: 10rem;
    }
}

.credential-list {
    padding: 0;
    margin: 0;
    list-style: none;
}

.credential-row {
    display: grid;
    gap: 0.25rem 1rem;
    padding: 0.875rem 0;
    border-top: 1px solid var(--ctms-border);
}

.credential-row:first-child {
    border-top: none;
    padding-top: 0;
}

.credential-label {
    font-size: 0.8125rem;
    font-weight: 600;
    color: var(--ctms-text-muted);
}

.credential-value {
    overflow-wrap: anywhere;
}

/* Stands where the button it replaces would stand, so the row keeps its shape either way. */
.credential-note {
    max-width: 16rem;
    font-size: 0.8125rem;
    color: var(--ctms-text-muted);
}

@media (min-width: 576px) {
    .credential-row {
        grid-template-columns: 9rem minmax(0, 1fr) auto;
        align-items: center;
    }
}

.crop-hint {
    font-size: 0.875rem;
    color: var(--ctms-text-muted);
}

/* Cropper swaps in a sized canvas, so the stage caps how tall it may grow. */
.crop-stage {
    max-height: 60vh;
    overflow: hidden;
}

.crop-stage img {
    display: block;
    max-width: 100%;
}

/* ----------------------------------------------------------------------------------------------
Avatars

The user images are line-art icons, so they sit centred inside a tinted circle with padding around
them rather than cropped to fill it.
---------------------------------------------------------------------------------------------- */

.avatar {
    display: block;
    flex-shrink: 0;
    border-radius: 50%;
    background-color: rgba(11, 79, 216, 0.08);
    padding: 0.25rem;
    object-fit: contain;
}

.avatar-sm {
    width: 3rem;
    height: 3rem;
}

.avatar-lg {
    width: 6rem;
    height: 6rem;
    padding: 0.5rem;
}

/* --- Testimonials -------------------------------------------------------------------------- */

.testimonial {
    display: flex;
    flex-direction: column;
    height: 100%;
    padding: 1.75rem;
    background-color: var(--ctms-surface);
    border-radius: var(--ctms-radius-lg);
    box-shadow: var(--ctms-shadow-sm);
}

.testimonial-quote {
    flex-grow: 1;
    font-size: 0.9375rem;
    line-height: 1.7;
    color: var(--ctms-text);
    margin-bottom: 1.25rem;
}

.testimonial-author {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    padding-top: 1.25rem;
    border-top: 1px solid var(--ctms-border);
}

.testimonial-name {
    font-size: 0.9375rem;
    font-weight: 700;
    margin-bottom: 0;
}

.testimonial-role {
    font-size: 0.8125rem;
    color: var(--ctms-text-muted);
    margin-bottom: 0;
}

/* --- Team ---------------------------------------------------------------------------------- */

.team-card {
    height: 100%;
    padding: 2rem 1.5rem;
    text-align: center;
    background-color: var(--ctms-surface);
    border: 1px solid var(--ctms-border);
    border-radius: var(--ctms-radius-lg);
    box-shadow: var(--ctms-shadow-sm);
}

.team-card .avatar {
    margin: 0 auto 1.125rem;
}

.team-name {
    font-size: 1.125rem;
    font-weight: 700;
    margin-bottom: 0.25rem;
}

.team-role {
    font-size: 0.75rem;
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--ctms-primary);
    margin-bottom: 0.75rem;
}

.team-bio {
    font-size: 0.9375rem;
    color: var(--ctms-text-muted);
    margin-bottom: 0;
}

/* --- Partner logos ------------------------------------------------------------------------- */

.partner-strip {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: center;
    gap: 1.5rem 2.5rem;
    padding: 0;
    margin: 0;
    list-style: none;
}

.partner-strip img {
    height: 1.5rem;
    width: auto;
    opacity: 0.55;
    filter: grayscale(100%);
    transition: opacity var(--ctms-transition), filter var(--ctms-transition);
}

.partner-strip img:hover {
    opacity: 1;
    filter: grayscale(0);
}

/* --- Footer -------------------------------------------------------------------------------- */

.site-footer {
    padding: 3.5rem 0 1.75rem;
    color: rgba(240, 249, 255, 0.75);
    background-color: var(--ctms-surface-dark);
}

.site-footer h3 {
    font-size: 0.875rem;
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--ctms-text-inverse);
    margin-bottom: 1rem;
}

.site-footer-links {
    padding: 0;
    margin: 0;
    list-style: none;
    line-height: 2;
    font-size: 0.9375rem;
}

.site-footer a {
    color: inherit;
    text-decoration: none;
}

.site-footer a:hover,
.site-footer a:focus {
    color: var(--ctms-accent);
}

.site-footer-about {
    font-size: 0.9375rem;
    line-height: 1.7;
    margin-bottom: 0;
}

.site-footer-social {
    display: flex;
    flex-wrap: wrap;
    gap: 0.75rem;
    padding: 0;
    margin: 2rem 0 0;
    list-style: none;
}

.site-footer-social a {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2.25rem;
    height: 2.25rem;
    font-size: 1.125rem;
    color: var(--ctms-text-inverse);
    border-radius: 50%;
    box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.3);
    transition: background-color var(--ctms-transition), box-shadow var(--ctms-transition);
}

.site-footer-social a:hover,
.site-footer-social a:focus {
    color: var(--ctms-text-inverse);
    background-color: var(--ctms-primary);
    box-shadow: inset 0 0 0 1px var(--ctms-primary);
}

.site-footer-legal {
    margin-top: 2.5rem;
    padding-top: 1.5rem;
    border-top: 1px solid rgba(255, 255, 255, 0.12);
    font-size: 0.8125rem;
    color: rgba(240, 249, 255, 0.55);
    text-align: center;
    margin-bottom: 0;
}

/* ----------------------------------------------------------------------------------------------
Scroll-to-top control

Hidden until the page is scrolled; the site script toggles the is-visible class.
---------------------------------------------------------------------------------------------- */

.scroll-to-top {
    position: fixed;
    right: 1rem;
    bottom: 1rem;
    z-index: 1030;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2.75rem;
    height: 2.75rem;
    color: var(--ctms-text-inverse);
    background-color: rgba(11, 79, 216, 0.85);
    border-radius: 50%;
    box-shadow: var(--ctms-shadow-md);
    opacity: 0;
    visibility: hidden;
    transition: opacity var(--ctms-transition), visibility var(--ctms-transition), background-color var(--ctms-transition);
}

.scroll-to-top.is-visible {
    opacity: 1;
    visibility: visible;
}

.scroll-to-top:hover,
.scroll-to-top:focus {
    color: var(--ctms-text-inverse);
    background-color: var(--ctms-primary-dark);
}

/* ----------------------------------------------------------------------------------------------
Billing

A checkout puts what is owed beside what settles it, and an invoice reads as the document it is.
The file a visitor downloads is drawn separately, so the two are laid out from different rules.
---------------------------------------------------------------------------------------------- */

.checkout {
    display: grid;
    gap: 1.5rem;
    align-items: start;
}

.checkout-summary,
.checkout-form-card {
    padding: 1.75rem 1.5rem;
    background-color: var(--ctms-surface);
    border: 1px solid var(--ctms-border);
    border-radius: var(--ctms-radius-lg);
    box-shadow: var(--ctms-shadow-sm);
}

.checkout-summary-title,
.checkout-title {
    display: flex;
    align-items: center;
    gap: 0.625rem;
    font-size: 1.125rem;
    font-weight: 700;
    margin-bottom: 1.25rem;
}

.checkout-title i {
    color: var(--ctms-primary);
}

.checkout-lines {
    margin-bottom: 0;
}

.checkout-line {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 1rem;
    padding: 0.625rem 0;
    font-size: 0.9375rem;
}

.checkout-line:not(:last-child) {
    border-bottom: 1px solid var(--ctms-border);
}

.checkout-line dt {
    font-weight: 400;
    color: var(--ctms-text-muted);
}

.checkout-line dd {
    margin-bottom: 0;
    text-align: right;
    overflow-wrap: anywhere;
}

.checkout-line-total {
    padding-top: 1rem;
    font-size: 1.25rem;
    font-weight: 700;
}

.checkout-line-total dt {
    font-weight: 700;
    color: var(--ctms-text);
}

.checkout-note,
.checkout-hint {
    font-size: 0.875rem;
    color: var(--ctms-text-muted);
}

.checkout-note {
    padding: 0.875rem 1rem;
    margin-bottom: 1.5rem;
    background-color: var(--ctms-surface-muted);
    border-left: 3px solid var(--ctms-warning);
    border-radius: var(--ctms-radius);
}

.checkout-hint {
    margin-top: -0.5rem;
    margin-bottom: 1.25rem;
}

.checkout-submit {
    width: 100%;
    margin-top: 1rem;
}

/* --- Payment on an order page -------------------------------------------------------------- */

.order-billing {
    padding: 1.5rem;
    margin-top: 1.75rem;
    background-color: var(--ctms-surface-muted);
    border-radius: var(--ctms-radius-lg);
}

.order-billing-title {
    display: flex;
    align-items: center;
    gap: 0.625rem;
    font-size: 1.0625rem;
    font-weight: 700;
    margin-bottom: 0.875rem;
}

.order-billing-title i {
    color: var(--ctms-primary);
}

.order-billing-state {
    font-size: 0.9375rem;
    color: var(--ctms-text-muted);
    margin-bottom: 1.25rem;
}

.order-billing-state-paid {
    color: var(--ctms-success);
}

.order-billing-state-refunded,
.order-billing-state-payment-pending {
    color: var(--ctms-warning);
}

.order-billing-state-failed {
    color: var(--ctms-danger);
}

.order-billing-facts {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(10rem, 1fr));
    gap: 0.875rem 1.5rem;
    margin: 0 0 1.25rem;
}

.order-billing-fact dt {
    font-size: 0.75rem;
    font-weight: 700;
    letter-spacing: 0.03em;
    text-transform: uppercase;
    color: var(--ctms-text-muted);
    margin-bottom: 0.25rem;
}

.order-billing-fact dd {
    margin-bottom: 0;
    overflow-wrap: anywhere;
}

.order-billing-actions {
    display: flex;
    flex-wrap: wrap;
    gap: 0.75rem;
}

/* --- Saved cards --------------------------------------------------------------------------- */

.card-list {
    list-style: none;
    padding-left: 0;
    margin-bottom: 0;
}

.card-row {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem 1.25rem;
    padding: 1rem;
    background-color: var(--ctms-surface-muted);
    border-radius: var(--ctms-radius);
}

.card-row:not(:last-child) {
    margin-bottom: 0.75rem;
}

/* An expired card stays listed so it can be removed, but reads as no longer usable. */
.card-row-expired {
    color: var(--ctms-text-muted);
}

.card-row-brand {
    font-weight: 700;
}

.card-row-digits {
    letter-spacing: 0.08em;
}

.card-row-expiry,
.card-row-name {
    font-size: 0.875rem;
    color: var(--ctms-text-muted);
}

.card-row .panel-action {
    margin-left: auto;
}

/* --- The invoice --------------------------------------------------------------------------- */

/* Held to the document's width, so the controls line up with the paper, not the page. */
.invoice-controls {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
    max-width: 52rem;
    margin: 0 auto 1.25rem;
}

/* The link keeps its quiet colouring, which must stop there: a button beside it has its own. */
.invoice-controls .order-back {
    margin-bottom: 0;
}

.invoice {
    max-width: 52rem;
    margin: 0 auto;
    padding: 2rem 1.5rem;
    background-color: var(--ctms-surface);
    border: 1px solid var(--ctms-border);
    border-radius: var(--ctms-radius-lg);
    box-shadow: var(--ctms-shadow-sm);
}

.invoice-head {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-start;
    justify-content: space-between;
    gap: 1.25rem;
    padding-bottom: 1.5rem;
    margin-bottom: 1.5rem;
    border-bottom: 2px solid var(--ctms-border);
}

/* The mark and the name read as one thing, with the sender's details beneath both. */
.invoice-brand-lockup {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    margin-bottom: 0.5rem;
}

.invoice-brand-name {
    font-size: 1.5rem;
    font-weight: 700;
    line-height: 1;
    color: var(--ctms-primary);
}

.invoice-brand-line {
    display: block;
    font-size: 0.8125rem;
    line-height: 1.6;
    color: var(--ctms-text-muted);
}

.invoice-meta {
    text-align: left;
}

.invoice-title {
    display: block;
    margin-bottom: 0.5rem;
    font-size: 0.8125rem;
    font-weight: 700;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--ctms-text-muted);
}

.invoice-number {
    display: block;
    margin-bottom: 0.625rem;
    font-size: 1.125rem;
    font-weight: 700;
    line-height: 1.2;
}

.invoice-parties {
    display: grid;
    gap: 1.5rem;
    margin-bottom: 1.75rem;
}

.invoice-party-title {
    font-size: 0.75rem;
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--ctms-text-muted);
    margin-bottom: 0.5rem;
}

.invoice-party-body {
    font-size: 0.9375rem;
    line-height: 1.7;
    margin-bottom: 0;
}

.invoice-facts {
    margin-bottom: 0;
    font-size: 0.9375rem;
}

.invoice-fact {
    display: flex;
    justify-content: space-between;
    gap: 1rem;
    padding: 0.1875rem 0;
}

.invoice-fact dt {
    font-weight: 400;
    color: var(--ctms-text-muted);
}

.invoice-fact dd {
    margin-bottom: 0;
    font-weight: 600;
    text-align: right;
    overflow-wrap: anywhere;
}

/* Stacked by default: the heading row is dropped and each cell names itself instead. */
.invoice-table,
.invoice-table tbody,
.invoice-table tfoot,
.invoice-table tr,
.invoice-table td,
.invoice-table tfoot th {
    display: block;
}

.invoice-table {
    width: 100%;
    margin-bottom: 1.5rem;
    border-collapse: collapse;
}

.invoice-table thead {
    display: none;
}

.invoice-table tbody tr {
    padding-bottom: 0.5rem;
    border-bottom: 1px solid var(--ctms-border);
}

.invoice-table td {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    justify-content: space-between;
    gap: 0.25rem 1rem;
    padding: 0.375rem 0;
    text-align: left;
}

.invoice-table tbody td::before {
    content: attr(data-label);
    flex-shrink: 0;
    font-size: 0.6875rem;
    font-weight: 700;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--ctms-text-muted);
}

.invoice-table tfoot tr {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    padding-top: 0.75rem;
}

.invoice-table tfoot th,
.invoice-table tfoot td {
    padding: 0;
    font-size: 1.125rem;
    font-weight: 700;
}

.invoice-item {
    display: block;
    font-weight: 600;
}

.invoice-item-note {
    display: block;
    font-size: 0.875rem;
    color: var(--ctms-text-muted);
}

.invoice-foot {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 0.5rem;
    padding-top: 1.5rem;
    border-top: 1px solid var(--ctms-border);
}

/* A tilted rubber stamp: the border rings it, two inset shadows draw the inner ring, and the
margin is the room the tilt needs, since a rotated box still lays out square. */
.invoice-stamp {
    display: inline-flex;
    flex-direction: column;
    align-items: center;
    gap: 0.125rem;
    margin: 1rem 0.5rem;
    padding: 0.625rem 1.5rem;
    color: var(--ctms-text-muted);
    border: 3px solid currentColor;
    border-radius: var(--ctms-radius);
    box-shadow: inset 0 0 0 3px var(--ctms-surface), inset 0 0 0 4.5px currentColor;
    transform: rotate(-12deg);
}

.invoice-stamp-label {
    font-size: 1.125rem;
    font-weight: 700;
    letter-spacing: 0.14em;
    line-height: 1.1;
    text-transform: uppercase;
}

.invoice-stamp-date {
    font-size: 0.6875rem;
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
}

.invoice-stamp-paid {
    color: var(--ctms-success);
}

.invoice-stamp-refunded {
    color: var(--ctms-warning);
}

.invoice-stamp-failed {
    color: var(--ctms-danger);
}

.invoice-stamp-payment-pending {
    color: var(--ctms-text-muted);
}

.invoice-foot-note {
    font-size: 0.8125rem;
    color: var(--ctms-text-muted);
    margin-bottom: 0;
}

.money-total {
    margin-bottom: 1.25rem;
    font-size: 0.875rem;
    color: var(--ctms-text-muted);
}

.money-total-value {
    display: block;
    font-size: clamp(1.75rem, 1.3rem + 2vw, 2.5rem);
    font-weight: 700;
    line-height: 1.1;
    color: var(--ctms-text);
}

@media (min-width: 576px) {
    /* Room enough for the columns to stand side by side, so the table is a table again. */
    .invoice-table {
        display: table;
    }

    .invoice-table thead {
        display: table-header-group;
    }

    .invoice-table tbody {
        display: table-row-group;
    }

    .invoice-table tfoot {
        display: table-footer-group;
    }

    .invoice-table tr,
    .invoice-table tfoot tr {
        display: table-row;
        padding: 0;
        border-bottom: 0;
    }

    /* The stacked rule stripping the total row's padding outscores a plain cell, so both halves
    are named again here or the figure hangs past its column. */
    .invoice-table td,
    .invoice-table th,
    .invoice-table tfoot th,
    .invoice-table tfoot td {
        display: table-cell;
        padding: 0.75rem 0.5rem;
    }

    .invoice-table thead th {
        font-size: 0.75rem;
        font-weight: 700;
        letter-spacing: 0.06em;
        text-transform: uppercase;
        color: var(--ctms-text-muted);
        border-bottom: 1px solid var(--ctms-border);
    }

    .invoice-table tbody td {
        vertical-align: top;
        border-bottom: 1px solid var(--ctms-border);
    }

    .invoice-table tbody td::before {
        content: none;
    }

    .invoice-table tfoot th,
    .invoice-table tfoot td {
        padding-top: 1rem;
    }

    /* Amounts are compared down the column, so they align on the last digit, not the first. */
    .invoice-table th:last-child,
    .invoice-table td:last-child,
    .invoice-table tfoot th {
        text-align: right;
    }
}

@media (min-width: 768px) {
    .invoice {
        padding: 2.5rem;
    }

    .invoice-meta {
        text-align: right;
    }

    .invoice-brand-lockup {
        margin-bottom: 0.625rem;
    }

    .invoice-parties {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }
}

@media (min-width: 992px) {
    .checkout {
        grid-template-columns: minmax(0, 1fr) minmax(0, 1.15fr);
    }

    .checkout-submit {
        width: auto;
        min-width: 14rem;
    }
}

/* ----------------------------------------------------------------------------------------------
Flash messages

Pinned below the fixed header so a message is visible wherever the page is scrolled.
---------------------------------------------------------------------------------------------- */

.message-stack {
    position: fixed;
    top: calc(var(--ctms-header-height) + 0.75rem);
    left: 50%;
    transform: translateX(-50%);
    z-index: 1040;
    width: min(100% - 1.5rem, 34rem);
}

.message-stack .alert {
    box-shadow: var(--ctms-shadow-lg);
}

/* ----------------------------------------------------------------------------------------------
Contact page

An information panel beside the message form. Both are full width on a phone and sit side by side
from the lg breakpoint, where the panel is the narrower of the two.
---------------------------------------------------------------------------------------------- */

.contact-details,
.contact-form-card {
    height: 100%;
    padding: 1.5rem 1.25rem;
    background-color: var(--ctms-surface);
    border: 1px solid var(--ctms-border);
    border-radius: var(--ctms-radius-lg);
    box-shadow: var(--ctms-shadow-sm);
}

.contact-details-title,
.contact-form-title {
    font-size: 1.125rem;
    font-weight: 700;
    margin-bottom: 1.25rem;
}

.contact-channels {
    display: grid;
    gap: 1.125rem;
    margin: 0;
    padding: 0;
    list-style: none;
}

.contact-channel {
    display: flex;
    align-items: flex-start;
    gap: 0.875rem;
}

.contact-channel-icon {
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    width: 2.5rem;
    height: 2.5rem;
    border-radius: 50%;
    color: var(--ctms-primary);
    background-color: rgba(11, 79, 216, 0.1);
}

/* Long addresses have no natural break, so the column wraps rather than overflows. */
.contact-channel-body {
    display: flex;
    flex-direction: column;
    min-width: 0;
}

.contact-channel-label {
    font-size: 0.75rem;
    font-weight: 700;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--ctms-text-muted);
}

.contact-channel-value {
    color: var(--ctms-text);
    text-decoration: none;
    overflow-wrap: anywhere;
}

a.contact-channel-value:hover,
a.contact-channel-value:focus {
    color: var(--ctms-primary);
}

.contact-details-note {
    margin: 1.5rem 0 0;
    padding-top: 1.25rem;
    border-top: 1px solid var(--ctms-border);
    font-size: 0.875rem;
    color: var(--ctms-text-muted);
}

.contact-submit {
    width: 100%;
    margin-top: 1.25rem;
}

@media (min-width: 576px) {
    .contact-details,
    .contact-form-card {
        padding: 2rem 1.75rem;
    }

    /* Auto margins centre the button under the fields once it stops spanning them. */
    .contact-submit {
        display: block;
        width: auto;
        min-width: 12rem;
        margin-left: auto;
        margin-right: auto;
    }
}

/* ----------------------------------------------------------------------------------------------
Transport orders

The order form and its rate card, the list of an account's orders, and one order in full. Every
block is a single column on a phone and gains its columns at the breakpoint where they still fit.
---------------------------------------------------------------------------------------------- */

.order-form-card,
.rate-card,
.order-detail,
.empty-state {
    padding: 1.5rem 1.25rem;
    background-color: var(--ctms-surface);
    border: 1px solid var(--ctms-border);
    border-radius: var(--ctms-radius-lg);
    box-shadow: var(--ctms-shadow-sm);
}

.order-form-actions {
    display: flex;
    flex-wrap: wrap;
    gap: 0.75rem;
    margin-top: 1.5rem;
}

/* Full width on a phone puts the two actions one above the other, both tappable. */
.order-form-actions .btn {
    flex: 1 1 100%;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.5rem;
}

.rate-card-title {
    font-size: 1.125rem;
    font-weight: 700;
    margin-bottom: 0.5rem;
}

.rate-card-note {
    font-size: 0.875rem;
    color: var(--ctms-text-muted);
    margin-bottom: 1.25rem;
}

.rate-list {
    display: grid;
    gap: 0.25rem;
    margin: 0;
    padding: 0;
    list-style: none;
}

.rate-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    padding: 0.625rem 0;
    border-bottom: 1px solid var(--ctms-border);
}

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

.rate-mode {
    display: inline-flex;
    align-items: center;
    gap: 0.625rem;
    color: var(--ctms-text);
}

.rate-mode i {
    color: var(--ctms-primary);
}

.rate-unit {
    font-weight: 400;
    font-size: 0.8125rem;
    color: var(--ctms-text-muted);
}

/* --- Order list ---------------------------------------------------------------------------- */

.orders-header {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    margin-bottom: 1.75rem;
}

.orders-title {
    font-weight: 700;
    font-size: clamp(1.5rem, 1.15rem + 1.6vw, 2.25rem);
    margin-bottom: 0.25rem;
}

.orders-count {
    color: var(--ctms-text-muted);
    margin-bottom: 0;
}

.orders-header .btn {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
}

.order-list {
    display: grid;
    gap: 1rem;
    margin: 0;
    padding: 0;
    list-style: none;
}

.order-card {
    padding: 1.25rem;
    background-color: var(--ctms-surface);
    border: 1px solid var(--ctms-border);
    border-radius: var(--ctms-radius-lg);
    box-shadow: var(--ctms-shadow-sm);
    transition: box-shadow var(--ctms-transition), transform var(--ctms-transition);
}

.order-card:hover {
    box-shadow: var(--ctms-shadow-md);
    transform: translateY(-2px);
}

.order-card-head {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.75rem 1rem;
}

.order-card-mode {
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    width: 2.75rem;
    height: 2.75rem;
    border-radius: var(--ctms-radius);
    font-size: 1.125rem;
    color: var(--ctms-primary);
    background-color: rgba(11, 79, 216, 0.1);
}

/* Takes the space left over, so the status pill is pushed to the far end of the row. */
.order-card-heading {
    flex: 1 1 10rem;
    min-width: 0;
}

.order-card-reference {
    font-weight: 700;
    color: var(--ctms-text);
    text-decoration: none;
}

.order-card-reference:hover,
.order-card-reference:focus {
    color: var(--ctms-primary);
}

.order-card-route {
    margin-bottom: 0;
    font-size: 0.9375rem;
    color: var(--ctms-text-muted);
    overflow-wrap: anywhere;
}

.order-card-arrow {
    margin: 0 0.25rem;
    color: var(--ctms-primary);
}

.order-card-facts {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 0.875rem 1rem;
    margin: 1.125rem 0 0;
    padding-top: 1.125rem;
    border-top: 1px solid var(--ctms-border);
}

.order-fact dt {
    font-size: 0.75rem;
    font-weight: 700;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--ctms-text-muted);
}

.order-fact dd {
    margin-bottom: 0;
    overflow-wrap: anywhere;
}

.order-fact-cost {
    font-weight: 700;
}

@media (min-width: 768px) {
    .order-card-facts {
        grid-template-columns: repeat(4, minmax(0, 1fr));
    }
}

/* --- Status pill --------------------------------------------------------------------------- */

.status-pill {
    display: inline-flex;
    align-items: center;
    flex-shrink: 0;
    padding: 0.25rem 0.75rem;
    border-radius: 2rem;
    font-size: 0.75rem;
    font-weight: 700;
    letter-spacing: 0.03em;
    text-transform: uppercase;
    white-space: nowrap;
}

.status-pill-pending {
    color: var(--ctms-warning);
    background-color: rgba(255, 152, 0, 0.16);
}

.status-pill-processing {
    color: var(--ctms-primary);
    background-color: rgba(11, 79, 216, 0.1);
}

.status-pill-cancelled,
.status-pill-returned {
    color: var(--ctms-danger);
    background-color: rgba(220, 53, 69, 0.12);
}

/* Confirming through delivering is all work in hand, so it reads as one colour. */
.status-pill-confirmed,
.status-pill-ready-for-pickup,
.status-pill-picked-up,
.status-pill-in-transit,
.status-pill-out-for-delivery {
    color: var(--ctms-primary);
    background-color: rgba(11, 79, 216, 0.1);
}

.status-pill-delivered,
.status-pill-completed {
    color: var(--ctms-success);
    background-color: rgba(25, 135, 84, 0.12);
}

.status-pill-archived {
    color: var(--ctms-text-muted);
    background-color: var(--ctms-surface-alt);
}

/* An enquiry runs an order's shape: waiting, in hand, finished, or ended early. */
.status-pill-new {
    color: var(--ctms-warning);
    background-color: rgba(255, 152, 0, 0.16);
}

.status-pill-in-progress {
    color: var(--ctms-primary);
    background-color: rgba(11, 79, 216, 0.1);
}

.status-pill-resolved {
    color: var(--ctms-success);
    background-color: rgba(25, 135, 84, 0.12);
}

.status-pill-closed {
    color: var(--ctms-text-muted);
    background-color: var(--ctms-surface-alt);
}

/* A payment either stands or has been given back, so it needs only the two. */
.status-pill-paid {
    color: var(--ctms-success);
    background-color: rgba(25, 135, 84, 0.12);
}

.status-pill-payment-pending {
    color: var(--ctms-warning);
    background-color: rgba(255, 152, 0, 0.16);
}

.status-pill-failed {
    color: var(--ctms-danger);
    background-color: rgba(220, 53, 69, 0.12);
}

.status-pill-refunded {
    color: var(--ctms-warning);
    background-color: rgba(255, 152, 0, 0.16);
}

/* --- Progress tracker ---------------------------------------------------------------------- */

/* Upright on a phone, where a row would be narrower than the wording inside one stage. */
.order-progress {
    width: fit-content;
    margin: 1.75rem auto;
    padding: 0;
    list-style: none;
}

.order-progress-step {
    position: relative;
    display: grid;
    grid-template-columns: 2rem minmax(0, 1fr);
    align-items: center;
    gap: 0.875rem;
    padding-bottom: 1.125rem;
}

.order-progress-step:last-child {
    padding-bottom: 0;
}

/* The line runs down from each marker to the next, so the last stage has none below it. */
.order-progress-step::before {
    content: '';
    position: absolute;
    top: 2rem;
    bottom: 0;
    left: 0.9375rem;
    width: 2px;
    background-color: var(--ctms-border);
}

.order-progress-step:last-child::before {
    content: none;
}

.order-progress-marker {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 2rem;
    height: 2rem;
    font-size: 0.75rem;
    color: var(--ctms-text-muted);
    background-color: var(--ctms-surface-alt);
    border-radius: 50%;
}

.order-progress-label {
    font-size: 0.9375rem;
    color: var(--ctms-text-muted);
}

.order-progress-done .order-progress-marker,
.order-progress-current .order-progress-marker {
    color: var(--ctms-text-inverse);
    background-color: var(--ctms-primary);
}

.order-progress-done::before {
    background-color: var(--ctms-primary);
}

.order-progress-current .order-progress-marker {
    box-shadow: 0 0 0 4px rgba(11, 79, 216, 0.18);
}

.order-progress-current .order-progress-label {
    font-weight: 700;
    color: var(--ctms-text);
}

.order-progress-done .order-progress-label {
    color: var(--ctms-text);
}

/* --- The tracker as a snake ---------------------------------------------------------------- */

/* The track runs across and folds back: left to right, down a row, right to left, down again.

Each stage draws the line leaving it, so a row's last stage draws the top half of the turn and the
stage below draws the bottom half; they meet in the row gap, neither needing the other's height.
Which stage ends a row depends on how many fit, so the two foldings are written as alternatives. */
@media (min-width: 576px) {
    .order-progress {
        --track-marker: 2.5rem;
        --track-column-gap: 1.5rem;
        --track-row-gap: 2.25rem;
        --track-line: 2px;
        --track-turn-radius: 0.875rem;
        /* A turn drops in the gutter, clear of the wording below. The percentage resolves against
        the stage, so this is half a stage plus half the gap: the middle of the gutter. */
        --track-turn-reach: calc(50% + var(--track-column-gap) / 2);
        /* A straight rule spans the gap between two markers, less the halves it starts and ends at. */
        --track-line-length: calc(100% + var(--track-column-gap) - var(--track-marker));
        --track-line-top: calc(var(--track-marker) / 2 - var(--track-line) / 2);
        --track-marker-edge: calc(50% + var(--track-marker) / 2);

        display: grid;
        /* Ordinary placement never steps back into a passed column, so dense packing fills them. */
        grid-auto-flow: row dense;
        column-gap: var(--track-column-gap);
        row-gap: var(--track-row-gap);
        grid-template-columns: repeat(2, minmax(0, 1fr));
        width: 100%;
        max-width: 34rem;
    }

    .order-progress-step {
        display: flex;
        flex-direction: column;
        align-items: center;
        gap: 0.5rem;
        padding-bottom: 0;
        text-align: center;
    }

    .order-progress-marker {
        width: var(--track-marker);
        height: var(--track-marker);
        font-size: 0.875rem;
        /* Lifted above the line, so a connector passes behind the circle rather than across it. */
        position: relative;
        z-index: 1;
    }

    .order-progress-label {
        font-size: 0.8125rem;
        line-height: 1.35;
    }

    /* Named through the list to outweigh the upright rule: a folded last stage needs its turn. */
    /* Named through the list to outweigh the upright rules: folded, connectors are drawn from
    borders, and each role below sets only the edges it needs. */
    .order-progress .order-progress-step::before,
    .order-progress .order-progress-step::after {
        content: '';
        position: absolute;
        top: auto;
        right: auto;
        bottom: auto;
        left: auto;
        width: var(--track-turn-reach);
        height: auto;
        background-color: transparent;
        border: 0 solid var(--ctms-border);
    }

    /* A line leaving or entering a stage already reached is solid; named through the list to match
    the weight of the neutral rule above. */
    .order-progress .order-progress-done::after,
    .order-progress .order-progress-done::before,
    .order-progress .order-progress-current::before {
        border-color: var(--ctms-primary);
    }
}

/* Two across, so a row folds every second stage and the pattern repeats every four. */
@media (min-width: 576px) and (max-width: 991.98px) {
    .order-progress-step:nth-child(4n+1),
    .order-progress-step:nth-child(4n+4) {
        grid-column: 1;
    }

    .order-progress-step:nth-child(4n+2),
    .order-progress-step:nth-child(4n+3) {
        grid-column: 2;
    }

    .order-progress-step:nth-child(4n+1)::after {
        top: var(--track-line-top);
        left: var(--track-marker-edge);
        width: var(--track-line-length);
        border-top-width: var(--track-line);
    }

    .order-progress-step:nth-child(4n+3)::after {
        top: var(--track-line-top);
        right: var(--track-marker-edge);
        width: var(--track-line-length);
        border-top-width: var(--track-line);
    }

    .order-progress-step:nth-child(4n+2)::after {
        top: var(--track-line-top);
        bottom: calc(var(--track-row-gap) / -2);
        left: 50%;
        border-top-width: var(--track-line);
        border-right-width: var(--track-line);
        border-top-right-radius: var(--track-turn-radius);
    }

    .order-progress-step:nth-child(4n+4)::after {
        top: var(--track-line-top);
        bottom: calc(var(--track-row-gap) / -2);
        right: 50%;
        border-top-width: var(--track-line);
        border-left-width: var(--track-line);
        border-top-left-radius: var(--track-turn-radius);
    }

    .order-progress-step:nth-child(4n+3)::before {
        top: calc(var(--track-row-gap) / -2);
        height: calc(var(--track-row-gap) / 2 + var(--track-marker) / 2);
        left: 50%;
        border-bottom-width: var(--track-line);
        border-right-width: var(--track-line);
        border-bottom-right-radius: var(--track-turn-radius);
    }

    .order-progress-step:nth-child(4n+1)::before {
        top: calc(var(--track-row-gap) / -2);
        height: calc(var(--track-row-gap) / 2 + var(--track-marker) / 2);
        right: 50%;
        border-bottom-width: var(--track-line);
        border-left-width: var(--track-line);
        border-bottom-left-radius: var(--track-turn-radius);
    }

    /* Nothing follows the last stage, and nothing leads into the first. */
    .order-progress-step:last-child::after,
    .order-progress-step:first-child::before {
        content: none;
    }
}

/* Three across, so a row folds every third stage and the pattern repeats every six. */
@media (min-width: 992px) {
    .order-progress {
        grid-template-columns: repeat(3, minmax(0, 1fr));
        max-width: 46rem;
    }

    .order-progress-step:nth-child(6n+1),
    .order-progress-step:nth-child(6n+6) {
        grid-column: 1;
    }

    .order-progress-step:nth-child(6n+2),
    .order-progress-step:nth-child(6n+5) {
        grid-column: 2;
    }

    .order-progress-step:nth-child(6n+3),
    .order-progress-step:nth-child(6n+4) {
        grid-column: 3;
    }

    .order-progress-step:nth-child(6n+1)::after,
    .order-progress-step:nth-child(6n+2)::after {
        top: var(--track-line-top);
        left: var(--track-marker-edge);
        width: var(--track-line-length);
        border-top-width: var(--track-line);
    }

    .order-progress-step:nth-child(6n+4)::after,
    .order-progress-step:nth-child(6n+5)::after {
        top: var(--track-line-top);
        right: var(--track-marker-edge);
        width: var(--track-line-length);
        border-top-width: var(--track-line);
    }

    .order-progress-step:nth-child(6n+3)::after {
        top: var(--track-line-top);
        bottom: calc(var(--track-row-gap) / -2);
        left: 50%;
        border-top-width: var(--track-line);
        border-right-width: var(--track-line);
        border-top-right-radius: var(--track-turn-radius);
    }

    .order-progress-step:nth-child(6n+6)::after {
        top: var(--track-line-top);
        bottom: calc(var(--track-row-gap) / -2);
        right: 50%;
        border-top-width: var(--track-line);
        border-left-width: var(--track-line);
        border-top-left-radius: var(--track-turn-radius);
    }

    .order-progress-step:nth-child(6n+4)::before {
        top: calc(var(--track-row-gap) / -2);
        height: calc(var(--track-row-gap) / 2 + var(--track-marker) / 2);
        left: 50%;
        border-bottom-width: var(--track-line);
        border-right-width: var(--track-line);
        border-bottom-right-radius: var(--track-turn-radius);
    }

    .order-progress-step:nth-child(6n+1)::before {
        top: calc(var(--track-row-gap) / -2);
        height: calc(var(--track-row-gap) / 2 + var(--track-marker) / 2);
        right: 50%;
        border-bottom-width: var(--track-line);
        border-left-width: var(--track-line);
        border-bottom-left-radius: var(--track-turn-radius);
    }

    .order-progress-step:last-child::after,
    .order-progress-step:first-child::before {
        content: none;
    }
}

/* --- Order detail -------------------------------------------------------------------------- */

.order-back {
    margin-bottom: 1.25rem;
    font-size: 0.875rem;
}

.order-back a {
    color: var(--ctms-text-muted);
    text-decoration: none;
}

.order-back a:hover,
.order-back a:focus {
    color: var(--ctms-primary);
}

.order-detail {
    max-width: 48rem;
    margin: 0 auto;
}

.order-detail-head {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem 1rem;
    padding-bottom: 1.25rem;
    border-bottom: 1px solid var(--ctms-border);
}

.order-detail-reference {
    font-weight: 700;
    font-size: clamp(1.375rem, 1.2rem + 0.8vw, 1.75rem);
    margin-bottom: 0.25rem;
}

.order-detail-placed {
    margin-bottom: 0;
    font-size: 0.875rem;
    color: var(--ctms-text-muted);
}

/* The two places stack with the mode between them, and become one line from sm upward. */
.order-route {
    display: grid;
    gap: 0.75rem;
    margin: 1.5rem 0;
}

.order-route-point {
    display: flex;
    flex-direction: column;
    min-width: 0;
}

.order-route-label {
    font-size: 0.75rem;
    font-weight: 700;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--ctms-text-muted);
}

.order-route-place {
    font-size: 1.0625rem;
    font-weight: 600;
    overflow-wrap: anywhere;
}

/* The mode centres on the track, so the line reads as the journey, not a trail from one end. */
.order-route-link {
    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;
    min-height: 2.25rem;
}

.order-route-mode {
    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    width: 2.25rem;
    height: 2.25rem;
    border: 3px solid var(--ctms-surface);
    border-radius: 50%;
    color: var(--ctms-text-inverse);
    background-color: var(--ctms-primary);
}

.order-route-track {
    position: absolute;
    left: 0;
    right: 0;
    height: 2px;
    background-image: linear-gradient(90deg, var(--ctms-primary) 50%, transparent 50%);
    background-size: 8px 2px;
}

@media (min-width: 576px) {
    .order-route {
        /* The middle column needs a share of its own, or the track collapses to nothing. */
        grid-template-columns: minmax(0, 1fr) minmax(6rem, 0.7fr) minmax(0, 1fr);
        align-items: center;
        gap: 1rem;
    }

    .order-route-point-end {
        text-align: right;
    }
}

.order-cancelled-note {
    display: flex;
    align-items: center;
    gap: 0.625rem;
    margin: 1.75rem 0;
    padding: 0.875rem 1rem;
    border-radius: var(--ctms-radius);
    font-size: 0.9375rem;
    color: var(--ctms-danger);
    background-color: rgba(220, 53, 69, 0.08);
}

/* --- Order summary ------------------------------------------------------------------------- */

.order-summary {
    margin: 0;
    padding-top: 1.25rem;
    border-top: 1px solid var(--ctms-border);
}

.order-summary-row {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    justify-content: space-between;
    gap: 0.25rem 1rem;
    padding: 0.625rem 0;
}

.order-summary-row dt {
    font-weight: 400;
    color: var(--ctms-text-muted);
}

.order-summary-row dd {
    margin-bottom: 0;
    font-weight: 600;
}

/* A typed reason takes its own line beneath the figure rather than widening the row; named through
the row to outweigh the rule that makes a total bold and blue. */
.order-summary-row .order-cost-note {
    flex: 0 0 100%;
    font-size: 0.8125rem;
    font-weight: 400;
    color: var(--ctms-text-muted);
}

.order-pricing-form {
    margin-bottom: 0.75rem;
}

.order-pricing-fields {
    display: grid;
    gap: 0 1rem;
}

.order-pricing-note {
    display: flex;
    align-items: baseline;
    gap: 0.5rem;
    margin-bottom: 0;
    font-size: 0.8125rem;
    color: var(--ctms-text-muted);
}

.order-summary-total {
    margin-top: 0.25rem;
    padding-top: 0.875rem;
    border-top: 1px solid var(--ctms-border);
    font-size: 1.125rem;
}

.order-summary-total dd {
    font-weight: 700;
    color: var(--ctms-primary);
}

.order-detail-actions {
    margin-top: 1.5rem;
    padding-top: 1.25rem;
    border-top: 1px solid var(--ctms-border);
}

.order-detail-actions .btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.5rem;
    width: 100%;
}

.order-detail-hint {
    margin: 0.875rem 0 0;
    font-size: 0.8125rem;
    color: var(--ctms-text-muted);
}

/* --- Confirm dialogue ---------------------------------------------------------------------- */

.modal-content {
    border: 1px solid var(--ctms-border);
    border-radius: var(--ctms-radius-lg);
    box-shadow: var(--ctms-shadow-lg);
}

.modal-header,
.modal-footer {
    border-color: var(--ctms-border);
}

.modal-title {
    font-size: 1.0625rem;
    font-weight: 700;
    margin-bottom: 0;
}

.confirm-detail {
    margin-bottom: 0;
    font-size: 0.9375rem;
    color: var(--ctms-text-muted);
}

/* The two ways out are the same size, so neither is the one the pointer lands on by accident. */
.modal-footer .btn {
    flex: 1 1 auto;
    justify-content: center;
}

@media (min-width: 576px) {
    .modal-footer .btn {
        flex: 0 0 auto;
    }
}

/* --- Empty state --------------------------------------------------------------------------- */

.empty-state {
    max-width: 32rem;
    margin: 0 auto;
    text-align: center;
}

.empty-state-icon {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 3.5rem;
    height: 3.5rem;
    margin: 0 auto 1rem;
    border-radius: 50%;
    font-size: 1.5rem;
    color: var(--ctms-primary);
    background-color: rgba(11, 79, 216, 0.1);
}

.empty-state-title {
    font-size: 1.25rem;
    font-weight: 700;
    margin-bottom: 0.5rem;
}

.empty-state-text {
    color: var(--ctms-text-muted);
    margin-bottom: 1.5rem;
}

@media (min-width: 576px) {
    .order-form-card,
    .rate-card,
    .order-detail,
    .empty-state {
        padding: 2rem 1.75rem;
    }

    .order-card {
        padding: 1.5rem;
    }

    .order-form-actions .btn,
    .order-detail-actions .btn {
        flex: 0 0 auto;
        width: auto;
        min-width: 11rem;
    }
}

/* ----------------------------------------------------------------------------------------------
Control panel

The back office: heading, section tabs, stat tiles and the data tables. A table carries far more
columns than a phone can show, so each row is a stacked block by default and becomes a real table
row from the lg breakpoint, where the columns fit. One markup serves both.
---------------------------------------------------------------------------------------------- */

.panel-header {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    justify-content: space-between;
    gap: 1rem;
    margin-bottom: 1.5rem;
}

.panel-heading {
    min-width: 0;
}

.panel-eyebrow {
    margin-bottom: 0.25rem;
    font-size: 0.6875rem;
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--ctms-primary);
}

.panel-title {
    font-weight: 700;
    font-size: clamp(1.5rem, 1.15rem + 1.6vw, 2.25rem);
    margin-bottom: 0.25rem;
}

.panel-intro {
    margin-bottom: 0;
    color: var(--ctms-text-muted);
}

.panel-actions .btn {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
}

/* --- Section tabs -------------------------------------------------------------------------- */

.panel-nav {
    margin-bottom: 1.5rem;
    border-bottom: 1px solid var(--ctms-border);
    /* Narrow screens scroll the tabs sideways rather than wrapping them into a second row. */
    overflow-x: auto;
}

.panel-nav-list {
    display: flex;
    gap: 0.25rem;
    margin: 0;
    padding: 0;
    list-style: none;
}

.panel-nav-link {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.75rem 1rem;
    border-bottom: 2px solid transparent;
    font-size: 0.9375rem;
    font-weight: 600;
    white-space: nowrap;
    color: var(--ctms-text-muted);
    text-decoration: none;
    transition: color var(--ctms-transition), border-color var(--ctms-transition);
}

.panel-nav-link:hover,
.panel-nav-link:focus {
    color: var(--ctms-primary);
}

.panel-nav-link-current {
    color: var(--ctms-primary);
    border-bottom-color: var(--ctms-primary);
}

/* --- Stat tiles ---------------------------------------------------------------------------- */

/* One population divided between ranks, so it is drawn as one bar, not four figures. */
.role-bar {
    display: flex;
    overflow: hidden;
    height: 0.75rem;
    margin-bottom: 1.25rem;
    background-color: var(--ctms-surface-alt);
    border-radius: 2rem;
}

.role-bar-slice {
    height: 100%;
}

.role-bar-slice-member {
    background-color: var(--ctms-text-muted);
}

.role-bar-slice-staff {
    background-color: var(--ctms-warning);
}

.role-bar-slice-administrator {
    background-color: var(--ctms-primary);
}

.role-bar-slice-superuser {
    background-color: var(--ctms-success);
}

.role-legend {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 0.875rem 1.25rem;
    list-style: none;
    padding-left: 0;
    margin-bottom: 0;
}

.role-legend-item {
    display: grid;
    grid-template-columns: auto auto 1fr;
    align-items: baseline;
    gap: 0.5rem;
}

/* A block of its slice's colour, aligned to the text rather than to the line. */
.role-legend-key {
    align-self: center;
    width: 0.75rem;
    height: 0.75rem;
    border-radius: 0.25rem;
}

.role-legend-count {
    font-size: 1.125rem;
    font-weight: 700;
}

.role-legend-label {
    font-size: 0.8125rem;
    letter-spacing: 0.03em;
    text-transform: uppercase;
    color: var(--ctms-text-muted);
}

/* Enquiries are a queue rather than a journey, so each status is a card of its own count. */
.status-grid {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 0.75rem;
    list-style: none;
    padding-left: 0;
    margin-bottom: 0;
}

.status-grid-item {
    padding: 1rem 1.125rem;
    background-color: var(--ctms-surface-muted);
    border-left: 3px solid var(--ctms-text-muted);
    border-radius: var(--ctms-radius);
}

.status-grid-item-new {
    border-left-color: var(--ctms-warning);
}

.status-grid-item-in-progress {
    border-left-color: var(--ctms-primary);
}

.status-grid-item-resolved {
    border-left-color: var(--ctms-success);
}

.status-grid-item-closed {
    border-left-color: var(--ctms-text-muted);
}

.status-grid-count {
    display: block;
    font-size: clamp(1.5rem, 1.2rem + 1.2vw, 2rem);
    font-weight: 700;
    line-height: 1.1;
}

.status-grid-label {
    display: block;
    margin-top: 0.25rem;
    font-size: 0.8125rem;
    font-weight: 700;
    letter-spacing: 0.03em;
    text-transform: uppercase;
    color: var(--ctms-text-muted);
}

.status-grid-share {
    display: block;
    margin-top: 0.125rem;
    font-size: 0.75rem;
    color: var(--ctms-text-muted);
}

/* A mode is named by its icon before its wording, so the icon leads the tile. */
.mode-grid {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 0.75rem;
    list-style: none;
    padding-left: 0;
    margin-bottom: 0;
}

.mode-grid-item {
    padding: 1rem 1.125rem;
    background-color: var(--ctms-surface-muted);
    border-left: 3px solid var(--ctms-primary);
    border-radius: var(--ctms-radius);
}

.mode-grid-icon {
    display: block;
    margin-bottom: 0.5rem;
    font-size: 1.25rem;
    color: var(--ctms-primary);
}

.mode-grid-count {
    display: block;
    font-size: clamp(1.5rem, 1.2rem + 1.2vw, 2rem);
    font-weight: 700;
    line-height: 1.1;
}

.mode-grid-label {
    display: block;
    margin-top: 0.25rem;
    font-size: 0.8125rem;
    font-weight: 700;
    letter-spacing: 0.03em;
    text-transform: uppercase;
}

.mode-grid-share {
    display: block;
    margin-top: 0.125rem;
    font-size: 0.75rem;
    color: var(--ctms-text-muted);
}

.mode-grid-completed {
    display: block;
    margin-top: 0.125rem;
    font-size: 0.75rem;
    font-weight: 700;
    color: var(--ctms-success);
}

@media (min-width: 768px) {
    .role-legend {
        grid-template-columns: repeat(4, minmax(0, 1fr));
    }

    .status-grid,
    .mode-grid {
        grid-template-columns: repeat(4, minmax(0, 1fr));
    }
}

/* --- Table controls ------------------------------------------------------------------------ */

/* A row from md, so the search box is not squeezed beside two dropdowns. */
.panel-controls {
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
    margin-bottom: 1.25rem;
}

.panel-controls-search {
    position: relative;
    flex: 1;
}

.panel-controls-icon {
    position: absolute;
    top: 50%;
    left: 0.875rem;
    transform: translateY(-50%);
    font-size: 0.875rem;
    color: var(--ctms-text-muted);
    pointer-events: none;
}

.panel-controls-search .form-control {
    padding-left: 2.375rem;
}

.panel-controls-choices {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
}

.panel-controls-choices .form-select {
    flex: 1 1 10rem;
    width: auto;
}

@media (min-width: 768px) {
    .panel-controls {
        flex-direction: row;
        align-items: center;
    }

    .panel-controls-choices {
        flex-wrap: nowrap;
    }

    .panel-controls-choices .form-select {
        flex: 0 0 auto;
    }
}

/* --- Cards and counts ---------------------------------------------------------------------- */

.panel-card {
    margin-top: 1.5rem;
    padding: 1.5rem 1.25rem;
    background-color: var(--ctms-surface);
    border: 1px solid var(--ctms-border);
    border-radius: var(--ctms-radius-lg);
    box-shadow: var(--ctms-shadow-sm);
}

.panel-card-head {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    justify-content: space-between;
    gap: 0.5rem 1rem;
    margin-bottom: 1.25rem;
}

.panel-card-title {
    display: flex;
    align-items: center;
    gap: 0.625rem;
    font-size: 1.125rem;
    font-weight: 700;
    margin-bottom: 1.25rem;
}

/* Inside a head the title's own gap would double the row's, so it is dropped there. */
.panel-card-head .panel-card-title {
    margin-bottom: 0;
}

.panel-card-total {
    font-size: 0.875rem;
    font-weight: 600;
    color: var(--ctms-primary);
    text-decoration: none;
}

.panel-card-total:hover,
.panel-card-total:focus {
    color: var(--ctms-primary-dark);
    text-decoration: underline;
}

.panel-card-title i {
    color: var(--ctms-primary);
}

.panel-count {
    margin-bottom: 0;
    font-size: 0.875rem;
    color: var(--ctms-text-muted);
}

/* --- Status breakdown ---------------------------------------------------------------------- */

.status-breakdown {
    display: grid;
    gap: 0.875rem;
    margin: 0;
    padding: 0;
    list-style: none;
}

.status-row {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    align-items: center;
    gap: 0.5rem 1rem;
}

.status-row-bar {
    grid-column: 1 / -1;
    grid-row: 2;
    height: 0.5rem;
    border-radius: 1rem;
    background-color: var(--ctms-surface-alt);
    overflow: hidden;
}

.status-row-fill {
    display: block;
    height: 100%;
    border-radius: inherit;
}

.status-row-fill-pending,
.status-row-fill-payment-pending {
    background-color: var(--ctms-warning);
}

/* Confirming through delivering is all work in hand, so it reads as one colour. */
.status-row-fill-confirmed,
.status-row-fill-processing,
.status-row-fill-ready-for-pickup,
.status-row-fill-picked-up,
.status-row-fill-in-transit,
.status-row-fill-out-for-delivery {
    background-color: var(--ctms-primary);
}

.status-row-fill-delivered,
.status-row-fill-completed {
    background-color: var(--ctms-success);
}

.status-row-fill-cancelled,
.status-row-fill-returned {
    background-color: var(--ctms-danger);
}

.status-row-fill-archived {
    background-color: var(--ctms-text-muted);
}

.status-row-fill-paid {
    background-color: var(--ctms-success);
}

.status-row-fill-refunded {
    background-color: var(--ctms-warning);
}

.status-row-fill-failed {
    background-color: var(--ctms-danger);
}

.status-row-count {
    font-weight: 700;
    white-space: nowrap;
}

.status-row-share {
    font-weight: 400;
    font-size: 0.8125rem;
    color: var(--ctms-text-muted);
}

@media (min-width: 768px) {
    .status-row {
        grid-template-columns: 8rem minmax(0, 1fr) auto;
    }

    .status-row-bar {
        grid-column: 2;
        grid-row: 1;
    }
}

/* --- Data tables --------------------------------------------------------------------------- */

.panel-table-wrap {
    background-color: var(--ctms-surface);
    border: 1px solid var(--ctms-border);
    border-radius: var(--ctms-radius-lg);
    box-shadow: var(--ctms-shadow-sm);
}

.panel-table {
    width: 100%;
    margin: 0;
    border-collapse: collapse;
}

/* Stacked by default: the header is redundant once every cell names itself. */
.panel-table thead {
    display: none;
}

.panel-table,
.panel-table tbody,
.panel-table tr,
.panel-table td {
    display: block;
}

.panel-table tr {
    padding: 1rem 1.25rem;
    border-bottom: 1px solid var(--ctms-border);
}

.panel-table tr:last-child {
    border-bottom: 0;
}

.panel-table tbody tr {
    transition: background-color var(--ctms-transition);
}

.panel-table tbody tr:hover {
    background-color: var(--ctms-surface-muted);
}

.panel-table td {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    justify-content: space-between;
    gap: 0.25rem 1rem;
    padding: 0.3125rem 0;
}

.panel-table td::before {
    content: attr(data-label);
    flex-shrink: 0;
    font-size: 0.75rem;
    font-weight: 700;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--ctms-text-muted);
}

/* Actions sit under their label, so the buttons keep a tappable width. */
.panel-table td[data-label='Action'] {
    padding-top: 0.75rem;
}

.panel-count-bar {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem 1rem;
    margin-bottom: 0.875rem;
}

.panel-strong {
    display: block;
    font-weight: 600;
}

/* Only text that needs it breaks mid-word: a figure such as a cost must never be split. */
.panel-muted,
.panel-person-email,
.panel-cell-wide {
    overflow-wrap: anywhere;
}

/* A date and the time on it read as one moment, and are never broken between two lines. */
.panel-when {
    white-space: nowrap;
}

.panel-muted {
    display: block;
    font-size: 0.8125rem;
    color: var(--ctms-text-muted);
    text-decoration: none;
}

a.panel-muted:hover,
a.panel-muted:focus {
    color: var(--ctms-primary);
}

.panel-person {
    display: flex;
    align-items: center;
    gap: 0.625rem;
    min-width: 0;
}

.panel-person-avatar {
    flex-shrink: 0;
    width: 2.25rem;
    height: 2.25rem;
    border-radius: 50%;
    object-fit: cover;
}

.panel-person-body {
    display: flex;
    flex-direction: column;
    min-width: 0;
}

.panel-person-name {
    font-weight: 600;
}

.panel-person-email {
    font-size: 0.8125rem;
    color: var(--ctms-text-muted);
}

/* --- Account detail ------------------------------------------------------------------------ */

/* It opens the page rather than following a card, so the margin moves from above it to below. */
.account-summary {
    display: flex;
    flex-direction: column;
    gap: 1.25rem;
    margin-top: 0;
    margin-bottom: 1.5rem;
}

.account-summary-avatar {
    width: 5.5rem;
    height: 5.5rem;
    object-fit: cover;
    border-radius: 50%;
    border: 2px solid var(--ctms-border);
}

/* Takes the width the picture leaves, so the facts lay out in columns, not a strip. */
.account-summary-body {
    flex: 1;
    min-width: 0;
}

.account-summary-facts {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr));
    gap: 0.875rem 1.5rem;
    margin: 1rem 0 0;
}

.account-summary-fact dt {
    font-size: 0.75rem;
    font-weight: 700;
    letter-spacing: 0.03em;
    text-transform: uppercase;
    color: var(--ctms-text-muted);
}

.account-summary-fact dd {
    margin-bottom: 0;
    overflow-wrap: anywhere;
}

.account-flags {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr));
    gap: 0.5rem 1.5rem;
}

/* A checkbox row already carries its own bottom margin from the form furniture. */
.account-flags .form-field {
    margin-bottom: 0;
}

.account-actions {
    display: flex;
    flex-wrap: wrap;
    gap: 0.75rem;
    margin-top: 1.5rem;
}

/* A row that opens a record reads as one target, so the whole cell carries the link. */
.panel-person-link {
    color: inherit;
    text-decoration: none;
}

.panel-person-link:hover .panel-person-name,
.panel-person-link:focus .panel-person-name {
    color: var(--ctms-primary);
    text-decoration: underline;
}

.panel-person-open {
    font-size: 0.75rem;
    color: var(--ctms-text-muted);
}

/* Beside the facts from sm and above them below it, so a narrow screen gives them full width. */
@media (min-width: 576px) {
    .account-summary {
        flex-direction: row;
        align-items: flex-start;
    }
}

/* --- Pages --------------------------------------------------------------------------------- */

.panel-pages {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: center;
    gap: 0.75rem;
    margin-top: 1.5rem;
}

.panel-pages-count {
    font-size: 0.875rem;
    color: var(--ctms-text-muted);
}

/* The end of the run is shown, not hidden, so the control keeps its shape. */
.panel-pages-spent {
    opacity: 0.45;
    pointer-events: none;
}

/* --- Badges and flags ---------------------------------------------------------------------- */

.panel-badge {
    display: inline-block;
    padding: 0.1875rem 0.625rem;
    border-radius: 2rem;
    font-size: 0.6875rem;
    font-weight: 700;
    letter-spacing: 0.03em;
    text-transform: uppercase;
    color: var(--ctms-text-muted);
    background-color: var(--ctms-surface-alt);
}

.panel-badge-superuser {
    color: var(--ctms-success);
    background-color: rgba(25, 135, 84, 0.12);
}

.panel-badge-administrator {
    color: var(--ctms-primary);
    background-color: rgba(11, 79, 216, 0.1);
}

.panel-badge-staff {
    color: var(--ctms-warning);
    background-color: rgba(255, 152, 0, 0.16);
}

.panel-flag {
    display: inline-flex;
    align-items: center;
    gap: 0.375rem;
    font-size: 0.875rem;
}

.panel-flag-yes {
    color: var(--ctms-success);
}

.panel-flag-no {
    color: var(--ctms-text-muted);
}

/* --- Row actions --------------------------------------------------------------------------- */

.panel-action-group {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
}

.panel-action-group .btn {
    display: inline-flex;
    align-items: center;
    gap: 0.375rem;
    white-space: nowrap;
}

.panel-status-form {
    display: flex;
    gap: 0.5rem;
}

.panel-status-form .form-select {
    width: auto;
    min-width: 8rem;
}

@media (min-width: 992px) {
    .panel-table-wrap {
        /* Columns can still outgrow a narrow laptop, so the wrapper scrolls. */
        overflow-x: auto;
    }

    .panel-table {
        display: table;
        table-layout: auto;
    }

    .panel-table thead {
        display: table-header-group;
    }

    .panel-table tbody {
        display: table-row-group;
    }

    .panel-table tr {
        display: table-row;
        padding: 0;
    }

    .panel-table th {
        position: relative;
        padding: 0.875rem 1rem;
        font-size: 0.75rem;
        font-weight: 700;
        letter-spacing: 0.04em;
        text-transform: uppercase;
        text-align: left;
        white-space: nowrap;
        color: var(--ctms-text-muted);
        background-color: var(--ctms-surface-muted);
        border-bottom: 1px solid var(--ctms-border);
    }

    .panel-table td {
        display: table-cell;
        padding: 0.875rem 1rem;
        vertical-align: middle;
    }

    .panel-table td::before {
        content: none;
    }

    .panel-table td[data-label='Action'] {
        padding-top: 0.875rem;
    }

    /* A figure and its unit are one thing, so neither is left alone; the wrapper scrolls. */
    .panel-table td[data-label='Weight'],
    .panel-table td[data-label='Cost'],
    .panel-table td[data-label='Amount'] {
        white-space: nowrap;
    }

    /* Resizing only means anything once rows are real; the grip shows on approach. */
    .panel-column-grip {
        position: absolute;
        top: 0;
        right: 0;
        width: 0.75rem;
        height: 100%;
        cursor: col-resize;
        border-right: 2px solid transparent;
        transition: border-color var(--ctms-transition);
        touch-action: none;
    }

    .panel-column-grip:hover,
    .panel-column-grip.is-resizing {
        border-right-color: var(--ctms-primary);
    }

    /* Dragging a heading must not start selecting the wording it is dragging. */
    .panel-table.is-resizing {
        user-select: none;
    }

    /* As table cells the actions keep one line; the wrapper scrolls if the table outgrows it. */
    .panel-action-group {
        flex-wrap: nowrap;
    }

    .panel-cell-wide {
        min-width: 18rem;
    }

    .panel-card {
        padding: 2rem 1.75rem;
    }
}

/* ----------------------------------------------------------------------------------------------
Routing

The address suggestions on the order form, and the journey panel and map on the order page. The map
is sized in viewport units so it keeps a usable height on a phone without dominating a laptop.
---------------------------------------------------------------------------------------------- */

/* Anchors the suggestion list to the box it belongs to rather than to the page. */
.place-field {
    position: relative;
}

.place-field-help {
    margin-top: 0.75rem;
}

.place-suggestions {
    position: absolute;
    z-index: 5;
    left: 0;
    right: 0;
    margin: 0.25rem 0 0;
    padding: 0.25rem;
    list-style: none;
    background-color: var(--ctms-surface);
    border: 1px solid var(--ctms-border);
    border-radius: var(--ctms-radius);
    box-shadow: var(--ctms-shadow-lg);
    /* A long list scrolls inside itself instead of running past the bottom of the card. */
    max-height: 15rem;
    overflow-y: auto;
}

.place-suggestion {
    display: block;
    width: 100%;
    padding: 0.5rem 0.625rem;
    border: 0;
    border-radius: var(--ctms-radius);
    font-size: 0.9375rem;
    text-align: left;
    color: var(--ctms-text);
    background-color: transparent;
}

.place-suggestion:hover,
.place-suggestion:focus {
    color: var(--ctms-primary);
    background-color: var(--ctms-surface-muted);
}

/* --- Journey panel ------------------------------------------------------------------------- */

.route-panel {
    margin: 1.75rem 0;
    padding-top: 1.25rem;
    border-top: 1px solid var(--ctms-border);
}

.route-panel-head {
    margin-bottom: 1rem;
}

.route-panel-title {
    display: flex;
    align-items: center;
    gap: 0.625rem;
    font-size: 1.0625rem;
    font-weight: 700;
    margin-bottom: 0.25rem;
}

.route-panel-title i {
    color: var(--ctms-primary);
}

.route-panel-note {
    margin-bottom: 0;
    font-size: 0.8125rem;
    color: var(--ctms-text-muted);
}

.route-figures {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 0.75rem;
    margin-bottom: 1rem;
}

.route-figure {
    display: flex;
    flex-direction: column;
    padding: 0.875rem 1rem;
    border-radius: var(--ctms-radius);
    background-color: var(--ctms-surface-muted);
}

.route-figure-value {
    font-size: 1.125rem;
    font-weight: 700;
}

.route-figure-label {
    font-size: 0.75rem;
    font-weight: 700;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--ctms-text-muted);
}

/* --- Map ----------------------------------------------------------------------------------- */

.route-map {
    height: 60vw;
    max-height: 26rem;
    min-height: 14rem;
    border: 1px solid var(--ctms-border);
    border-radius: var(--ctms-radius);
    /* Leaflet paints to the container's corners, which would spill past the radius. */
    overflow: hidden;
}

/* Bootstrap gives every image a max-width, which stops Leaflet's tiles tiling correctly. */
.route-map img {
    max-width: none;
}

.route-map .leaflet-container {
    font: inherit;
}

@media (min-width: 576px) {
    .route-map {
        height: 22rem;
    }
}

/* While the geocoder is answering, the row says so rather than leaving an empty box. */
.place-suggestions-busy {
    padding: 0.75rem 0.875rem;
    font-size: 0.875rem;
    color: var(--ctms-text-muted);
}

/* The two rates stack in the row so the distance one reads as an addition to the weight one. */
.rate-value {
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    font-weight: 700;
    text-align: right;
    white-space: nowrap;
}

.rate-distance {
    font-weight: 400;
    font-size: 0.75rem;
    color: var(--ctms-text-muted);
}

/* The reference in a control panel table opens the record it names. */
.panel-link {
    display: block;
    font-weight: 700;
    color: var(--ctms-text);
    text-decoration: none;
}

.panel-link:hover,
.panel-link:focus {
    color: var(--ctms-primary);
}

/* --- Who placed an order ------------------------------------------------------------------- */

.order-owner {
    display: flex;
    align-items: center;
    gap: 0.875rem;
    margin-top: 1.25rem;
    padding: 0.875rem 1rem;
    border-radius: var(--ctms-radius);
    background-color: var(--ctms-surface-muted);
}

.order-owner-avatar {
    flex-shrink: 0;
    width: 2.5rem;
    height: 2.5rem;
    border-radius: 50%;
    object-fit: cover;
}

.order-owner-body {
    display: flex;
    flex-direction: column;
    min-width: 0;
}

.order-owner-label {
    font-size: 0.6875rem;
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--ctms-text-muted);
}

.order-owner-name {
    font-weight: 600;
}

.order-owner-email {
    font-size: 0.875rem;
    color: var(--ctms-text-muted);
    text-decoration: none;
    overflow-wrap: anywhere;
}

.order-owner-email:hover,
.order-owner-email:focus {
    color: var(--ctms-primary);
}

/* The status control and the deletion sit on one row from the point they both fit. */
.order-admin-actions {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.75rem;
}

.order-admin-actions .panel-status-form {
    flex: 1 1 16rem;
}

.order-admin-actions .form-select {
    flex: 1 1 auto;
}
