/* ================================================================================================
   Applicant portal (ARCHITECTURE.md §6.5, §11)

   TWO DENSITIES, AND THE ORDINARY ONE IS THE DEFAULT.

   Carvin, 2026-08-09: "running on a kiosk is not the norm and we should not design with one UI
   experience in mind."

   This file used to be sized for a lobby kiosk throughout - 18px body, 3rem inputs - which made
   every other visit look like somebody had zoomed in. §6.5 calls kiosk a MODE ("kiosk mode replaces
   a mobile build"); the stylesheet had quietly promoted it to the only one.

   So the sizes below are tokens, and kiosk mode overrides them. Add ?kiosk=1 to any portal URL and
   the whole page steps up: bigger type, taller controls, for somebody standing at a lobby tablet
   who did not bring their reading glasses.

   What holds in BOTH: §6.5 makes tablet-usable a design constraint even though phone is not, so the
   ordinary density still has finger-sized targets - it is a normal web form, not the admin's 28px
   back-office density.

   - rem throughout, never px, so browser text scaling actually works.
   - Generous line-height and a bounded line length: Spanish runs ~20% longer than English for the
     same content, so a layout tuned to English wraps badly in the language half our applicants use.
   - Focus rings kept visible. A kiosk is often driven by keyboard or a stylus.
   ============================================================================================= */

/* ---- Palette -----------------------------------------------------------------------------------
   ALIASES ONTO THE SHARED TOKENS, not seven more colors.

   These names are used by five hundred lines below and by three pages, so they stay - but every one
   of them now resolves to the token the admin uses. Two sites that agree about "muted text" only
   because somebody typed #5a6472 in one place and #616170 in another do not actually agree; they
   drift the first time either is touched.

   The geometry is a separate question from the palette, and it is answered by the two density
   tokens below rather than by one hard-coded size. */

:root {
    --carvin-ink: var(--cv-text);
    --carvin-muted: var(--cv-text-muted);
    --carvin-line: var(--cv-border);
    --carvin-accent: var(--cv-accent);
    --carvin-danger: var(--cv-danger-text);
    --carvin-surface: var(--cv-surface);
    --carvin-page: var(--cv-page);

    /* ---- Density ------------------------------------------------------------------------------
       The ordinary visit. Not the admin's 13px/28px - §6.5 makes tablet-usable a constraint on this
       portal even though phone is not, and a 28px target is not finger-sized. A normal web form. */
    --portal-text: var(--cv-text-lg);
    --portal-text-small: var(--cv-text-base);
    --portal-control: 2.75rem;
    --portal-h1: 1.75rem;
    --portal-field-gap: 1.25rem;
}

/* ---- Kiosk mode ---------------------------------------------------------------------------------
   ?kiosk=1 on any portal URL. App.razor reads it and stamps the attribute on <html>, the same way
   it stamps the color scheme - so one place decides, and every rule below simply reads a token.

   This is what §6.5 actually describes: a MODE for a lobby tablet, for somebody standing who did not
   bring their reading glasses. It was the file's only density until 2026-08-09, which made every
   ordinary visit look zoomed in. */

[data-carvin-density="kiosk"] {
    --portal-text: 1.125rem;
    --portal-text-small: 1rem;
    --portal-control: 3rem;
    --portal-h1: 2rem;
    --portal-field-gap: 1.75rem;
}

body {
    /* STATED HERE, because nothing else states it any more.

       DevExpress's Bootstrap layer used to supply the body font, and CarvinThemes turns that layer
       off (ApplyToPageElements = false) so the vendor styles its own components and we style
       everything else. The admin's body rule was given a font at the same time; this one was not,
       and a page with no font-family falls back to the browser default - which is a SERIF, so the
       whole registration form rendered in Times. */
    font-family: var(--cv-font-sans);

    font-size: var(--portal-text);
    line-height: 1.6;
    color: var(--carvin-ink);
    background: var(--carvin-page);
}

h1:focus {
    outline: none;
}

/* ---- Registration ---------------------------------------------------------------------------- */

.register,
.office {
    max-width: 46rem;
    margin: 0 auto;
    padding: 1.5rem 1.25rem 4rem;
}

.office {
    max-width: 68rem;
}

.register__header,
.office__header {
    display: flex;
    flex-wrap: wrap;
    gap: 1rem;
    align-items: baseline;
    justify-content: space-between;
    border-bottom: 2px solid var(--carvin-line);
    padding-bottom: 1rem;
    margin-bottom: 1.5rem;
}

.register__header h1,
.office__header h1 {
    font-size: var(--portal-h1);
    margin: 0;
}

.register__office,
.office__name {
    font-weight: 600;
    color: var(--carvin-muted);
    margin: 0 0 1rem;
}

.register__intro {
    max-width: 34rem;
    margin-bottom: 2rem;
}

/* The employer's own greeting, above everything the software says about itself.
   Given a surface and a rule so it reads as a statement from the agency rather than as
   another paragraph of instructions — it carries an equal-opportunity claim and the
   conditions for disqualification, and the two must not blur together.
   Tokens rather than hex: the file's own header argues for it, and the raw values in
   here already fail AA where the tokens pass. */
.register__greeting {
    max-width: 34rem;
    margin-bottom: 2rem;
    padding: 1rem 1.25rem;
    border-left: 3px solid var(--carvin-accent);
    background: var(--carvin-surface);
    color: var(--carvin-ink);
}

.register__greeting p {
    margin: 0 0 0.75rem;
}

.register__greeting p:last-child {
    margin-bottom: 0;
}

.register__section {
    background: var(--carvin-surface);
    border: 1px solid var(--carvin-line);
    border-radius: 0.5rem;
    padding: 1.5rem;
    margin-bottom: 1.5rem;
}

.register__errors {
    background: #fdecea;
    border-left: 4px solid var(--carvin-danger);
    padding: 1rem 1.25rem;
    margin-bottom: 1.5rem;
    border-radius: 0.25rem;
}

.register__empty,
.office__empty {
    background: var(--carvin-surface);
    border: 1px solid var(--carvin-line);
    border-radius: 0.5rem;
    padding: 2rem;
    text-align: center;
    color: var(--carvin-muted);
}

/* ---- Fields ---------------------------------------------------------------------------------- */

.field {
    margin-bottom: var(--portal-field-gap);
}

.field__label {
    display: block;
    color: var(--cv-text);
    font-weight: var(--cv-weight-semibold);
    margin-bottom: 0.4rem;
}

/* ---- The vendor's editors, wearing our palette -------------------------------------------------
   Every input on this form is a DevExpress editor - DxTextBox, DxComboBox, DxDateEdit, DxSpinEdit,
   DxMemo - so the border, background and text color come from Fluent rather than from anything
   above. That is why the form kept looking like somebody else's software next to the admin.

   The same remap the grid contract uses, and the same rules: only PUBLIC --dxds-* variables, which
   Fluent publishes and CarvinThemes keeps available by cloning Fluent rather than replacing it.
   Vendor class names appear nowhere.

   The accent needs no remapping - CarvinThemes already sets it to --cv-accent through
   SetCustomAccentColor, so focus rings and selection are correct already. */

/* One selector, because custom properties inherit: setting them on the editor's own element reaches
   every part DevExpress renders inside it without naming any of them. */
.field__input {
    --dxds-font-family-sans-serif: var(--cv-font-sans);
    --dxds-color-surface-neutral-default-rest: var(--cv-input-bg);
    --dxds-color-content-neutral-default-rest: var(--cv-text);
    --dxds-color-border-neutral-default-rest: var(--cv-border);
}

/* Marked in WORDS as well as color. A red asterisk alone is invisible to a color-blind applicant
   and silent to a screen reader, which is why DynamicField gives it an aria-label too. */
.field__required {
    color: var(--carvin-danger);
    margin-left: 0.25rem;
}

.field__help {
    color: var(--carvin-muted);
    font-size: var(--portal-text-small);
    margin: 0 0 0.5rem;
}

.field__input {
    width: 100%;
    min-height: var(--portal-control);
}

.field--error .field__input {
    outline: 2px solid var(--carvin-danger);
}

.field__error {
    color: var(--carvin-danger);
    font-size: var(--portal-text-small);
    margin: 0.35rem 0 0;
}

/* ---- The applicant card ---------------------------------------------------------------------- */

/* The single artefact of the whole process. An applicant with no email cannot be sent it again and
   cannot recover it themselves, so it is deliberately the largest thing on the screen (§6.1, §6.4). */
.applicant-card {
    background: var(--carvin-surface);
    border: 3px solid var(--carvin-ink);
    border-radius: 0.75rem;
    padding: 2.5rem 2rem;
    margin: 2rem 0;
    text-align: center;
}

.applicant-card__label {
    text-transform: uppercase;
    letter-spacing: 0.08em;
    font-size: var(--portal-text-small);
    color: var(--carvin-muted);
    margin: 0 0 0.75rem;
}

.applicant-card__code {
    /* Monospace and wide tracking: this gets read aloud down a phone line and copied by hand onto
       paper. Ambiguity between characters is the failure mode the Crockford alphabet already
       fights; the typeface should not undo that. */
    font-family: ui-monospace, "Cascadia Mono", "Consolas", monospace;
    font-size: clamp(2rem, 7vw, 3.25rem);
    font-weight: 700;
    letter-spacing: 0.12em;
    margin: 0 0 1.25rem;
    word-break: break-all;
}

.applicant-card__warning {
    max-width: 30rem;
    margin: 0 auto;
    color: var(--carvin-muted);
}

/* ---- Registration confirmation ---------------------------------------------------------------- */

/* The heading pair the applicant reads first, held together and separated from whatever follows -
   the card on the PIN path, the sign-in sentence on the others. Without it the title, the name and
   the next block run together as one paragraph. */
.confirmation {
    margin-bottom: 1.5rem;
}

.confirmation__title {
    font-size: 1.6rem;
    margin: 0 0 0.35rem;
}

.confirmation__who {
    color: var(--carvin-muted);
    margin: 0;
}

/* Deliberately understated. The card above it is what the applicant must not miss; this is a
   caution, and a caution competing with the card for attention would lose them both. */
.confirmation__pin-note {
    max-width: 34rem;
    color: var(--carvin-muted);
    font-size: var(--portal-text-small);
    margin: 0 0 1.5rem;
}

/* THE SENTENCE THAT REPLACES THE CARD, on the email and mobile paths. It is the one thing that
   applicant has to leave with, so it is ordinary body text at full weight rather than the muted
   aside the reference below it is. Bounded like the note above: Spanish runs longer and a reminder
   that wraps four times stops reading like one. */
.confirmation__how {
    max-width: 34rem;
    margin: 0 0 0.5rem;
}

/* Quiet on purpose. The applicant code is here because branch staff ask for it on the telephone,
   not because it is how they sign in - and giving it the same weight as the line above would make
   the screen offer two ways in when it means to offer one. */
.confirmation__reference {
    max-width: 34rem;
    color: var(--carvin-muted);
    font-size: var(--portal-text-small);
    margin: 0;
}

/* Below the print button, not beside it. Printing the card is what the applicant at a kiosk must do
   before walking away; signing in is what the one on their own phone wants next, and putting them
   side by side would make the more consequential of the two a coin toss. */
.confirmation__sign-in {
    margin: 1.25rem 0 0;
}


/* ---- Print ----------------------------------------------------------------------------------- */

/* The card is the only thing worth printing, and the only thing the applicant leaves with. */
@media print {
    .register__header,
    .register__intro,
    .register__section,
    .register__errors,

    /* `button` alone, not .dxbl-btn as well: DevExpress renders real <button> elements, so the
       vendor class was always redundant - and it is an internal name that an upgrade may change,
       which would break this silently. */
    button {
        display: none !important;
    }

    .applicant-card {
        border-width: 2px;
        margin: 0;
        page-break-inside: avoid;
    }

    body {
        background: #fff;
    }
}

.valid.modified:not([type=checkbox]) {
    outline: 1px solid #26b050;
}

.invalid {
    outline: 1px solid #e50000;
}

.validation-message {
    color: #e50000;
}

.blazor-error-boundary {
    background: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTYiIGhlaWdodD0iNDkiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIG92ZXJmbG93PSJoaWRkZW4iPjxkZWZzPjxjbGlwUGF0aCBpZD0iY2xpcDAiPjxyZWN0IHg9IjIzNSIgeT0iNTEiIHdpZHRoPSI1NiIgaGVpZ2h0PSI0OSIvPjwvY2xpcFBhdGg+PC9kZWZzPjxnIGNsaXAtcGF0aD0idXJsKCNjbGlwMCkiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0yMzUgLTUxKSI+PHBhdGggZD0iTTI2My41MDYgNTFDMjY0LjcxNyA1MSAyNjUuODEzIDUxLjQ4MzcgMjY2LjYwNiA1Mi4yNjU4TDI2Ny4wNTIgNTIuNzk4NyAyNjcuNTM5IDUzLjYyODMgMjkwLjE4NSA5Mi4xODMxIDI5MC41NDUgOTIuNzk1IDI5MC42NTYgOTIuOTk2QzI5MC44NzcgOTMuNTEzIDI5MSA5NC4wODE1IDI5MSA5NC42NzgyIDI5MSA5Ny4wNjUxIDI4OS4wMzggOTkgMjg2LjYxNyA5OUwyNDAuMzgzIDk5QzIzNy45NjMgOTkgMjM2IDk3LjA2NTEgMjM2IDk0LjY3ODIgMjM2IDk0LjM3OTkgMjM2LjAzMSA5NC4wODg2IDIzNi4wODkgOTMuODA3MkwyMzYuMzM4IDkzLjAxNjIgMjM2Ljg1OCA5Mi4xMzE0IDI1OS40NzMgNTMuNjI5NCAyNTkuOTYxIDUyLjc5ODUgMjYwLjQwNyA1Mi4yNjU4QzI2MS4yIDUxLjQ4MzcgMjYyLjI5NiA1MSAyNjMuNTA2IDUxWk0yNjMuNTg2IDY2LjAxODNDMjYwLjczNyA2Ni4wMTgzIDI1OS4zMTMgNjcuMTI0NSAyNTkuMzEzIDY5LjMzNyAyNTkuMzEzIDY5LjYxMDIgMjU5LjMzMiA2OS44NjA4IDI1OS4zNzEgNzAuMDg4N0wyNjEuNzk1IDg0LjAxNjEgMjY1LjM4IDg0LjAxNjEgMjY3LjgyMSA2OS43NDc1QzI2Ny44NiA2OS43MzA5IDI2Ny44NzkgNjkuNTg3NyAyNjcuODc5IDY5LjMxNzkgMjY3Ljg3OSA2Ny4xMTgyIDI2Ni40NDggNjYuMDE4MyAyNjMuNTg2IDY2LjAxODNaTTI2My41NzYgODYuMDU0N0MyNjEuMDQ5IDg2LjA1NDcgMjU5Ljc4NiA4Ny4zMDA1IDI1OS43ODYgODkuNzkyMSAyNTkuNzg2IDkyLjI4MzcgMjYxLjA0OSA5My41Mjk1IDI2My41NzYgOTMuNTI5NSAyNjYuMTE2IDkzLjUyOTUgMjY3LjM4NyA5Mi4yODM3IDI2Ny4zODcgODkuNzkyMSAyNjcuMzg3IDg3LjMwMDUgMjY2LjExNiA4Ni4wNTQ3IDI2My41NzYgODYuMDU0N1oiIGZpbGw9IiNGRkU1MDAiIGZpbGwtcnVsZT0iZXZlbm9kZCIvPjwvZz48L3N2Zz4=) no-repeat 1rem/1.8rem, #b32121;
    padding: 1rem 1rem 1rem 3.7rem;
    color: white;
}

    .blazor-error-boundary::after {
        content: "An error has occurred."
    }

/* ---- Signing (ARCHITECTURE.md §7.3) -------------------------------------------------------------
   MOVED TO THE LIBRARY (#64): carvin-signature.css, beside the SignaturePad component that emits
   these classes. This host held one copy and TenantAdmin held another, and they had already drifted
   - four rules apart on borders and error color - so an applicant and the staff member
   countersigning were not looking at the same pad. App.razor links the shared file. */

/* ---- Completing a form (ARCHITECTURE.md §7.3) ----------------------------------------------- */

.form-steps {
    display: flex;
    gap: 1.5rem;
    list-style: none;
    padding: 0;
    margin: 0 0 1.25rem;
    font-size: var(--portal-text-small);
    color: #6b7280;
    flex-wrap: wrap;
}

.form-steps .current { font-weight: 700; color: #111; }
.form-steps .done { color: #2b7a2b; }

.form-questions { max-width: 34rem; }

.form-question { margin-bottom: 1rem; }

.form-question label {
    display: block;
    font-weight: 600;
}

/* textarea joins these rather than getting its own rule. Contact Us is the first portal screen with
   a free-text box, and a textarea that does not inherit the field geometry renders at the browser's
   default width - narrower than every control above it, which reads as a broken layout. */
.form-question input,
.form-question select,
.form-question textarea {
    display: block;
    width: 100%;
    margin-top: 0.25rem;
    font-weight: 400;
}

/* Explicit, because a textarea does NOT inherit the page font the way an input does - it falls back
   to a monospace default in most browsers, and the message box would be the one part of the portal
   in a different typeface. */
.form-question textarea {
    font-family: inherit;
    font-size: inherit;
    line-height: 1.5;
    padding: 0.5rem;
    border: 1px solid var(--carvin-line);
    border-radius: 0.4rem;
    resize: vertical;
}

.form-question input[type="checkbox"] { width: auto; }

/* "CHOOSE ANY NUMBER" (#229): one checkbox per option, the box beside its words. The fieldset's own
   border and padding are removed so the group lines up with every other question in the column, and
   the per-option label undoes the block, bold label every other question uses. */
.form-question__choices {
    border: 0;
    margin: 0;
    padding: 0;
    min-width: 0;
}

.form-question__choices legend {
    font-weight: 600;
    padding: 0;
}

.form-question .form-question__choice {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    font-weight: 400;
    padding: 0.45rem 0;
    min-height: 2.25rem;
}

.form-question .form-question__choice input[type="checkbox"] {
    display: inline-block;
    margin: 0;
    width: 1.15rem;
    height: 1.15rem;
    flex: none;
}

/* Visibly not yours to change. An employer value in an ordinary box invites an applicant to try. */
.form-question input:disabled {
    background: #f3f4f6;
    color: #4b5563;
}

.form-hint {
    display: block;
    font-size: 0.85rem;
    font-weight: 400;
    color: #6b7280;
    margin-top: 0.2rem;
}

.required { color: #b32121; margin-left: 0.2rem; }

/* ---- The blank form, beside the questions (#102) -------------------------------------------------
   ONE COLUMN UNTIL THERE IS ROOM FOR TWO. The questions are 34rem wide, so two columns need roughly
   double that plus a gutter before the reference stops squeezing them - below that the reference
   falls under the questions, which is why it comes AFTER them in the markup rather than before.

   §6.5 KIOSK MODE IS WHY THE BREAKPOINT IS NOT SMALLER. A branch kiosk is a fixed screen, often
   narrower than a laptop; making the second column appear early would give it two cramped columns
   instead of one usable one. */
.form-fill {
    display: grid;
    gap: 1.5rem;
    align-items: start;
}

@media (min-width: 75rem) {
    .form-fill {
        grid-template-columns: minmax(0, 34rem) minmax(0, 1fr);
    }

    /* Sticky, because the questions are the taller column on a long form and a reference that
       scrolls away at question six is a reference nobody looks at. */
    .form-reference {
        position: sticky;
        top: 1rem;
    }
}

.form-reference {
    border: 1px solid #d0d7de;
    border-radius: 4px;
    padding: 0.75rem;
    background: #f6f8fa;
    min-width: 0;
}

.form-reference > summary {
    cursor: pointer;
    font-weight: 600;
}

.form-reference__pages {
    display: flex;
    gap: 0.4rem;
    flex-wrap: wrap;
    margin: 0.75rem 0;
}

.form-reference__pages button {
    min-width: 2.75rem;
    min-height: 2.75rem;
    border: 1px solid #d0d7de;
    border-radius: 4px;
    background: #fff;
    cursor: pointer;
}

/* Not colour alone - the current page is also heavier and outlined, because §12's WCAG commitment
   means a colour-blind applicant must be able to tell which page they are looking at. */
.form-reference__pages button.current {
    font-weight: 700;
    background: #111;
    color: #fff;
    border-color: #111;
}

/* Capped on a phone so the reference cannot become a screenful of scrolling between the last
   question and the Continue button. */
.form-reference__page {
    display: block;
    width: 100%;
    height: auto;
    max-height: 60vh;
    object-fit: contain;
    object-position: top;
    border: 1px solid #d0d7de;
    background: #fff;
}

@media (min-width: 75rem) {
    .form-reference__page { max-height: calc(100vh - 8rem); }
}

/* THE DOCUMENT ITSELF, not a summary of the answers. What the applicant agrees to is the form, and
   a summary that disagreed with it would be the thing they actually read. */
.form-preview {
    width: 100%;
    height: 70vh;
    border: 1px solid #d0d7de;
    margin: 1rem 0;
}

.form-actions {
    display: flex;
    gap: 0.75rem;
    flex-wrap: wrap;
    margin: 1rem 0;
}

/* ---- Choosing where and how ---------------------------------------------------------------------
   The first step of registration, and the first thing an applicant ever sees of this product. It is
   also frequently seen on a branch tablet held at arm's length, so the targets are large and the
   chosen one has to be obvious across a room rather than at reading distance. */

.method-choice,
.language-choice {
    display: grid;
    gap: 0.75rem;
    margin: 0.5rem 0 0.25rem;
}

.method-choice__option,
.language-choice__option {
    display: block;
    width: 100%;
    text-align: left;
    padding: 0.9rem 1.1rem;
    border: 2px solid var(--carvin-line);
    border-radius: 0.5rem;
    background: var(--carvin-surface);
    cursor: pointer;
    font: inherit;
}

.method-choice__option:hover:not(:disabled) {
    border-color: var(--carvin-accent);
}

.method-choice__option strong {
    display: block;
    margin-bottom: 0.15rem;
}

.method-choice__option span {
    color: var(--carvin-muted);
    font-size: 0.9rem;
}

/* NOT COLOR ALONE. The border weight and the tick both change, because a chosen option that differs
   only in hue is not chosen at all to somebody who cannot see the difference - and this decides how
   they get back into their account. */
.method-choice__option.is-chosen {
    border-color: var(--carvin-accent);
    box-shadow: inset 0 0 0 1px var(--carvin-accent);
}

.method-choice__option.is-chosen strong::after {
    content: " ✓";
    color: var(--carvin-accent);
}

.method-choice__option:disabled {
    opacity: 0.6;
    cursor: default;
}

/* ---- Choosing the language, which comes before either of those ---------------------------------
   The same card, because it is the same kind of question in the same place - so the rules above are
   shared rather than copied, and a card that changes changes for both.

   ANCHORS RATHER THAN BUTTONS, because taking this choice is a page load and nothing else can set
   the culture cookie (see LanguageSwitcher.razor). That costs the three things a button gave for
   free: a link is inline, underlined, and accent-coloured. All three are put back here. */

.language-choice__option {
    color: var(--carvin-ink);
    text-decoration: none;
    font-weight: 600;
}

/* KEYBOARD-VISIBLE, not just hoverable. This is the first control an applicant meets and there is
   no way past it, so somebody tabbing has to be able to see where they are (§12). */
.language-choice__option:hover,
.language-choice__option:focus-visible {
    border-color: var(--carvin-accent);
}

.register__section-title {
    margin: 0 0 0.5rem;
}

/* A way out of consent that is not agreeing to it. Quiet, because it is the second choice - but
   present, because consent that can only be given is not consent. */
.register__back {
    display: inline-block;
    margin-left: 1rem;
    background: none;
    border: none;
    padding: 0;
    color: var(--carvin-muted);
    text-decoration: underline;
    cursor: pointer;
    font: inherit;
}

/* A neutral note on the verify step - "a new code is on its way". Deliberately not the error style:
   it is confirmation that something worked, and rendering it in red teaches people to stop reading
   the red ones. */
.register__notice {
    background: var(--carvin-surface);
    border-left: 4px solid var(--carvin-accent);
    padding: 1rem 1.25rem;
    margin-bottom: 1.5rem;
    border-radius: 0.25rem;
}

/* The front door's one action. A link rather than a button because it navigates - a button that
   navigates loses middle-click, "open in new tab", and the browser's own affordances. */
.home-action {
    display: inline-block;
    padding: 0.75rem 1.5rem;
    margin-bottom: 1.5rem;
    background: var(--carvin-accent);
    color: #fff;
    border-radius: 0.375rem;
    text-decoration: none;
    font-weight: 600;
}

.home-action:hover {
    filter: brightness(1.08);
}

/* ---- The privacy notice -------------------------------------------------------------------------
   MOVED TO carvin-primitives.css (#64), numbers unchanged. FormattedPolicy renders this text on both
   sites and TenantAdmin's preview had drifted to a different line length while claiming to mirror
   these rules; the component now takes its appearance from the library, and this host's numbers are
   the ones it took. */

.policy-agree {
    display: grid;
    grid-template-columns: auto 1fr;
    column-gap: 0.6rem;
    align-items: start;
    margin-bottom: 1.25rem;
}

.policy-agree input {
    margin-top: 0.3rem;
    width: 1.15rem;
    height: 1.15rem;
}

/* ---- The applicant's own data rights -----------------------------------------------------------
   Two consequential actions on one page — one reversible, one not. Boxed apart so the delete is
   never a stray click away from the download. */

.data-right {
    border: 1px solid var(--carvin-line);
    border-radius: 0.5rem;
    padding: 1.25rem 1.5rem;
    margin-bottom: 1.5rem;
    max-width: 60ch;
}

.data-right h2 {
    margin-top: 0;
    font-size: 1.1rem;
}

.data-right ul {
    margin: 0 0 1rem;
    padding-left: 1.25rem;
}

.data-right li {
    margin-bottom: 0.4rem;
}

/* Where a request for a copy of your information has got to (#117). Separated from the paragraph
   above so an applicant scanning the section sees "you asked on the 3rd" without reading the
   explanation again.

   ⚠ IT WAS var(--carvin-muted) UNTIL 2026-08-31, on the reasoning that it is a statement of fact
   rather than a warning. That was right about the tone and wrong about the weight: Carvin, looking
   at the screen, said the request "does not stand out". Faded grey at the small size put the one
   thing an applicant came to check below the explanation they had already read. It reads at body
   weight now - still no colour, still not a warning. */
.data-right__state {
    margin: 0.75rem 0;
}

/* ---- The applicant's own pages ----------------------------------------------------------------

   NONE OF THESE CLASSES EXISTED. MyForms, MyData and the review step were written with the admin
   host's class names - .packet, .field-key, .lede, .scope-tenant - none of which this stylesheet
   defines, so the page rendered as bare text: "Default Packet1 left to do", a bulleted link, and no
   separation between sections. Carvin, 2026-08-12: "We need to give this page more structure."

   This is the same fault as the sign-in notice that rendered unstyled because it used
   .upload-errors, a class this host never defined. Two hosts, two stylesheets, one set of habits. */

.lede {
    max-width: 44rem;
    color: var(--carvin-muted);
    margin: 0 0 1.5rem;
}

.packet {
    border: 1px solid var(--carvin-line);
    border-radius: 0.5rem;
    padding: 1rem 1.25rem;
    margin: 0 0 1rem;
    background: var(--carvin-surface);
}

/* Flex with a gap rather than margins on the children: the status is sometimes a span and
   sometimes a count, and "Default Packet1 left to do" is what happens when neither carries one. */
.packet-header {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 0.75rem;
    margin-bottom: 0.75rem;
}

/* .form-list MOVED TO carvin-primitives.css (#64). It was defined here and used by TenantAdmin's
   applicant detail page as well, which never links this file. */

/* A status word, not a decoration. Kept legible in forced-colours rather than relying on the tint. */
.scope-tenant,
.scope-company,
.scope-unset {
    font-size: var(--portal-text-small);
    border-radius: 1rem;
    padding: 0.1rem 0.6rem;
    border: 1px solid currentColor;
}

.scope-tenant { color: #1a6b3c; }
.scope-company { color: #1c4f8b; }
.scope-unset { color: #8a5000; }

.field-key {
    color: var(--carvin-muted);
    font-size: var(--portal-text-small);
}

.upload-hint {
    max-width: 44rem;
    margin: 1rem 0 0;
}

/* ---- The review step -------------------------------------------------------------------------

   A definition list rather than a table: it is one column of label-and-value read top to bottom on
   a phone, and a table would need horizontal scrolling to say the same thing. */

.review {
    max-width: 44rem;
    margin: 0 0 1.5rem;
}

.review__row {
    display: flex;
    flex-wrap: wrap;
    gap: 0.25rem 1rem;
    padding: 0.5rem 0;
    border-top: 1px solid var(--carvin-line);
}

.review__row dt {
    flex: 0 0 14rem;
    color: var(--carvin-muted);
}

/* ⚠ FLEX WITH A GAP, BECAUSE RAZOR GIVES NO SPACE BETWEEN TWO @if BLOCKS. The value and the
   Change button are separate conditional blocks inside this cell, and the newline between them in
   the markup is whitespace Razor does not emit - so they rendered welded together as
   "Not givenChange" (Carvin, 2026-10-10: "Put spaces between the wording.").

   A gap rather than an &nbsp; or a margin on the button: the cell can hold a value, a button, and
   the change controls, and spacing belongs to the container that arranges them rather than to
   whichever child happens to be second today.

   align-items: baseline so the button's text sits on the same line as the value rather than being
   centred against it. */
.review__row dd {
    flex: 1 1 12rem;
    margin: 0;
    font-weight: 600;

    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 0.25rem 0.5rem;
}

/* Said in words, not by an empty cell. Somebody proof-reading needs to see that a mobile number is
   missing, which is exactly the field they will need to sign back in with. */
.review__blank {
    font-weight: 400;
    color: var(--carvin-muted);
    font-style: italic;
}

.register__actions {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 1rem;
}

/* The employer's logo on the registration page. Bounded rather than sized: an agency
   uploads whatever their designer gave them, and a logo three times the width of the
   form would push the greeting off the first screen. Height caps it for a tall mark,
   width for a wide one, and the aspect ratio is left alone. */
.register__logo {
    display: block;
    max-width: 14rem;
    max-height: 5rem;
    width: auto;
    height: auto;
    margin-bottom: 1.5rem;
}

/* One previous job. Boxed because the section repeats and a run of unboxed fields gives
   no clue where one job ends and the next begins. */
.register__job {
    border: 1px solid var(--carvin-line);
    border-radius: 0.5rem;
    padding: 1rem 1.25rem;
    margin-bottom: 1.25rem;
}

.register__job legend {
    font-weight: 600;
    padding: 0 0.5rem;
}

/* ⚠ THE PERMISSION AND THE NUMBER, TIED TOGETHER VISUALLY.
   A recruiter ringing a current supervisor can cost the applicant their job, so the
   consent must be read in the same glance as the field it governs. The rule down the
   left is what stops the checkbox looking like one more question in a column of them. */
.register__contact-consent {
    border-left: 3px solid var(--carvin-accent);
    padding-left: 1rem;
    margin-bottom: var(--portal-field-gap);
}

/* ---- The signed-in shell -----------------------------------------------------------------------

   THE PORTAL HAD NO NAVIGATION AT ALL. Sections were reached by paragraphs written into the bottom
   of other pages, and there was no way out of /forms/{id} except the browser's back button.

   ALSO: .language-switcher was referenced by the component and defined by nothing. That is the
   same fault this file's other headers describe - a class that matches nothing is silent, so the
   selector on the home page has been rendering as an unstyled label and control since it was
   written. It is styled here because the header is where it now lives.

   The header stays out of the way rather than dominating: an applicant is here to finish
   paperwork, and the bar above it is how they get back, not the point of the visit. */

.portal-shell {
    min-height: 100vh;
    display: flex;
    flex-direction: column;
}

.portal-header {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 1rem 1.5rem;
    padding: 0.75rem 1.25rem;
    border-bottom: 1px solid var(--carvin-line);
    background: var(--carvin-surface);
}

.portal-brand {
    font-weight: 700;
    font-size: var(--portal-text);
    color: var(--carvin-ink);
    text-decoration: none;
}

.portal-nav {
    display: flex;
    flex-wrap: wrap;
    gap: 0.25rem;
}

/* Targets sized for a finger, in the ordinary density as well as kiosk. §6.5 makes tablet-usable a
   constraint on this portal, and a nav is the one thing on every screen. */
.portal-nav a {
    display: inline-block;
    padding: 0.5rem 0.85rem;
    border-radius: 0.4rem;
    color: var(--carvin-muted);
    text-decoration: none;
    font-size: var(--portal-text-small);
}

.portal-nav a:hover,
.portal-nav a:focus-visible {
    color: var(--carvin-ink);
    background: var(--carvin-page);
}

/* The current section, marked by weight and a rule rather than by color alone - the same reason
   the forms carry text beside every status colour. */
.portal-nav a.active {
    color: var(--carvin-ink);
    font-weight: 600;
    box-shadow: inset 0 -2px 0 var(--carvin-accent);
}

/* Pushed to the far end, and allowed to wrap underneath on a narrow tablet rather than squeezing
   the sections into two characters each. */
.portal-header__end {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.75rem 1rem;
    margin-left: auto;
}

.portal-user {
    color: var(--carvin-muted);
    font-size: var(--portal-text-small);
}

.portal-signout {
    color: var(--carvin-ink);
    font-size: var(--portal-text-small);
    padding: 0.5rem 0.85rem;
    border: 1px solid var(--carvin-line);
    border-radius: 0.4rem;
    text-decoration: none;
}

.portal-signout:hover,
.portal-signout:focus-visible {
    border-color: var(--carvin-accent);
}

/* No max-width and no padding. Every page inside already centres itself - .register is 46rem and
   .office is 68rem - so constraining here would centre a centred thing and halve the width the
   branch queue needs. */
.portal-main {
    flex: 1;
}

/* ---- Language selection ------------------------------------------------------------------------
   Anchors rather than a <select>, because a select needs a circuit and the home page has none.
   See LanguageSwitcher.razor. */

.language-switcher {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 0.5rem;
    font-size: var(--portal-text-small);
}

.language-switcher__label {
    color: var(--carvin-muted);
}

/* The language already in use is NOT a link. A row of two links where one does nothing leaves
   somebody unsure which they are reading. */
.language-switcher__current {
    font-weight: 600;
    color: var(--carvin-ink);
}

.language-switcher__choice {
    color: var(--carvin-accent);
}

/* A boxed section on an applicant page. Named .panel rather than reusing .data-right, which is
   named for the two data-rights actions it boxes and would be a lie on any other screen — and
   rather than the admin's .settings-card, which is a LINK card with a hover state that would make
   a static block look clickable. */
.panel {
    border: 1px solid var(--carvin-line);
    border-radius: 0.5rem;
    background: var(--carvin-surface);
    padding: 1.25rem 1.5rem;
    margin: 0 0 1.5rem;
    max-width: 46rem;
}

/* ---- Activity ----------------------------------------------------------------------------------
   The applicant's transparency log. A list rather than a table: it is read top to bottom on a
   phone, and a two-column table at 380px is a table nobody reads. */

.activity {
    list-style: none;
    margin: 0 0 2rem;
    padding: 0;
    max-width: 46rem;
}

.activity__item {
    display: flex;
    flex-wrap: wrap;
    gap: 0.25rem 1.5rem;
    padding: 0.85rem 0;
    border-bottom: 1px solid var(--carvin-line);
}

/* Fixed-ish width so the timestamps line up as a column on a wide screen, and wrap above the
   description on a narrow one rather than squeezing it to two words. */
.activity__when {
    flex: 0 0 14rem;
    color: var(--carvin-muted);
    font-size: var(--portal-text-small);
    font-variant-numeric: tabular-nums;
}

.activity__what {
    flex: 1 1 18rem;
}

/* The field names, quieter than the sentence they qualify. They are names and never values -
   see ApplicantActivityService. */
.activity__fields {
    display: block;
    color: var(--carvin-muted);
    font-size: var(--portal-text-small);
}

/* The answer beside a question on the review step (#47). Its siblings — .field__label, .field__input
   and .field__required — were all defined; this one was named in the markup and never written, so
   the value an applicant is being asked to confirm rendered as plain body text. */
.field__value {
    margin: 0.15rem 0 0;
    color: var(--cv-text);
}

/* ---- Photographing an attachment (#131) ---------------------------------------------------------

   The live camera feed and the captured still share one rule so the layout does not jump between
   them: a preview that changes size on capture makes somebody think they photographed the wrong
   thing.

   Bounded rather than full width. A card photographed on a phone is portrait and would otherwise
   fill the screen, pushing Accept and Retake below the fold on the one screen where both need to be
   visible together. */
.attachment-preview {
    display: block;
    width: 100%;
    max-width: 30rem;
    max-height: 22rem;
    object-fit: contain;
    background: #000;
    border-radius: 0.375rem;
    margin-bottom: 0.5rem;
}

.attachment-actions {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    align-items: center;
}

/* ---- The attachments step, in two columns (#130) ------------------------------------------------

   Carvin, 2026-09-01: "This screen is confusing and a list of what has been added should appear on
   the right side."

   ⚠ WHAT WAS CONFUSING WAS THE LIST, NOT THE COLUMN COUNT, and moving it alone would not have
   fixed it. It rendered through .form-list, which is a flex row aligned on one baseline - correct
   for "I9   optional", wrong for an attachment, which carries four separate facts: what it is, the
   note the applicant wrote, its state, and its controls. On one baseline those read as a sentence.
   The screen Carvin sent said "Other Contract Checking Remove", which is a PDF named Hampton
   Contract awaiting its scan, and reads as four unrelated words. So the list is BOTH moved and
   restacked; each attachment is a block of lines below.

   THE FORM IS THE WIDER COLUMN because it holds a select, a text box and a file picker, where the
   list holds short lines. minmax(0, ...) on both tracks so a long note wraps instead of widening
   its column - the default of min-content would let one unbroken filename push the form off screen.

   ONE COLUMN ON A NARROW WINDOW. Two columns of this on a phone would put the list below the fold
   anyway, and stacking keeps it directly under the Add button that changes it. */

.attachment-columns {
    display: grid;
    grid-template-columns: minmax(0, 3fr) minmax(0, 2fr);
    gap: 1.5rem;
    align-items: start;
}

@media (max-width: 60rem) {
    .attachment-columns {
        grid-template-columns: minmax(0, 1fr);
    }
}

/* .data-right carries its own max-width of 60ch, which is narrower than this track on a wide
   screen. Left alone: the add form reading at a sane measure is the point of that rule, and
   stretching it to fill a column would undo it. */
.attachment-columns__add > .data-right {
    margin-bottom: 0;
}

.attachment-held {
    border: 1px solid var(--carvin-line);
    border-radius: 0.5rem;
    padding: 1.25rem 1.5rem;
    background: var(--cv-surface);
}

.attachment-held h2 {
    margin-top: 0;
    font-size: 1.1rem;
}

.attachment-held__empty {
    margin: 0;
    color: var(--carvin-muted);
}

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

/* ⚠ A BLOCK PER ATTACHMENT, NOT A ROW. The whole point of the rewrite - see the note above. */
.attachment-held__item {
    padding: 0.75rem 0;
    border-top: 1px solid var(--carvin-line);
}

.attachment-held__item:first-child {
    padding-top: 0;
    border-top: none;
}

.attachment-held__kind {
    margin: 0;
    font-weight: 600;
}

/* The applicant's own words, so they read as body text rather than as metadata. It is often the
   only thing distinguishing two attachments of the same kind. */
.attachment-held__note {
    margin: 0.15rem 0 0;
    color: var(--cv-text);
}

.attachment-held__status {
    margin: 0.15rem 0 0;
    color: var(--carvin-muted);
    font-size: var(--portal-text-small);
}

/* ⚠ NOT MUTED, UNLIKE THE STATUS DIRECTLY ABOVE IT. The status is something being done to the
   file; this is something the applicant has to do, and it is the only thing on the screen that
   stops the step finishing. The same amber .scope-unset uses for a returned form, because it means
   the same thing to the person reading it: this one is waiting on you. */
.attachment-held__wanted {
    margin: 0.15rem 0 0;
    color: #8a5000;
}

.attachment-held__actions {
    display: flex;
    flex-wrap: wrap;
    gap: 0.75rem;
    margin-top: 0.4rem;
}

/* ---- The schools an applicant listed (#246) ------------------------------------------------------
   A block per school, the shape the attachments list takes and for its reason: on a phone a row of
   name, years, GPA and two links is a row nobody can read. Its own names rather than borrowing
   .attachment-held__*, which would be a lie on this screen. */

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

.school-list__item {
    padding: 0.75rem 0;
    border-top: 1px solid var(--carvin-line);
}

.school-list__item:first-child {
    padding-top: 0;
    border-top: none;
}

.school-list__name {
    margin: 0;
    font-weight: 600;
    overflow-wrap: anywhere;
}

/* The applicant's own words - years, GPA, awards - so body text, not muted metadata. */
.school-list__detail {
    margin: 0.15rem 0 0;
    color: var(--cv-text);
    overflow-wrap: anywhere;
}

.school-list__actions {
    display: flex;
    flex-wrap: wrap;
    gap: 0.75rem;
    margin-top: 0.4rem;
}

/* Says the photograph was taken (#131). Carvin, 2026-09-02: "When taking a photo, it does not tell
   me that the photo is taken or some type of success message."

   ⚠ IT SITS ABOVE THE PREVIEW, NOT IN THE NOTICE AT THE TOP OF THE PAGE. A tall preview pushes the
   camera controls a long way down, so a banner announcing the capture would appear off screen at
   the moment it was needed - this has to be where the eyes already are.

   Green, matching .scope-tenant, because it is the same message every other confirmation on this
   product gives: the thing you did worked. */
.attachment-taken {
    margin: 0 0 0.5rem;
    font-weight: 600;
    color: #1a6b3c;
}

/* ================================================================================================
   THE ARBORWEB LOOK, AND EACH COMPANY'S COLOR ON IT (Carvin, 2026-10-12)

   "What I like about it is the color schema." The ArborWeb portal's palette and type, taken from its
   site.css rather than guessed from a screenshot: Source Sans Pro, a blue banner on a 135-degree
   gradient, white cards with soft borders and 12px corners, a white menu bar with a light shadow.

   APPLICANT PORTAL ONLY. The staff portal keeps its compact desk-work style (Carvin's choice).

   ONE COMPANY COLOR, THROUGH TWO VARIABLES. --brand-accent and --brand-accent-dark default to
   Staffily navy here (#227) and are set per company, by the pages that know whose portal this is
   (registration; the signed-in shell). The color is checked for 4.5:1 against white when a company
   saves it, so white banner text and colored links stay readable whatever was chosen.

   DevExpress buttons are NOT recolored per company: they take the theme's accent from C#, and
   overriding the vendor's internal variables is how an upgrade silently breaks a page.
   ============================================================================================= */

/* Served from here, not Google Fonts, so an applicant's browser contacts no third party - the same
   reason ArborWeb self-hosts it. SIL Open Font License 1.1: fonts/source-sans-pro/OFL.txt. */
@font-face {
    font-family: 'Source Sans Pro';
    font-style: normal;
    font-weight: 400;
    font-display: swap;
    src: url(fonts/source-sans-pro/source-sans-pro-latin-ext-400-normal.woff2) format('woff2');
    unicode-range: U+0100-02AF, U+0304, U+0308, U+0329, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
    font-family: 'Source Sans Pro';
    font-style: normal;
    font-weight: 400;
    font-display: swap;
    src: url(fonts/source-sans-pro/source-sans-pro-latin-400-normal.woff2) format('woff2');
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
    font-family: 'Source Sans Pro';
    font-style: normal;
    font-weight: 700;
    font-display: swap;
    src: url(fonts/source-sans-pro/source-sans-pro-latin-ext-700-normal.woff2) format('woff2');
    unicode-range: U+0100-02AF, U+0304, U+0308, U+0329, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
    font-family: 'Source Sans Pro';
    font-style: normal;
    font-weight: 700;
    font-display: swap;
    src: url(fonts/source-sans-pro/source-sans-pro-latin-700-normal.woff2) format('woff2');
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

:root {
    --cv-font-sans: 'Source Sans Pro', system-ui, -apple-system, "Segoe UI", Roboto, Arial, sans-serif;

    /* The company's color, or STAFFILY NAVY when it has chosen none (#227; Carvin, 2026-10-16: "We
       can still do our colors until they decide otherwise but not our logo"). navy-800 #12305b is
       13.13:1 on white, the banner's darker end is navy-900 #0d2445 and the soft tint navy-50 -
       the website's own ramp. These three must match PortalBrand.StandardAccent and
       StandardAccentDark; StaffilyPaletteTests holds them equal. A company's color, served by
       CompanyBrandEndpoint, replaces all of this - only the "Powered by" footer stays Staffily's. */
    --brand-accent: #12305b;
    --brand-accent-dark: #0d2445;
    --brand-soft: #eef3fa;

    --carvin-accent: var(--brand-accent);
    --carvin-page: #f7f9fc;
    --portal-card-border: #e3e8ef;
    --portal-card-radius: 12px;
}

a {
    color: var(--brand-accent);
}

a:hover {
    color: var(--brand-accent-dark);
}

/* ---- The banner ------------------------------------------------------------------------------
   Every public page's header - home, registration, sign-in, terms - is the ArborWeb banner: white
   text on the company's color, running to its darker shade. */
.register__header,
.office__header {
    background: linear-gradient(135deg, var(--brand-accent), var(--brand-accent-dark));
    color: #fff;
    border: none;
    border-radius: var(--portal-card-radius);
    padding: 1.25rem 1.75rem;
    margin: 1.5rem 0;
    align-items: center;
}

.register__header h1,
.office__header h1 {
    color: #fff;
    font-weight: 400;
}

.register__header .language-switcher,
.register__header .language-switcher__label,
.register__header .language-switcher__current,
.register__header a {
    color: #fff;
}

/* The company's logo on its own white tile, so a dark or transparent logo stays visible on the banner. */
.register__logo {
    background: #fff;
    border-radius: 8px;
    padding: 0.35rem 0.6rem;
}

/* ---- Cards --------------------------------------------------------------------------------------
   The surfaces that hold a step or a section: white, a soft border, rounded - ArborWeb's home-card. */
.register__greeting,
.register__section,
.panel,
.data-right,
.applicant-card {
    background: var(--carvin-surface);
    border: 1px solid var(--portal-card-border);
    border-radius: var(--portal-card-radius);
}

.register__greeting {
    border-left: 4px solid var(--brand-accent);
}

/* The front door's action, as ArborWeb's primary button. */
.home-action {
    background: var(--brand-accent);
    border-radius: 8px;
    font-weight: 700;
}

.home-action:hover {
    background: var(--brand-accent-dark);
}

/* ---- The signed-in shell ------------------------------------------------------------------------
   ArborWeb's menu bar: white, dark text, a light shadow; the company's name in its color. */
.portal-header {
    border-bottom: 1px solid var(--portal-card-border);
    box-shadow: 0 1px 6px rgba(20, 40, 80, 0.08);
}

.portal-brand {
    display: inline-flex;
    align-items: center;
    gap: 0.6rem;
    color: var(--brand-accent-dark);
}

.portal-brand__logo {
    height: 30px;
    width: auto;
}

.portal-nav a:hover,
.portal-nav a:focus-visible {
    background: var(--brand-soft);
    color: var(--brand-accent-dark);
}

.portal-nav a.active {
    box-shadow: inset 0 -2px 0 var(--brand-accent);
}

/* ---- The applicant's onboarding checklist (issue #202) ------------------------------------------
   Their own steps on My forms, as an ArborWeb-style card: a tick for what they do, a mark for what
   happens on its own, and the due date - late ones bold and red. */
.checklist {
    background: var(--carvin-surface);
    border: 1px solid var(--portal-card-border);
    border-radius: var(--portal-card-radius);
    padding: 1rem 1.25rem;
    margin: 1.5rem 0;
}

.checklist h2 {
    font-size: 1.15rem;
    margin: 0 0 0.5rem;
}

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

.checklist__item {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem 0.75rem;
    padding: 0.5rem 0;
    border-bottom: 1px solid var(--portal-card-border);
}

.checklist__item:last-child {
    border-bottom: none;
}

.checklist__item input[type="checkbox"] {
    width: 1.25rem;
    height: 1.25rem;
}

.checklist__item--done label {
    color: var(--carvin-muted);
    text-decoration: line-through;
}

.checklist__auto {
    width: 1.25rem;
    text-align: center;
    color: var(--brand-accent);
}

.checklist__due {
    margin-left: auto;
    font-size: var(--portal-text-small);
    color: var(--carvin-muted);
}

.checklist__due--late {
    color: var(--carvin-danger);
    font-weight: 700;
}

/* ---- Sign in, forgot password, set a new PIN ---------------------------------------------------
   Carvin, 2026-10-13: "This screen is very unprofessional and has that amateur look, lets clean it up.
   Center the login box." The three are one family - somebody moves between them while locked out - so
   they share one card rather than three left-aligned pages with full-width rules. */
.auth-card {
    box-sizing: border-box;
    width: calc(100% - 2rem);
    max-width: 28rem;
    margin: clamp(1.5rem, 10vh, 6rem) auto 2rem;
    padding: 2rem 2rem 1.5rem;
    background: var(--cv-surface);
    border: 1px solid var(--cv-border);
    border-radius: var(--cv-radius-lg);
    box-shadow: var(--cv-shadow-raised);
}

.auth-card h1 {
    margin: 0 0 0.5rem;
    font-size: 1.75rem;
    text-align: center;
}

.auth-card .lede {
    margin: 0 0 1.5rem;
    text-align: center;
    font-size: 0.95rem;
}

.auth-card .form-questions {
    max-width: none;
}

.auth-card .form-question label {
    font-size: 0.9rem;
}

.auth-card .form-question input {
    box-sizing: border-box;
    padding: 0.6rem 0.75rem;
    font-size: 1rem;
    border: 1px solid var(--cv-border);
    border-radius: var(--cv-radius-md);
}

.auth-card button.primary {
    width: 100%;
    margin-top: 0.5rem;
    padding: 0.7rem 1rem;
    font-size: 1rem;
}

.auth-card .field__help {
    margin: 1rem 0 0;
    text-align: center;
}

.auth-card .field__help + .field__help {
    margin-top: 0.5rem;
}

/* Forgot and Set a new PIN build their fields from .field rather than .form-question; the card makes the
   two look the same, with hints under the box they describe rather than centered like the links. */
.auth-card .field {
    margin-bottom: 1rem;
}

.auth-card .field__label {
    display: block;
    margin-bottom: 0.25rem;
    font-size: 0.9rem;
    font-weight: 600;
}

.auth-card .field__input {
    box-sizing: border-box;
    width: 100%;
    padding: 0.6rem 0.75rem;
    font-size: 1rem;
    border: 1px solid var(--cv-border);
    border-radius: var(--cv-radius-md);
}

.auth-card .field .field__help {
    margin: 0.35rem 0 0;
    text-align: left;
}

.auth-card .home-action {
    display: block;
    border: none;
    padding: 0.7rem 1rem;
    font: inherit;
    font-size: 1rem;
    font-weight: 600;
    cursor: pointer;
    box-sizing: border-box;
    width: 100%;
    margin-top: 0.5rem;
    text-align: center;
}

/* ---- The signed-in pages, as one product ---------------------------------------------------------
   Carvin, 2026-10-13: "Lets try to clean up the look and feel and make the applicant portal more
   professional, it seems messy, and looks like an amatuer did it."

   What made it look that way, seen on every signed-in page at desktop and phone width:
   - THE PAGE MOVED BETWEEN TABS. Your details, Jobs and Activity centered themselves at 46rem; Your
     forms, Your information, Contact us and every form ran from the left edge of the window.
   - TWO KINDS OF TEXT BOX. The PIN boxes were styled; name, address, state and the message box were
     the browser's own thin grey outline, on the same page.
   - THE FORMS LIST WAS UNDERLINED WORDS, with nothing saying each one was a task to open.

   So: one column (MainLayout marks it), one box, and rows that look like what they are. */

.portal-main--app {
    box-sizing: border-box;
    width: 100%;
    max-width: 54rem;
    margin: 0 auto;
    padding: 2rem 1.25rem 3rem;
}

/* A form beside its blank reference needs the room for two columns (.form-fill, 75rem) - and only then. */
.portal-main--app:has(.form-reference) {
    max-width: 80rem;
}

/* The pages that used to center themselves now sit in the column like the rest. */
.portal-main--app .register,
.portal-main--app .office {
    max-width: none;
    padding: 0;
    margin: 0;
}

.portal-main--app h1 {
    margin: 0 0 0.5rem;
    font-size: var(--portal-h1);
    line-height: 1.25;
}

.portal-main--app .lede {
    margin: 0 0 1.5rem;
}

.portal-main--app .panel,
.portal-main--app .data-right,
.portal-main--app .register__section {
    max-width: none;
}

.portal-main--app .panel .form-questions,
.portal-main--app .register__section .form-questions {
    max-width: none;
}

/* ONE TEXT BOX - the sign-in card's, which Carvin had already approved. Checkboxes, radios and the
   file picker keep their own shapes; a full-width checkbox is the bug .form-question already fixes. */
.portal-main--app input:not([type="checkbox"]):not([type="radio"]):not([type="file"]):not([type="hidden"]),
.portal-main--app select,
.portal-main--app textarea {
    box-sizing: border-box;
    width: 100%;
    min-height: var(--portal-control);
    padding: 0.55rem 0.75rem;
    font: inherit;
    font-size: 1rem;
    color: var(--cv-text);
    background: var(--cv-input-bg, #fff);
    border: 1px solid var(--portal-card-border);
    border-radius: var(--cv-radius-md);
    transition: border-color 0.15s ease, box-shadow 0.15s ease;
}

.portal-main--app input:focus-visible,
.portal-main--app select:focus-visible,
.portal-main--app textarea:focus-visible {
    outline: none;
    border-color: var(--brand-accent);
    box-shadow: 0 0 0 3px var(--brand-soft);
}

.portal-main--app input:disabled,
.portal-main--app select:disabled {
    background: var(--carvin-page);
    color: var(--carvin-muted);
}

/* ---- Tasks: Your forms ---------------------------------------------------------------------------
   One card, one row per form, the whole row the link - the shape of the admin's Go to tiles, laid
   flat so a phone reads it top to bottom. */
.task-list {
    list-style: none;
    margin: 1rem 0 1.5rem;
    padding: 0;
    background: var(--carvin-surface);
    border: 1px solid var(--portal-card-border);
    border-radius: var(--portal-card-radius);
    overflow: hidden;
}

.task-list > li + li {
    border-top: 1px solid var(--portal-card-border);
}

.task-list__row {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    padding: 0.9rem 1.25rem;
    color: var(--carvin-ink);
    text-decoration: none;
}

a.task-list__row:hover,
a.task-list__row:focus-visible {
    background: var(--brand-soft);
    color: var(--carvin-ink);
}

a.task-list__row:focus-visible {
    outline: 2px solid var(--brand-accent);
    outline-offset: -2px;
}

.task-list__name {
    flex: 1 1 auto;
    min-width: 0;
    font-weight: 600;
}

.task-list__hint {
    display: block;
    margin-top: 0.15rem;
    font-weight: 400;
    font-size: var(--portal-text-small);
    color: var(--carvin-muted);
}

.task-list__go {
    flex: none;
    font-size: 1.5rem;
    line-height: 1;
    color: var(--carvin-muted);
}

a.task-list__row:hover .task-list__go {
    color: var(--brand-accent);
}

.task-list__row--done .task-list__name {
    font-weight: 400;
}

.task-list__tick {
    flex: none;
    display: inline-grid;
    place-items: center;
    width: 1.5rem;
    height: 1.5rem;
    border-radius: 50%;
    background: #e3f4ea;
    color: #1a6b3c;
    font-size: 0.85rem;
    font-weight: 700;
}

.task-list__action {
    flex: none;
    font-size: var(--portal-text-small);
}

/* The routes below the tabs, set apart from the work above them. */
.task-list--more {
    margin-top: 0.75rem;
}

.task-pill {
    flex: none;
    padding: 0.1rem 0.65rem;
    border-radius: 999px;
    font-size: 0.85rem;
    color: var(--carvin-muted);
    background: var(--carvin-page);
    border: 1px solid var(--portal-card-border);
    white-space: nowrap;
}

.task-pill--warn {
    color: #8a5000;
    background: #fff6e5;
    border-color: #f1d9a8;
}

/* ---- Activity ------------------------------------------------------------------------------------ */
.portal-main--app .activity {
    max-width: none;
    padding: 0 1.25rem;
    background: var(--carvin-surface);
    border: 1px solid var(--portal-card-border);
    border-radius: var(--portal-card-radius);
}

.portal-main--app .activity__item:last-child {
    border-bottom: none;
}

.activity__count {
    margin-left: 0.5rem;
    padding: 0.05rem 0.55rem;
    border-radius: 999px;
    font-size: 0.8rem;
    color: var(--carvin-muted);
    background: var(--carvin-page);
    border: 1px solid var(--portal-card-border);
}

/* ---- Completing a form: the steps as a stepper, not three words ---------------------------------- */
.portal-main--app .form-steps {
    gap: 0.5rem;
    margin: 0.75rem 0 1.5rem;
    counter-reset: step;
}

.portal-main--app .form-steps li {
    counter-increment: step;
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.3rem 0.9rem 0.3rem 0.35rem;
    border-radius: 999px;
    background: var(--carvin-surface);
    border: 1px solid var(--portal-card-border);
    color: var(--carvin-muted);
}

.portal-main--app .form-steps li::before {
    content: counter(step);
    display: inline-grid;
    place-items: center;
    width: 1.5rem;
    height: 1.5rem;
    border-radius: 50%;
    background: var(--carvin-page);
    font-size: 0.8rem;
    font-weight: 700;
}

.portal-main--app .form-steps .current {
    color: var(--brand-accent-dark);
    border-color: var(--brand-accent);
}

.portal-main--app .form-steps .current::before {
    background: var(--brand-accent);
    color: #fff;
}

.portal-main--app .form-steps .done {
    color: #1a6b3c;
}

.portal-main--app .form-steps .done::before {
    content: "\2713";
    background: #e3f4ea;
}

/* ---- The header on a phone ----------------------------------------------------------------------
   It wrapped into four rows - brand, two rows of sections, code and language, then Sign out - which
   pushed the page itself below the fold. The sections now scroll sideways on one line, and the
   applicant code steps back, since the Sign out beside it is what a shared tablet needs. */
@media (max-width: 40rem) {
    .portal-header {
        gap: 0.5rem 1rem;
        padding: 0.6rem 1rem;
    }

    .portal-nav {
        order: 3;
        flex-wrap: nowrap;
        width: 100%;
        overflow-x: auto;
        scrollbar-width: none;
    }

    .portal-nav a {
        white-space: nowrap;
    }

    .portal-header__end {
        gap: 0.5rem 0.75rem;
    }

    .portal-header__end .language-switcher__label,
    .portal-user {
        display: none;
    }

    .portal-signout {
        padding: 0.35rem 0.7rem;
    }

    .portal-main--app {
        padding: 1.25rem 1rem 2.5rem;
    }
}

/* The sign-in rows run the width of their card, like every other line in it. */
.portal-main--app .review {
    max-width: none;
}

.portal-main--app .checklist {
    margin-top: 0;
}

/* The plain buttons beside DevExpress's: the same size and no browser border, so a page with both
   does not show two kinds of button. */
.portal-main--app button.home-action {
    border: none;
    padding: 0.5rem 1.1rem;
    color: #fff;
    font: inherit;
    font-size: 0.95rem;
    font-weight: 600;
    cursor: pointer;
}

.portal-main--app button.home-action:disabled {
    opacity: 0.6;
    cursor: default;
}

/* ---- The quote signing page (#260) --------------------------------------------------------------
   An agency's client, not an applicant: one card, the agency's name at the top, and the quote itself
   as the page's main content once the emailed code has been entered. Narrow for the code steps, as
   the sign-in family is; wide for reading the quote and signing it. Nothing here frames anything but
   the quote's own data: PDF. */
.quote-sign {
    box-sizing: border-box;
    width: calc(100% - 2rem);
    max-width: 32rem;
    margin: clamp(1.5rem, 8vh, 4rem) auto 2rem;
    padding: 1.5rem 2rem 2rem;
    background: var(--cv-surface);
    border: 1px solid var(--cv-border);
    border-radius: var(--cv-radius-lg);
    box-shadow: var(--cv-shadow-raised);
}

.quote-sign--wide {
    max-width: 60rem;
}

.quote-sign__header {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
    margin-bottom: 1.25rem;
    padding-bottom: 0.75rem;
    border-bottom: 1px solid var(--cv-border);
}

.quote-sign__agency {
    display: inline-flex;
    align-items: center;
    gap: 0.6rem;
    font-weight: 700;
    color: var(--cv-text);
}

.quote-sign__logo {
    max-height: 2.5rem;
    max-width: 10rem;
    object-fit: contain;
}

.quote-sign h1 {
    margin: 0 0 0.5rem;
    font-size: var(--portal-h1);
    line-height: 1.25;
}

.quote-sign h2 {
    margin: 0 0 0.75rem;
    font-size: 1.15rem;
}

.quote-sign .lede {
    margin: 0 0 1.25rem;
    color: var(--cv-text-muted);
}

.quote-sign .field {
    margin-bottom: 1rem;
}

.quote-sign .field__label {
    display: block;
    margin-bottom: 0.25rem;
    font-weight: 600;
}

.quote-sign .field__input {
    box-sizing: border-box;
    width: 100%;
    padding: 0.6rem 0.75rem;
    font: inherit;
    border: 1px solid var(--cv-border);
    border-radius: var(--cv-radius-md);
    background: var(--cv-input-bg);
    color: var(--cv-text);
}

/* Six digits read across a room: spaced, monospaced, and no wider than they need. */
.quote-sign__code {
    max-width: 12rem;
    font-family: var(--cv-font-mono);
    font-size: 1.35rem;
    letter-spacing: 0.3em;
}

.quote-sign__actions {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.75rem 1.25rem;
    margin: 1rem 0 0;
}

.quote-sign__pdf {
    display: block;
    width: 100%;
    height: 75vh;
    min-height: 24rem;
    border: 1px solid var(--cv-border);
    border-radius: var(--cv-radius-md);
    background: var(--cv-surface-subtle);
}

.quote-sign__download {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem 1.25rem;
    align-items: center;
    margin: 0.75rem 0 0;
}

.quote-sign__panel {
    margin-top: 1.5rem;
    padding-top: 1.25rem;
    border-top: 1px solid var(--cv-border);
}

.quote-sign__authority {
    margin: 0.5rem 0 1rem;
}

/* A phone: the card becomes the page, and the quote frame gives way to the download link above it -
   most phone browsers will not draw a PDF inside a frame at all. */
@media (max-width: 40rem) {
    .quote-sign {
        width: 100%;
        margin: 0;
        padding: 1rem 1rem 1.5rem;
        border: none;
        border-radius: 0;
        box-shadow: none;
    }

    .quote-sign__pdf {
        height: 60vh;
        min-height: 18rem;
    }
}

/* The signature pad's own name and typed-signature boxes, as this page's other boxes. The pad's
   stylesheet leaves them to each page; here they would otherwise be the browser's thin default. */
.quote-sign .signature-name input,
.quote-sign .signature-typed {
    display: block;
    box-sizing: border-box;
    width: 100%;
    max-width: 28rem;
    margin-top: 0.25rem;
    padding: 0.6rem 0.75rem;
    font: inherit;
    border: 1px solid var(--cv-border);
    border-radius: var(--cv-radius-md);
    background: var(--cv-input-bg);
    color: var(--cv-text);
    font-weight: 400;
}

.quote-sign .signature-name,
.quote-sign .signature-typed-label {
    font-weight: 600;
}
