/* ==========================================================================
   Bikabo Website — overrides.

   Loaded last, after the vendor theme. Every Bikabo-specific rule lives here
   and the vendor CSS is never edited, so a theme file can be replaced wholesale
   without hunting for our changes inside 146 KB of compiled output. This is the
   same separation the application keeps with bikabo-overrides.css.
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. Brand
   --------------------------------------------------------------------------
   The theme drives its entire palette from three custom properties, so the
   brand is a three-line change here rather than a search through main.css.

   #005949 is the application's brand green (theme/assets/css/bikabo-overrides.css
   in bikabo-backend), which is hsl(169, 100%, 17%). Matching it means a visitor
   moving from bikabo.com to app.bikabo.com does not see the brand shift.

   main.css itself was hand-edited at some point to 165.14deg / 99.85% / 30.29%,
   a lighter relative of the same green. To go back to that, comment out the
   three lines below. Nothing else needs to change.
   -------------------------------------------------------------------------- */

:root {
    /* Interactive green: buttons, links, accents. Bright enough to carry the
       theme's energy, dark enough that white text on it clears WCAG AA. An
       earlier single dark green (169 100% 17%) was the app's #005949 exactly,
       and it drained the design: at that lightness every button reads black. */
    --main-h: 168;
    --main-s: 100%;
    --main-l: 25%;

    /* Deep surfaces: the hero gradient, the header, the CTA panel. Separate
       variables so the surfaces can be as saturated as the theme intends
       without dragging the interactive colour along with them. These are the
       theme's own gradient stops. */
    --bikabo-deep-1: #003D3D;
    --bikabo-deep-2: #00664E;
    --bikabo-deep-3: #008C63;
    --bikabo-header: #0f6555;

    /* For text and icons on the deep surfaces, where --main-600 sits too close
       to the background to read. */
    --bikabo-bright: #2fd39c;
    --bikabo-bright-soft: #9defcd;
}

/* --------------------------------------------------------------------------
   2. Accessibility
   -------------------------------------------------------------------------- */

.skip-link {
    position: absolute;
    inset-inline-start: 1rem;
    inset-block-start: -100%;
    z-index: 1100;
    padding: 0.75rem 1.25rem;
    background: hsl(var(--white));
    color: var(--main-600);
    font-weight: 700;
    border-radius: 0.5rem;
    box-shadow: 0 5px 16px rgba(0, 0, 0, 0.15);
    transition: inset-block-start 0.15s ease-out;
}

.skip-link:focus {
    inset-block-start: 1rem;
}

/* The theme suppresses focus rings in several places. Put one back everywhere,
   because keyboard users need to see where they are. */
a:focus-visible,
button:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible,
summary:focus-visible,
[tabindex]:focus-visible {
    outline: 3px solid var(--main-600);
    outline-offset: 2px;
    border-radius: 4px;
}

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

/* --------------------------------------------------------------------------
   3. Header
   --------------------------------------------------------------------------
   The vendor header is position-absolute and gets a .fixed-header class added
   by a scroll handler in main.js. Sticky positioning does the same job with no
   JavaScript, no scroll listener, and no layout jump when the header changes
   from flow to fixed.
   -------------------------------------------------------------------------- */

/* The .site-header rules that used to sit here are gone: the header now uses
   the theme's own structure and two-state behaviour, and a sticky white bar
   was overriding both. */

/* Grouped dropdown. The theme's submenu is a flat list; the Product and
   Solutions menus are grouped by section (Master Spec §7), which needs a wider
   panel and headings the flat version has no styling for. */

.nav-submenu--grouped {
    min-width: 260px;
    box-shadow: 0 12px 32px rgba(0, 0, 0, 0.12);
}

.nav-submenu__heading {
    letter-spacing: 0.08em;
    margin-block-end: 0.25rem;
}

.nav-submenu__group ul,
.nav-submenu ul {
    list-style: none;
    padding: 0;
    margin: 0;
}

.nav-submenu__hub {
    border-block-end: 1px solid hsl(var(--neutral-200, 220 13% 91%));
    padding-block-end: 0.5rem;
}

/* Desktop: open on hover and on keyboard focus within, so the menu is reachable
   without a click but does not require one either. */
@media (min-width: 992px) {
    .nav-menu__item.has-submenu > .nav-submenu {
        opacity: 0;
        visibility: hidden;
        transform: translateY(8px);
        transition: opacity 0.15s ease, transform 0.15s ease, visibility 0.15s;
    }

    .nav-menu__item.has-submenu:hover > .nav-submenu,
    .nav-menu__item.has-submenu:focus-within > .nav-submenu,
    .nav-menu__item.has-submenu.active > .nav-submenu {
        opacity: 1;
        visibility: visible;
        transform: translateY(0);
    }
}

/* Mobile: collapsed until the trigger is pressed. Plain display toggling,
   because the vendor implementation used jQuery slideToggle. */
@media (max-width: 991.98px) {
    .nav-menu--mobile .nav-submenu {
        display: none;
        position: static;
        margin: 0;
        box-shadow: none;
    }

    .nav-menu--mobile .has-submenu.active > .nav-submenu {
        display: block;
    }

    .mobile-menu {
        padding-block-end: 6rem;
    }
}

.nav-menu__trigger {
    cursor: pointer;
}

/* --------------------------------------------------------------------------
   4. Page header and breadcrumb
   -------------------------------------------------------------------------- */

.page-header {
    padding-block: clamp(3rem, 6vw, 5.5rem);
}

.bikabo-breadcrumb ol {
    padding: 0;
}

.eyebrow {
    letter-spacing: 0.1em;
}

/* --------------------------------------------------------------------------
   5. Asset placeholders
   --------------------------------------------------------------------------
   A slot with no artwork yet. Reserves the exact box the real image will
   occupy, so filling it later shifts nothing, and labels itself loudly enough
   that it cannot be mistaken for finished design in a review.
   -------------------------------------------------------------------------- */

.bikabo-asset-placeholder {
    position: relative;
    inline-size: 100%;
    block-size: 0;
    border: 2px dashed var(--main-300);
    border-radius: 1rem;
    background:
        repeating-linear-gradient(
            45deg,
            hsl(var(--neutral-50, 210 20% 98%)),
            hsl(var(--neutral-50, 210 20% 98%)) 12px,
            hsl(var(--neutral-100, 220 14% 96%)) 12px,
            hsl(var(--neutral-100, 220 14% 96%)) 24px
        );
}

.bikabo-asset-placeholder__id,
.bikabo-asset-placeholder__name {
    position: absolute;
    inset-inline: 0;
    text-align: center;
    font-weight: 700;
    color: var(--main-600);
}

.bikabo-asset-placeholder__id {
    inset-block-start: calc(50% - 1.5rem);
    font-size: 0.875rem;
    letter-spacing: 0.08em;
}

.bikabo-asset-placeholder__name {
    inset-block-start: calc(50% + 0.25rem);
    font-size: 1rem;
    font-weight: 600;
    color: hsl(var(--body));
    padding-inline: 1rem;
}

/* --------------------------------------------------------------------------
   6. Sections
   -------------------------------------------------------------------------- */

.cta-panel {
    background-color: var(--main-800, #00463a);
}

.related-card {
    border: 1px solid hsl(var(--neutral-200, 220 13% 91%));
    transition: box-shadow 0.2s ease, transform 0.2s ease;
}

.related-card:hover,
.related-card:focus-visible {
    box-shadow: 0 12px 32px rgba(0, 0, 0, 0.08);
}

/* Long-form pages (Security, Legal) — a sticky table of contents beside
   flowing prose.

   Deliberately not the vendor theme's vertical pill tabs, which hide all but
   one panel behind JavaScript. Master Spec §10 requires principal content to be
   present and visible without JS, and a reader should be able to Ctrl-F the
   whole page. */

.longform-toc {
    position: sticky;
    inset-block-start: 6rem;
}

.longform-toc a {
    display: block;
    padding: 0.5rem 0.75rem;
    border-radius: 0.5rem;
    color: hsl(var(--body));
    font-weight: 600;
    line-height: 1.4;
}

.longform-toc a:hover,
.longform-toc a:focus-visible {
    background: hsl(var(--neutral-100, 220 14% 96%));
    color: var(--main-600);
}

.longform-section {
    scroll-margin-block-start: 6rem;
}

.longform-section + .longform-section {
    margin-block-start: 3rem;
}

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

.claim-list li {
    position: relative;
    padding-inline-start: 1.75rem;
    margin-block-end: 0.75rem;
    line-height: 1.9;
}

.claim-list li::before {
    content: "";
    position: absolute;
    inset-inline-start: 0;
    inset-block-start: 0.7em;
    inline-size: 0.5rem;
    block-size: 0.5rem;
    border-radius: 50%;
    background: var(--main-600);
}

/* The "what we do not claim" list. Same shape, opposite meaning, so it needs to
   read differently at a glance rather than looking like more features. */
.claim-list--negative li::before {
    background: transparent;
    border: 2px solid hsl(var(--body));
    inset-block-start: 0.65em;
}

/* --------------------------------------------------------------------------
   7. Back to top
   -------------------------------------------------------------------------- */

.scroll-top {
    position: fixed;
    inset-inline-end: 1.5rem;
    inset-block-end: 1.5rem;
    inline-size: 3rem;
    block-size: 3rem;
    border: 0;
    border-radius: 50%;
    background: var(--main-600);
    color: hsl(var(--white));
    display: flex;
    align-items: center;
    justify-content: center;
    z-index: 98;
    box-shadow: 0 8px 20px rgba(0, 0, 0, 0.18);
}

.scroll-top[hidden] {
    display: none;
}

/* --------------------------------------------------------------------------
   8. Cost figures and formulas
   -------------------------------------------------------------------------- */

/* The coloured top border that used to live here read as a stray dark line
   across the top of each card, and it is not something the theme does. The
   cards now match the theme's own treatment: a faint off-white fill against a
   white section, a hairline border, and the colour arriving on hover instead. */
.cost-card {
    border: 1px solid hsl(var(--neutral-200, 220 13% 91%));
    background: hsl(var(--neutral-50, 210 20% 98%)) !important;
}

/* The three cost figures are deliberately equal in weight. They are three
   different facts about the same work, not a ranking. */
.cost-three-up .cost-card {
    display: flex;
    flex-direction: column;
}

.formula-row {
    padding: 1.5rem 0;
    border-block-end: 1px solid hsl(var(--neutral-200, 220 13% 91%));
}

.formula-row:last-child {
    border-block-end: 0;
}

.formula-row__equation {
    font-weight: 700;
    color: var(--main-600);
    font-size: clamp(1rem, 0.9rem + 0.4vw, 1.25rem);
    line-height: 1.6;
    margin: 0;
}

/* A worked example. Monospaced so the columns line up and the arithmetic can be
   read down the page rather than across a sentence. */
.worked-example {
    background: hsl(var(--neutral-50, 210 20% 98%));
    border: 1px solid hsl(var(--neutral-200, 220 13% 91%));
    border-radius: 1rem;
    padding: clamp(1.25rem, 3vw, 2rem);
    overflow-x: auto;
}

.worked-example table {
    inline-size: 100%;
    border-collapse: collapse;
    font-variant-numeric: tabular-nums;
}

.worked-example td {
    padding: 0.5rem 0;
    white-space: nowrap;
}

.worked-example td:last-child {
    text-align: end;
    font-weight: 700;
    padding-inline-start: 2rem;
}

.worked-example tr.is-total td {
    border-block-start: 2px solid hsl(var(--neutral-300, 216 12% 84%));
    padding-block-start: 0.75rem;
    color: var(--main-600);
}

/* A pair of statements that are easy to conflate, shown as a contrast rather
   than as two more feature cards. */
.distinction {
    display: grid;
    gap: 1.5rem;
    grid-template-columns: 1fr;
}

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

.distinction__side {
    background: hsl(var(--white));
    border: 1px solid hsl(var(--neutral-200, 220 13% 91%));
    border-radius: 1rem;
    padding: clamp(1.25rem, 3vw, 2rem);
}

.distinction__side--accent {
    border-color: var(--main-600);
}

/* --------------------------------------------------------------------------
   9. The operating chain
   --------------------------------------------------------------------------
   A grid of nine equal boxes shows nine things. It does not show a chain. This
   draws one: steps are nodes on a rail with an arrow in every gap, rails are
   grouped into named phases, and the phases hang off a vertical spine down the
   left. The phase name is what makes the first step legible to someone who does
   not know the model yet, because "Client" on its own does not explain why the
   chain starts there and "Agree the work" does.

   Both devices are the theme's. work-process-five runs a line behind evenly
   spaced dots; the roadmap block on the theme home page puts an icon in a
   coloured circle with a small number chip on its shoulder.

   Contrast: the chip is white on --main-600 at 4.94:1, and inverts to green on
   white at the same ratio once the badge fills. The rail and the arrowheads are
   decorative, so they are tuned for visibility rather than to a text ratio.
   -------------------------------------------------------------------------- */

.chain {
    --chain-badge: 3.5rem;
    --chain-gap: 1.75rem;
    --chain-cols: 3;
    /* The --main ramp is useless for a rule: at 100% saturation every step from
       main-100 to main-500 lands within 1.14:1 and 1.29:1 of white, so a line in
       any of them is the invisible-pale-number mistake again. Desaturating gets
       a sage green that actually draws at 2.43:1. */
    --chain-rail: hsl(var(--main-h) 35% 55%);
}

.chain__phase {
    position: relative;
}

.chain__phase + .chain__phase {
    margin-block-start: 2.5rem;
}

.chain__phase-head {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    margin-block-end: 1.25rem;
}

.chain__marker {
    inline-size: 0.875rem;
    block-size: 0.875rem;
    flex-shrink: 0;
    border-radius: 50%;
    background: var(--main-600);
    box-shadow: 0 0 0 4px var(--main-50);
}

.chain__phase-label {
    font-size: 0.8125rem;
    font-weight: 800;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--main-700);
}

.chain__rail {
    list-style: none;
    padding: 0;
    margin: 0;
    display: flex;
    gap: var(--chain-gap);
}

/* Fixed column width rather than flex-grow, so a phase holding fewer steps than
   its neighbours still lines its nodes up with theirs instead of spreading them
   across the row. */
.chain__node {
    position: relative;
    flex: 0 0 calc((100% - (var(--chain-cols) - 1) * var(--chain-gap)) / var(--chain-cols));
    min-inline-size: 0;
}

.chain__badge {
    position: relative;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    inline-size: var(--chain-badge);
    block-size: var(--chain-badge);
    flex-shrink: 0;
    border-radius: 50%;
    background: var(--main-50);
    border: 1px solid var(--main-100);
    color: var(--main-600);
    font-size: 1.5rem;
    line-height: 1;
    transition: background 0.3s ease, border-color 0.3s ease, color 0.3s ease, transform 0.3s ease;
}

.chain__badge-number {
    font-size: 1.0625rem;
    font-weight: 800;
    font-variant-numeric: tabular-nums;
}

/* The number rides on the badge's shoulder, the way the theme's roadmap balls
   carry theirs, so the icon can hold the middle. */
.chain__index {
    position: absolute;
    inset-block-start: -0.3rem;
    inset-inline-start: -0.3rem;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    inline-size: 1.5rem;
    block-size: 1.5rem;
    border-radius: 50%;
    background: var(--main-600);
    color: hsl(var(--white));
    font-size: 0.6875rem;
    font-weight: 800;
    font-variant-numeric: tabular-nums;
    line-height: 1;
    transition: background 0.3s ease, color 0.3s ease;
}

.chain__node:hover .chain__badge {
    background: var(--main-600);
    border-color: var(--main-600);
    color: hsl(var(--white));
    transform: translateY(-4px);
}

/* Once the badge fills, a green chip on green would vanish, so it inverts. */
.chain__node:hover .chain__index {
    background: hsl(var(--white));
    color: var(--main-600);
}

.chain__body {
    display: block;
}

.chain__label {
    display: block;
    font-weight: 700;
    font-size: 1.0625rem;
    line-height: 1.35;
    color: hsl(var(--heading-color));
}

.chain__note {
    display: block;
    margin-block-start: 0.5rem;
    font-size: 0.9375rem;
    line-height: 1.7;
    color: hsl(var(--body));
}

/* The step this page is about, filled from the start rather than on hover. */
.chain__node--focus .chain__badge {
    background: var(--main-600);
    border-color: var(--main-600);
    color: hsl(var(--white));
}

.chain__node--focus .chain__index {
    background: var(--bikabo-deep-1);
    color: hsl(var(--white));
}

/* Wide: rails run across, phases hang off a spine on the left. */
@media (min-width: 992px) {
    .chain--phased .chain__phase {
        display: flex;
        align-items: flex-start;
        gap: 2.5rem;
    }

    .chain--phased .chain__phase-head {
        flex: 0 0 11rem;
        margin-block-end: 0;
        /* Puts the marker on the same line as the badge centres. */
        padding-block-start: 1.35rem;
    }

    .chain--phased .chain__rail {
        flex: 1 1 auto;
        min-inline-size: 0;
    }

    .chain--phased .chain__phase:not(:last-child)::before {
        content: "";
        position: absolute;
        inset-inline-start: 0.375rem;
        inset-block-start: 2.25rem;
        inset-block-end: -2.5rem;
        inline-size: 2px;
        background: var(--chain-rail);
    }

    .chain__node {
        display: flex;
        flex-direction: column;
        align-items: center;
        text-align: center;
    }

    .chain__body {
        margin-block-start: 1rem;
    }

    .chain--compact .chain__body {
        margin-block-start: 0.875rem;
    }

    /* The rail itself: drawn from the previous badge's edge to this one's, so
       the line stops at the circles instead of running under them. */
    .chain__node:not(:first-child)::before {
        content: "";
        position: absolute;
        inset-block-start: calc(var(--chain-badge) / 2 - 1px);
        inset-inline-start: calc(-1 * var(--chain-gap) - 50% + var(--chain-badge) / 2);
        inline-size: calc(100% + var(--chain-gap) - var(--chain-badge));
        block-size: 2px;
        background: var(--chain-rail);
    }

    /* Direction. Without this the rail is a line, and a line is not a chain. */
    .chain__node:not(:first-child)::after {
        content: "";
        position: absolute;
        inline-size: 0;
        block-size: 0;
        inset-block-start: calc(var(--chain-badge) / 2 - 0.3rem);
        inset-inline-start: calc(50% - var(--chain-badge) / 2 - 0.6rem);
        border-block: 0.3rem solid transparent;
        border-inline-start: 0.45rem solid var(--main-600);
    }
}

/* Narrow: the same chain, turned on its side. A horizontal rail cannot survive
   one column, and a stack of unconnected nodes would be the card grid again. */
@media (max-width: 991.98px) {
    .chain__rail {
        flex-direction: column;
        gap: 1.5rem;
    }

    .chain__node {
        display: flex;
        align-items: flex-start;
        gap: 1.125rem;
        /* The column basis above would be read as a height here. */
        flex: 0 0 auto;
    }

    .chain__body {
        padding-block-start: 0.55rem;
    }

    .chain__node:not(:last-child)::before {
        content: "";
        position: absolute;
        inset-inline-start: calc(var(--chain-badge) / 2 - 1px);
        inset-block-start: var(--chain-badge);
        inset-block-end: -1.5rem;
        inline-size: 2px;
        background: var(--chain-rail);
    }
}

.section-deep .chain__badge {
    background: hsl(var(--white) / 0.08);
    border-color: hsl(var(--white) / 0.18);
    color: var(--bikabo-bright);
}

.section-deep .chain__index,
.section-deep .chain__node--focus .chain__index {
    background: var(--bikabo-bright);
    color: var(--bikabo-deep-1);
}

.section-deep .chain__node--focus .chain__badge,
.section-deep .chain__node:hover .chain__badge {
    background: var(--bikabo-bright);
    border-color: var(--bikabo-bright);
    color: var(--bikabo-deep-1);
}

.section-deep .chain__node:hover .chain__index {
    background: var(--bikabo-deep-1);
    color: var(--bikabo-bright);
}

.section-deep .chain__label {
    color: hsl(var(--white)) !important;
}

.section-deep .chain__note {
    color: hsl(var(--white) / 0.82) !important;
}

.section-deep .chain__phase-label {
    color: var(--bikabo-bright-soft);
}

.section-deep .chain__marker {
    background: var(--bikabo-bright);
    box-shadow: 0 0 0 4px hsl(var(--white) / 0.1);
}

.section-deep .chain__node::before,
.section-deep .chain__phase::before {
    background: hsl(var(--white) / 0.25);
}

.section-deep .chain__node::after {
    border-inline-start-color: var(--bikabo-bright);
}

/* --------------------------------------------------------------------------
   10. Role matrix
   --------------------------------------------------------------------------
   The table scrolls inside its own container rather than making the page scroll
   sideways. The container is focusable so a keyboard user can reach the
   scrollable region, which is the part people usually forget.
   -------------------------------------------------------------------------- */

.matrix-scroll {
    overflow-x: auto;
    border: 1px solid hsl(var(--neutral-200, 220 13% 91%));
    border-radius: 1rem;
    background: hsl(var(--white));
}

.matrix {
    inline-size: 100%;
    min-inline-size: 720px;
    border-collapse: collapse;
}

.matrix th,
.matrix td {
    padding: 1rem 1.25rem;
    text-align: start;
    border-block-end: 1px solid hsl(var(--neutral-200, 220 13% 91%));
    vertical-align: top;
}

.matrix thead th {
    font-size: 0.8125rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: hsl(var(--body));
    background: hsl(var(--neutral-50, 210 20% 98%));
    white-space: normal;
    min-inline-size: 110px;
}

.matrix tbody tr:last-child th,
.matrix tbody tr:last-child td {
    border-block-end: 0;
}

.matrix__role {
    display: block;
    font-weight: 700;
    color: hsl(var(--heading-color));
    white-space: nowrap;
}

.matrix__note {
    display: block;
    margin-block-start: 0.25rem;
    font-size: 0.8125rem;
    font-weight: 400;
    line-height: 1.5;
    color: hsl(var(--body));
    max-inline-size: 220px;
}

/* The value is spelled out rather than shown as a tick or a cross. A symbol
   alone carries meaning by shape and colour only, which fails for anyone who
   cannot distinguish them, and "view only" has no symbol anyway. */
.matrix__value {
    font-weight: 600;
    font-size: 0.9375rem;
}

.matrix td.is-yes .matrix__value {
    color: var(--main-600);
}

.matrix td.is-view .matrix__value {
    color: hsl(var(--body));
}

.matrix td.is-no .matrix__value {
    color: hsl(var(--neutral-400, 218 11% 65%));
}

/* --------------------------------------------------------------------------
   11. Comparison table
   -------------------------------------------------------------------------- */

.comparison-table th[scope="row"] {
    max-inline-size: 240px;
}

.comparison-table th[scope="row"] .matrix__role {
    white-space: normal;
}

.comparison-table td,
.comparison-table thead th {
    min-inline-size: 220px;
    white-space: normal;
    line-height: 1.7;
}

.comparison-table .is-bikabo {
    background: var(--main-50);
}

.comparison-table thead th.is-bikabo {
    color: var(--main-600);
}

/* --------------------------------------------------------------------------
   12. Forms
   --------------------------------------------------------------------------
   The vendor theme applies a global appearance:none to every input, select and
   textarea and only redraws specific controls, so a form control written by
   hand can render as nothing at all. These rules make the standard Bootstrap
   form classes visible under this theme rather than assuming they already are.
   -------------------------------------------------------------------------- */

.contact-form .form-control,
.contact-form .form-select {
    inline-size: 100%;
    padding: 0.875rem 1rem;
    border: 1px solid hsl(var(--neutral-300, 216 12% 84%));
    border-radius: 0.75rem;
    background: hsl(var(--white));
    color: hsl(var(--heading-color));
    font: inherit;
    line-height: 1.5;
}

/* A select with appearance:none loses its arrow, so draw one back. */
.contact-form .form-select {
    appearance: none;
    background-image: linear-gradient(45deg, transparent 50%, hsl(var(--body)) 50%),
                      linear-gradient(135deg, hsl(var(--body)) 50%, transparent 50%);
    background-position: calc(100% - 20px) center, calc(100% - 15px) center;
    background-size: 5px 5px, 5px 5px;
    background-repeat: no-repeat;
    padding-inline-end: 2.5rem;
}

.contact-form .form-control:focus,
.contact-form .form-select:focus {
    border-color: var(--main-600);
    outline: 3px solid var(--main-200);
    outline-offset: 0;
}

.contact-form .form-label {
    display: block;
    margin-block-end: 0.5rem;
}

/* Errors carry an icon and a border as well as colour, so they are not
   signalled by colour alone. */
.field-error {
    display: flex;
    align-items: flex-start;
    gap: 0.5rem;
    margin-block-start: 0.5rem;
    margin-block-end: 0;
    color: #b42318;
    font-weight: 600;
    font-size: 0.9375rem;
    line-height: 1.5;
}

.field-error__icon {
    display: inline-flex;
    flex-shrink: 0;
    margin-block-start: 0.15em;
}

.contact-form [aria-invalid="true"] {
    border-color: #b42318;
}

.form-panel {
    padding: 1.25rem 1.5rem;
    border-radius: 1rem;
    margin-block-end: 2rem;
    border: 1px solid hsl(var(--neutral-200, 220 13% 91%));
}

.form-panel--success {
    border-color: var(--main-600);
    background: var(--main-50);
}

.form-panel--error {
    border-color: #b42318;
    background: #fef3f2;
}

.form-panel--error ul {
    padding-inline-start: 1.25rem;
    margin-block-end: 0;
}

.form-panel--error a {
    color: #b42318;
    font-weight: 600;
}

.form-panel--blocked {
    border-style: dashed;
    background: hsl(var(--neutral-50, 210 20% 98%));
}

/* Hidden from sight and from assistive technology. Not display:none, because
   some automated submitters skip fields that are display:none. */
.visually-hidden-field {
    position: absolute;
    inline-size: 1px;
    block-size: 1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
}

/* Hidden from sight, available to assistive technology. */
.visually-hidden {
    position: absolute;
    inline-size: 1px;
    block-size: 1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
}

/* --------------------------------------------------------------------------
   13. Legal documents
   -------------------------------------------------------------------------- */

.legal-meta {
    display: flex;
    flex-wrap: wrap;
    gap: 1.5rem 3rem;
    padding: 1.25rem 1.5rem;
    border: 1px solid hsl(var(--neutral-200, 220 13% 91%));
    border-radius: 1rem;
    margin: 0;
}

.legal-meta dt {
    font-size: 0.8125rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: hsl(var(--body));
    margin-block-end: 0.25rem;
}

.legal-meta dd {
    margin: 0;
    font-weight: 600;
    color: hsl(var(--heading-color));
}

.legal-pending {
    margin: 0.75rem 0 0;
    padding: 0.75rem 1rem;
    border-inline-start: 3px solid var(--main-300);
    background: hsl(var(--neutral-50, 210 20% 98%));
    color: hsl(var(--body));
    font-style: italic;
}

/* --------------------------------------------------------------------------
   14. Guides
   --------------------------------------------------------------------------
   Long-form reading. Prose gets a comfortable measure and generous leading,
   because these pages are meant to be read rather than scanned for a feature.
   -------------------------------------------------------------------------- */

.guide-byline {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem 0.75rem;
    color: hsl(var(--body));
    font-size: 0.9375rem;
}

.guide-prose > section + section {
    margin-block-start: 3.5rem;
}

.guide-prose h2 {
    scroll-margin-block-start: 6rem;
    margin-block-end: 1.25rem;
}

.guide-prose h3 {
    margin-block: 2rem 1rem;
    font-size: 1.25rem;
}

.guide-prose p {
    color: hsl(var(--body));
    line-height: 2.1;
    margin-block-end: 1.25rem;
    max-inline-size: 68ch;
}

.guide-prose ul,
.guide-prose ol {
    color: hsl(var(--body));
    line-height: 2.1;
    max-inline-size: 68ch;
    margin-block-end: 1.5rem;
    padding-inline-start: 1.5rem;
}

.guide-prose li {
    margin-block-end: 0.5rem;
}

.guide-prose li::marker {
    color: var(--main-600);
    font-weight: 700;
}

/* A worked figure inside prose: an example, a checklist, a caution. Set apart
   so the eye can find it again, without becoming a decorative callout box on
   every third paragraph. */
.guide-note {
    border-inline-start: 4px solid var(--main-600);
    background: hsl(var(--neutral-50, 210 20% 98%));
    padding: 1.25rem 1.5rem;
    border-radius: 0 0.75rem 0.75rem 0;
    margin-block: 2rem;
    max-inline-size: 68ch;
}

.guide-note p:last-child,
.guide-note ul:last-child {
    margin-block-end: 0;
}

.guide-note__label {
    display: block;
    font-size: 0.75rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: var(--main-600);
    margin-block-end: 0.5rem;
}

.guide-card {
    border: 1px solid hsl(var(--neutral-200, 220 13% 91%));
    border-radius: 1rem;
    background: hsl(var(--white));
    padding: 2rem;
    block-size: 100%;
    display: flex;
    flex-direction: column;
}

.guide-card__topic {
    font-size: 0.75rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: var(--main-600);
    margin-block-end: 0.75rem;
}

/* --------------------------------------------------------------------------
   15. Templates
   -------------------------------------------------------------------------- */

.template-download {
    border: 2px solid var(--main-600);
    border-radius: 1rem;
    background: var(--main-50);
    padding: clamp(1.5rem, 4vw, 2.5rem);
    margin-block-end: 2.5rem;
}

.template-download__label {
    font-size: 0.75rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: var(--main-600);
    margin-block-end: 0.5rem;
}

.template-download p:last-child {
    margin-block-end: 0;
}

/* --------------------------------------------------------------------------
   16. Theme fidelity
   --------------------------------------------------------------------------
   The theme's "home-three" design is a dark green header over a gradient hero,
   with deep bands alternating against light ones down the page. An earlier
   version of this site rendered everything on white with green accents, which
   was legible and had none of the theme's character.

   These rules come after the sections above on purpose: they override the
   earlier light-header rules by cascade order rather than by editing them, so
   the diff stays readable.
   -------------------------------------------------------------------------- */

/* Header
   --------------------------------------------------------------------------
   The theme handles both states itself: absolute and translucent at rest,
   then .fixed-header pinned and solid #0f6555 once main.js sees 100px of
   scroll. Nothing here should fight that. What is left is the colour of the
   navigation inside it, which the theme leaves to the markup. */

.header .nav-menu__link,
.header .nav-menu__trigger {
    color: hsl(var(--white)) !important;
}

.header .nav-menu__link:hover,
.header .nav-menu__trigger:hover,
.header .nav-menu__item.activePage > .nav-menu__link {
    color: hsl(var(--spring-green)) !important;
}

/* The dropdown panel stays light, as in the theme: dark text on white reads
   better for a dense list than white on green. */
.header .nav-submenu {
    background: hsl(var(--white));
}

.header .nav-submenu__link {
    color: hsl(var(--heading-color)) !important;
}

.header .nav-submenu__link:hover {
    color: var(--main-600) !important;
}

.header .nav-submenu__heading {
    color: hsl(var(--body)) !important;
}

/* Hero and page-header bands
   -------------------------------------------------------------------------- */

.bikabo-hero,
.page-header {
    background: linear-gradient(69.92deg, var(--bikabo-deep-1) 28.63%, var(--bikabo-deep-2) 87.07%, var(--bikabo-deep-3) 112.98%);
    position: relative;
    z-index: 1;
    overflow: hidden;
    border-end-start-radius: 30px;
    border-end-end-radius: 30px;
}

.bikabo-hero {
    /* The header sits over this band rather than above it, so the top padding
       has to clear roughly 120px of header plus its offset. */
    padding-block: clamp(9.5rem, 15vw, 13rem) clamp(4rem, 9vw, 7rem);
}

.page-header {
    padding-block: clamp(9rem, 13vw, 11rem) clamp(3rem, 6vw, 5rem);
}

/* Everything inside a dark band inverts. Scoped to the band so the rest of the
   page keeps the light treatment. */
.bikabo-hero h1, .bikabo-hero h2, .bikabo-hero h3,
.page-header h1, .page-header h2, .page-header h3,
.bikabo-hero .text-heading,
.page-header .text-heading {
    color: hsl(var(--white)) !important;
}

.bikabo-hero p,
.page-header p,
.bikabo-hero li,
.page-header li {
    color: hsl(var(--white) / 0.82);
}

.bikabo-hero .eyebrow,
.page-header .eyebrow {
    color: var(--bikabo-bright) !important;
}

.bikabo-hero .bikabo-breadcrumb a,
.page-header .bikabo-breadcrumb a {
    color: hsl(var(--white) / 0.75);
}

.bikabo-hero .bikabo-breadcrumb a:hover,
.page-header .bikabo-breadcrumb a:hover {
    color: var(--bikabo-bright);
}

.bikabo-hero .bikabo-breadcrumb [aria-current],
.page-header .bikabo-breadcrumb [aria-current],
.bikabo-hero .bikabo-breadcrumb span,
.page-header .bikabo-breadcrumb span {
    color: hsl(var(--white));
}

.page-header .guide-byline,
.page-header .guide-byline time {
    color: hsl(var(--white) / 0.72);
}

.page-header .guide-byline .text-heading {
    color: hsl(var(--white)) !important;
}

/* The italic serif accent the theme uses inside headings. On a dark band the
   teal gradient is too dark, so it gets the bright accent instead. */
.heading-accent {
    font-family: "DM Serif Display", Georgia, serif;
    font-style: italic;
    font-weight: 400;
}

.bikabo-hero .heading-accent,
.page-header .heading-accent {
    color: var(--bikabo-bright);
}

.heading-accent--gradient {
    background: linear-gradient(270deg, #06766E 0%, #20BA8B 100%);
    -webkit-background-clip: text;
    background-clip: text;
    -webkit-text-fill-color: transparent;
}

/* A soft glow behind the hero, in place of the theme's cloud PNG. Purely
   decorative and pointer-transparent. */
.bikabo-hero::after {
    content: "";
    position: absolute;
    inset-inline-end: -12%;
    inset-block-start: -30%;
    inline-size: 60%;
    aspect-ratio: 1;
    border-radius: 50%;
    background: radial-gradient(circle, rgba(47, 211, 156, 0.22) 0%, rgba(47, 211, 156, 0) 68%);
    pointer-events: none;
    z-index: -1;
}

/* Deep section band, for alternating down a page the way the theme does.
   -------------------------------------------------------------------------- */

.section-deep {
    background: var(--bikabo-deep-1);
    color: hsl(var(--white));
}

.section-deep h2, .section-deep h3, .section-deep .text-heading {
    color: hsl(var(--white)) !important;
}

.section-deep p, .section-deep li {
    color: hsl(var(--white) / 0.82);
}

.section-deep .eyebrow {
    color: var(--bikabo-bright) !important;
}

.section-deep .cost-card,
.section-deep .guide-card,
.section-deep .distinction__side {
    background: hsl(var(--white) / 0.06);
    border-color: hsl(var(--white) / 0.14);
}

.section-deep .claim-list li::before {
    background: var(--bikabo-bright);
}

/* Cards: one accent card per grid, as the theme does
   -------------------------------------------------------------------------- */

.cost-card--accent {
    background: linear-gradient(150deg, var(--bikabo-deep-2) 0%, var(--bikabo-deep-3) 100%) !important;
    border-color: transparent !important;
}

.cost-card--accent h3,
.cost-card--accent .text-heading {
    color: hsl(var(--white)) !important;
}

.cost-card--accent p {
    color: hsl(var(--white) / 0.85) !important;
}

.cost-card__icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    inline-size: 3rem;
    block-size: 3rem;
    border-radius: 0.9rem;
    background: var(--main-50);
    color: var(--main-600);
    font-size: 1.5rem;
    margin-block-end: 1.25rem;
    transition: transform 0.25s ease, background 0.25s ease;
}

.cost-card:hover .cost-card__icon {
    transform: translateY(-4px) rotate(-6deg);
}

.cost-card--accent .cost-card__icon {
    background: hsl(var(--white) / 0.16);
    color: hsl(var(--white));
}

/* Cards lift on hover, which the theme does everywhere and the earlier flat
   version did nowhere. */
.cost-card,
.guide-card {
    transition: transform 0.25s ease, box-shadow 0.25s ease;
}

.cost-card:hover,
.guide-card:hover {
    transform: translateY(-6px);
    box-shadow: 0 18px 40px rgba(0, 61, 61, 0.12);
}

/* Preloader safety
   --------------------------------------------------------------------------
   The theme fades the preloader out on window load. If JavaScript never runs,
   that overlay would sit over the page permanently, so it is hidden outright
   when the no-js class survives. */
.no-js .preloader,
.no-js .cursor,
.no-js .dot {
    display: none !important;
}

/* The custom cursor is a pointer decoration. Anything without a fine pointer,
   or anyone who has asked for less motion, gets the normal cursor. */
@media (hover: none), (pointer: coarse), (prefers-reduced-motion: reduce) {
    .cursor,
    .dot {
        display: none !important;
    }
}

/* --------------------------------------------------------------------------
   17. Text on dark bands
   --------------------------------------------------------------------------
   The theme's colour utilities all carry !important:

       .text-neutral-600 { color: var(--neutral-600) !important; }

   which means the element-level rules in section 16 lose to any markup that
   uses one. Since almost every paragraph on the site does, the intro text on
   the gradient bands was rendering dark grey on dark green.

   Rather than strip the utilities out of the markup, the utilities are
   overridden inside a dark band. Specificity is the same, so these win by
   coming later in the file.
   -------------------------------------------------------------------------- */

.bikabo-hero p,
.bikabo-hero li,
.bikabo-hero .text-neutral-500,
.bikabo-hero .text-neutral-600,
.bikabo-hero .text-neutral-700,
.page-header p,
.page-header li,
.page-header .text-neutral-500,
.page-header .text-neutral-600,
.page-header .text-neutral-700,
.section-deep p,
.section-deep li,
.section-deep .text-neutral-500,
.section-deep .text-neutral-600,
.section-deep .text-neutral-700 {
    color: hsl(var(--white) / 0.82) !important;
}

/* Breadcrumb separators and muted meta sit a step further back. */
.bikabo-hero .text-neutral-400,
.page-header .text-neutral-400,
.section-deep .text-neutral-400 {
    color: hsl(var(--white) / 0.5) !important;
}

/* Links inside a dark band take the bright accent, not the interactive green,
   which is nearly invisible against these surfaces. */
.bikabo-hero a.text-main-600,
.page-header a.text-main-600,
.section-deep a.text-main-600,
.bikabo-hero .bikabo-breadcrumb a,
.page-header .bikabo-breadcrumb a,
.section-deep a.text-neutral-600 {
    color: var(--bikabo-bright) !important;
}

.bikabo-hero a:hover,
.page-header a:hover,
.section-deep a:hover {
    color: var(--bikabo-bright-soft) !important;
}

/* Headings keep the strongest weight available. */
.bikabo-hero .text-heading,
.page-header .text-heading,
.section-deep .text-heading {
    color: hsl(var(--white)) !important;
}

/* Cards that sit on a dark band keep their own light surface, so their text
   must stay dark. This undoes the inheritance above inside a white card. */
.section-deep .cost-card:not(.cost-card--accent) p,
.section-deep .cost-card:not(.cost-card--accent) li,
.section-deep .guide-card p,
.section-deep .guide-card li {
    color: hsl(var(--white) / 0.82) !important;
}

/* --------------------------------------------------------------------------
   18. Final CTA panel
   --------------------------------------------------------------------------
   Matches the hero rather than being a flat block of --main-800, so the page
   opens and closes on the same gradient.
   -------------------------------------------------------------------------- */

.cta-panel {
    background: linear-gradient(69.92deg, var(--bikabo-deep-1) 18%, var(--bikabo-deep-2) 72%, var(--bikabo-deep-3) 118%) !important;
    position: relative;
    overflow: hidden;
}

.cta-panel::after {
    content: "";
    position: absolute;
    inset-inline-start: -10%;
    inset-block-end: -55%;
    inline-size: 45%;
    aspect-ratio: 1;
    border-radius: 50%;
    background: radial-gradient(circle, rgba(47, 211, 156, 0.25) 0%, rgba(47, 211, 156, 0) 70%);
    pointer-events: none;
}

.cta-panel h2,
.cta-panel .text-heading {
    color: hsl(var(--white)) !important;
}

.cta-panel p {
    color: hsl(var(--white) / 0.82) !important;
}

/* The secondary button on the panel needs an outline, since a transparent
   button on a gradient is invisible until hovered. */
.cta-panel .btn:not(.btn-main),
.bikabo-hero .btn:not(.btn-main) {
    border: 1px solid hsl(var(--white) / 0.45);
    color: hsl(var(--white)) !important;
}

.cta-panel .btn:not(.btn-main):hover,
.bikabo-hero .btn:not(.btn-main):hover {
    border-color: var(--bikabo-bright);
    color: var(--bikabo-bright) !important;
}

/* --------------------------------------------------------------------------
   19. Feature cards, pills and icons
   --------------------------------------------------------------------------
   The theme carries hover-gradient-bg-five, the .group hover system and the
   animation-item keyframes already, so these rules only supply what the theme
   leaves to the markup: icon sizing, the pill treatments, and the colour of an
   icon before and after the card fills.
   -------------------------------------------------------------------------- */

.feature-card__icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    inline-size: 3rem;
    block-size: 3rem;
    flex-shrink: 0;
    font-size: 1.75rem;
    color: var(--main-600);
    transition: color 0.3s ease;
}

/* The whole card fills with the gradient on hover, so the icon has to invert
   with the text rather than staying green on green. */
.group:hover .feature-card__icon {
    color: hsl(var(--white)) !important;
}

/* On a deep band the cards start translucent, so the icon needs the bright
   accent rather than the interactive green. */
.section-deep .feature-card__icon {
    color: var(--bikabo-bright);
}

.section-deep .group-item {
    background: hsl(var(--white) / 0.06) !important;
    border-color: hsl(var(--white) / 0.14) !important;
}

.section-deep .group-item h3,
.section-deep .group-item p {
    color: hsl(var(--white) / 0.85) !important;
}

/* Eyebrow pill. The theme uses this shape for the offer badge above a heading;
   here it carries a category or a qualifier. */
.pill-eyebrow {
    background: var(--main-50);
    color: var(--main-600);
    border: 1px solid var(--main-200);
}

.bikabo-hero .pill-eyebrow,
.page-header .pill-eyebrow,
.section-deep .pill-eyebrow {
    background: hsl(var(--white) / 0.13);
    border-color: hsl(var(--white) / 0.22);
    color: hsl(var(--white)) !important;
}

/* Check pills, from the theme's "Supercharge Daily Work" block. */
.check-pill {
    background: hsl(var(--neutral-100, 220 14% 96%));
    border-radius: 999px;
    padding: 0.75rem 1.5rem 0.75rem 0.75rem;
    transition: background 0.25s ease, transform 0.25s ease;
    align-self: flex-start;
}

.check-pill:hover {
    background: var(--main-50);
    transform: translateX(4px);
}

.check-pill__mark {
    inline-size: 2rem;
    block-size: 2rem;
    border-radius: 50%;
    background: var(--main-600);
    color: hsl(var(--white));
    font-size: 1.1rem;
}

.section-deep .check-pill {
    background: hsl(var(--white) / 0.08);
}

.section-deep .check-pill:hover {
    background: hsl(var(--white) / 0.14);
}

.section-deep .check-pill span:last-child {
    color: hsl(var(--white)) !important;
}

.section-deep .check-pill__mark {
    background: var(--bikabo-bright);
    color: var(--bikabo-deep-1);
}

/* The yellow accent the theme uses on a single word inside body copy, as in
   "Sassly-CRM". Warm against all the green, and used sparingly. */
.text-accent-warm {
    color: hsl(var(--yellow)) !important;
    font-weight: 700;
}

/* Icons sitting inline with a label, anywhere. Matches the project's rule that
   an icon beside text is always a flex row, never nudged with vertical-align. */
.icon-inline {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
}
