﻿/* ==========================================================================
   OSTEO ON THE GO — AUTHENTICATION DESIGN LAYER
   ==========================================================================

   Single source of truth for the visual design of every unauthenticated
   screen: Sign Up (patient + practitioner), Sign In, Forgot Password,
   Reset Password and Profile Under Review.

   Built directly against the approved reference sheet. The structure it
   expects is:

       .oa-shell                     page background + decorative field
         .oa-frame                   rounded white frame (the "device")
           .oa-header                pale mint bar with brand + nav
           .oa-body                  everything below the bar
             .oa-head                page title + subtitle
             .oa-stepper             full-width progress rail
             .oa-split               mint aside + white content panel
             .oa-trust               reassurance strip

   LOAD ORDER MATTERS. This file is loaded last, after auth.min.css and
   signupdesign.css, and a handful of rules below are deliberately written
   with extra specificity (or !important) where those older sheets set a
   conflicting value on a bare element selector. Each of those is commented
   with the rule it is overriding, so none of them is cargo cult.

   Namespacing: every new class is prefixed `oa-`. Legacy ids and the
   classes that JavaScript binds to (.type-option, .type-card, .fv-row,
   .submitButton, .form-section, .auth-otp__box, …) are preserved untouched
   on the same elements, so no behaviour moves when the paint changes.
   ========================================================================== */

/* Fonts, brand colours and the lockup live in osteo-brand.css, which
   _AuthLayout loads immediately before this file. */

/* --------------------------------------------------------------------------
   1. TOKENS
   -------------------------------------------------------------------------- */

:root {
    /* Brand colours and fonts: osteo-brand.css. */


    /* ----------------------------------------------------------------
       FLUID SIZING

       The auth screens have to fit a laptop viewport without scrolling, and
       the binding constraint is vertical, not horizontal — so the type ramp
       and the vertical rhythm are driven by vh, clamped at both ends.

       These are the MOBILE / short-viewport baseline: every value sits at or
       near its minimum, which is the comfortable size for a phone. The
       desktop block near the end of this file re-declares the same tokens
       with vh-based clamps, so a tall desktop gets the full-size design and a
       1366x768 laptop gets a proportionally tighter one. Components only ever
       read var(--oa-...), so there is a single place to tune each dimension.
       ---------------------------------------------------------------- */
    --oa-topbar-py:      14px;
    --oa-topbar-px:      clamp(16px, 3vw, 44px);
    --oa-topbar-h:       62px;   /* py*2 + the brand's line box */
    --oa-shell-pad-y:    20px;

    --oa-gap-xs:          6px;
    --oa-gap-sm:         12px;
    --oa-gap-md:         18px;
    --oa-gap-lg:         26px;

    --oa-ctl-h:          50px;
    --oa-card-py:        30px;
    --oa-card-px:        24px;
    --oa-choice-py:      20px;
    --oa-choice-icon:    62px;

    --oa-fs-eyebrow:     11.5px;
    --oa-fs-title:       28px;
    --oa-fs-sub:         15px;
    --oa-fs-h2:          17px;
    --oa-fs-body:        14px;
    --oa-fs-label:       14.5px;
    --oa-fs-hero-title:  30px;

    /* Geometry. */
    --oa-r-frame:        22px;
    --oa-r-card:         16px;
    --oa-r-control:      10px;
    --oa-r-pill:         999px;

    /* Elevation. */
    --oa-shadow-frame:   0 24px 60px rgba(17, 36, 90, .10);
    --oa-shadow-card:    0 6px 22px rgba(17, 36, 90, .05);
    --oa-shadow-btn:     0 8px 18px rgba(11, 178, 123, .28);

}

/* --------------------------------------------------------------------------
   2. SHELL + FRAME
   --------------------------------------------------------------------------
   The reference does not fill the browser edge to edge. It shows a rounded
   frame floating on a pale mint field, with botanical art bleeding around
   it. `.oa-shell` is that field; `.oa-frame` is the floating frame.
   -------------------------------------------------------------------------- */

/*  PAGE SCROLLING — do not simplify this block.

    auth.min.css ships two rules that together make a tall auth page
    unscrollable:

        body, html { height: 100%; }
        body       { display: flex; padding: .5rem .75rem .75rem; }

    A hard `height: 100%` on <body> plus `display: flex` makes .oa-shell a
    flex item stretched to exactly the viewport height. Anything past the
    fold overflows a box that cannot grow, so the document never becomes
    taller than the window and there is nothing to scroll — the sign-up
    steps with long forms were simply cut off.

    Both are plain element selectors, so a single class on <html> and <body>
    outranks them without !important. <html class="oa-html-auth"> is set by
    _AuthLayout; the two must stay in step. */
html.oa-html-auth {
    height: auto;
    min-height: 100%;
    overflow-y: auto;
}

body.oa-body-auth {
    display: block;
    height: auto;
    min-height: 100%;
    margin: 0;
    padding: 0;                 /* auth.min.css adds .5rem/.75rem; .oa-shell owns its own */
    overflow-y: visible;
    font-family: var(--oa-font);
    color: var(--oa-ink);
    -webkit-font-smoothing: antialiased;
    background: var(--brand-soft-weak, #eef9f4);
}

.oa-shell {
    position: relative;
    /* min-height, never height: the shell has to be free to grow past the
       viewport or the long wizard steps get clipped again. */
    min-height: 100vh;
    height: auto;
    padding: 28px 24px 44px;
    box-sizing: border-box;
    display: flex;
    flex-direction: column;
    align-items: center;
    font-family: var(--oa-font);
    /* Soft mint wash: brighter at the top, cooling toward the bottom. */
    background:
        radial-gradient(1200px 520px at 50% -10%, var(--brand-soft-strong, #d9f5e9) 0%, rgba(217, 245, 233, 0) 70%),
        linear-gradient(180deg, var(--brand-soft-weak, #edf9f4) 0%, var(--bg-page, #f6fbf9) 45%, var(--brand-soft-weak, #eef8f3) 100%);
}

/*  DEFENSIVE OVERRIDE
    auth.min.css ships `section { position: fixed; background: #e3f2fd; }`,
    a page-specific rule from the old marketing template. Any <section> used
    inside the auth screens would be torn out of flow by it. Neutralised for
    this subtree only. */
.oa-shell section {
    position: static !important;
    background: transparent;
}

.oa-frame {
    position: relative;
    z-index: 2;
    width: 100%;
    max-width: 1180px;
    background: var(--oa-white);
    border-radius: var(--oa-r-frame);
    box-shadow: var(--oa-shadow-frame);
    overflow: hidden;
}

.oa-frame--compact { max-width: 560px; }
.oa-frame--wide    { max-width: 1180px; }

/* --------------------------------------------------------------------------
   3. BOTANICAL DECORATION
   --------------------------------------------------------------------------
   The reference frames each screen with soft watercolour foliage. Drawn as
   inline SVG data URIs rather than bitmaps: no extra requests, no new binary
   assets in the repo, and they stay crisp at any density. Purely decorative,
   so they sit behind the frame and are hidden from assistive tech.
   -------------------------------------------------------------------------- */

.oa-leaf {
    /*  Fixed, not absolute. These sit outside the frame and two of them hang
        past its bottom edge; as absolutely-positioned children of .oa-shell
        they extended the document by ~42px and put a scrollbar on a page that
        otherwise fit exactly. Fixed keeps them where they are visually and
        takes them out of the scroll calculation entirely. */
    position: fixed;
    z-index: 1;
    pointer-events: none;
    background-repeat: no-repeat;
    background-size: contain;
    opacity: .85;
}

/* A sprig of three leaves, used at several scales and rotations. */
.oa-leaf--sprig {
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 200 240'%3E%3Cdefs%3E%3ClinearGradient id='g' x1='0' y1='0' x2='1' y2='1'%3E%3Cstop offset='0' stop-color='%2372d9ab'/%3E%3Cstop offset='1' stop-color='%23b7ecd4'/%3E%3C/linearGradient%3E%3C/defs%3E%3Cg fill='url(%23g)'%3E%3Cpath d='M96 236c-6-52 4-96 30-131 26-35 58-54 70-58-4 14-14 52-38 88s-42 60-62 101z' opacity='.55'/%3E%3Cpath d='M92 168c-30-6-52-24-64-46-12-22-14-46-12-58 12 4 36 14 54 34s24 46 22 70z'/%3E%3Cpath d='M106 116c20-24 28-52 28-76 0-24-8-40-14-40-6 10-18 34-20 60s2 44 6 56z' opacity='.8'/%3E%3Cpath d='M112 196c26-4 48-18 60-36 12-18 16-38 14-48-10 2-32 10-48 26s-24 38-26 58z' opacity='.65'/%3E%3C/g%3E%3C/svg%3E");
}

/* A single broad leaf. */
.oa-leaf--single {
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 160 200'%3E%3Cdefs%3E%3ClinearGradient id='h' x1='0' y1='1' x2='1' y2='0'%3E%3Cstop offset='0' stop-color='%234ecb97'/%3E%3Cstop offset='1' stop-color='%23a9e9cf'/%3E%3C/linearGradient%3E%3C/defs%3E%3Cpath d='M20 192C6 142 12 92 40 56S112 4 148 2c2 40-10 92-40 128s-64 56-88 62z' fill='url(%23h)'/%3E%3Cpath d='M22 190C46 140 84 84 146 6' stroke='%23ffffff' stroke-opacity='.45' stroke-width='3' fill='none'/%3E%3C/svg%3E");
}

/* Placement — deliberately outside the frame so nothing overlaps content. */
.oa-leaf--tl { top: -10px;  left: calc(50% - 700px); width: 230px; height: 280px; transform: rotate(-18deg); }
.oa-leaf--bl { bottom: 0;   left: calc(50% - 720px); width: 300px; height: 360px; transform: rotate(12deg); }
.oa-leaf--tr { top: 40px;   right: calc(50% - 690px); width: 200px; height: 250px; transform: scaleX(-1) rotate(-14deg); }
.oa-leaf--br { bottom: -20px; right: calc(50% - 730px); width: 280px; height: 340px; transform: scaleX(-1) rotate(10deg); }

@media (max-width: 1500px) {
    .oa-leaf { display: none; }
}

/* --------------------------------------------------------------------------
   4. TOP BAR  (shared header)
   --------------------------------------------------------------------------
   ONE header for every unauthenticated screen — sign up, sign in, forgot and
   reset password — and the intended header for the marketing home page too.
   Rendered by Views/Shared/_OsteoHeader.cshtml.

   It is deliberately transparent and overlaid rather than a solid bar. On the
   split screens it spans both panels: the brand sits over the pale form side
   and the nav over the mint hero side, and navy reads correctly on both, so
   one bar serves without a colour switch. On the wizard it sits over the pale
   page above the frame. That is what makes the same component work on every
   screen instead of needing a variant per background.
   -------------------------------------------------------------------------- */

.oa-topbar {
    position: relative;
    z-index: 30;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 24px;
    width: 100%;
    box-sizing: border-box;
    padding: var(--oa-topbar-py) var(--oa-topbar-px);
    font-family: var(--oa-font);
}

/*  Overlay mode: used by the split layout, where the two panels run to the
    top of the viewport and the bar floats on top of them. */
.oa-topbar--overlay {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
}


.oa-nav {
    display: flex;
    align-items: center;
    gap: 8px;
    margin: 0;
    padding: 0;
    list-style: none;
}

.oa-nav__link {
    display: inline-block;
    padding: 11px 20px;
    border-radius: 11px;
    font-size: 15px;
    font-weight: 600;
    color: var(--oa-ink-900);
    text-decoration: none;
    background: transparent;
    transition: background .15s ease, box-shadow .15s ease, color .15s ease;
}

.oa-nav__link:hover { color: var(--oa-ink-900); background: rgba(255, 255, 255, .5); }

/*  The current page is a raised white pill. Set from the route by the partial,
    never hardcoded per view. */
.oa-nav__link.is-active {
    background: var(--bg-surface, #ffffff);
    color: var(--oa-ink-900);
    box-shadow: 0 6px 16px rgba(17, 36, 90, .12);
}

@media (max-width: 640px) {
    .oa-topbar { padding: 14px 16px; gap: 10px; }
    .oa-brand__word { font-size: 21px; }
    .oa-brand__tag { padding: 6px 9px 5px; font-size: 10px; letter-spacing: 1.2px; }
    .oa-nav { gap: 2px; }
    .oa-nav__link { padding: 9px 12px; font-size: 13.5px; }
}

@media (max-width: 400px) {
    .oa-brand__tag { display: none; }
}

/* --------------------------------------------------------------------------
   5. BODY + PAGE HEAD
   -------------------------------------------------------------------------- */

.oa-body { padding: 26px 30px 30px; }
.oa-body--compact { padding: 30px 34px 34px; }

.oa-head { margin: 0 0 18px; }

.oa-head--center { text-align: center; }

.oa-title {
    margin: 0 0 4px;
    font-size: 30px;
    font-weight: 700;
    line-height: 1.16;
    letter-spacing: -.3px;
    color: var(--oa-ink);
}

.oa-title--sm { font-size: 26px; }

.oa-subtitle {
    margin: 0;
    font-size: 14px;
    font-weight: 400;
    line-height: 1.5;
    color: var(--oa-muted);
}

/* --------------------------------------------------------------------------
   6. STEPPER
   --------------------------------------------------------------------------
   A full-width rail above the split. The previous build let the labels wrap,
   which pushed the circles off a shared baseline and read as broken. Here the
   circles live in their own fixed-height row so they are always aligned, and
   labels sit under them in a reserved two-line box.
   -------------------------------------------------------------------------- */

/*  The rail keys off the class contract that is ALREADY in the markup and in
    create-account.js — `.stepper-nav > .stepper-item`, with `.current` /
    `.completed` on the item (KTStepper) and `.current-step` / `.completed` on
    the inner `.step-icon-wrapper` (the app's own updateStepperProgress).
    Inventing new state names here would have meant touching the JS for no
    gain, so the design is expressed against the existing hooks. */

.oa-stepper {
    display: grid;
    grid-auto-flow: column;
    grid-auto-columns: 1fr;
    margin: 0 0 22px;
    padding: 0;
    list-style: none;
}

.oa-stepper .stepper-item {
    position: relative;
    display: flex;
    flex-direction: column;
    align-items: center;
    min-width: 0;
    text-align: center;
    /* Metronic's own stepper-links styling assumes an inline row; reset the
       bits of it that fight this grid. */
    margin: 0;
    padding: 0;
    flex: initial;
}

/* Connector: drawn on each step except the first, reaching back to the one
   before it. Sits behind the bubble, centred on the bubble's vertical axis. */
.oa-stepper .stepper-item::before {
    content: "";
    position: absolute;
    top: 17px;
    right: 50%;
    left: -50%;
    height: 2px;
    background: var(--oa-border);
    z-index: 0;
}

.oa-stepper .stepper-item:first-child::before { display: none; }

/* The segment leading into a reached step is green. */
.oa-stepper .stepper-item.current::before,
.oa-stepper .stepper-item.completed::before { background: var(--oa-green-light); }

.oa-stepper .step-icon-wrapper {
    position: relative;
    z-index: 1;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 36px;
    height: 36px;
    border-radius: 50%;
    background: var(--oa-white);
    border: 2px solid var(--oa-border-strong);
    line-height: 1;
    transition: background .18s ease, border-color .18s ease;
}

.oa-stepper .step-icon {
    font-size: 14px;
    font-weight: 700;
    color: var(--oa-ink);
    line-height: 1;
}

/* --- current --- */
.oa-stepper .stepper-item.current .step-icon-wrapper,
.oa-stepper .step-icon-wrapper.current-step {
    background: var(--oa-green);
    border-color: var(--oa-green);
    box-shadow: 0 0 0 5px rgba(11, 178, 123, .14);
}

.oa-stepper .stepper-item.current .step-icon,
.oa-stepper .step-icon-wrapper.current-step .step-icon { color: var(--brand-on-primary, #ffffff); }

/* --- completed: green disc with a tick instead of the digit --- */
.oa-stepper .stepper-item.completed .step-icon-wrapper,
.oa-stepper .step-icon-wrapper.completed {
    background: var(--oa-green);
    border-color: var(--oa-green);
    box-shadow: none;
}

.oa-stepper .stepper-item.completed .step-icon,
.oa-stepper .step-icon-wrapper.completed .step-icon { font-size: 0; color: transparent; }

.oa-stepper .stepper-item.completed .step-icon-wrapper::after,
.oa-stepper .step-icon-wrapper.completed::after {
    content: "\f00c";                /* Font Awesome check */
    position: absolute;
    font-family: "Font Awesome 6 Free", "Font Awesome 5 Free", "FontAwesome";
    font-weight: 900;
    font-size: 13px;
    line-height: 1;
    color: #ffffff;
}

.oa-stepper .step-label {
    margin-top: 8px;
    padding: 0 4px;
    font-size: 11.5px;
    font-weight: 500;
    line-height: 1.25;
    color: var(--oa-muted);
    /* Reserve two lines so a wrapping label never shifts the bubbles off a
       shared baseline — which is exactly what the previous build did. */
    min-height: 2.5em;
    word-break: normal;
    overflow-wrap: break-word;
}

.oa-stepper .stepper-item.current .step-label { color: var(--oa-ink); font-weight: 700; }
.oa-stepper .stepper-item.completed .step-label { color: var(--oa-ink-soft); font-weight: 600; }

/* --------------------------------------------------------------------------
   7. SPLIT: ASIDE + PANEL
   -------------------------------------------------------------------------- */

/*  Two columns, two rows. The aside spans both rows so it runs to the bottom
    of the frame exactly as the reference draws it, while the reassurance strip
    sits in the second row of the content column — aligned with the card above
    it, not with the aside. */
.oa-split {
    display: grid;
    grid-template-columns: 236px minmax(0, 1fr);
    grid-template-rows: auto auto;
    gap: 18px;
    align-items: stretch;
}

.oa-split > .oa-aside { grid-column: 1; grid-row: 1 / -1; }
.oa-split > .oa-panel { grid-column: 2; grid-row: 1; }
.oa-split > .oa-trust { grid-column: 2; grid-row: 2; margin-top: 2px; }

.oa-aside {
    position: relative;
    overflow: hidden;
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
    padding: 34px 22px 26px;
    border-radius: var(--oa-r-card);
    background: linear-gradient(180deg, var(--brand-soft-strong, #ddf6ec) 0%, var(--brand-soft-strong, #d2f2e5) 55%, var(--brand-soft-stronger, #c8efdf) 100%);
}

/* Foliage in the lower corner of the aside, as in every reference tile. */
.oa-aside::after {
    content: "";
    position: absolute;
    left: -30px;
    bottom: -18px;
    width: 160px;
    height: 195px;
    background-repeat: no-repeat;
    background-size: contain;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 200 240'%3E%3Cdefs%3E%3ClinearGradient id='a' x1='0' y1='1' x2='1' y2='0'%3E%3Cstop offset='0' stop-color='%234cc492'/%3E%3Cstop offset='1' stop-color='%23a6e6ce'/%3E%3C/linearGradient%3E%3C/defs%3E%3Cg fill='url(%23a)'%3E%3Cpath d='M28 238C10 190 14 136 44 96S124 28 166 24c0 44-16 100-52 140s-70 66-86 74z' opacity='.9'/%3E%3Cpath d='M96 214c-34-10-58-32-70-56S12 108 14 96c14 6 42 20 60 44s24 52 22 74z' opacity='.55'/%3E%3C/g%3E%3C/svg%3E");
    opacity: .55;
    pointer-events: none;
}

.oa-aside > * { position: relative; z-index: 1; }

/*  The aside carries one pane per wizard step. create-account.js toggles
    .is-current on [data-step-pane] as the card moves, so the supporting copy
    tracks the step instead of sitting static. */
.oa-aside [data-step-pane] { display: none; }
.oa-aside [data-step-pane].is-current { display: block; }

.oa-aside__icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 72px;
    height: 72px;
    margin-bottom: 18px;
    font-size: 44px;
    line-height: 1;
    color: var(--oa-ink);
}

.oa-aside__icon svg { width: 64px; height: 64px; display: block; }

.oa-aside__title {
    margin: 0 0 12px;
    font-size: 19px;
    font-weight: 700;
    line-height: 1.28;
    color: var(--oa-ink);
}

.oa-aside__body {
    margin: 0;
    font-size: 12.5px;
    font-weight: 400;
    line-height: 1.62;
    color: var(--oa-ink-soft);
}

/* The handwritten sign-off that appears at the foot of the aside in the
   reference ("Knowledge Creates Healthier Tomorrows", "Better Care
   Brighter", …). */
.oa-aside__script {
    margin: auto 0 0;
    padding-top: 22px;
    font-family: var(--oa-font-script);
    font-size: 24px;
    font-weight: 600;
    line-height: 1.35;
    color: var(--state-info-ink, #1f3f86);
    transform: rotate(-4deg);
}

.oa-panel {
    display: flex;
    flex-direction: column;
    min-width: 0;
    padding: 26px 28px;
    border-radius: var(--oa-r-card);
    background: var(--oa-white);
    border: 1px solid var(--oa-border);
    box-shadow: var(--oa-shadow-card);
}

.oa-panel__title {
    margin: 0 0 3px;
    font-size: 23px;
    font-weight: 700;
    line-height: 1.22;
    color: var(--oa-ink);
}

.oa-panel__subtitle {
    margin: 0 0 20px;
    font-size: 13.5px;
    font-weight: 400;
    line-height: 1.5;
    color: var(--oa-muted);
}

/* --------------------------------------------------------------------------
   8. TRUST STRIP
   -------------------------------------------------------------------------- */

.oa-trust {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 18px;
    margin-top: 20px;
    padding: 0 4px;
}

.oa-trust__item { display: flex; align-items: center; gap: 11px; }

.oa-trust__icon {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 30px;
    height: 30px;
    font-size: 22px;
    line-height: 1;
    color: var(--oa-green);
}

.oa-trust__title {
    display: block;
    font-size: 12.5px;
    font-weight: 700;
    line-height: 1.3;
    color: var(--oa-ink);
}

.oa-trust__body {
    display: block;
    font-size: 11px;
    font-weight: 400;
    line-height: 1.35;
    color: var(--oa-muted);
}

/* --------------------------------------------------------------------------
   9. ROLE / OPTION CARDS
   --------------------------------------------------------------------------
   Used for "Choose Your Account Type" on sign-up and "Choose account Type"
   on sign-in and forgot-password. The selected state in the reference is
   unmistakable: mint fill, green border, green tick badge. The previous
   build showed only an empty radio ring, so nothing ever looked chosen.

   The native radio stays in the DOM (it carries the value and the name the
   model binder needs) but is visually hidden; the label is the control.
   -------------------------------------------------------------------------- */

.oa-choices {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 16px;
    margin-bottom: 22px;
}

.oa-choice {
    position: relative;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: flex-start;
    gap: 6px;
    padding: 22px 16px 20px;
    border-radius: 13px;
    border: 1.5px solid var(--oa-border);
    background: var(--oa-white);
    text-align: center;
    cursor: pointer;
    transition: border-color .16s ease, background .16s ease, box-shadow .16s ease;
}

.oa-choice:hover { border-color: var(--oa-green-light); background: var(--brand-soft-weak, #f7fdfa); }

/*  On sign-in and forgot-password the radio is a sibling of the card rather
    than a child, because .type-option (the wrapper) is what carries the click
    handler and the data-value the script reads. The wrapper is therefore the
    grid cell, and the card stretches to fill it so two cards with different
    text lengths stay the same height. */
.oa-choices > .type-option {
    position: relative;
    display: flex;
    min-width: 0;
}

.oa-choices > .type-option > .oa-choice { flex: 1 1 auto; }

.oa-choice__input {
    position: absolute;
    opacity: 0;
    width: 1px;
    height: 1px;
    margin: 0;
    pointer-events: none;
}

.oa-choice__icon {
    display: block;
    width: 56px;
    height: 56px;
    margin-bottom: 4px;
    color: var(--oa-ink);
}

.oa-choice__icon svg { width: 100%; height: 100%; display: block; }

/* The title and the description are separate blocks. A previous revision lost
   this rule and the two ran together on one line. */
.oa-choice__title,
.oa-choice__desc { display: block; }

.oa-choice__title {
    font-size: 16px;
    font-weight: 700;
    line-height: 1.3;
    color: var(--oa-ink);
}

.oa-choice__desc {
    font-size: 12.5px;
    font-weight: 400;
    line-height: 1.45;
    color: var(--oa-muted);
}

/* Tick badge — rendered always, revealed on selection. */
.oa-choice__tick {
    position: absolute;
    top: 12px;
    right: 12px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 24px;
    height: 24px;
    border-radius: 50%;
    background: var(--oa-green);
    color: var(--brand-on-primary, #ffffff);
    font-size: 11px;
    line-height: 1;
    opacity: 0;
    transform: scale(.6);
    transition: opacity .16s ease, transform .16s ease;
}

/*  Three ways a card can read as selected, all styled identically:
      .is-selected              set by new code
      :has(:checked)            pure CSS, keyboard and autofill safe
      .type-card.active         set by $.Account.LoginUsertypeChnage and by
                                $.SignUp.SelectUserType — the legacy state
                                class. Mapping it here is what makes the
                                selected state finally appear on screen: the
                                script was already setting it, the old
                                stylesheet just never drew anything for it. */
.oa-choice.is-selected,
.oa-choice.active,
.oa-choice:has(.oa-choice__input:checked),
.type-option:has(> .oa-choice__input:checked) > .oa-choice {
    border-color: var(--oa-green);
    background: var(--oa-mint-200);
    box-shadow: 0 0 0 3px rgba(11, 178, 123, .10);
}

.oa-choice.is-selected .oa-choice__tick,
.oa-choice.active .oa-choice__tick,
.oa-choice:has(.oa-choice__input:checked) .oa-choice__tick,
.type-option:has(> .oa-choice__input:checked) > .oa-choice .oa-choice__tick {
    opacity: 1;
    transform: scale(1);
}

/* Keyboard focus has to be visible even though the input itself is hidden. */
.oa-choice:focus-within,
.type-option:focus-within > .oa-choice { outline: 2px solid var(--oa-green); outline-offset: 2px; }

/* Compact variant for sign-in / forgot-password, which show icon + name only. */
.oa-choice--compact { padding: 16px 12px 14px; }
.oa-choice--compact .oa-choice__icon { width: 44px; height: 44px; }
.oa-choice--compact .oa-choice__title { font-size: 14px; }

/* --------------------------------------------------------------------------
   10. FORM CONTROLS
   --------------------------------------------------------------------------
   Label above (bold ink, red asterisk when required), control below with a
   leading glyph inside the field, 48px tall, 10px radius, lavender border.
   -------------------------------------------------------------------------- */

.oa-grid {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 0 18px;
}

.oa-grid--1 { grid-template-columns: minmax(0, 1fr); }
.oa-grid--3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.oa-span-2  { grid-column: 1 / -1; }

.oa-field { margin-bottom: 16px; min-width: 0; }

.oa-label {
    display: block;
    margin-bottom: 6px;
    font-size: 13px;
    font-weight: 600;
    line-height: 1.3;
    color: var(--oa-ink);
}

.oa-label .oa-req { color: var(--oa-danger); margin-left: 2px; font-weight: 700; }

.oa-label__optional { font-weight: 500; color: var(--oa-muted); }

.oa-control { position: relative; display: block; }

/* Unit shown inside the right edge of a numeric input ("KM"). */
.oa-control--suffix .form-control,
.oa-control--suffix .oa-input { padding-right: 52px; -moz-appearance: textfield; appearance: textfield; }
/* The unit sits where the number spinner would; the spinner adds nothing for a typed value. */
.oa-control--suffix input[type="number"]::-webkit-inner-spin-button,
.oa-control--suffix input[type="number"]::-webkit-outer-spin-button { -webkit-appearance: none; margin: 0; }
.oa-control__suffix {
    position: absolute;
    top: 50%;
    right: 16px;
    transform: translateY(-50%);
    font-size: 12px;
    font-weight: 700;
    letter-spacing: .4px;
    color: var(--oa-muted);
    pointer-events: none;
}

/* Groups a label with several inputs (Daily Patient Load) without browser chrome. */
.oa-fieldset { min-width: 0; margin: 0 0 16px; padding: 0; border: 0; }
.oa-fieldset > legend.oa-label { float: none; width: auto; margin-bottom: 2px; padding: 0; }

.oa-load__help { margin: 0 0 10px; }
.oa-load__grid .oa-field { margin-bottom: 0; }
.oa-load__label { display: flex; align-items: baseline; gap: 6px; margin-bottom: 6px; font-size: 12.5px; font-weight: 600; }
.oa-load__unit { font-size: 11px; font-weight: 500; color: var(--oa-muted); }

/* Distance: the "Other" entry opens directly under the select, inside the same field. */
.oa-distance__other { margin-top: 10px; }
.oa-distance__other-label { margin-bottom: 6px; font-size: 12.5px; font-weight: 600; }

.oa-control__glyph {
    position: absolute;
    top: 50%;
    left: 15px;
    transform: translateY(-50%);
    font-size: 15px;
    line-height: 1;
    color: var(--oa-muted-2);
    pointer-events: none;
}

/* The input rules are written against `.oa-control > .form-control` as well as
   `.oa-input`, because Metronic's `.form-control` is already on these fields
   for FormValidation and we are not going to strip a class the validator
   looks for. */
.oa-input,
.oa-control .form-control,
.oa-control .form-select {
    width: 100%;
    height: 48px;
    padding: 0 16px;
    box-sizing: border-box;
    font-family: var(--oa-font);
    font-size: 14px;
    font-weight: 400;
    color: var(--oa-ink);
    background-color: var(--oa-white);
    border: 1px solid var(--oa-border);
    border-radius: var(--oa-r-control);
    box-shadow: none;
    transition: border-color .15s ease, box-shadow .15s ease;
}

.oa-control--icon .oa-input,
.oa-control--icon .form-control { padding-left: 42px; }

.oa-control--action .oa-input,
.oa-control--action .form-control { padding-right: 46px; }

.oa-input::placeholder,
.oa-control .form-control::placeholder { color: var(--oa-muted-2); opacity: 1; }

.oa-input:focus,
.oa-control .form-control:focus,
.oa-control .form-select:focus {
    outline: none;
    border-color: var(--oa-green);
    box-shadow: 0 0 0 3px rgba(11, 178, 123, .13);
}

textarea.oa-input,
.oa-control textarea.form-control {
    height: auto;
    min-height: 118px;
    padding: 13px 16px;
    line-height: 1.55;
    resize: vertical;
}

select.oa-input,
.oa-control select.form-control,
.oa-control .form-select {
    appearance: none;
    -webkit-appearance: none;
    padding-right: 40px;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='9' viewBox='0 0 14 9'%3E%3Cpath d='M1 1l6 6 6-6' stroke='%2317246b' stroke-width='2' fill='none' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 16px center;
}

/* Trailing action (password eye). */
.oa-control__action {
    position: absolute;
    top: 50%;
    right: 8px;
    transform: translateY(-50%);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 34px;
    height: 34px;
    padding: 0;
    border: 0;
    border-radius: 8px;
    background: transparent;
    color: var(--oa-muted);
    font-size: 15px;
    cursor: pointer;
}

.oa-control__action:hover { color: var(--oa-ink); background: var(--oa-mint-100); }

/*  Password strength meter. KTPasswordMeter finds the container by
    [data-kt-password-meter-control="highlight"] and adds .active to as many
    child divs as the score warrants — it does not care what they are called,
    so the bars can carry our own class names. */
.oa-meter {
    display: flex;
    gap: 6px;
    margin-top: 9px;
}

.oa-meter__bar {
    flex: 1 1 0;
    height: 5px;
    border-radius: 3px;
    background: var(--oa-border);
    transition: background .18s ease;
}

.oa-meter__bar.active { background: var(--oa-green); }

.oa-help {
    display: block;
    margin-top: 5px;
    font-size: 11.5px;
    font-weight: 400;
    line-height: 1.4;
    color: var(--oa-muted);
}

.oa-counter { float: right; font-size: 11px; color: var(--oa-muted-2); }

/* Phone (.oa-phone, the +1 / Canada control of _PhonePrefix): defined in osteo-brand.css,
   which both layouts load, so Create Event's "invite by phone" uses the same control. */

/* Email + Phone share a row when two ~250px columns fit, and stack below
   that. Width-driven by the container, not the viewport, so it behaves the
   same in the wide wizard panel and the narrower sign-in card. Hidden
   children (Login/Forgot show one role-specific field at a time) take no
   track, so the visible one spans the row. */
.oa-grid--contact {
    grid-template-columns: repeat(auto-fit, minmax(min(100%, 250px), 1fr));
    align-items: start;
}

/* Radio / checkbox rows. */
.oa-radio-list { display: flex; flex-direction: column; gap: 9px; }
.oa-radio-row  { display: flex; flex-wrap: wrap; align-items: center; gap: 18px; }

.oa-radio,
.oa-check {
    display: inline-flex;
    align-items: center;
    gap: 9px;
    font-size: 13.5px;
    font-weight: 400;
    color: var(--oa-ink-soft);
    cursor: pointer;
    margin: 0;
}

.oa-radio input,
.oa-check input {
    width: 17px;
    height: 17px;
    margin: 0;
    accent-color: var(--oa-green);
    cursor: pointer;
    flex: 0 0 auto;
}

/* Dropzone / file drop area. */
.oa-drop {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 6px;
    min-height: 122px;
    padding: 18px;
    text-align: center;
    border: 1.5px dashed var(--oa-border-strong);
    border-radius: 12px;
    background: var(--oa-surface);
    color: var(--oa-muted);
    cursor: pointer;
    transition: border-color .15s ease, background .15s ease;
}

.oa-drop:hover { border-color: var(--oa-green-light); background: var(--brand-soft-weak, #f6fdfa); }
.oa-drop__icon { font-size: 26px; color: var(--state-info, #5f8ce0); line-height: 1; }
.oa-drop__title { font-size: 13px; font-weight: 500; color: var(--oa-ink-soft); }
.oa-drop__hint  { font-size: 11px; color: var(--oa-muted-2); }

/* --------------------------------------------------------------------------
   11. BUTTONS
   -------------------------------------------------------------------------- */

.oa-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 10px;
    height: 50px;
    padding: 0 30px;
    /* Required: .oa-btn--block sets width:100%, and without border-box the
       horizontal padding and border push the button past its container —
       which is what made Cancel wider than the primary above it. */
    box-sizing: border-box;
    border: 1.5px solid transparent;
    border-radius: var(--oa-r-control);
    font-family: var(--oa-font);
    font-size: 15px;
    font-weight: 600;
    line-height: 1;
    text-decoration: none;
    cursor: pointer;
    transition: transform .12s ease, box-shadow .16s ease, background .16s ease, border-color .16s ease;
}

.oa-btn:active { transform: translateY(1px); }

.oa-btn--primary {
    background: linear-gradient(90deg, var(--oa-green) 0%, var(--oa-green-dark) 100%);
    color: var(--brand-on-primary, #ffffff);
    box-shadow: var(--oa-shadow-btn);
}

.oa-btn--primary:hover { color: var(--brand-on-primary, #ffffff); box-shadow: 0 10px 24px rgba(11, 178, 123, .36); }

.oa-btn--ghost {
    background: var(--oa-white);
    border-color: var(--oa-border-strong);
    color: var(--oa-ink);
}

.oa-btn--ghost:hover { border-color: var(--oa-ink-soft); color: var(--oa-ink); background: var(--bg-surface-2, #f8faff); }

.oa-btn--link {
    height: auto;
    padding: 0;
    background: none;
    border: 0;
    color: var(--oa-green-ink);
    font-weight: 600;
    text-decoration: underline;
}

.oa-btn--block { width: 100%; }

/*  A disabled primary must still read as green — muted, not washed out to the
    point of looking like a placeholder, which is how the previous build's
    permanently pale Continue button read. */
.oa-btn--primary:disabled,
.oa-btn--primary.disabled {
    background: linear-gradient(90deg, var(--brand-soft-strongest, #7fd8b8) 0%, var(--brand-primary-light, #6fcfab) 100%);
    box-shadow: none;
    cursor: not-allowed;
    opacity: 1;
}

.oa-btn__arrow { font-size: 15px; line-height: 1; }

/*  Loading state. Metronic drives this with data-kt-indicator="on" and its
    own rules are not scoped to .btn, but these buttons are not .btn elements
    and the auth screens should not depend on the theme bundle being present
    for a control to look right. Same contract, stated locally. */
.oa-btn .indicator-progress { display: none; align-items: center; gap: 8px; }
.oa-btn[data-kt-indicator="on"] .indicator-progress { display: inline-flex; }
.oa-btn[data-kt-indicator="on"] .indicator-label,
.oa-btn[data-kt-indicator="on"] .oa-btn__arrow { display: none; }

/* Footer action bar inside a panel. */
.oa-actions {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 14px;
    margin-top: auto;
    padding-top: 22px;
}

.oa-actions--divided { border-top: 1px solid var(--oa-border); margin-top: 20px; }
.oa-actions--end     { justify-content: flex-end; }
.oa-actions--stack   { flex-direction: column; align-items: stretch; }

.oa-actions__note {
    margin: 14px 0 0;
    text-align: center;
    font-size: 13px;
    color: var(--oa-muted);
}

.oa-actions__note a { color: var(--oa-green-ink); font-weight: 600; text-decoration: none; }
.oa-actions__note a:hover { text-decoration: underline; }

/* DEFERRING THE QUALIFICATION STEP.
   The "Skip for now" control needs the sentence under it to carry equal weight to the link: the
   whole point is that the applicant understands deferring delays approval rather than removing
   the requirement. Constrained width so the sentence reads as one paragraph, not a banner. */
.oa-defer { display: flex; flex-direction: column; align-items: center; gap: 6px; }
.oa-defer__hint {
    margin: 0;
    max-width: 52ch;
    text-align: center;
    font-size: 12.5px;
    line-height: 1.5;
    color: var(--oa-muted);
}

/* Remember-me / forgot-password row. */
.oa-inline-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    margin: 4px 0 18px;
}

.oa-inline-row a {
    font-size: 13px;
    font-weight: 600;
    color: var(--oa-ink);
    text-decoration: underline;
}

.oa-inline-row a:hover { color: var(--oa-green-ink); }

/* --------------------------------------------------------------------------
   12. OTP
   -------------------------------------------------------------------------- */

.oa-contact {
    display: flex;
    align-items: center;
    gap: 14px;
    margin-bottom: 18px;
}

/* The middle column takes the slack so Edit stays pinned to the right edge
   of the panel, as it is drawn in the reference. */
.oa-contact__text { flex: 1 1 auto; min-width: 0; }
.oa-contact__text .oa-label { margin-bottom: 2px; }
.oa-contact__text .oa-help { margin-top: 0; }
.oa-contact__edit { flex: 0 0 auto; margin-left: auto; }

.oa-contact__icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 52px;
    height: 52px;
    border-radius: 50%;
    background: var(--oa-mint-200);
    color: var(--oa-ink);
    font-size: 21px;
    flex: 0 0 auto;
}

.oa-contact__value:not(:empty) {
    display: block;
    margin-bottom: 2px;
    font-size: 16px;
    font-weight: 700;
    color: var(--oa-ink);
    letter-spacing: .2px;
}

.oa-contact__edit {
    font-size: 13.5px;
    font-weight: 600;
    color: var(--oa-green-ink);
    text-decoration: underline;
    background: none;
    border: 0;
    padding: 0;
    cursor: pointer;
}

.oa-otp {
    display: flex;
    gap: 11px;
    margin-bottom: 14px;
    flex-wrap: wrap;
}

.oa-otp__box {
    width: 52px;
    height: 56px;
    padding: 0;
    text-align: center;
    font-family: var(--oa-font);
    font-size: 21px;
    font-weight: 700;
    color: var(--oa-ink);
    background: var(--oa-white);
    border: 1.5px solid var(--oa-border);
    border-radius: 10px;
    transition: border-color .15s ease, box-shadow .15s ease;
}

.oa-otp__box:focus {
    outline: none;
    border-color: var(--oa-green);
    box-shadow: 0 0 0 3px rgba(11, 178, 123, .14);
}

.oa-otp__box.is-filled { border-color: var(--oa-green-light); background: var(--brand-soft-weak, #f4fdf9); }

/*  The real, model-bound code field. Moved off-screen rather than hidden:
    FormValidation's field discovery skips `:hidden` inputs, and
    `display:none` / `visibility:hidden` would silently disable the rule that
    makes the code required. */
.oa-otp__value {
    position: absolute !important;
    left: -9999px;
    top: auto;
    width: 1px;
    height: 1px;
    opacity: 0;
}

/*  "Didn't receive the code?  ↻ Resend code"  /  "…  ◷ Resend in 0:42".
    A quiet text action, not a filled button: it is secondary to Verify & Continue.
    The label is rendered by renderResendState() (loginforgotpassScript.js). */
.oa-resend {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 4px 8px;
    margin: 0;
    font-size: 13px;
    color: var(--oa-muted);
}

.oa-resend__link {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    min-height: 30px;
    padding: 4px 12px;
    font: inherit;
    font-weight: 600;
    color: var(--oa-green-ink);
    background: var(--oa-mint-50);
    border: 1px solid var(--oa-mint-200);
    border-radius: 999px;
    cursor: pointer;
    transition: background-color .15s ease, border-color .15s ease, color .15s ease;
}

.oa-resend__link i { font-size: 11.5px; }

.oa-resend__link:hover:not(:disabled) {
    background: var(--oa-mint-100);
    border-color: var(--oa-mint-300);
}

.oa-resend__link:focus-visible {
    outline: 2px solid var(--oa-green);
    outline-offset: 2px;
}

.oa-resend__link:disabled,
.oa-resend__link.is-waiting {
    color: var(--oa-muted);
    background: transparent;
    border-color: var(--oa-border);
    cursor: default;
}

/* Sign In's code fields use the same row inside their .oa-help line. */
.oa-help.oa-resend { margin-top: 8px; }

.oa-resend__timer {
    font-weight: 700;
    color: var(--oa-ink);
    font-variant-numeric: tabular-nums;
}

/*  Verify step (Sign Up): each code block reads as one unit — contact, boxes, the
    validation message directly under the boxes, then resend — and the email and
    phone blocks are separated. FormValidation appends its message container at the
    end of .fv-row, hence the order values rather than moving markup. */
.auth-otp-block {
    display: flex;
    flex-direction: column;
}
.auth-otp-block > .oa-contact { order: 1; }
.auth-otp-block > .oa-otp { order: 2; margin-bottom: 0; }
.auth-otp-block > .fv-plugins-message-container { order: 3; margin-top: 8px; }
.auth-otp-block > .oa-resend { order: 4; margin-top: 12px; }
.auth-otp-block > .js-contact-update-panel { order: 5; margin-top: 12px; }

.auth-otp-block + .auth-otp-block {
    margin-top: 22px;
    padding-top: 22px;
    border-top: 1px solid var(--oa-border);
}

/* Invalid code: the boxes carry the error colour, not just the message. */
.auth-otp-block:has(> .fv-plugins-message-container:not(:empty)) .oa-otp__box:not(.is-filled) {
    border-color: var(--oa-danger);
}

/* --------------------------------------------------------------------------
   13. STATUS / COMPLETION SCREENS
   -------------------------------------------------------------------------- */

/*  Signup outcome (practitioner Under Review, patient Account Ready): illustration,
    title, lead, progress track, one explanatory line, actions. Centred column with a
    readable measure; the actions stack full-width on phones. */
.oa-outcome {
    display: flex;
    flex-direction: column;
    align-items: center;
    max-width: 560px;
    margin: 0 auto;
    padding: 8px 0 4px;
    text-align: center;
}

.oa-outcome__art { display: block; width: 168px; height: auto; margin: 0 auto 8px; }
.oa-art__halo { fill: var(--oa-mint-100); }
.oa-art__stem { fill: none; stroke: var(--oa-green); stroke-width: 2.5; stroke-linecap: round; }
.oa-art__leaf { fill: var(--oa-green); }
.oa-art__leaf--light { fill: var(--oa-green-light); }
.oa-art__paper { fill: var(--oa-white); stroke: var(--oa-ink); stroke-width: 3; stroke-linejoin: round; }
.oa-art__fold { fill: none; stroke: var(--oa-ink); stroke-width: 3; stroke-linejoin: round; }
.oa-art__line { fill: none; stroke: var(--oa-mint-400); stroke-width: 3.5; stroke-linecap: round; }
.oa-art__badge circle { fill: var(--oa-green); stroke: var(--oa-white); stroke-width: 3; }
.oa-art__badge path { fill: none; stroke: var(--brand-on-primary, #ffffff); stroke-width: 3.5; stroke-linecap: round; stroke-linejoin: round; }

.oa-outcome__title {
    margin: 0 0 6px;
    font-size: 24px;
    font-weight: 700;
    line-height: 1.25;
    color: var(--oa-ink);
}
.oa-outcome__lead { margin: 0; font-size: 14.5px; color: var(--oa-muted); }

.oa-outcome .oa-track {
    flex-wrap: nowrap;
    width: 100%;
    margin: 22px 0 18px;
    padding: 16px 12px;
    list-style: none;
    background: var(--oa-mint-50);
    border: 1px solid var(--oa-mint-200);
    border-radius: 16px;
}

.oa-outcome .oa-track__step { flex: 1 1 0; min-width: 0; }
.oa-outcome .oa-track__arrow { flex: 0 0 auto; margin-top: -30px; }
/* Metronic sizes and greys every <i>; the track glyphs follow their node instead. */
.oa-outcome .oa-track__node i,
.oa-outcome .oa-track__arrow i,
.oa-outcome__meta i { color: inherit; font-size: inherit; line-height: 1; }

/* Outstanding requirements on the "profile under review" screen. Requirement NAMES only:
   nothing here ever carries a document name or a storage location. */
.oa-outcome__list {
    max-width: 460px;
    margin: 0 0 14px;
    padding: 12px 14px;
    list-style: none;
    text-align: left;
    font-size: 14px;
    line-height: 1.6;
    color: var(--oa-ink-soft);
    background: var(--oa-surface);
    border: 1px solid var(--oa-border);
    border-radius: 12px;
}
.oa-outcome__list li { display: flex; align-items: flex-start; gap: 9px; }
.oa-outcome__list li + li { margin-top: 6px; }
.oa-outcome__list i { flex: 0 0 auto; margin-top: 3px; font-size: 12.5px; color: var(--oa-danger); }

.oa-outcome__note {
    max-width: 460px;
    margin: 0 0 14px;
    font-size: 14px;
    line-height: 1.6;
    color: var(--oa-ink-soft);
}

.oa-outcome__meta {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    margin: 0 0 6px;
    padding: 6px 12px;
    font-size: 12.5px;
    color: var(--oa-green-ink);
    background: var(--oa-mint-100);
    border-radius: 999px;
}
.oa-outcome__meta.is-pending { color: var(--oa-muted); background: var(--oa-surface); }
.oa-outcome__meta span { text-align: left; }

.oa-outcome__actions {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 12px;
    width: 100%;
    margin-top: 14px;
}
.oa-outcome__btn { min-width: 220px; justify-content: center; }

.oa-status { text-align: center; }

.oa-status__icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 84px;
    height: 84px;
    margin-bottom: 16px;
    border-radius: 50%;
    background: linear-gradient(135deg, var(--oa-green-light) 0%, var(--oa-green) 100%);
    color: var(--brand-on-primary, #ffffff);
    font-size: 38px;
    box-shadow: 0 10px 26px rgba(11, 178, 123, .26);
}

.oa-checklist {
    display: flex;
    flex-direction: column;
    gap: 14px;
    margin: 22px 0 0;
    padding: 0;
    list-style: none;
    text-align: left;
}

.oa-checklist__item { display: flex; align-items: flex-start; gap: 13px; }

.oa-checklist__tick {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 28px;
    height: 28px;
    border-radius: 50%;
    background: var(--oa-green);
    color: var(--brand-on-primary, #ffffff);
    font-size: 12px;
}

.oa-checklist__title { display: block; font-size: 14px; font-weight: 700; color: var(--oa-ink); line-height: 1.35; }
.oa-checklist__body  { display: block; font-size: 12.5px; color: var(--oa-muted); line-height: 1.4; }

/* Registered -> Verified -> Under Review. */
.oa-track {
    display: flex;
    align-items: flex-start;
    justify-content: center;
    gap: 6px;
    margin: 24px 0;
    flex-wrap: wrap;
}

.oa-track__step { flex: 0 1 150px; text-align: center; }

.oa-track__node {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 38px;
    height: 38px;
    margin-bottom: 8px;
    border-radius: 50%;
    background: var(--oa-green);
    color: var(--brand-on-primary, #ffffff);
    font-size: 14px;
}

.oa-track__step--current .oa-track__node {
    background: var(--oa-mint-200);
    color: var(--oa-green-ink);
    box-shadow: 0 0 0 4px rgba(11, 178, 123, .16);
}

.oa-track__title { display: block; font-size: 13px; font-weight: 700; color: var(--oa-ink); }
.oa-track__body  { display: block; font-size: 11.5px; color: var(--oa-muted); line-height: 1.4; }

.oa-track__arrow { align-self: center; margin-top: -22px; color: var(--oa-green-light); font-size: 14px; }

@media (max-width: 640px) {
    .oa-outcome__art { width: 150px; }
    .oa-outcome__title { font-size: 21px; }
    .oa-outcome .oa-track { padding: 14px 6px; }
    .oa-outcome .oa-track__arrow { display: none; }
    .oa-outcome__actions { flex-direction: column-reverse; }
    .oa-outcome__btn { width: 100%; min-width: 0; }
}

/* --------------------------------------------------------------------------
   14. MESSAGES / VALIDATION
   -------------------------------------------------------------------------- */

.oa-alert {
    display: flex;
    align-items: flex-start;
    gap: 11px;
    padding: 13px 15px;
    margin-bottom: 16px;
    border-radius: 11px;
    font-size: 13px;
    line-height: 1.5;
}

.oa-alert__icon { flex: 0 0 auto; font-size: 15px; line-height: 1.4; }
.oa-alert__title { display: block; font-weight: 700; margin-bottom: 2px; }

.oa-alert--info    { background: var(--oa-mint-100); color: var(--oa-ink-soft); border: 1px solid var(--oa-mint-300); }
.oa-alert--error   { background: var(--oa-danger-bg); color: var(--state-danger-ink, #9b2531); border: 1px solid var(--state-danger-soft, #f6c9ce); }
.oa-alert--warn    { background: var(--oa-warn-bg);   color: var(--state-warning-ink, #8a5f00); border: 1px solid var(--state-warning-soft, #f3dfa8); }
.oa-alert--success { background: var(--brand-soft, #e6f9f1); color: var(--oa-green-ink); border: 1px solid var(--oa-mint-300); }

/*  FormValidation and the unobtrusive validation helpers both write their
    messages into these. Styled together so a server-side error and a
    client-side one look identical. */
.oa-field .invalid-feedback,
.oa-field .field-validation-error,
.oa-field .fv-plugins-message-container,
.oa-field [data-valmsg-for] {
    display: block;
    margin-top: 5px;
    font-size: 11.5px;
    font-weight: 500;
    line-height: 1.35;
    color: var(--oa-danger);
}

.oa-field .field-validation-valid:empty { display: none; }

.oa-field.is-invalid .oa-input,
.oa-field.fv-plugins-bootstrap5-row-invalid .oa-input,
.oa-field.fv-plugins-bootstrap5-row-invalid .oa-phone,
.oa-field .oa-input.input-validation-error,
.oa-field .form-control.is-invalid,
.oa-field .form-control.input-validation-error {
    border-color: var(--oa-danger);
    box-shadow: 0 0 0 3px rgba(232, 67, 79, .10);
}

/* A checkbox row (terms) is a flex label; FormValidation puts its message
   inside it for checkboxes, so give the message its own full-width line. */
.oa-check { flex-wrap: wrap; }
.oa-check > span { flex: 1 1 0; min-width: 0; }
.oa-check > .fv-plugins-message-container { flex-basis: 100%; margin-top: 2px; }

/* The phone's inner input never shows its own error ring; the box does. */
.oa-field.fv-plugins-bootstrap5-row-invalid .oa-phone .oa-input { box-shadow: none; }

.oa-validation-summary { margin-bottom: 16px; }
.oa-validation-summary ul { margin: 0; padding-left: 18px; }

/* --------------------------------------------------------------------------
   15. WIZARD STEP VISIBILITY
   --------------------------------------------------------------------------
   KTStepper toggles `current` on the step content it is showing. Everything
   else stays in the DOM (so its fields keep posting) but is taken out of
   view. Matching what Metronic itself does, expressed here so the auth
   screens do not depend on a rule buried in the theme bundle.
   -------------------------------------------------------------------------- */

.oa-step-content { display: none; }
.oa-step-content[data-kt-stepper-element="content"].current { display: block; }
.oa-step-content.current { display: block; }

/*  Credential section swap on sign-in and forgot-password. Exactly one
    .form-section carries .active; showForm() in loginforgotpassScript.js
    owns that class. Declared here because osteo-auth.css is now the only
    stylesheet these screens rely on for layout. */
.form-section { display: none; }
.form-section.active { display: block; }

/*  #verficationProcess starts hidden and is revealed with jQuery .show(),
    which writes an inline display that beats this rule. Written as a rule
    rather than a `hidden` attribute so the reveal does not need to know to
    remove one. */
#verficationProcess { display: none; }

/* --------------------------------------------------------------------------
   16. RESPONSIVE
   -------------------------------------------------------------------------- */

@media (max-width: 1080px) {
    .oa-split { grid-template-columns: 200px minmax(0, 1fr); }
    .oa-aside { padding: 26px 16px 20px; }
    .oa-aside__title { font-size: 17px; }
}

@media (max-width: 900px) {
    .oa-shell { padding: 16px 14px 28px; }
    .oa-split { grid-template-columns: minmax(0, 1fr); }
    .oa-split > .oa-aside,
    .oa-split > .oa-panel,
    .oa-split > .oa-trust { grid-column: 1; grid-row: auto; }
    .oa-aside { padding: 22px 20px; }
    .oa-aside::after { width: 150px; height: 180px; left: -26px; bottom: -20px; }
    .oa-aside__script { display: none; }
    .oa-body { padding: 20px 18px 24px; }
    .oa-title { font-size: 25px; }
    .oa-grid { grid-template-columns: minmax(0, 1fr); }
    .oa-grid--3 { grid-template-columns: minmax(0, 1fr); }
    .oa-trust { grid-template-columns: minmax(0, 1fr); gap: 12px; }
}

@media (max-width: 640px) {
    /*  The header's own narrow-screen rules live with the component in
        section 4. They used to be duplicated here against the retired
        .oa-header class, and the stale `.oa-nav { gap: 18px }` was winning on
        source order — which pushed the nav 15px past the right edge on a
        414px phone. Removed; section 4 owns the top bar. */
    .oa-panel { padding: 20px 16px; }
    .oa-choices { grid-template-columns: minmax(0, 1fr); gap: 12px; }
    .oa-otp { gap: 7px; }
    .oa-otp__box { width: 42px; height: 48px; font-size: 18px; }
    .oa-actions { flex-direction: column-reverse; align-items: stretch; }
    .oa-actions .oa-btn { width: 100%; }
    .oa-title { font-size: 22px; }
    .oa-panel__title { font-size: 19px; }
    /* Below this width the six-step rail cannot show six readable labels, so
       it collapses to a scrollable row rather than shrinking to illegibility. */
    .oa-stepper {
        grid-auto-columns: minmax(84px, 1fr);
        overflow-x: auto;
        padding-bottom: 6px;
        scrollbar-width: thin;
    }
}

@media (max-width: 400px) {
    .oa-otp__box { width: 38px; height: 44px; font-size: 16px; }
}

/* --------------------------------------------------------------------------
   17. MOTION + PRINT
   -------------------------------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
    .oa-btn, .oa-choice, .oa-choice__tick, .oa-input, .oa-step__bubble { transition: none; }
}

@media print {
    .oa-leaf, .oa-aside::after, .oa-header { display: none; }
    .oa-frame { box-shadow: none; }
}

/* --------------------------------------------------------------------------
   18. PROVINCE MULTI-SELECT
   --------------------------------------------------------------------------
   Ported from auth-signup.css onto the --oa-* tokens so the auth screens no
   longer depend on that sheet. The class names are NOT ours to rename:
   province-multiselect.js creates .auth-chip / .auth-chip__remove and toggles
   .auth-multiselect--open and .auth-multiselect__summary--filled, and
   signupsettingcustom.js injects the option rows.
   -------------------------------------------------------------------------- */

.auth-multiselect { position: relative; }

.auth-multiselect__toggle {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    width: 100%;
    height: 48px;
    padding: 0 16px;
    font-family: var(--oa-font);
    font-size: 14px;
    text-align: left;
    color: var(--oa-ink);
    background: var(--oa-white);
    border: 1px solid var(--oa-border);
    border-radius: var(--oa-r-control);
    cursor: pointer;
    transition: border-color .15s ease, box-shadow .15s ease;
}

.auth-multiselect__toggle:hover { border-color: var(--oa-border-strong); }

.auth-multiselect__toggle:focus-visible,
.auth-multiselect--open .auth-multiselect__toggle {
    outline: none;
    border-color: var(--oa-green);
    box-shadow: 0 0 0 3px rgba(11, 178, 123, .13);
}

/* Placeholder until something is chosen, then normal text weight. */
.auth-multiselect__summary { color: var(--oa-muted-2); }
.auth-multiselect__summary--filled { color: var(--oa-ink); font-weight: 600; }

.auth-multiselect__chevron {
    flex: 0 0 auto;
    width: 0;
    height: 0;
    border-left: 5px solid transparent;
    border-right: 5px solid transparent;
    border-top: 6px solid var(--oa-ink);
    transition: transform .15s ease;
}

.auth-multiselect--open .auth-multiselect__chevron { transform: rotate(180deg); }

.auth-multiselect__panel {
    position: absolute;
    z-index: 20;
    top: calc(100% + 6px);
    left: 0;
    right: 0;
    max-height: 320px;
    overflow-y: auto;
    padding: 10px;
    background: var(--oa-white);
    border: 1px solid var(--oa-border);
    border-radius: 12px;
    box-shadow: 0 16px 36px rgba(17, 36, 90, .12);
}

.auth-multiselect__panel[hidden] { display: none; }

.auth-multiselect__search-wrap {
    position: sticky;
    top: -10px;
    margin: -10px -10px 10px;
    padding: 10px;
    background: var(--oa-white);
    border-bottom: 1px solid var(--oa-border);
}

.auth-multiselect__search {
    width: 100%;
    height: 40px;
    padding: 0 12px;
    font-family: var(--oa-font);
    font-size: 13px;
    color: var(--oa-ink);
    background: var(--oa-surface);
    border: 1px solid var(--oa-border);
    border-radius: 8px;
}

.auth-multiselect__search:focus {
    outline: none;
    border-color: var(--oa-green);
    box-shadow: 0 0 0 3px rgba(11, 178, 123, .13);
}

/*  Options grid. The injected wrappers carry Bootstrap column classes, which
    are neutralised here so this grid owns the layout.

    COLUMN COUNT IS MEASURED, NOT ASSUMED (Trello #34). This was
    repeat(2, minmax(0, 1fr)), i.e. always two columns. The widest province
    label, "Newfoundland and Labrador", is 189px at 13px/600, and a row is
    label + 16px box + 8px gap + 16px row padding = 229px. The panel is as wide
    as the control, so its content box is 380px on desktop and 236px at a 320px
    viewport: two 229px tracks never fit, at ANY breakpoint. Six of thirteen
    names wrapped onto two or three lines on a phone and four still wrapped at
    1280px. auto-fit lays out as many 190px tracks as genuinely fit and
    otherwise one, so names stay on one line instead. */
.auth-multiselect__options {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
    gap: 2px 10px;
    margin: 0;
}

/*  flex-start, not center: a label that does wrap (a longer localised name, a
    larger font) must keep its checkbox on the FIRST line. Centring put the box
    10px below the first line on a two-line name and 20px below on a
    three-line one. */
.auth-multiselect__options > * {
    width: 100% !important;
    max-width: none !important;
    flex: none !important;
    display: flex;
    align-items: flex-start;
    gap: 8px;
    padding: 6px 8px;
    border-radius: 8px;
    transition: background .15s ease;
}

.auth-multiselect__options > *:hover { background: var(--oa-mint-100); }
.auth-multiselect__options > *[hidden] { display: none !important; }

/*  Defensive: auth.min.css ships .setcheckpadding { padding-left: 3.25rem
    !important } and Bootstrap's .form-check adds another 2.25rem plus a float
    on the input. signupsettingcustom.js no longer emits either class, but a
    server-rendered or copy-pasted option row still might, and inside this grid
    that padding is what squeezed the labels. !important is required to answer
    !important. */
.auth-multiselect__options > .setcheckpadding,
.auth-multiselect__options > .form-check {
    padding-left: 8px !important;
    min-height: 0;
    margin-bottom: 0;
}

.auth-multiselect__options > * > .form-check-input {
    float: none;
}

/*  flex: 0 0 auto IS THE FIX FOR THE CRUSHED CHECKBOXES (Trello #34). The row
    is a flex container, so the box inherited flex-shrink: 1 and width: 16px was
    only a starting size. Measured before: boxes rendered at 2, 7, 8, 9, 10, 12,
    13, 14, 15, 17, 18 and 20px in the same list - the "Prince Edward Island"
    box was 2px wide at 320px, which is what read as a cut-off checkbox.
    margin-top centres the 16px box in the label's 19.5px first line box
    ((19.5 - 16) / 2 = 1.75px) now that the row aligns to flex-start. */
.auth-multiselect__options input[type="checkbox"] {
    flex: 0 0 auto;
    width: 16px;
    height: 16px;
    min-width: 16px;
    margin: 2px 0 0;
    accent-color: var(--oa-green);
    cursor: pointer;
}

/*  min-width: 0 lets the label shrink to its grid track instead of spilling out
    of it - without it "Saskatchewan" overhung the panel's right edge by 32px at
    320px and 12px at 360px. overflow-wrap is the backstop for a name with no
    break opportunity at all. */
.auth-multiselect__options .check-label,
.auth-multiselect__options .form-check-label {
    min-width: 0;
    margin: 0;
    font-size: 13px;
    line-height: 1.5;
    font-weight: 500;
    color: var(--oa-ink);
    overflow-wrap: break-word;
    cursor: pointer;
}

.auth-multiselect__empty {
    margin: 10px 0 0;
    padding: 0 8px;
    font-size: 13px;
    color: var(--oa-muted);
}

.auth-multiselect__chips { display: flex; flex-wrap: wrap; gap: 6px; }
.auth-multiselect__chips:not(:empty) { margin-top: 10px; }

.auth-chip {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    padding: 4px 6px 4px 10px;
    font-size: 12.5px;
    font-weight: 600;
    color: var(--oa-green-ink);
    background: var(--oa-mint-200);
    border-radius: var(--oa-r-pill);
}

.auth-chip__remove {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 18px;
    height: 18px;
    padding: 0;
    border: 0;
    border-radius: 50%;
    background: transparent;
    color: var(--oa-green-ink);
    font-size: 15px;
    line-height: 1;
    cursor: pointer;
}

.auth-chip__remove:hover { background: rgba(11, 178, 123, .18); }

/* --------------------------------------------------------------------------
   19. FAMILY MEMBER CARDS
   -------------------------------------------------------------------------- */

.oa-member-card,
.rowslist {
    position: relative;
    padding: 18px;
    margin-bottom: 14px;
    border: 1px solid var(--oa-border);
    border-radius: 12px;
    background: var(--oa-surface);
}

/* The remove control is appended by $.SignUP.AddFamiliMembers. */
.removemembers {
    position: absolute;
    top: 10px;
    right: 10px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 30px;
    height: 30px;
    border: 0;
    border-radius: 50%;
    background: var(--oa-danger-bg);
    color: var(--oa-danger);
    cursor: pointer;
}

.oa-addcard {
    display: flex;
    align-items: center;
    gap: 14px;
    width: 100%;
    padding: 16px 18px;
    margin-bottom: 16px;
    text-align: left;
    border: 1.5px dashed var(--oa-border-strong);
    border-radius: 12px;
    background: var(--oa-surface);
    cursor: pointer;
    transition: border-color .15s ease, background .15s ease;
}

.oa-addcard:hover { border-color: var(--oa-green); background: var(--oa-mint-50); }

.oa-addcard__icon {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 40px;
    height: 40px;
    border-radius: 50%;
    background: var(--oa-mint-200);
    color: var(--oa-green-ink);
    font-size: 15px;
}

.oa-addcard__title { display: block; font-size: 14px; font-weight: 700; color: var(--oa-ink); }
.oa-addcard__meta  { display: block; font-size: 12px; color: var(--oa-muted); }

/* --------------------------------------------------------------------------
   20. STEP-BOUND BLOCKS OUTSIDE THE PANEL
   --------------------------------------------------------------------------
   The reassurance strip only appears on step 1 in the reference. It reuses
   the [data-step-pane] contract create-account.js already drives for the
   aside, so no new JS is needed to show and hide it.
   -------------------------------------------------------------------------- */

.oa-trust[data-step-pane] { display: none; }
.oa-trust[data-step-pane].is-current { display: grid; }

@media (max-width: 900px) {
    .oa-trust[data-step-pane].is-current { grid-template-columns: minmax(0, 1fr); }
}

/* --------------------------------------------------------------------------
   20b. NOTIFICATION PERMISSION PROMPT
   --------------------------------------------------------------------------
   CustomStyle.css opens this with `section.active .modal-box` / `.overlay`,
   but that sheet is not loaded on the auth screens, which left the prompt
   with no closed state at all. Stated here so it is shut unless something
   adds .active, and so it never paints over the sign-in card.
   -------------------------------------------------------------------------- */

section.noti { position: fixed; inset: 0; z-index: 1050; pointer-events: none; }
/*  Closed, it must not cover the page at all: a full-viewport fixed layer
    swallows wheel and touch events in some engines even with
    pointer-events:none, which would look exactly like "the page won't
    scroll". Collapsed to nothing until something opens it. */
section.noti:not(.active) { inset: auto; width: 0; height: 0; overflow: hidden; }
section.noti .overlay { position: fixed; inset: 0; background: rgba(12, 25, 55, .35); opacity: 0; pointer-events: none; transition: opacity .2s ease; }
section.noti .modal-box {
    position: fixed;
    left: 50%;
    top: 34%;
    transform: translate(-50%, -50%) scale(.96);
    max-width: 420px;
    width: calc(100% - 32px);
    padding: 4px 14px;
    border-radius: 12px;
    background: var(--oa-white);
    box-shadow: 0 24px 60px rgba(17, 36, 90, .22);
    opacity: 0;
    pointer-events: none;
    transition: opacity .2s ease, transform .2s ease;
}
section.noti.active { pointer-events: auto; }
section.noti.active .overlay { opacity: 1; pointer-events: auto; }
section.noti.active .modal-box { opacity: 1; pointer-events: auto; transform: translate(-50%, -50%) scale(1); }

/* --------------------------------------------------------------------------
   21. DROPZONE + SELECT2 BRIDGES
   --------------------------------------------------------------------------
   Two third-party widgets render their own chrome inside our fields. These
   rules bring them into the design rather than leaving them looking like a
   different product.
   -------------------------------------------------------------------------- */

.oa-drop.dz-drag-hover { border-color: var(--oa-green); background: var(--oa-mint-50); }
.oa-drop .dz-message { margin: 0; display: flex; flex-direction: column; align-items: center; gap: 6px; }

.select2-container--bootstrap5 .select2-selection,
.oa-field .select2-container .select2-selection--single {
    height: 48px !important;
    padding: 0 16px !important;
    display: flex !important;
    align-items: center;
    border: 1px solid var(--oa-border) !important;
    border-radius: var(--oa-r-control) !important;
    background: var(--oa-white) !important;
    font-family: var(--oa-font);
    font-size: 14px;
    color: var(--oa-ink);
}

.select2-container--bootstrap5.select2-container--focus .select2-selection,
.select2-container--bootstrap5.select2-container--open .select2-selection {
    border-color: var(--oa-green) !important;
    box-shadow: 0 0 0 3px rgba(11, 178, 123, .13) !important;
}

/* --------------------------------------------------------------------------
   22. SPLIT LAYOUT  (sign in / forgot password / reset password)
   --------------------------------------------------------------------------
   The reference for these three screens is a full-bleed two-panel split: a
   pale form side carrying one raised white card, and a mint hero. The shared
   top bar floats across both.

   `min-height`, never `height`. The page is sized to fit the viewport by
   shrinking its contents (section 27), not by clipping them — so on the rare
   viewport where the content genuinely cannot fit (a very short window, a
   large browser zoom, a stack of validation errors) the page still scrolls
   and nothing becomes unreachable.

   _AuthLayout renders this when ViewData["OaLayout"] == "split".
   -------------------------------------------------------------------------- */

.oa-page {
    position: relative;
    display: grid;
    /* 56/44, as measured off the reference — the form side carries more. */
    grid-template-columns: minmax(0, 1.27fr) minmax(0, 1fr);
    min-height: 100vh;
    min-height: 100dvh;              /* dvh where supported: mobile URL bar */
    font-family: var(--oa-font);
    background: var(--oa-page-bg, #f4f7fc);
}

/* Left: the form side. Centred, with room for the overlaid bar above it. */
.oa-pane {
    display: flex;
    /*  flex-start + auto margins on the child, rather than align-items:center.
        Centred content that overflows a scroll container is clipped at the
        TOP and can never be scrolled to; auto margins centre when there is
        room and collapse to zero when there is not. */
    align-items: flex-start;
    justify-content: center;
    min-width: 0;
    padding: var(--oa-topbar-h) var(--oa-card-px) var(--oa-gap-sm);
    box-sizing: border-box;
    background:
        radial-gradient(760px 420px at 20% 0%, var(--bg-surface, #ffffff) 0%, rgba(255, 255, 255, 0) 70%),
        linear-gradient(160deg, var(--bg-surface-hover, #f6f8fd) 0%, var(--state-info-soft, #eff3fa) 100%);
}

.oa-pane > * { margin-top: auto; margin-bottom: auto; }

/* --------------------------------------------------------------------------
   23. AUTH CARD  (the white card on the form side)
   -------------------------------------------------------------------------- */

.oa-authcard {
    width: 100%;
    max-width: 520px;
    padding: var(--oa-card-py) var(--oa-card-px);
    box-sizing: border-box;
    background: var(--oa-white);
    border-radius: 24px;
    box-shadow: 0 30px 70px rgba(17, 36, 90, .10), 0 2px 6px rgba(17, 36, 90, .04);
}

.oa-eyebrow {
    display: block;
    margin: 0 0 var(--oa-gap-xs);
    font-size: var(--oa-fs-eyebrow);
    font-weight: 700;
    letter-spacing: 3px;
    line-height: 1;
    text-transform: uppercase;
    color: var(--state-info-ink, #52618f);
}

.oa-authcard__title {
    margin: 0 0 6px;
    font-size: var(--oa-fs-title);
    font-weight: 700;
    line-height: 1.1;
    letter-spacing: -.8px;
    color: var(--oa-ink-900);
}

.oa-authcard__subtitle {
    margin: 0 0 var(--oa-gap-md);
    font-size: var(--oa-fs-sub);
    font-weight: 400;
    line-height: 1.45;
    color: var(--text-secondary, #5d6b91);
}

.oa-section__title {
    margin: 0 0 2px;
    font-size: var(--oa-fs-h2);
    font-weight: 700;
    line-height: 1.3;
    color: var(--oa-ink-900);
}

.oa-section__hint {
    margin: 0 0 var(--oa-gap-sm);
    font-size: var(--oa-fs-body);
    font-weight: 400;
    line-height: 1.4;
    color: var(--text-secondary, #6a7899);
}

/*  Roomier account-type cards than the wizard's: the reference gives these a
    circled icon and a two-line description. */
.oa-choice--roomy {
    padding: var(--oa-choice-py) 16px calc(var(--oa-choice-py) - 2px);
    border-radius: 16px;
    gap: 3px;
}

.oa-choice--roomy .oa-choice__icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: var(--oa-choice-icon);
    height: var(--oa-choice-icon);
    margin-bottom: var(--oa-gap-xs);
    border-radius: 50%;
    background: var(--bg-surface-hover, #f5f8fd);
    color: var(--oa-ink-900);
}

/* The glyph keeps a constant ratio to the disc it sits in. */
.oa-choice--roomy .oa-choice__icon svg {
    width: calc(var(--oa-choice-icon) * .57);
    height: calc(var(--oa-choice-icon) * .57);
}

.oa-choice--roomy.is-selected .oa-choice__icon,
.oa-choice--roomy.active .oa-choice__icon,
.type-option:has(> .oa-choice__input:checked) > .oa-choice--roomy .oa-choice__icon { background: var(--bg-surface, #ffffff); }

.oa-choice--roomy .oa-choice__title { font-size: var(--oa-fs-label); }
.oa-choice--roomy .oa-choice__desc { font-size: var(--oa-fs-body); line-height: 1.4; }

/*  Unselected cards show an empty ring where the tick will land, so the
    control reads as a choice before anything is picked. */
.oa-choice--roomy .oa-choice__tick {
    top: 14px;
    right: 14px;
    width: 24px;
    height: 24px;
    opacity: 1;
    transform: none;
    background: transparent;
    border: 2px solid var(--border-default, #e2e7f2);
    color: transparent;
    font-size: 11px;
}

.oa-choice--roomy.is-selected .oa-choice__tick,
.oa-choice--roomy.active .oa-choice__tick,
.oa-choice--roomy:has(.oa-choice__input:checked) .oa-choice__tick,
.type-option:has(> .oa-choice__input:checked) > .oa-choice--roomy .oa-choice__tick {
    background: var(--oa-green);
    border-color: var(--oa-green);
    color: var(--brand-on-primary, #ffffff);
}

.oa-authcard .oa-choices { gap: 14px; margin-bottom: var(--oa-gap-sm); }
.oa-authcard .oa-field { margin-bottom: var(--oa-gap-sm); }

/* Controls and buttons share one height token, so they always line up. */
.oa-authcard .oa-input,
.oa-authcard .oa-control .form-control,
.oa-authcard .oa-phone { height: var(--oa-ctl-h); border-radius: 12px; }
.oa-authcard .oa-phone .oa-input { height: 100%; border-radius: 0 12px 12px 0; }

.oa-authcard textarea.oa-input { height: auto; }

.oa-authcard .oa-control__glyph { left: 18px; font-size: 17px; }
.oa-authcard .oa-control--icon .oa-input,
.oa-authcard .oa-control--icon .form-control { padding-left: 48px; }

.oa-authcard .oa-btn {
    height: var(--oa-ctl-h);
    border-radius: 12px;
    font-size: var(--oa-fs-label);
}

.oa-authcard .oa-label { font-size: var(--oa-fs-label); margin-bottom: 6px; }
.oa-authcard .oa-meter { margin-top: 7px; }
.oa-authcard .oa-help { font-size: calc(var(--oa-fs-body) - 1.5px); }

/* Stacked full-width actions: primary, then the quiet escape hatch. */
.oa-stack { display: flex; flex-direction: column; gap: 10px; margin-top: 2px; }

/* "———— Back to Login ————" */
.oa-divider-link {
    display: flex;
    align-items: center;
    gap: 16px;
    margin: var(--oa-gap-sm) 0 0;
    font-size: var(--oa-fs-body);
    font-weight: 600;
    color: var(--text-secondary, #5d6b91);
}

.oa-divider-link::before,
.oa-divider-link::after {
    content: "";
    flex: 1 1 auto;
    height: 1px;
    background: var(--oa-border);
}

.oa-divider-link a { color: var(--oa-green-ink); text-decoration: none; font-weight: 700; }
.oa-divider-link a:hover { text-decoration: underline; }

/*  Remember me / Forgot password. */
.oa-authcard .oa-inline-row { margin: 0 0 var(--oa-gap-sm); }

/*  Sign In renders two cards — the credentials card and the verification card
    that replaces it — so the pane's single centred child is this stack. */
.oa-pane__stack {
    display: flex;
    flex-direction: column;
    gap: 20px;
    width: 100%;
    max-width: 520px;
}

.oa-pane__stack > .oa-authcard { max-width: none; }

/* --------------------------------------------------------------------------
   24. HERO PANEL
   --------------------------------------------------------------------------
   A flex column whose illustration is the flexible item. Everything else —
   heading, copy, value props, keyword strip — has a size it needs; the art is
   the one element happy to be any height, so it absorbs whatever space is
   left. That is what lets the panel fill a 1080px screen and still fit a
   768px one without a media query per breakpoint.
   -------------------------------------------------------------------------- */

.oa-hero {
    position: relative;
    overflow: hidden;
    display: flex;
    align-items: stretch;
    min-width: 0;
    padding: var(--oa-topbar-h) var(--oa-card-px) var(--oa-gap-lg);
    box-sizing: border-box;
    color: var(--oa-ink-900);
    /*  Sampled from the supplied illustration's own ground — #00E6C1 at the
        left, a #52EDCE wash top-right — so the artwork sits in the panel
        without a visible rectangle. Change the image, re-sample these. */
    /*  Kept deliberately close to flat. Behind the figure the image is fully
        opaque, so any tone the panel has there that the image's ground does
        not have shows up as the image's rectangle. The measured ground runs
        #00E6C1 -> #06D9AD -> #00E1B9; the panel sits on the same line, and the
        only variation is a faint wash near the panel's own corners, well away
        from where the image is opaque. */
    background:
        radial-gradient(420px 320px at 100% 0%, rgba(255, 255, 255, .16) 0%, rgba(255, 255, 255, 0) 70%),
        radial-gradient(380px 300px at 0% 100%, rgba(255, 255, 255, .10) 0%, rgba(255, 255, 255, 0) 70%),
        linear-gradient(170deg, var(--primary, #02e2bd) 0%, var(--primary, #04e2be) 55%, #0ee5c2 100%);
}

/* The two soft discs the reference floats behind the content. */
.oa-hero::before,
.oa-hero::after {
    content: "";
    position: absolute;
    border-radius: 50%;
    background: rgba(255, 255, 255, .13);
    pointer-events: none;
}

.oa-hero::before { width: 380px; height: 380px; top: -170px; right: -170px; }
.oa-hero::after  { width: 300px; height: 300px; bottom: -190px; right: 8%; background: rgba(255, 255, 255, .08); }

.oa-hero__inner {
    position: relative;
    z-index: 1;
    display: flex;
    flex-direction: column;
    justify-content: center;
    width: 100%;
    max-width: 560px;
    margin: 0 auto;
}

.oa-hero__title {
    margin: 0 0 10px;
    font-size: var(--oa-fs-hero-title);
    font-weight: 700;
    line-height: 1.15;
    letter-spacing: -.8px;
    color: var(--oa-ink-900);
}

.oa-hero__body {
    margin: 0;
    max-width: 30em;
    font-size: var(--oa-fs-sub);
    font-weight: 400;
    line-height: 1.5;
    color: var(--text-body, #1d3352);
}

/*  The flexible item. min-height:0 is required — without it a flex item will
    not shrink below its content's intrinsic size and the art would push the
    value props off the bottom. */
.oa-hero__art {
    flex: 1 1 auto;
    min-height: 0;
    /* Negative inline margin: the asset's outer ~15% on each side is the
       transparent fade, so the box may run into the panel's padding without
       anything visible touching the edge. Keeps the figure at full size. */
    margin: 0 -13%;
    display: flex;
    align-items: center;
    justify-content: center;
}

.oa-hero__art picture { display: contents; }

.oa-hero__art img {
    display: block;
    width: 100%;
    height: 100%;
    max-width: none;
    /* contain, not cover: the whole figure is always visible, and the image
       shrinks with the space the flex column gives it. The soft edge is baked
       into the asset's alpha (see _AuthHero), so no CSS mask is needed. */
    object-fit: contain;
}

.oa-hero__props {
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    margin: 0 0 var(--oa-gap-md);
    padding: 0;
    list-style: none;
    flex: 0 0 auto;
}

.oa-hero__prop {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 8px;
    padding: 0 8px;
    text-align: center;
}

/* Hairlines between the four, not around them. */
.oa-hero__prop + .oa-hero__prop { border-left: 1px solid rgba(16, 26, 60, .14); }

.oa-hero__prop-icon { display: block; width: 28px; height: 28px; color: var(--oa-ink-900); }
.oa-hero__prop-icon svg { width: 100%; height: 100%; display: block; }

.oa-hero__prop-label {
    font-size: var(--oa-fs-body);
    font-weight: 500;
    line-height: 1.3;
    color: var(--oa-ink-900);
}

.oa-hero__strip {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 12px;
    margin: 0;
    flex: 0 0 auto;
    font-size: 11.5px;
    font-weight: 500;
    letter-spacing: 2.2px;
    text-transform: uppercase;
    color: rgba(16, 26, 60, .62);
}

.oa-hero__strip > span:not(.oa-hero__rule) { white-space: nowrap; }
.oa-hero__strip i { font-style: normal; color: rgba(16, 26, 60, .34); }
.oa-hero__rule { flex: 0 0 42px; height: 1px; background: rgba(16, 26, 60, .28); }

/* --------------------------------------------------------------------------
   25. WIZARD SHELL — FIT TO VIEWPORT
   --------------------------------------------------------------------------
   Sign Up's step 4 (Qualification) is a twelve-field form; no type ramp makes
   that fit a 768px laptop, and shrinking it until it did would make it
   unusable. So the wizard becomes a fixed-height shell instead: the frame is
   capped to the viewport, the heading, the stepper rail, the aside and the
   reassurance strip stay put, and the step's own panel is the scroll region.

   That is a layout decision, not a hidden scrollbar — the long form is still
   fully reachable, and the page around it never moves.
   -------------------------------------------------------------------------- */

.oa-shell > .oa-topbar {
    max-width: 1180px;
    padding-left: 6px;
    padding-right: 6px;
    padding-bottom: var(--oa-gap-sm);
    flex: 0 0 auto;
}

.oa-frame { display: flex; flex-direction: column; min-height: 0; }
.oa-body  { display: flex; flex-direction: column; min-height: 0; flex: 1 1 auto; }

/* KTStepper's root sits between .oa-body and .oa-split on Sign Up. */
.oa-body > .stepper { display: flex; flex-direction: column; min-height: 0; flex: 1 1 auto; }

.oa-head    { flex: 0 0 auto; }
.oa-stepper { flex: 0 0 auto; }

.oa-split {
    flex: 1 1 auto;
    min-height: 0;
    grid-template-rows: minmax(0, 1fr) auto;
}

.oa-aside { overflow: hidden; }

/*  The scroll region. Padding-right leaves the scrollbar its own gutter so
    the form fields do not shift when it appears. */
.oa-split > .oa-panel {
    min-height: 0;
    overflow-y: auto;
    overscroll-behavior: contain;
    scrollbar-width: thin;
}

/* --------------------------------------------------------------------------
   26. RESPONSIVE — STACKED (phones and small tablets)
   --------------------------------------------------------------------------
   Below the breakpoint the split stacks: form first, because that is what the
   visitor came to do, then the hero as a shorter marketing block. Nothing is
   height-locked here — a phone scrolls, which is correct and expected.
   -------------------------------------------------------------------------- */

@media (max-width: 1320px) {
    /* The four-word strip stops fitting on one line before the panel does. */
    .oa-hero__strip { font-size: 10.5px; letter-spacing: 1.6px; gap: 9px; }
    .oa-hero__rule { flex-basis: 28px; }
}

@media (max-width: 991.98px) {
    .oa-page { grid-template-columns: minmax(0, 1fr); min-height: 0; }
    .oa-pane { padding: calc(var(--oa-topbar-h) + 16px) 20px 36px; }

    .oa-hero { padding: 36px 24px 32px; align-items: flex-start; }
    .oa-hero__inner { max-width: 640px; }
    /* Decoration goes first: on a phone it would push the value props a whole
       screen further down. */
    .oa-hero__art { display: none; }
    .oa-hero__title { font-size: 26px; }
    .oa-hero__props { gap: 18px 0; }

    /*  The frame shell releases its height cap so the page flows again.
        .oa-shell keeps its flex centring; only the descendants that were
        turned into a fixed-height column go back to normal flow. */
    .oa-frame { max-height: none; }
    .oa-body,
    .oa-body > .stepper { display: block; min-height: 0; flex: none; }
    .oa-split { min-height: 0; grid-template-rows: auto auto; }
    .oa-split > .oa-panel { min-height: 0; overflow: visible; }
}

@media (max-width: 680px) {
    .oa-authcard { border-radius: 18px; }
    .oa-hero__props { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    /* With two per row the vertical hairline lands in the wrong places. */
    .oa-hero__prop + .oa-hero__prop { border-left: 0; }
    .oa-hero__prop:nth-child(2n) { border-left: 1px solid rgba(16, 26, 60, .14); }
    .oa-hero__strip { flex-wrap: wrap; gap: 8px; font-size: 10.5px; letter-spacing: 1.6px; }
    .oa-hero__rule { display: none; }
}

/* --------------------------------------------------------------------------
   27. DESKTOP — THE HEIGHT-DRIVEN SCALE
   --------------------------------------------------------------------------
   This is the block that makes the pages fit. Every token from section 1 is
   re-declared as clamp(min, <vh>, max): the max is the full-size design a
   1080px screen gets, the min is the tightest the design still reads well at,
   and between them the whole page scales with the window's height.

   Gated on BOTH axes. Width, because below 992px the layout stacks and should
   flow rather than compress. Height, because under ~560px there is nothing
   sensible left to shrink and the page is better off scrolling.

   To retune the fit, change the numbers here — not the component rules.
   -------------------------------------------------------------------------- */

@media (min-width: 992px) and (min-height: 560px) {
    :root {
        --oa-topbar-py:      clamp(8px,  1.5vh, 20px);
        --oa-topbar-h:       calc(var(--oa-topbar-py) * 2 + 38px);
        --oa-shell-pad-y:    clamp(10px, 2vh, 28px);

        --oa-gap-xs:         clamp(3px,  .7vh,  10px);
        --oa-gap-sm:         clamp(6px,  1.25vh, 16px);
        --oa-gap-md:         clamp(8px,  1.8vh, 24px);
        --oa-gap-lg:         clamp(12px, 2.6vh, 34px);

        --oa-ctl-h:          clamp(40px, 5.2vh, 52px);
        --oa-card-py:        clamp(16px, 3.2vh, 40px);
        --oa-card-px:        clamp(26px, 2.8vw, 48px);
        --oa-choice-py:      clamp(10px, 2vh,   22px);
        --oa-choice-icon:    clamp(36px, 6.4vh, 68px);

        --oa-fs-eyebrow:     clamp(10px,   1.25vh, 12px);
        --oa-fs-title:       clamp(22px,   3.5vh,  36px);
        --oa-fs-sub:         clamp(12.5px, 1.6vh,  15.5px);
        --oa-fs-h2:          clamp(15px,   1.95vh, 18px);
        --oa-fs-body:        clamp(12px,   1.55vh, 14.5px);
        --oa-fs-label:       clamp(13px,   1.6vh,  15px);
        --oa-fs-hero-title:  clamp(24px,   3.7vh,  38px);
    }

    /*  THE SPLIT PAGE GETS A DEFINITE HEIGHT.

        This is the fix for the scrollbar reported on a 1350x630 window. With
        only min-height, the grid row sized itself to its tallest child — and
        the hero's tallest child was the illustration at its natural,
        width-driven height. So the art never shrank, the row grew past the
        window, and the page scrolled. A definite height gives the hero's flex
        column a size to divide up, and the art (flex: 1 1 auto; min-height: 0)
        takes only what is left after the heading, copy and value props.

        Each column then owns its own overflow: the hero clips (it is
        decoration), and the form pane scrolls internally in the rare case the
        card cannot fit — so nothing is ever unreachable, and the page itself
        never scrolls. */
    .oa-page {
        height: 100vh;
        height: 100dvh;
        min-height: 0;
        grid-template-rows: minmax(0, 1fr);
        overflow: hidden;
    }

    .oa-pane {
        min-height: 0;
        overflow-y: auto;
        overscroll-behavior: contain;
        scrollbar-width: thin;
    }

    .oa-hero        { min-height: 0; }
    .oa-hero__inner { height: 100%; min-height: 0; }

    /*  The wizard frame is capped to what is left of the viewport after the
        shell's padding and the top bar. Expressed in dvh so the cap is always
        a definite length, which is what lets .oa-panel below it become a
        scroll container at all. */
    .oa-shell {
        padding-top: var(--oa-shell-pad-y);
        padding-bottom: var(--oa-shell-pad-y);
    }

    .oa-frame {
        max-height: calc(100dvh - (var(--oa-shell-pad-y) * 2)
                                - var(--oa-topbar-h)
                                - var(--oa-gap-sm));
    }

    /*  Wizard type also rides the scale. */
    .oa-title    { font-size: var(--oa-fs-title); }
    .oa-title--sm{ font-size: calc(var(--oa-fs-title) * .78); }
    .oa-subtitle { font-size: var(--oa-fs-sub); }
    .oa-head     { margin-bottom: var(--oa-gap-sm); }

    .oa-body     { padding: var(--oa-gap-md) var(--oa-gap-lg) var(--oa-gap-md); }
    .oa-stepper  { margin-bottom: var(--oa-gap-md); }
    .oa-stepper .step-icon-wrapper { width: clamp(30px, 4vh, 36px); height: clamp(30px, 4vh, 36px); }
    .oa-stepper .stepper-item::before { top: calc(clamp(30px, 4vh, 36px) / 2 - 1px); }
    .oa-stepper .step-icon  { font-size: clamp(12px, 1.5vh, 14px); }
    .oa-stepper .step-label { font-size: clamp(10px, 1.25vh, 11.5px); margin-top: 6px; }

    .oa-panel        { padding: var(--oa-gap-md) var(--oa-gap-lg); }
    .oa-panel__title { font-size: calc(var(--oa-fs-title) * .62); }
    .oa-panel__subtitle { font-size: var(--oa-fs-body); margin-bottom: var(--oa-gap-sm); }
    .oa-aside        { padding: var(--oa-gap-lg) var(--oa-gap-sm) var(--oa-gap-md); }
    .oa-aside__icon  { width: clamp(46px, 7vh, 72px); height: clamp(46px, 7vh, 72px); margin-bottom: var(--oa-gap-sm); }
    .oa-aside__icon svg { width: 100%; height: 100%; }
    .oa-aside__title { font-size: var(--oa-fs-h2); margin-bottom: var(--oa-gap-xs); }
    .oa-aside__body  { font-size: calc(var(--oa-fs-body) - 1px); }
    .oa-aside__script{ font-size: clamp(17px, 2.6vh, 24px); padding-top: var(--oa-gap-sm); }

    .oa-field  { margin-bottom: var(--oa-gap-sm); }
    .oa-actions{ padding-top: var(--oa-gap-sm); }
    .oa-trust  { margin-top: var(--oa-gap-sm); }
}

/*  Short-but-wide desktop windows — a 1024x640 or 1280x680 browser, or a
    maximised window on a 16:10 panel with a deep bookmarks bar. Everything in
    the scale is already at its clamp minimum here, so the last few pixels
    come from tightening leading rather than shrinking type any further:
    dropping type below the minimums would start to hurt legibility, and the
    account-type descriptions are the only multi-line copy on the card. */
@media (min-width: 992px) and (max-height: 700px) {
    .oa-choice--roomy .oa-choice__desc { line-height: 1.28; }
    .oa-authcard__subtitle { line-height: 1.35; }
}

/*  Very short desktop windows (a 1366x600 window, or heavy browser zoom).
    Everything is already at its clamp minimum, so the only honest thing left
    is to let the page scroll. Stated explicitly rather than left to chance. */
@media (min-width: 992px) and (max-height: 559.98px) {
    .oa-page  { height: auto; min-height: 100vh; overflow: visible; }
    .oa-pane  { overflow: visible; }
    .oa-frame { max-height: none; }
    .oa-split > .oa-panel { overflow: visible; }
}

/* --------------------------------------------------------------------------
   18. NARROW-SCREEN FIXES  (Trello #32, #33, #34)
   --------------------------------------------------------------------------
   Appended last on purpose: every rule below overrides a component earlier in
   this sheet, and osteo-auth.css is itself loaded after auth.min.css by
   _AuthLayout, so this is the last word on the auth screens.
   -------------------------------------------------------------------------- */

/* ---- #32  reCAPTCHA on sign up (mobile) ---------------------------------
   Google injects a FIXED 304x78 iframe inside a fixed-width wrapper, and this
   sheet had no rule for it at all. The panel's content box on a phone is
   viewport - 32px of padding, so anything under 336px wide could not hold the
   widget: it ran past the panel's right edge, the "I'm not a robot" checkbox
   sat half off-screen, and the page grew a horizontal scrollbar.

   SCALED, NOT STRETCHED. The iframe's contents are laid out by Google at 304px
   and an iframe cannot be reflowed from the outside, so the only honest options
   are to scale the box or to let it overflow. transform does not change the
   layout box, which is why each step also sets the height the scaled widget
   actually occupies - otherwise the Continue button below rides up into it. */
.g-recaptcha { max-width: 100%; }
.g-recaptcha > div { max-width: 100%; }

@media (max-width: 400px) {
    .g-recaptcha {
        transform: scale(.88);
        transform-origin: 0 0;
        height: 69px;  /* 78 * .88 */
    }
}

@media (max-width: 344px) {
    .g-recaptcha {
        transform: scale(.78);
        height: 61px;  /* 78 * .78 */
    }
}

/* ---- #33  Verify email / phone step ------------------------------------
   THE ADDRESS IS ONE LONG UNBREAKABLE WORD. .oa-contact__text already had
   min-width:0 so its column was ALLOWED to shrink, but nothing told the
   address it may break - so on a phone "somebody.long@example.com" ran out of
   its column, over the Edit link and off the panel's right edge. The label,
   help line and value all get the same treatment; only the value could
   realistically be a single long token, but a pasted address can land in any
   of them. */
.oa-contact__text,
.oa-contact__value,
.oa-contact__text .oa-help { overflow-wrap: anywhere; }

@media (max-width: 480px) {
    /* Edit moves to the TOP of the row rather than being vertically centred
       against a two-line address, and the text column is free to shrink because
       the address can now wrap. Deliberately NOT flex-wrap: wrap - tried, and
       it drops Edit onto a line of its own below the help text, where it reads
       as orphaned. Keeping all three in one row with the link aligned to the
       label is what the desktop layout looks like, just narrower. */
    .oa-contact {
        align-items: flex-start;
        gap: 10px;
    }

    .oa-contact__edit { padding-top: 2px; }

    /* 52px of circle is a lot of a 328px row. */
    .oa-contact__icon { width: 42px; height: 42px; font-size: 18px; }
    .oa-contact__value:not(:empty) { font-size: 15px; }

    /* The resend row is prompt + button; on a narrow screen it wraps rather
       than pushing the button out of the panel. */
    .oa-resend { flex-wrap: wrap; }
}

/* ---- #34  Provinces willing to travel (multi-select) --------------------
   Two defects, both only visible on a narrow screen.

   1. THE PANEL WAS ABSOLUTELY POSITIONED AND COULD BE CLIPPED. A 320px-tall
      overlay hung below a control that sits low in a long scrolling step, so
      on a phone it was cut off by the step's own box and the list could not be
      reached. Below 640px the panel is laid out IN FLOW instead: the page
      simply grows, nothing can clip it, and the list scrolls inside itself.
      Desktop keeps the overlay, which is what the design asks for there.

   2. THE SUMMARY PUSHED THE CHEVRON OUT. "3 provinces selected" is fine;
      the placeholder plus a long localised string is not, and the toggle is a
      flex row whose text child had no min-width:0 and no truncation, so the
      chevron was pushed past the control's right edge. */
.auth-multiselect__toggle { min-width: 0; }

.auth-multiselect__summary {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* Never taller than the screen, whatever the province list grows to. */
.auth-multiselect__panel { max-height: min(320px, 60vh); }

/* A long province name wraps inside its chip instead of stretching it past the
   field. */
.auth-chip {
    max-width: 100%;
    overflow-wrap: anywhere;
}

@media (max-width: 640px) {
    .auth-multiselect__panel {
        position: static;
        z-index: auto;
        max-height: 44vh;
        margin-top: 8px;
        box-shadow: none;
    }

    /* 44px is the smallest comfortable touch target; the option rows were
       sized for a mouse. Padding rather than min-height: the rows align to
       flex-start now, so a min-height taller than the content would strand the
       label and its checkbox at the top of an over-tall row. 12 + 19.5 + 12
       is a 43.5px row that grows with a label that wraps. */
    .auth-multiselect__options > * { padding: 12px 8px; }
    .auth-multiselect__search { height: 42px; }
}
