/* ---- The public website ---- */

/*
 * The palette comes from the logo: its blue, its deeper blue and its yellow,
 * on white. Everything below refers to these variables rather than repeating
 * hex codes, so re-branding is a change in one place.
 */
:root {
    --brand-blue: #2d8de1;
    --brand-blue-deep: #2370b4;
    --brand-blue-dark: #1b5688;
    --brand-blue-soft: #eaf4fd;
    --brand-blue-tint: #f4f9fe;
    --brand-blue-line: #7cc0f4;
    --brand-yellow: #f9ee3c;
    --brand-yellow-soft: #fefbdc;
    --brand-yellow-deep: #d9cc17;
    --brand-ink: #1b3a52;

    /* The redesign's own three: the pale grey the services sit on, the softer
       yellow of the closing strip, and the near-black of the footer. */
    --surface-muted: #ececec;
    --brand-yellow-band: #fbf273;
    --footer-ink: #262626;
}

.public-body {
    background: #ffffff;
    color: #1e293b;
}

/*
 * The public site runs close to the edges of the window rather than inside
 * Bootstrap's fixed-width container: in the design the logo sits a little in
 * from the left of the screen and the header's button a little in from the
 * right, and the footer's four columns spread across the same width.
 *
 * A percentage gutter rather than a max-width keeps that proportion at every
 * window size, and the floor and ceiling stop it from crushing the content on
 * a phone or drifting apart on a very wide monitor.
 */
.public-body .container {
    max-width: none;
    padding-inline: clamp(1.25rem, 4vw, 4rem);
}

.text-brand-blue {
    color: var(--brand-blue-deep) !important;
}

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

/* The yellow call to action, for use against blue. An outline rather than a
   slab: its own yellow draws the edge and the label, and hovering washes that
   yellow in behind the text instead of filling it. */
.btn-brand-yellow {
    background: transparent;
    border: 1px solid var(--brand-yellow);
    color: var(--brand-yellow);
    font-weight: 700;
}

.btn-brand-yellow:hover,
.btn-brand-yellow:focus {
    background: rgba(249, 238, 60, .18);
    border-color: var(--brand-yellow);
    color: var(--brand-yellow);
}

.btn-brand-blue {
    background: transparent;
    border: 1px solid var(--brand-blue);
    color: var(--brand-blue-deep);
    font-weight: 600;
}

.btn-brand-blue:hover,
.btn-brand-blue:focus {
    background: rgba(45, 141, 225, .12);
    border-color: var(--brand-blue);
    color: var(--brand-blue-deep);
}

/* The one solid blue button: the header's Log In, set beside the outlined
   Sign Up so the two doors are told apart at a glance. */
.btn-brand-blue-solid {
    background: var(--brand-blue-deep);
    border: 1px solid var(--brand-blue-deep);
    color: #fff;
    font-weight: 600;
}

.btn-brand-blue-solid:hover,
.btn-brand-blue-solid:focus {
    background: var(--brand-blue-dark);
    border-color: var(--brand-blue-dark);
    color: #fff;
}

/* Kept as its own class because the markup names it, but with the filled blue
   one now outlined too the two read alike - there is only the one blue button. */
.btn-outline-brand-blue {
    background: transparent;
    border: 1px solid var(--brand-blue);
    color: var(--brand-blue-deep);
    font-weight: 600;
}

.btn-outline-brand-blue:hover,
.btn-outline-brand-blue:focus {
    background: rgba(45, 141, 225, .12);
    border-color: var(--brand-blue);
    color: var(--brand-blue-deep);
}

/* Fully rounded, which is the shape every call to action wears in the
   redesign - in the header, in the hero and on the closing strip. */
.btn-pill {
    border-radius: 999px;
}

/* The hero's quiet button: white outline on blue, washing white in behind the
   label on hover rather than filling with it, so it neither competes with the
   yellow one beside it nor turns solid. */
.btn-hero-ghost {
    background: transparent;
    border: 1px solid rgba(255, 255, 255, .85);
    color: #fff;
    font-weight: 600;
}

.btn-hero-ghost:hover,
.btn-hero-ghost:focus {
    background: rgba(255, 255, 255, .18);
    border-color: #fff;
    color: #fff;
}

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

/* A pale bar rather than a white one with a blue rule under it: the hero
   below is a solid slab of blue, and two blue edges meeting read as a seam. */
.public-navbar {
    background: #f6f8fa;
    border-bottom: 1px solid #e3e8ee;
    padding-block: .55rem;
}

.public-brand-logo {
    height: 42px;
    width: auto;
    object-fit: contain;
}

/* Stands in for the logo before one is uploaded, so the header keeps its
   shape instead of jumping when branding is set. */
.public-brand-placeholder {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 42px;
    height: 42px;
    border-radius: 12px;
    background: var(--brand-blue);
    color: #fff;
    font-weight: 700;
    font-size: 1.2rem;
}

.public-brand-name {
    font-weight: 700;
    color: var(--brand-blue-dark);
}

.public-navbar .nav-link {
    position: relative;
    font-weight: 500;
    color: #3f4c5a;
    padding-inline: 1.25rem;
}

.public-navbar .nav-link:hover {
    color: var(--brand-blue-deep);
}

.public-navbar .nav-link.active {
    color: var(--brand-blue);
    font-weight: 600;
}

/* The current page is underlined rather than merely tinted, which is how the
   design marks it. */
.public-navbar .nav-link.active::after {
    content: "";
    position: absolute;
    left: 1.25rem;
    right: 1.25rem;
    bottom: .1rem;
    height: 2px;
    border-radius: 999px;
    background: var(--brand-blue);
}

/* The bell is centred in the topbar of the portals; here it sits inline. */
.public-nav-actions .notification-bell {
    margin-left: 0;
}

/* ---- Home: hero ----
   One flat blue field, centred, ending in the framed photograph. Flat rather
   than a gradient because the photograph is the only thing in it meant to
   hold the eye. */

.home-hero {
    background: var(--brand-blue-deep);
    color: #fff;
    padding-block: 4rem 5rem;
    text-align: center;
}

.home-hero-badge {
    display: inline-block;
    background: var(--brand-yellow);
    color: var(--brand-ink);
    border-radius: 999px;
    padding: .45rem 1.4rem;
    font-size: .88rem;
    font-weight: 600;
    margin-bottom: 1.6rem;
}

.home-hero-heading {
    font-size: clamp(2.1rem, 5vw, 3.5rem);
    font-weight: 800;
    line-height: 1.15;
    max-width: 18ch;
    margin: 0 auto;
}

.home-hero-description {
    font-size: 1.05rem;
    color: rgba(255, 255, 255, .88);
    max-width: 58ch;
    margin: 1.4rem auto 0;
}

.home-hero-actions {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: .75rem;
    margin-top: 1.9rem;
}

.home-hero-figure {
    max-width: 62rem;
    margin: 3.5rem auto 0;
    border-radius: .9rem;
    overflow: hidden;
    box-shadow: 0 18px 44px rgba(9, 41, 70, .32);
    background: rgba(255, 255, 255, .08);
}

.home-hero-figure img {
    display: block;
    width: 100%;
    height: auto;
}

/* Before a photograph is uploaded the frame keeps its proportions, so the
   hero does not change height the day branding is filled in. */
.home-hero-figure-empty {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: .5rem;
    aspect-ratio: 16 / 7;
    border: 1px dashed rgba(255, 255, 255, .45);
    border-radius: .9rem;
    color: rgba(255, 255, 255, .75);
    font-size: .9rem;
}

.home-hero-figure-empty i {
    font-size: 1.8rem;
}

/* ---- Home: services ---- */

.home-services {
    background: var(--surface-muted);
}

.home-services-head {
    margin-bottom: 3.5rem;
}

/* The centred headings on the homepage carry no rule under them - the
   eyebrow above already separates them from what came before. */
.home-section-heading {
    font-size: clamp(1.6rem, 3vw, 2.2rem);
    font-weight: 800;
    color: #3b4551;
}

.home-service-card {
    position: relative;
    height: 100%;
    background: #fff;
    border-radius: 1.1rem;
    padding: 3rem 1.75rem 2.25rem;
    text-align: center;
    box-shadow: 0 6px 20px rgba(15, 42, 68, .07);
    transition: transform .18s ease, box-shadow .18s ease;
}

.home-service-card:hover {
    transform: translateY(-4px);
    box-shadow: 0 16px 34px rgba(15, 42, 68, .14);
}

.home-service-image {
    display: block;
    width: 100%;
    aspect-ratio: 16 / 9;
    object-fit: cover;
    border-radius: .75rem;
    background: #e2e8f0;
    margin: 0 auto 1.4rem;
}

.home-service-image-empty {
    display: flex;
    align-items: center;
    justify-content: center;
    color: #9aa7b4;
    font-size: 2rem;
}

/* The number straddles the card's top edge, which is what gives the row its
   rhythm; the card's own padding leaves the room for it. */
.home-service-number {
    position: absolute;
    top: -1.6rem;
    left: 50%;
    transform: translateX(-50%);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 3.2rem;
    height: 3.2rem;
    border-radius: 50%;
    background: #cfe2f4;
    color: var(--brand-blue-deep);
    font-weight: 700;
    font-size: 1.05rem;
}

.home-service-title {
    font-size: 1.15rem;
    font-weight: 700;
    color: #3b4551;
    margin-bottom: .9rem;
}

.home-service-text {
    color: #6b7683;
    font-size: .92rem;
    margin-bottom: 0;
}

/* ---- The closing strip ----
   Shared by Home and About: the same yellow band, a different sentence. Named
   for what it is rather than for the first page that used it. */

.public-cta {
    background: var(--brand-yellow-band);
    padding-block: 2.5rem;
}

.public-cta-inner {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 1.25rem;
}

.public-cta-heading {
    font-size: 1.4rem;
    font-weight: 800;
    color: var(--brand-blue-dark);
    margin-bottom: .3rem;
}

.public-cta-text {
    color: #4b5563;
    margin-bottom: 0;
    font-size: .95rem;
}

/* ---- About ---- */

.about-journey-figure {
    border-radius: 1rem;
    overflow: hidden;
    background: #f1f5f9;
    box-shadow: 0 8px 24px rgba(15, 42, 68, .12);
}

.about-journey-figure img {
    display: block;
    width: 100%;
    height: auto;
}

/* Lighter than a section heading elsewhere: the paragraph beside it is the
   point, and a heavy title would talk over it. */
.about-journey-heading {
    font-size: clamp(1.4rem, 2.6vw, 1.9rem);
    font-weight: 500;
    color: #3b4551;
    margin-bottom: 1rem;
}

.about-journey-text {
    color: #6b7683;
    line-height: 1.75;
}

.about-values {
    background: var(--brand-blue-deep);
    color: #fff;
    padding-block: 4rem;
}

.about-values-head {
    margin-bottom: 3rem;
}

/* The eyebrow turns yellow on the blue band. Qualified by the section so it
   outranks the base .public-eyebrow colour, which is declared later. */
.about-values .about-values-eyebrow {
    color: var(--brand-yellow);
}

.about-values-heading {
    font-size: clamp(1.5rem, 3vw, 2.1rem);
    font-weight: 500;
    color: #fff;
}

.about-value-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 3.1rem;
    height: 3.1rem;
    border-radius: .75rem;
    background: #dde9f5;
    color: var(--brand-blue-deep);
    font-size: 1.4rem;
    margin-bottom: 1.1rem;
}

.about-value-title {
    font-size: 1.1rem;
    font-weight: 700;
    color: #fff;
    margin-bottom: .6rem;
}

.about-value-text {
    color: rgba(255, 255, 255, .82);
    font-size: .92rem;
    margin-bottom: 0;
}

.about-owners {
    background: #f4f6f9;
}

.about-owners-head {
    margin-bottom: 3rem;
}

.about-owners-heading {
    font-size: clamp(1.5rem, 3vw, 2.1rem);
    font-weight: 500;
    color: #3b4551;
}

.about-owner-photo {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 8.5rem;
    height: 8.5rem;
    border-radius: 50%;
    object-fit: cover;
    background: #e2e8f0;
    margin-bottom: 1.1rem;
}

.about-owner-photo-empty {
    color: #9aa7b4;
    font-size: 3rem;
}

.about-owner-name {
    font-size: 1.05rem;
    font-weight: 700;
    color: #3b4551;
    margin-bottom: .2rem;
}

.about-owner-contact {
    color: #6b7683;
    font-size: .88rem;
    margin-bottom: 0;
}

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

.contact-hero {
    background: #d3e3f5;
    padding-block: 4.5rem;
}

.contact-hero-heading {
    font-size: clamp(2rem, 4.5vw, 3rem);
    font-weight: 800;
    color: var(--brand-blue-deep);
    margin-bottom: 1rem;
}

.contact-hero-text {
    color: var(--brand-blue);
    font-size: 1.05rem;
    max-width: 56ch;
    margin-inline: auto;
}

.contact-body {
    background: var(--surface-muted);
}

.contact-form-card {
    background: #fff;
    border-radius: 1.5rem;
    padding: 2.5rem;
    margin-bottom: 3.5rem;
}

.contact-form-heading {
    font-size: 1.6rem;
    font-weight: 800;
    color: var(--brand-blue-deep);
    margin-bottom: .75rem;
}

.contact-form-intro {
    color: #4b5563;
    max-width: 62ch;
    margin-bottom: 0;
}

.contact-form-card .form-label {
    color: #4b5563;
    font-size: .95rem;
}

/* Filled rather than outlined, which is how the design draws them - and it
   reads as "not open yet" without the flat grey of a plain disabled field. */
.contact-field:disabled,
.contact-field[disabled] {
    background: #d6e4f5;
    border: 1px solid #a9c8e8;
    border-radius: .55rem;
    opacity: 1;
}

.contact-form-note {
    color: #6b7683;
    font-size: .92rem;
    margin-top: 1.25rem;
}

.contact-info-heading {
    font-size: 1.6rem;
    font-weight: 800;
    color: var(--brand-blue-deep);
    margin-bottom: .5rem;
}

.contact-info-intro {
    color: #4b5563;
    margin-bottom: 1.5rem;
}

/* One blue card per way of reaching the company: the icon leads, the label
   names it, the value sits under both. */
.contact-info-cards {
    display: flex;
    flex-direction: column;
    gap: 1rem;
    height: 100%;
}

.contact-info-card {
    flex: 1 1 0;
    display: flex;
    flex-direction: column;
    justify-content: center;
    background: var(--brand-blue-deep);
    color: #fff;
    border-radius: .5rem;
    padding: 1.75rem 1.25rem;
    text-align: center;
}

.contact-info-icon {
    display: block;
    font-size: 2.4rem;
    line-height: 1;
    margin-bottom: .6rem;
}

.contact-info-label {
    font-size: 1.35rem;
    font-weight: 700;
    margin-bottom: .3rem;
}

.contact-info-value {
    font-size: .95rem;
    color: rgba(255, 255, 255, .9);
}

/* ---- Sections ---- */

.public-section {
    padding-block: 4.5rem;
}

.public-section-intro {
    color: #64748b;
    max-width: 60ch;
}

/* Set in sentence case rather than small capitals: it reads as the first line
   of the heading, not as a label. */
.public-eyebrow {
    font-size: .95rem;
    font-weight: 700;
    color: var(--brand-blue-deep);
}

.public-prewrap {
    white-space: pre-line;
}

/* ---- Media ---- */

/* Holds the space an image would take, so a page with nothing uploaded still
   reads as a designed layout rather than a gap. */
.public-image-placeholder {
    display: flex;
    align-items: center;
    justify-content: center;
    flex-direction: column;
    gap: .4rem;
    min-height: 220px;
    border: 1px dashed var(--brand-blue);
    border-radius: 1rem;
    background: var(--brand-blue-tint);
    color: #7ba9cf;
    font-size: .85rem;
    text-align: center;
    padding: 1rem;
}

/* Fills the column beside the contact cards rather than standing at a fixed
   height, so the map and the details end together. */
.public-map {
    width: 100%;
    height: 100%;
    min-height: 420px;
    border: 0;
    border-radius: .75rem;
}

/* ---- Page introduction panel ----
   The rounded grey slab the redesign opens an inner page with. Stated here
   rather than on My Projects alone, so any other page that needs a title band
   in the new style has one. */

.public-page-head {
    padding-block: 1.25rem 2.5rem;
}

.public-page-head-panel {
    position: relative;
    background: var(--surface-muted);
    border-radius: 1.25rem;
    padding: 3rem 1.5rem;
    text-align: center;
}

.public-page-head-heading {
    font-size: clamp(1.9rem, 4vw, 2.8rem);
    font-weight: 500;
    color: #3b4551;
    margin-bottom: 1rem;
}

.public-page-head-text {
    color: #6b7683;
    font-size: 1.05rem;
    max-width: 60ch;
    margin-inline: auto;
}

/* The count sits in the corner of the panel rather than beside the title:
   it is a fact about the list below, not part of the heading. */
.public-page-head-count {
    position: absolute;
    top: 1.1rem;
    right: 1.25rem;
    background: #fff;
    color: var(--brand-blue-deep);
    border-radius: 999px;
    padding: .3rem .9rem;
    font-size: .78rem;
    font-weight: 700;
}

/* ---- My Projects: a page heading rather than a banner ----
   The rounded introduction panel every other public page wears is deliberately
   absent here. This is a working list a client returns to, so the heading is
   sized as a heading and the space it gives back goes to the cards. */

.public-page-title {
    padding-block: 1.75rem 1.25rem;
}

.public-page-title-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: .75rem;
}

.public-page-title-heading {
    font-size: clamp(1.35rem, 2.4vw, 1.75rem);
    font-weight: 700;
    color: #3b4551;
    margin-bottom: .25rem;
}

.public-page-title-text {
    color: #6b7683;
    font-size: .95rem;
}

.public-page-title-count {
    background: #fff;
    color: var(--brand-blue-deep);
    border: 1px solid #e3e8ee;
    border-radius: 999px;
    padding: .3rem .9rem;
    font-size: .78rem;
    font-weight: 700;
    white-space: nowrap;
}

/* ---- My Projects: the filter bar ---- */

.project-filter-card {
    border: 0;
    border-radius: 1.1rem;
    box-shadow: 0 6px 20px rgba(15, 42, 68, .07);
}

.project-filter-card .form-control,
.project-filter-card .input-group-text {
    border-color: #e3e8ee;
}

/* ---- Project cards (Figure 11) ---- */

.project-card {
    height: 100%;
    border: 0;
    border-radius: 1.1rem;
    background: #fff;
    overflow: hidden;
    display: flex;
    flex-direction: column;
    box-shadow: 0 6px 20px rgba(15, 42, 68, .07);
    transition: transform .18s ease, box-shadow .18s ease;
}

.project-card:hover {
    transform: translateY(-4px);
    box-shadow: 0 16px 34px rgba(15, 42, 68, .14);
}

.project-card-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: .75rem;
    padding: .85rem 1.1rem;
    color: #fff;
}

.project-card-reference {
    font-size: .82rem;
    font-weight: 700;
}

.project-card-status {
    background: #fff;
    color: var(--brand-blue-dark);
    border-radius: 999px;
    padding: .2rem .7rem;
    font-size: .74rem;
    font-weight: 600;
    white-space: nowrap;
}

/* The card header's colours used to be declared here, as a palette of this
   page's own - grey pending, teal scheduled, blue in progress, green complete,
   red cancelled, and no Overdue at all, so a late project reached the client
   drawn as ordinary work in progress.

   They now come from projectStatus.css, keyed by the same data-status the
   office's badges and the schedule calendar are keyed by, so a project is one
   colour to everybody who can see it. See Project::STATUS_INK. */

.project-card-body {
    padding: 1.1rem;
    flex: 1 1 auto;
}

.project-card-title {
    font-size: 1.05rem;
    font-weight: 700;
    color: var(--brand-blue-dark);
    margin-bottom: .6rem;
}

.project-card-meta {
    font-size: .87rem;
    color: #475569;
    margin-bottom: .25rem;
}

.project-card-meta strong {
    color: var(--brand-blue-dark);
}

.project-card-description {
    font-size: .87rem;
    color: #64748b;
    margin-top: .8rem;
    margin-bottom: 0;
}

.project-card-updated {
    font-size: .76rem;
    color: #64748b;
    margin-top: .9rem;
}

/* ---- My Projects filter bar ---- */

.project-filter-tabs {
    display: flex;
    flex-wrap: wrap;
    gap: .4rem;
}

.project-filter-tab {
    display: inline-flex;
    align-items: center;
    gap: .4rem;
    border: 1px solid #dbe4ee;
    background: #fff;
    color: #475569;
    border-radius: 999px;
    padding: .35rem .85rem;
    font-size: .85rem;
    font-weight: 600;
    line-height: 1.4;
    transition: background-color .15s ease, border-color .15s ease, color .15s ease;
}

.project-filter-tab:hover {
    border-color: var(--brand-blue);
    color: var(--brand-blue-deep);
}

.project-filter-tab.active {
    background: var(--brand-blue);
    border-color: var(--brand-blue);
    color: #fff;
}

.project-filter-count {
    display: inline-block;
    min-width: 1.4rem;
    border-radius: 999px;
    background: #eef2f7;
    color: #475569;
    font-size: .72rem;
    font-weight: 700;
    text-align: center;
    padding: 0 .35rem;
}

.project-filter-tab.active .project-filter-count {
    background: rgba(255, 255, 255, .25);
    color: #fff;
}

@media (max-width: 575.98px) {
    .project-filter-tab {
        flex: 1 1 auto;
        justify-content: center;
    }
}

.project-card-footer {
    padding: .8rem 1.1rem;
    border-top: 1px solid #eef2f7;
}

.project-card-footer a {
    font-size: .9rem;
    font-weight: 600;
    color: var(--brand-blue-deep);
    text-decoration: none;
}

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

.public-empty-state {
    border: 1px dashed #cfd8e2;
    border-radius: 1.25rem;
    background: var(--brand-blue-tint);
    padding: 3.5rem 1.5rem;
    text-align: center;
    color: #6b7683;
}

/* ---- Client project details ---- */

/* The Super Admin card, restated in the brand colours. */
.client-card {
    border: 1px solid #e5e7eb;
    border-radius: .75rem;
}

.client-card > .card-header {
    border-bottom: 2px solid var(--brand-blue-deep);
}

.client-card > .card-header h2 {
    color: var(--brand-blue-dark);
}

.client-type-badge {
    border: 1px solid var(--brand-blue);
    color: var(--brand-blue-deep);
    background: var(--brand-blue-soft);
    font-weight: 600;
}

.client-lead-badge {
    background: var(--brand-blue);
    color: #fff;
}

.client-count-badge {
    background: var(--brand-blue-soft);
    color: var(--brand-blue-deep);
    font-weight: 700;
}

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

.client-range-list li {
    padding: .35rem 0;
    color: #334155;
}

.client-completion-panel {
    border-left: 4px solid #22c55e;
    background: #f0fdf4;
    border-radius: .5rem;
    padding: 1rem 1.1rem;
}

.client-cancellation-panel {
    border-left: 4px solid #ef4444;
    background: #fef2f2;
    border-radius: .5rem;
    padding: 1rem 1.1rem;
}

/* ---- The tracker: technician reports ---- */

/*
 * Given the strongest treatment on the page - a tinted panel with a yellow
 * edge - because following these reports is why a client opens it at all.
 */
.client-tracker {
    border: 1px solid var(--brand-blue);
    border-left: 5px solid var(--brand-blue-deep);
    border-radius: .75rem;
    background: var(--brand-blue-tint);
    padding: 1.25rem;
}

.client-tracker-heading {
    display: flex;
    align-items: center;
    gap: .75rem;
    padding-bottom: .9rem;
    margin-bottom: 1rem;
    border-bottom: 1px solid #d5e7f6;
}

.client-tracker-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 auto;
    width: 2.6rem;
    height: 2.6rem;
    border-radius: .75rem;
    background: var(--brand-yellow);
    color: var(--brand-ink);
    font-size: 1.2rem;
}

.client-tracker-heading h3 {
    color: var(--brand-blue-dark);
}

.client-report {
    background: #fff;
    border: 1px solid #e5e7eb;
    border-radius: .6rem;
    margin-bottom: .9rem;
    overflow: hidden;
}

.client-report:last-child {
    margin-bottom: 0;
}

.client-report.is-progress {
    border-left: 4px solid var(--brand-blue);
}

.client-report.is-incident {
    border-left: 4px solid #ef4444;
}

.client-report-header {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: .75rem;
    padding: .85rem 1rem;
    background: #fbfdff;
    border-bottom: 1px solid #eef2f7;
}

.client-report-header h4 {
    color: var(--brand-blue-dark);
}

.client-badge-progress {
    background: var(--brand-blue);
    color: #fff;
}

.client-badge-incident {
    background: #ef4444;
    color: #fff;
}

.client-report-body {
    padding: 1rem;
    color: #475569;
    font-size: .92rem;
}

.client-report-image {
    width: 100%;
    height: 150px;
    object-fit: cover;
    border-radius: .5rem;
    border: 1px solid #e5e7eb;
}

.client-tracker-empty {
    text-align: center;
    padding: 2rem 1rem;
    color: #7ba9cf;
    font-size: .9rem;
    background: #fff;
    border: 1px dashed var(--brand-blue);
    border-radius: .6rem;
}

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

/* Near-black rather than deep blue: the closing yellow strip sits directly on
   top of it on the homepage, and blue under yellow reads as a third band of
   colour rather than as the end of the page. */
.public-footer {
    background: var(--footer-ink);
    color: #cfd3d8;
    padding-block: 3.5rem 2rem;
    margin-top: 0;
}

.public-footer-logo {
    height: 38px;
    width: auto;
    object-fit: contain;
}

.public-footer-name {
    font-weight: 700;
    color: #fff;
}

.public-footer-text {
    font-size: .88rem;
    color: #a8adb4;
    max-width: 42ch;
    text-align: justify;
}

.public-footer-heading {
    color: #fff;
    font-size: 1rem;
    font-weight: 700;
    margin-bottom: 1rem;
}

.public-footer-links,
.public-footer-contact {
    list-style: none;
    padding: 0;
    margin: 0;
}

.public-footer-links li {
    margin-bottom: .45rem;
}

.public-footer-links a {
    color: #cfd3d8;
    text-decoration: none;
    font-size: .88rem;
}

.public-footer-links a:hover {
    color: var(--brand-yellow);
}

.public-footer-contact li {
    margin-bottom: .45rem;
    font-size: .88rem;
    color: #cfd3d8;
}

/* The glyphs themselves rather than icons inside grey buttons, so the column
   reads as one row of marks. */
.public-social {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    color: #dcdfe3;
    font-size: 1.75rem;
    line-height: 1;
    text-decoration: none;
    transition: color .15s ease;
}

.public-social:hover {
    color: var(--brand-yellow);
}

/* Inset from the columns above it, which is what makes the copyright read as
   a closing line rather than a fifth column. */
.public-footer-rule {
    border-color: rgba(255, 255, 255, .3);
    opacity: 1;
    width: 72%;
    margin: 2.75rem auto 1.5rem;
}

.public-footer-copyright {
    font-size: .85rem;
    color: #a8adb4;
    text-align: center;
}

.public-footer-meta {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: .8rem;
    text-align: center;
}

/* The Terms and Conditions link sits below the company line, so both closing
   items stay easy to read on any screen size. */
.public-footer-terms {
    font-size: .85rem;
    color: #a8adb4;
    text-decoration: underline;
    vertical-align: baseline;
}

.public-footer-terms:hover,
.public-footer-terms:focus {
    color: #fff;
}

/* ---- Responsive ---- */

@media (max-width: 991.98px) {
    .public-navbar .nav-link {
        padding-inline: 0;
    }

    .public-navbar .nav-link.active::after {
        display: none;
    }

    .public-nav-actions {
        margin-top: .75rem;
    }

    .home-hero {
        padding-block: 3rem 3.5rem;
    }

    .home-hero-figure {
        margin-top: 2.5rem;
    }

    .public-section {
        padding-block: 3rem;
    }

    .home-services-head {
        margin-bottom: 3rem;
    }

    .public-page-head-panel {
        padding: 2.25rem 1.25rem;
    }

    .contact-hero {
        padding-block: 3rem;
    }

    .contact-form-card {
        padding: 1.5rem;
        border-radius: 1rem;
    }

    .about-values {
        padding-block: 3rem;
    }

    .client-tracker {
        padding: 1rem;
    }
}

/* ---- The signed-in client's header link ----
   Who is signed in, and the caret that opens their menu, as one control:
   the picture leads, the name sits beside it, the caret closes the row. */
.public-profile-link {
    display: inline-flex;
    flex-direction: row;
    align-items: center;
    gap: .6rem;
    line-height: 1.2;
    text-align: left;
}

.public-profile-name {
    font-weight: 600;
    min-width: 0;
    max-width: 14rem;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* ---- Project documents ----
   The grouped cards from the Super Admin project page, so a client reads their
   documents in the same shape the office does. A row of loose buttons stopped
   reading as anything once one document could run to several files.

   Copied rather than shared because the two pages load different stylesheets
   and neither has a common one; the markup is identical, minus the remove
   button, which is not a client's to press. */
.project-document-groups {
    display: flex;
    flex-wrap: wrap;
    gap: 1rem;
}

.project-document-group {
    flex: 1 1 15rem;
    min-width: 0;
    border: 1px solid #e5e7eb;
    border-radius: 0.55rem;
    padding: 0.7rem 0.85rem;
    background: #fff;
}

.project-document-group-head {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    margin-bottom: 0.5rem;
    color: #0f172a;
}

.project-document-file {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem;
    padding: 0.3rem 0;
}

.project-document-file + .project-document-file {
    border-top: 1px dashed #e5e7eb;
}

/* The count is the one number on the card, so it wears yellow and is the
   thing the eye lands on; the files themselves are blue, which is what says
   they open. */
.project-document-count {
    background: #ffc107;
    border: 1px solid #e0a800;
    color: #3d2f00;
    font-size: 0.72rem;
    font-weight: 700;
}

/* The name is the wide part and the only part that may be cut. */
.project-document-link {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    min-width: 0;
    font-size: 0.85rem;
    font-weight: 600;
    color: #2370b4;
    text-decoration: none;
}

.project-document-link span {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.project-document-link:hover {
    color: #1b5688;
    text-decoration: underline;
}

/* The file icon takes the lighter brand blue, so the row reads as one blue
   thing rather than a grey mark beside a blue name. */
.project-document-link i {
    color: #2d8de1;
}

/*
    The Contact form's honeypot.

    Taken out of the layout entirely rather than hidden with `display:none`:
    some bots skip anything display-none, and a field pushed off-screen while
    still in the flow is one they will fill in. Nothing here is reachable by
    keyboard - the input carries tabindex="-1" - and the wrapper is
    aria-hidden, so no screen reader announces it either.
*/
.contact-honeypot {
    position: absolute;
    left: -9999px;
    width: 1px;
    height: 1px;
    overflow: hidden;
}
