/*
 * Copper & Vine Client Portal — the portal's ONLY stylesheet. Plain CSS on
 * purpose. Mobile-first (hamburger flyout) with the menu becoming a fixed
 * left rail at >=1024px. Layout stays plain like the Family Room; button and
 * link colors mimic the copperandvine.com website (copper on cream-white).
 */

:root {
    --cv-ink: #1e2637;
    --cv-muted: #4b5563;
    --cv-muted-dark: #353c49;
    --cv-navy: #232f4b;
    --cv-accent: #3f5f46;        /* brand forest green, lifted 2026-07-27: the header is a
                                    large plane and reads lighter than a small button of the
                                    same ink, so the accent is lightened to match it by eye */
    --cv-accent-dark: #2d4531;   /* hover — lands exactly on the shell/header green */
    --cv-accent-light: #718074;
    --cv-accent-contrast: #ffffff;   /* ink on accent fills */
    --cv-link: #b87333;          /* brand copper — hyperlinks (official) */
    --cv-link-dark: #9c5b26;     /* copper hover */
    --cv-copper: #b87333;        /* brand copper — wordmark + folders only */
    --cv-copper-dark: #9c5b26;
    --cv-moss: #5a6844;
    --cv-success: #2aa953;
    --cv-amber: #f59e0b;
    --cv-danger: #e5484d;
    --cv-bg: #fcfaf4;              /* soft cream — synced with the staff shell */
    --cv-shell-green: #2d4531;     /* the staff header green (Green Rabbit) */
    /* Card header bars — the same green as the sidebar's selected row. */
    --cv-cardbar: color-mix(in srgb, #2d4531 21%, #ffffff);
    --cv-card: #ffffff;
    --cv-border: #e5e7eb;          /* cards + dividers — soft */
    --cv-border-strong: #c6ccd8;   /* form controls — survives bright monitors */
    --cv-hairline: rgba(184, 115, 51, 0.45);

    /* Alert set (2026-07-27): bootstrap-adjacent, tuned to the brand.
       Green = adds/saves/any success, pink = errors, yellow = warnings.
       System-wide — keep in sync with global/_base.scss. */
    --cv-alert-success-bg: #dbe9de;
    --cv-alert-success-border: #b9d4c0;
    --cv-alert-success-ink: #1d4425;
    --cv-alert-error-bg: #fadde2;
    --cv-alert-error-border: #f2bcc6;
    --cv-alert-error-ink: #8f2136;
    --cv-alert-warning-bg: #fcf3d0;
    --cv-alert-warning-border: #eedfa2;
    --cv-alert-warning-ink: #6b5210;
    --cv-alert-info-bg: #dde7f3;
    --cv-alert-info-border: #bccfe6;
    --cv-alert-info-ink: #1f3f6b;
}

* {
    box-sizing: border-box;
    margin: 0;
    padding: 0;
}

html {
    -webkit-text-size-adjust: 100%;
}

body {
    font-family: 'Jost', -apple-system, 'Segoe UI', sans-serif;
    background: var(--cv-bg);
    color: var(--cv-ink);
    line-height: 1.55;
    min-height: 100vh;
    display: flex;
    flex-direction: column;
}

a {
    color: var(--cv-link);
    text-decoration: none;
}

a:hover {
    color: var(--cv-link-dark);
}

a:hover,
a:focus {
    text-decoration: underline;
}

a:focus-visible,
button:focus-visible,
input:focus-visible {
    outline: 2px solid var(--cv-accent);
    outline-offset: 2px;
}

/* ---- header --------------------------------------------------------- */

/* Deep forest green bar with the white wordmark — the staff shell's header. */
.cv-header {
    background: var(--cv-shell-green);
    border-bottom: 1px solid color-mix(in srgb, var(--cv-shell-green) 70%, #000);
    height: 76px;   /* $cv-topbar-h — same bar height as the staff shell */
    padding: 0 16px;
    display: flex;
    align-items: center;
    justify-content: space-between;
    position: sticky;
    top: 0;
    z-index: 20;
}

/* Brand lockup: wordmark + "Client Portal" to its right, vertically centered */
/* Brand logo lockup (logo-web.png, transparent). */
.cv-brand--logo {
    display: flex;
    align-items: center;
    gap: 10px;
}

.cv-logo-img {
    height: 44px;
    width: auto;
    display: block;
}

.cv-brand {
    display: flex;
    align-items: center;
    gap: 14px;
    color: var(--cv-ink);
}

.cv-brand:hover,
.cv-brand:focus {
    text-decoration: none;
    color: var(--cv-ink);
}

.cv-brand-name {
    font-family: 'Cormorant Garamond', Georgia, serif;
    font-size: 25px;
    letter-spacing: 0.06em;
    color: var(--cv-navy);
    line-height: 1.1;
    display: inline-block;
}

.cv-brand-name b {
    font-weight: 600;
}

.cv-brand-sub {
    font-family: 'Jost', sans-serif;
    font-size: 11px;
    font-weight: 500;
    letter-spacing: 0.42em;
    text-transform: uppercase;
    color: var(--cv-copper-dark);
    display: block;
    margin-top: 2px;
    border-top: 1px solid var(--cv-hairline);
    border-bottom: 1px solid var(--cv-hairline);
    padding: 1px 0;
    text-align: center;
}

.cv-brand-portal {
    font-size: 15px;
    font-weight: 500;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: rgba(255, 255, 255, 0.85);
    border-left: 1px solid rgba(255, 255, 255, 0.35);
    padding-left: 14px;
    line-height: 1;
}

.cv-menu-btn {
    width: 48px;
    height: 48px;
    margin: -10px -12px -10px 0;
    border: 0;
    background: none;
    cursor: pointer;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 5px;
}

.cv-menu-btn span {
    display: block;
    width: 20px;
    height: 2px;
    border-radius: 2px;
    background: #fff;
}

/* ---- flyout menu ---------------------------------------------------- */

.cv-backdrop {
    position: fixed;
    inset: 0;
    background: rgba(26, 31, 46, 0.4);
    z-index: 30;
    opacity: 0;
    transition: opacity 0.2s ease;
}

.cv-backdrop.is-open {
    opacity: 1;
}

.cv-menu {
    position: fixed;
    top: 0;
    right: 0;
    bottom: 0;
    width: min(300px, 85vw);
    /* Light wash of the header green — the staff sidenav plane. */
    background: color-mix(in srgb, var(--cv-shell-green) 11%, var(--cv-card));
    z-index: 40;
    padding: 24px 12px;
    display: flex;
    flex-direction: column;
    box-shadow: -8px 0 30px rgba(26, 31, 46, 0.12);
    transform: translateX(105%);
    transition: transform 0.25s ease;
    visibility: hidden;
}

.cv-menu.is-open {
    transform: translateX(0);
    visibility: visible;
}

.cv-menu-close {
    position: absolute;
    top: 10px;
    right: 10px;
    width: 44px;
    height: 44px;
    border: 0;
    background: none;
    cursor: pointer;
    font-size: 26px;
    line-height: 1;
    color: var(--cv-muted);
    border-radius: 8px;
}

.cv-menu-close {
    border-radius: 4px;
}

.cv-menu-close:hover,
.cv-menu-close:focus {
    background: color-mix(in srgb, var(--cv-shell-green) 18%, var(--cv-card));
    color: var(--cv-ink);
}

.cv-menu-name {
    font-weight: 600;
    color: var(--cv-muted);
    font-size: 13px;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    padding: 0 16px 14px;
    border-bottom: 1px solid var(--cv-border);
    margin-bottom: 8px;
}

.cv-menu a {
    display: flex;
    align-items: center;
    gap: 11px;
    padding: 12px 14px;
    min-height: 46px;
    font-size: 17px;   /* staff sidenav size */
    font-weight: 500;
    color: var(--cv-muted-dark);
    border-radius: 4px;
    margin: 1px 0;
}

.cv-menu a .cv-icon {
    width: 17px;
    height: 17px;
    flex: 0 0 auto;
}

/* NEW pill — a file the signed-in user hasn't seen (its folder wasn't
   opened since the file arrived), or a folder holding such files. */
.cv-new-pill {
    display: inline-block;
    margin-left: 4px;
    padding: 1px 6px 0;
    border-radius: 4px;
    background: var(--cv-copper);
    color: #fff;
    font-size: 10.5px;
    font-weight: 700;
    letter-spacing: 0.06em;
    line-height: 16px;
    vertical-align: 2px;
}

/* Sidebar count badges — brand copper, same geometry as the staff
   sidenav's. Rendered only when the count is nonzero. */
.cv-nav-badge {
    margin-left: auto;
    min-width: 22px;
    height: 21px;
    padding: 0 7px;
    border-radius: 5px;
    background: var(--cv-copper);
    color: #fff;
    font-size: 12px;
    font-weight: 700;
    line-height: 21px;
    text-align: center;
}

.cv-icon {
    fill: none;
    stroke: currentColor;
}

.cv-menu a:hover,
.cv-menu a:focus {
    background: color-mix(in srgb, var(--cv-shell-green) 18%, var(--cv-card));
    color: var(--cv-ink);
    text-decoration: none;
}

.cv-menu a.is-active {
    border-left: 4px solid var(--cv-accent);
    border-radius: 0 4px 4px 0;
    padding-left: 10px;
    background: color-mix(in srgb, var(--cv-shell-green) 21%, var(--cv-card));
    color: var(--cv-ink);
    font-weight: 600;
}

/* Disabled during onboarding (same treatment as the staff sidenav's
   coming-soon rows). The filter is the boundary; this is the mirror. */
.cv-menu a.is-soon {
    opacity: 0.45;
    cursor: default;
}

.cv-menu a.is-soon:hover,
.cv-menu a.is-soon:focus {
    background: transparent;
    color: var(--cv-muted-dark);
}

.cv-menu a.is-active .cv-icon {
    color: var(--cv-accent);
}

.cv-menu-signout {
    /* Sits right under the last nav link (not pinned to the rail bottom,
       where it scrolled out of sight on tall screens). */
    margin-top: 10px;
    color: var(--cv-muted) !important;
    border-top: 1px solid var(--cv-border);
    border-radius: 0 !important;
}

/* ---- page column ---------------------------------------------------- */

.cv-main {
    width: 100%;
    max-width: 680px;
    margin: 0 auto;
    padding: 16px 14px 28px;
    flex: 1;
}

/* Signed-out (auth) pages: a plain centered column — deliberately NOT
   .cv-main, whose desktop rules assume the sidebar's 240px offset. */
.cv-auth-main {
    width: 100%;
    max-width: 600px;
    margin: 0 auto;
    padding: 16px 14px 28px;
    flex: 1;
}

.cv-footer {
    text-align: center;
    font-size: 12px;
    color: var(--cv-muted);
    padding: 20px;
}

/* ---- flashes -------------------------------------------------------- */

.cv-flash {
    border-radius: 4px;
    padding: 11px 14px;
    font-size: 16px;
    margin-bottom: 8px;
    transition: opacity 0.4s ease;
}

.cv-flash--success {
    background: var(--cv-alert-success-bg);
    border: 1px solid var(--cv-alert-success-border);
    color: var(--cv-alert-success-ink);
}

.cv-flash--error {
    background: var(--cv-alert-error-bg);
    border: 1px solid var(--cv-alert-error-border);
    color: var(--cv-alert-error-ink);
}

.cv-flash--warning {
    background: var(--cv-alert-warning-bg);
    border: 1px solid var(--cv-alert-warning-border);
    color: var(--cv-alert-warning-ink);
}

/* Blue: a statement of fact, not an outcome (nothing succeeded or failed). */
.cv-flash--info {
    background: var(--cv-alert-info-bg);
    border: 1px solid var(--cv-alert-info-border);
    color: var(--cv-alert-info-ink);
}

.cv-flash.is-dismissed {
    opacity: 0;
}

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

.cv-card {
    background: var(--cv-card);
    border: 1px solid var(--cv-border);
    border-radius: 4px;
    box-shadow: 0 1px 3px rgba(26, 31, 46, 0.05);
    padding: 16px 16px;
    margin-bottom: 8px;
}

.cv-card--auth {
    margin-top: 4vh;
    text-align: center;
    padding-left: 40px;
    padding-right: 40px;
    padding-bottom: 40px;
}

/* Signed-out pages have no top chrome; the auth card carries the brand
   itself — a green head band with the white wordmark centered. */
.cv-card--auth::before {
    content: "";
    display: block;
    height: 76px;
    margin: -16px -40px 20px;
    border-radius: 3px 3px 0 0;
    background: var(--cv-shell-green) url("/assets/img/logo-white.png") no-repeat center / auto 44px;
}

/* Signed-in pages already wear the logo in the site header — the same
   card there keeps just a slim green crown instead of repeating it. */
.cv-main .cv-card--auth::before {
    height: 8px;
    background: var(--cv-shell-green);
}

.cv-card--auth .cv-sub {
    font-size: 17px;
}

.cv-card--auth .cv-alt-link {
    font-size: 16px;
}

.cv-card--auth .cv-btn-link {
    font-size: 16px;
}

.cv-card--auth .cv-task-notes summary {
    font-size: 16px;
}

.cv-card-heading {
    font-size: 13px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--cv-muted);
    margin-bottom: 8px;
}

.cv-card-link {
    display: inline-block;
    margin-top: 14px;
    font-weight: 700;
    font-size: 15px;
    color: var(--cv-accent);
}

.cv-muted {
    color: var(--cv-muted);
    font-size: 15px;
}

.cv-quiet-link {
    text-align: center;
    font-size: 15px;
    margin: 4px 0 14px;
}

.cv-quiet-link a {
    display: inline-block;
    font-weight: 600;
    padding: 8px 16px;
    border-radius: 4px;
    background: var(--cv-card);
    border: 1px solid var(--cv-border);
    color: var(--cv-accent);
}

.cv-quiet-link a:hover,
.cv-quiet-link a:focus {
    background: var(--cv-bg);
    text-decoration: none;
}

.cv-smallprint {
    font-size: 13px;
    color: var(--cv-muted);
    text-align: center;
    margin-top: 12px;
}

/* ---- titles --------------------------------------------------------- */

.cv-title {
    font-size: 22px;
    font-weight: 700;
    letter-spacing: -0.01em;
    margin-bottom: 8px;
}

.cv-sub {
    color: var(--cv-muted);
    font-size: 15px;
    margin-bottom: 10px;
}

.cv-page-title {
    font-size: 24px;
    font-weight: 700;
    letter-spacing: -0.01em;
}

.cv-page-sub {
    color: var(--cv-muted-dark);
    font-size: 15px;
    margin: 2px 0 14px;
}

.cv-greeting {
    font-size: 17px;
    color: var(--cv-muted-dark);
    margin-bottom: 10px;
}

/* ---- forms + buttons ------------------------------------------------ */

.cv-label {
    display: block;
    text-align: left;
    font-size: 15px;
    font-weight: 500;
    margin-bottom: 6px;
}

.cv-visually-hidden {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
}

.cv-input {
    width: 100%;
    font: inherit;
    font-size: 16px;
    padding: 12px 14px;
    min-height: 48px;
    border: 1px solid var(--cv-border-strong);
    border-radius: 4px;
    background: var(--cv-card);
    color: var(--cv-ink);
    margin-bottom: 16px;
}

.cv-input:focus {
    border-color: var(--cv-accent);
    outline: 2px solid rgba(52, 77, 47, 0.32);
    outline-offset: 0;
}

/* ---- stacked in-card forms (My Family invite) ------------------------ */

.cv-form {
    margin-top: 14px;
}

.cv-field {
    display: block;
    margin-bottom: 14px;
}

.cv-field > span {
    display: block;
    font-size: 15px;
    font-weight: 600;
    margin-bottom: 6px;
}

.cv-field em {
    font-weight: 400;
    font-style: normal;
    color: var(--cv-muted);
}

.cv-field input,
.cv-field select {
    width: 100%;
    font: inherit;
    font-size: 16px;
    padding: 12px 14px;
    min-height: 48px;
    border: 1px solid var(--cv-border-strong);
    border-radius: 4px;
    background: var(--cv-card);
    color: var(--cv-ink);
}


/* Custom chevron: the native one hugs the box edge and ignores padding.
   EVERY select, not just the ones inside .cv-field — a select outside that
   wrapper fell back to the native arrow jammed against the border, which is
   how the calendar's time pickers ended up looking wrong. */
select,
select.cv-input {
    appearance: none;
    -webkit-appearance: none;
    padding-right: 40px;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath d='M1 1l5 5 5-5' fill='none' stroke='%234b5563' stroke-width='2' stroke-linecap='round'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 14px center;
}


/* The hidden attribute always wins — component display rules kept beating
   the UA default and "hidden" elements stayed visible. */
[hidden] {
    display: none !important;
}

/* Radios/checkboxes are controls, not text fields — exempt them from the
   48px text-input treatment. */
.cv-field input[type='radio'],
.cv-field input[type='checkbox'] {
    width: 16px;
    height: 16px;
    min-height: 0;
    padding: 0;
    accent-color: var(--cv-accent);
    flex: 0 0 auto;
}

/* Questionnaire: textareas match the text-input treatment; auto-growing
   ones drop the manual resize handle (portal.js sizes them). */
.cv-field textarea {
    width: 100%;
    font: inherit;
    font-size: 16px;
    padding: 12px 14px;
    border: 1px solid var(--cv-border-strong);
    border-radius: 4px;
    background: var(--cv-card);
    color: var(--cv-ink);
}

.cv-field textarea[data-autogrow] {
    resize: none;
    overflow: hidden;
}

/* Outranks the .cv-field > span label rule, which display:block'ed the
   group and let the options squish together inline. */
.cv-radio-group,
.cv-field > span.cv-radio-group {
    display: flex;
    flex-direction: column;
    gap: 9px;
    margin-bottom: 0;
    font-weight: 400;
    font-size: 16px;
}

.cv-radio,
.cv-check {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    font-size: 16px;
}

.cv-check input[type='checkbox'],
.cv-radio input[type='radio'] {
    width: 16px;
    height: 16px;
    min-height: 0;
    padding: 0;
    accent-color: var(--cv-accent);
    flex: 0 0 auto;
}

.cv-field-error {
    display: block;
    margin-top: 5px;
    font-size: 14px;
    color: var(--cv-danger);
}

fieldset.cv-field {
    border: 0;
    padding: 0;
    margin: 0;
}

fieldset.cv-field legend {
    font-weight: 600;
    font-size: 15px;
    margin-bottom: 6px;
    padding: 0;
}

fieldset.cv-field label {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    margin-right: 18px;
    font-size: 15px;
}

.cv-field input:focus,
.cv-field select:focus {
    border-color: var(--cv-accent);
    outline: 2px solid rgba(52, 77, 47, 0.32);
    outline-offset: 0;
}

/* Room-access note (My Family) — quiet but readable, two centered lines. */
.cv-access-note {
    margin: 18px auto 0;
    font-size: 16px;
    line-height: 1.5;
    color: var(--cv-muted);
    text-align: center;
}

.cv-code-input {
    font-size: 24px;
    letter-spacing: 0.5em;
    text-align: center;
    text-indent: 0.5em; /* recenters despite the trailing letter-space */
    font-variant-numeric: tabular-nums;
}

.cv-btn {
    display: block;
    width: 100%;
    font: inherit;
    font-size: 16px;
    font-weight: 600;
    text-transform: capitalize;
    min-height: 48px;
    padding: 12px 20px;
    border-radius: 4px;
    border: 0;
    cursor: pointer;
    text-align: center;
}

.cv-btn:hover,
.cv-btn:focus {
    text-decoration: none;
}

/* Anchor-buttons: the global a:hover paints link text copper — buttons
   keep their own text colors on hover. */
a.cv-btn--primary:hover,
a.cv-btn--primary:focus {
    color: #fff;
}

a.cv-btn--secondary:hover,
a.cv-btn--secondary:focus {
    color: var(--cv-accent-dark);
}

/* File picker: the native input hides (still focusable for keyboards);
   the purple label IS the picker. Sending… state while the form posts. */
.cv-file-input {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
    border: 0;
}

.cv-file-btn {
    display: inline-block;
    width: auto;
    padding: 12px 24px;
    text-align: center;
    cursor: pointer;
    margin: 14px 0 0;
}

.cv-file-input:focus-visible + .cv-file-btn {
    outline: 2px solid var(--cv-accent, #b87333);
    outline-offset: 2px;
}

.cv-file-btn.is-busy {
    opacity: 0.7;
    pointer-events: none;
}

.cv-btn--primary {
    background: var(--cv-accent);
    color: #fff;
}

.cv-btn--primary:hover {
    background: var(--cv-accent-dark);
}

.cv-btn--secondary {
    background: var(--cv-card);
    color: var(--cv-accent-dark);
    border: 1px solid rgba(52, 77, 47, 0.65);
}

.cv-btn--secondary:hover {
    background: rgba(52, 77, 47, 0.08);
    color: var(--cv-accent-dark);
}

.cv-btn--request {
    margin-bottom: 10px;
}

.cv-btn-link {
    background: none;
    border: 0;
    font: inherit;
    font-size: 15px;
    color: var(--cv-link);
    cursor: pointer;
    padding: 12px;
    min-height: 44px;
}

.cv-btn-link:hover {
    text-decoration: underline;
}

.cv-resend {
    margin-top: 6px;
}

.cv-alt-link {
    font-size: 15px;
    margin-top: 4px;
}

/* ---- case chooser --------------------------------------------------- */

.cv-case-choice {
    margin-bottom: 8px;
}

.cv-case-btn {
    display: block;
    width: 100%;
    text-align: left;
    font: inherit;
    background: var(--cv-card);
    border: 1px solid var(--cv-border);
    border-radius: 4px;
    padding: 16px;
    cursor: pointer;
}

.cv-case-btn:hover,
.cv-case-btn:focus {
    border-color: var(--cv-accent);
}

.cv-case-name {
    display: block;
    font-weight: 600;
    font-size: 16px;
}

.cv-case-meta {
    display: block;
    color: var(--cv-muted);
    font-size: 15px;
    margin-top: 2px;
}

/* ---- dashboard ------------------------------------------------------ */

.cv-card--decedent {
    text-align: center;
    padding: 28px 20px;
}

.cv-decedent-name {
    font-size: 22px;
    font-weight: 700;
    letter-spacing: -0.01em;
}

.cv-decedent-case {
    color: var(--cv-muted-dark);
    font-size: 15px;
    margin-top: 4px;
}

.cv-latest {
    display: flex;
    align-items: flex-start;
    gap: 12px;
}

.cv-latest-title {
    font-weight: 600;
}

.cv-latest-time {
    color: var(--cv-muted-dark);
    font-size: 13px;
}

.cv-balance-amount {
    font-size: 24px;
    font-weight: 700;
    letter-spacing: -0.01em;
}

.cv-balance-amount--due {
    color: var(--cv-danger);
}

.cv-note {
    font-size: 15px;
    margin-top: 8px;
}

.cv-note--amber {
    color: #92650b;
    background: #fdf3e0;
    border: 1px solid #f6e0b3;
    border-radius: 4px;
    padding: 10px 12px;
}

/* ---- timeline ------------------------------------------------------- */

.cv-tl-day-label {
    font-size: 13px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--cv-muted-dark);
    margin: 22px 0 10px;
}

.cv-tl-day:first-child .cv-tl-day-label {
    margin-top: 0;
}

.cv-tl-event {
    display: flex;
    align-items: flex-start;
    gap: 12px;
    position: relative;
    padding-bottom: 18px;
}

/* the connecting rail — from each marker down to the next */
.cv-tl-event::before {
    content: '';
    position: absolute;
    left: 9px;
    top: 24px;
    bottom: -2px;
    width: 2px;
    background: var(--cv-border);
}

.cv-tl-event:last-child::before {
    display: none;
}

/* timeline markers: bare glyphs for settled steps, a circle for the
   current one */
.cv-mark {
    flex: 0 0 auto;
    width: 20px;
    text-align: center;
    line-height: 22px;
    position: relative;
    z-index: 1;
}

/* SVG-drawn glyphs — thick strokes that actually read at 18px (the
   unicode check was a hairline). Colors are baked into the data URIs
   (CSS vars can't reach inside them): success #2aa953, danger #e5484d. */
.cv-mark--check::after,
.cv-mark--x::after {
    content: '';
    display: inline-block;
    width: 18px;
    height: 18px;
    vertical-align: middle;
    background-repeat: no-repeat;
    background-size: 18px 18px;
}

.cv-mark--check::after {
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M2.5 8.5 6 12 13.5 3.5' fill='none' stroke='%232aa953' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
}

.cv-mark--x::after {
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M3.5 3.5 12.5 12.5 M12.5 3.5 3.5 12.5' fill='none' stroke='%23e5484d' stroke-width='3' stroke-linecap='round'/%3E%3C/svg%3E");
}

.cv-mark--now::after,
.cv-mark--pending::after {
    content: '';
    display: inline-block;
    width: 14px;
    height: 14px;
    border-radius: 50%;
    vertical-align: middle;
}

.cv-mark--now-good::after { background: var(--cv-success); }
.cv-mark--now-bad::after  { background: var(--cv-danger); }
.cv-mark--pending::after {
    background: var(--cv-card);
    border: 2px solid var(--cv-muted);
}

.cv-dot {
    flex: 0 0 auto;
    width: 14px;
    height: 14px;
    border-radius: 50%;
    margin-top: 4px;
    border: 2px solid var(--cv-muted);
    background: var(--cv-card);
}

.cv-dot--success { border-color: var(--cv-success); }
.cv-dot--warning { border-color: var(--cv-amber); }
.cv-dot--danger  { border-color: var(--cv-danger); }
.cv-dot--neutral { border-color: var(--cv-muted); }

.cv-dot--done.cv-dot--success { background: var(--cv-success); }
.cv-dot--done.cv-dot--warning { background: var(--cv-amber); }
.cv-dot--done.cv-dot--danger  { background: var(--cv-danger); }
.cv-dot--done.cv-dot--neutral { background: var(--cv-muted); }

.cv-tl-title {
    font-weight: 600;
    font-size: 16px;
}

.cv-tl-body--pending .cv-tl-title {
    color: var(--cv-muted);
    font-weight: 500;
}

.cv-tl-note {
    color: var(--cv-muted);
    font-size: 15px;
    margin-top: 2px;
}

.cv-tl-time {
    color: var(--cv-muted-dark);
    font-size: 12px;
    margin-top: 3px;
}

/* ---- order + payments ----------------------------------------------- */

.cv-order-list,
.cv-pay-list {
    list-style: none;
}

.cv-order-item,
.cv-pay-item {
    display: flex;
    justify-content: space-between;
    align-items: flex-start;
    gap: 14px;
    padding: 10px 0;
    border-bottom: 1px solid var(--cv-border);
    font-size: 16px;
}

.cv-order-item:last-child,
.cv-pay-item:last-child {
    border-bottom: 0;
}

.cv-order-item--sub {
    padding-left: 16px;
    color: var(--cv-muted);
}

.cv-order-name {
    min-width: 0;
}

.cv-order-qty {
    color: var(--cv-muted);
    font-size: 13px;
}

.cv-order-detail {
    display: block;
    color: var(--cv-muted);
    font-size: 13px;
}

.cv-order-amount,
.cv-pay-amount {
    white-space: nowrap;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
}

.cv-pay-amount--refund {
    color: var(--cv-danger);
}

.cv-pay-method {
    display: block;
    font-weight: 500;
}

.cv-pay-date {
    display: block;
    color: var(--cv-muted);
    font-size: 13px;
}

.cv-order-totals {
    border-top: 2px solid var(--cv-border);
    margin-top: 4px;
    padding-top: 10px;
}

.cv-order-total-row {
    display: flex;
    justify-content: space-between;
    font-size: 15px;
    padding: 3px 0;
    color: var(--cv-muted);
}

.cv-order-total-row--total {
    color: var(--cv-ink);
    font-weight: 700;
    font-size: 16px;
}

.cv-balance-due {
    color: var(--cv-danger);
}

.cv-balance-paid {
    color: var(--cv-success);
}

/* ---- account -------------------------------------------------------- */

.cv-account-name {
    font-size: 18px;
    font-weight: 600;
}

.cv-phone {
    font-size: 20px;
    font-weight: 600;
}

/* ---- motion --------------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
    *,
    *::before,
    *::after {
        transition: none !important;
        animation: none !important;
    }
}

/* ---- desktop: the menu becomes a fixed LEFT RAIL (>=1024px) ----------
   Mirrors the main FA app's left sidebar; the hamburger + slide-in
   behavior stays for phones/tablets below the breakpoint. */
@media (min-width: 1024px) {
    body { overflow-x: hidden; }
    .cv-menu-btn { display: none; }
    .cv-menu-close { display: none; }
    .cv-backdrop { display: none !important; }

    .cv-menu {
        left: 0;
        right: auto;
        top: 0;
        width: 240px;
        transform: none;
        visibility: visible;
        box-shadow: none;
        border-right: 1px solid var(--cv-border);
        padding-top: 112px;   /* clears the sticky header */
        z-index: 10;
    }

    .cv-header {
        padding-left: 24px;
        z-index: 30;
    }

    .cv-main {
        margin-left: 240px;
        /* width:auto, NOT the base width:100% — 100% of body plus the
           240px margin made the page 240px wider than the viewport, an
           invisible gutter until something (the PDF embed grabbing focus)
           scrolled the page into it and shoved everything under the rail. */
        width: auto;
        /* one reading column sitting right beside the rail (grid keeps
           children STACKED; flex laid them out in a row). 780 breathes —
           640 squeezed the task bars and the doc viewer (Tim, 2026-07-31). */
        display: grid;
        grid-template-columns: minmax(auto, 780px);
        justify-content: start;
        padding-left: 32px;
        /* pack rows at the top — the default stretch distributed the
           viewport's leftover height BETWEEN cards (huge gaps). */
        align-content: start;
        max-width: none;
    }
}

/* Between desktop-rail and full width, the rail collapses to a 72px icon
   strip — the staff shell's behavior: larger centered icons, tooltips. */
@media (min-width: 1024px) and (max-width: 1499px) {
    .cv-menu {
        width: 72px;
        padding-left: 10px;
        padding-right: 10px;
    }

    .cv-menu-name { display: none; }

    .cv-menu a {
        justify-content: center;
        gap: 0;
        padding: 13px 0;
    }

    .cv-menu a span { display: none; }

    .cv-menu a .cv-icon {
        width: 22px;
        height: 22px;
    }

    .cv-menu a.is-active { padding-left: 0; }

    /* Counts survive the collapse as a mini badge on the icon's corner. */
    .cv-menu a { position: relative; }

    .cv-menu a span.cv-nav-badge {
        display: block;
        position: absolute;
        top: 3px;
        right: 8px;
        min-width: 16px;
        height: 15px;
        padding: 0 4px;
        border-radius: 4px;
        font-size: 10px;
        line-height: 15px;
    }

    .cv-main {
        margin-left: 72px;
    }
}

/* ---- print: 8.5x11-friendly, full-width, chrome-free ----------------
   Billing/timeline/etc print as clean documents: no header bar, menu,
   buttons, or backdrops; cards flatten to bordered sections; the whole
   page uses the paper width instead of the phone column. */
@media print {
    .cv-header,
    .cv-menu,
    .cv-menu-btn,
    .cv-backdrop,
    .cv-flash,
    .cv-btn,
    button,
    .cv-footer { display: none !important; }

    body { background: #fff; color: #000; }

    .cv-main {
        margin: 0;
        padding: 0;
        display: block;
        max-width: none;
    }
    .cv-main > * { max-width: none; width: auto; }

    .cv-card {
        box-shadow: none;
        border: 1px solid #bbb;
        break-inside: avoid;
        margin-bottom: 14pt;
    }

    a { color: #000; text-decoration: none; }
    /* provider receipt links etc: show where they point */
    .cv-payments a[href^="http"]::after { content: " (" attr(href) ")"; font-size: 9pt; color: #555; }

    /* timeline markers keep their ink on paper */
    .cv-mark, .cv-mark::after, .cv-tl-event::before {
        -webkit-print-color-adjust: exact;
        print-color-adjust: exact;
    }

    @page { margin: 0.75in; }
}

/* ---- My Family ------------------------------------------------------ */

.cv-member {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    padding: 9px 0;
    border-bottom: 1px solid var(--cv-border);
}
.cv-member:last-child { border-bottom: 0; }
.cv-member-main { display: flex; flex-direction: column; min-width: 0; }
.cv-member-name { font-weight: 600; }
.cv-member-name em { font-weight: 400; color: var(--cv-muted); font-style: normal; }
.cv-member-sub { font-size: 13px; color: var(--cv-muted); }
.cv-member-status {
    flex: 0 0 auto;
    font-size: 12px;
    font-weight: 600;
    padding: 4px 10px;
    border-radius: 999px;
    background: var(--cv-bg);
    color: var(--cv-muted);
}
.cv-member-status--active { background: rgba(42, 169, 83, 0.12); color: #1e7c3e; }
.cv-member-status--pending_approval { background: rgba(245, 158, 11, 0.14); color: #92600a; }

/* ---- Messages (shared family chat) ---------------------------------- */

.cv-chat { padding: 0; display: flex; flex-direction: column; }
.cv-chat-scroll {
    flex: 1 1 auto;
    overflow-y: auto;
    max-height: min(60vh, 520px);
    min-height: 220px;
    padding: 14px 14px 8px;
    display: flex;
    flex-direction: column;
    gap: 10px;
}
.cv-chat-empty {
    color: var(--cv-muted);
    font-size: 15px;
    text-align: center;
    margin: auto 0;
    padding: 24px 8px;
}
.cv-chat-msg { max-width: 72%; align-self: flex-start; }
.cv-chat-msg--mine { align-self: flex-end; text-align: right; }
/* Sender avatars (2026-08-04): photo when servable on this host, colored
   initials otherwise. Own messages mirror the row. */
.cv-chat-msgrow { display: flex; gap: 8px; align-items: flex-end; }
.cv-chat-msg--mine .cv-chat-msgrow { flex-direction: row-reverse; }
.cv-chat-ava {
    width: 28px; height: 28px; flex: 0 0 28px;
    border-radius: 50%; overflow: hidden;
    display: grid; place-items: center;
    background: #5b6d99; color: #fff;
    font-size: 11px; font-weight: 600; letter-spacing: 0.02em;
    user-select: none;
}
.cv-chat-ava img { width: 100%; height: 100%; object-fit: cover; display: block; }
.cv-chat-msgcol { min-width: 0; display: flex; flex-direction: column; }
.cv-chat-msg--mine .cv-chat-msgcol { align-items: flex-end; }
.cv-chat-meta {
    font-size: 13px;
    color: var(--cv-muted);
    margin-bottom: 4px;
    padding: 0 4px;
}
/* Staff-shell bubble anatomy: 8px radius, 15px text. The client's own
   messages are brand green; Copper & Vine's are the light gray. */
.cv-chat-bubble {
    display: inline-block;
    text-align: left;
    background: color-mix(in srgb, var(--cv-ink) 6%, #fff);
    border-radius: 8px;
    padding: 12px 16px;
    font-size: 15px;
    line-height: 1.55;
    word-break: break-word;
}
.cv-chat-msg--mine .cv-chat-bubble {
    background: color-mix(in srgb, var(--cv-success) 18%, var(--cv-card));
    color: var(--cv-ink);
}
.cv-chat-msg--home .cv-chat-bubble {
    background: color-mix(in srgb, var(--cv-ink) 6%, #fff);
    color: var(--cv-ink);
}
.cv-chat-divider {
    display: flex;
    align-items: center;
    gap: 10px;
    color: var(--cv-muted);
    font-size: 12px;
    margin: 6px 0;
}
.cv-chat-divider::before,
.cv-chat-divider::after {
    content: "";
    flex: 1;
    border-top: 1px solid var(--cv-border);
}
.cv-chat-form {
    display: flex;
    gap: 8px;
    align-items: flex-end;
    padding: 10px 14px;
    border-top: 1px solid var(--cv-border);
}
.cv-chat-form textarea {
    flex: 1;
    min-width: 0;
    resize: none;
    border: 1px solid var(--cv-border-strong);
    border-radius: 8px;
    padding: 9px 12px;
    font: inherit;
    font-size: 15px;
    min-height: 40px;
    max-height: 120px;
    background: var(--cv-card);
}
.cv-chat-form textarea:focus {
    outline: 2px solid var(--cv-accent);
    outline-offset: -1px;
    background: #fff;
}
/* the base .cv-btn is block/full-width for tap targets — the chat Send
   sits BESIDE the textarea, so it must shrink to its label */
.cv-chat-form .cv-btn {
    display: inline-block;
    width: auto;
    flex: 0 0 auto;
    margin: 0;
    min-height: 40px;
    padding: 9px 18px;
}

@media print {
    .cv-chat-form { display: none !important; }
    .cv-chat-scroll { max-height: none; overflow: visible; }
}

/* ---- Tasks ---------------------------------------------------------- */

.cv-task {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    padding: 10px 0;
    border-bottom: 1px solid var(--cv-border);
}
.cv-task:last-of-type { border-bottom: 0; }
.cv-task-main { display: flex; flex-direction: column; min-width: 0; }
.cv-task-title { font-weight: 600; }
.cv-task-note { font-size: 13px; color: var(--cv-muted); }
.cv-task-btn {
    display: inline-block;
    width: auto;
    min-height: 36px;
    padding: 7px 14px;
    font-size: 15px;
}
.cv-task-status {
    flex: 0 0 auto;
    font-size: 12px;
    font-weight: 600;
    padding: 4px 10px;
    border-radius: 999px;
    background: var(--cv-bg);
    color: var(--cv-muted);
    white-space: nowrap;
}
.cv-task-status--done { background: rgba(42, 169, 83, 0.12); color: #1e7c3e; }
.cv-task-status--review { background: rgba(245, 158, 11, 0.14); color: #92600a; }

/* ---- Documents ------------------------------------------------------ */

.cv-doc {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 10px 0;
    border-bottom: 1px solid var(--cv-border);
}
.cv-doc:last-of-type { border-bottom: 0; }
.cv-doc-thumb {
    flex: 0 0 auto;
    width: 72px;
    height: 48px;
    border-radius: 4px;
    overflow: hidden;
    border: 1px solid var(--cv-border);
    background: var(--cv-bg);
}
.cv-doc-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.cv-doc-main { display: flex; flex-direction: column; min-width: 0; }
.cv-doc-name { font-weight: 600; }
.cv-doc-sub { font-size: 13px; color: var(--cv-muted); }
.cv-doc-privacy { margin-top: 10px; font-size: 12px; }
.cv-card--soon { opacity: 0.65; }
input[type="file"] {
    font: inherit;
    font-size: 15px;
    padding: 8px 0;
}

@media print {
    .cv-doc-thumb { display: none; }
}

/* non-image uploads: extension chip instead of a thumbnail */
.cv-doc-thumb--file {
    display: flex;
    align-items: center;
    justify-content: center;
    text-decoration: none;
}
.cv-doc-thumb--file:hover,
.cv-doc-thumb--file:focus { text-decoration: none; }
.cv-doc-ext {
    font-size: 12px;
    font-weight: 700;
    color: var(--cv-accent);
    letter-spacing: 0.04em;
}

/* ---- protected message segments (blur / blur+lock) ------------------- */
/* The decoy mask renders blurred; plaintext only ever arrives via the
   reveal endpoint and leaves the DOM again on re-lock. */

.cv-seg-blur,
.cv-seg-lock {
    filter: blur(5px);
    cursor: pointer;
    border-radius: 3px;
    transition: filter 0.15s ease;
}

.cv-seg-blur.is-revealed,
.cv-seg-lock.is-revealed {
    filter: none;
}

/* Composer preview: marked text blurs LIVE while writing — lighter than the
   recipient's 5px so the author can still click in and edit it. */
.cv-chat-input .cv-seg-blur,
.cv-chat-input .cv-seg-lock {
    filter: blur(3px);
    background: rgba(45, 69, 49, 0.10);
}

/* Caret inside the segment → clear while editing; re-blurs on focus out. */
.cv-chat-input .cv-seg-blur.is-editing,
.cv-chat-input .cv-seg-lock.is-editing {
    filter: none;
}

/* ---- composer selection toolbar (Blur / Blur + Lock) ----------------- */

.cv-seltools {
    position: absolute;
    z-index: 60;
    display: flex;
    align-items: center;
    gap: 2px;
    padding: 4px;
    background: #2a2f3a;
    border-radius: 8px;
    box-shadow: 0 8px 24px rgba(26, 31, 46, 0.35);
}

.cv-seltools[hidden] {
    display: none;
}

.cv-seltools-ic {
    padding: 0 4px 0 8px;
    color: var(--cv-accent-light);
    font-size: 12px;
}

.cv-seltools button {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 6px 10px;
    border: 0;
    background: none;
    cursor: pointer;
    border-radius: 6px;
    color: #fff;
    font: inherit;
    font-size: 13px;
    font-weight: 600;
    white-space: nowrap;
}

.cv-seltools button:hover {
    background: #3a4150;
}

/* ---- chat composer (contenteditable) --------------------------------- */

.cv-chat-composer {
    position: relative;
    display: flex;
    gap: 8px;
    align-items: flex-end;
    padding: 10px 14px;
    border-top: 1px solid var(--cv-border);
}

.cv-chat-input {
    flex: 1;
    min-width: 0;
    min-height: 42px;
    max-height: 120px;
    overflow-y: auto;
    border: 1px solid var(--cv-border-strong);
    border-radius: 8px;
    padding: 10px 12px;
    font: inherit;
    font-size: 15px;
    background: var(--cv-card);
}

.cv-chat-input:focus {
    outline: 2px solid var(--cv-accent);
    outline-offset: -1px;
    background: #fff;
}

.cv-chat-input:empty::before {
    content: attr(data-placeholder);
    color: var(--cv-muted);
}

.cv-chat-hint {
    font-size: 15px;
    color: var(--cv-muted);
    padding: 6px 14px 10px;
}

.cv-chat-composer .cv-btn {
    display: inline-block;
    width: auto;
    flex: 0 0 auto;
    margin: 0;
    min-height: 40px;
    padding: 9px 18px;
}

/* ---- password strength meter ------------------------------------------
   Ported from Funeral Analytics' fa-pw-meter. A FIXED red→green gradient
   with a grey cover slid off it one fifth per satisfied rule — not a bar
   that changes colour, so a given fill always means the same thing. The
   staff bundle carries the same rules in sass/global/_base.scss; this
   portal.css is frozen and separate, so both have to be edited together. */

/* Doubled with .cv-label: that class sets display:block and is declared
   later, so a bare .cv-pw-labelrow loses the cascade and the row stays a
   block — which collapses the meter to zero width. */
.cv-label.cv-pw-labelrow,
.cv-pw-labelrow {
    display: flex;
    align-items: center;
    gap: 20px;
}

.cv-pw-meter {
    position: relative;
    /* A real basis, not `auto`: the bar is empty, so an auto basis measures
       its content as zero and grow has nothing to divide. */
    flex: 1 1 120px;
    min-width: 80px;
    height: 8px;
    border-radius: 9999px;
    overflow: hidden;
    opacity: 0;
    transition: opacity 0.2s ease;
}

.cv-pw-meter.is-live {
    opacity: 1;
}

.cv-pw-meter::before {
    content: "";
    position: absolute;
    inset: 0;
    background: linear-gradient(90deg, #e5484d 0%, #f97316 35%, #eab308 65%, #2aa953 100%);
}

.cv-pw-meter-cover {
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    width: 100%;
    background: var(--cv-border-strong);
    transition: width 0.25s ease;
}

.cv-pw-match {
    display: block;
    margin-top: 6px;
    font-size: 13px;
    color: var(--cv-muted);
}

.cv-pw-match.is-ok { color: #1e7c3e; }

/* The rules line still fits one line where there's room — normal wrapping
   only breaks it when the card is narrower than the text. The old nowrap
   gambled that every card was wide enough; the setup-password card wasn't,
   and the line ran past the border. */
.cv-pw-rules {
    white-space: normal;
}

/* Generate + reveal, pushed to the right edge of the label row. */
.cv-pw-actions {
    flex: 0 0 auto;
    display: inline-flex;
    gap: 2px;
}

.cv-pw-action {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 30px;
    height: 30px;
    padding: 0;
    border: 0;
    border-radius: 4px;
    background: none;
    /* Ink, not muted: these are the only two controls in the card and they
       read as decoration at muted grey. */
    color: var(--cv-ink);
    cursor: pointer;
}

.cv-pw-action:hover {
    background: var(--cv-bg);
    color: var(--cv-accent);
}

/* Revealed is a STATE, not a moment — the eye stays lit while the password
   is on screen, because that is the thing worth noticing. */
.cv-pw-action.is-active { color: var(--cv-accent); }

.cv-pw-action .cv-icon {
    width: 20px;
    height: 20px;
    stroke-width: 2.1;
}

/* The 14px explanatory line the meter's rules text uses. Mirrors .cv-note
   in the staff bundle. */
/* The `.cv-field > span` variant is not decoration: that rule is the LABEL
   styling, sets its own font-size, and outranks a bare .cv-note — so a note
   rendered as a span inside a field silently kept the label's size. */
.cv-note,
.cv-field > span.cv-note {
    font-size: 15px;
    line-height: 1.45;
    font-weight: 400;
    color: var(--cv-muted);
    text-align: left;
    margin: 6px 0 0;
}


/* ---- Chat attachments -------------------------------------------------
   A plain link under the bubble, never an inline preview: rendering a file
   the other side supplied is how a chat window becomes an XSS surface. The
   staff bundle carries the same rules in sass/global/_messages.scss — this
   portal.css is frozen and separate, so both have to be edited together.

   Three states. 'view' is listed but not released for download, matching a
   locked document on the Documents page. 'redacted' is archived or hidden:
   the bar arrives with no filename at all, because the name can be the
   disclosure. */

/* NOT a flex column: alignment has to come from the message's own text-align
   (.cv-chat-msg--mine sets it), so the link lands under the sender's name and
   the bubble on both sides. align-items would pin every link to the left of
   the row, which on your own message is nowhere near its bubble. The 4px
   matches .cv-chat-meta, so the link lines up with the name above it. */
.cv-chat-docs {
    margin-top: 5px;
    padding: 0 4px;
}

.cv-chat-doc-line {
    display: block;
}

.cv-chat-doc-line + .cv-chat-doc-line {
    margin-top: 3px;
}

/* Outside the anchor, so the underline doesn't run under the icon.
   -2px, not `bottom`: bottom pins the icon to the floor of the line box, which
   sits below the baseline in the descender space, and the clip visibly sagged
   under the filename. This centres a 14px glyph on 15px text. */
.cv-chat-doc-clip {
    display: inline-block;
    margin-right: 5px;
    color: var(--cv-muted);
    vertical-align: -2px;
}

.cv-chat-doc-clip .cv-icon {
    width: 14px;
    height: 14px;
}

/* Layout only — shared by the download link and the view-only span, which is
   NOT interactive. Anything that says "clickable" (colour, underline, hover)
   hangs off a.cv-chat-doc below, so a span can never pick it up: a view-only
   line that turned copper under the cursor promised a download it won't give.

   Plain inline, with NO max-width. There used to be a calc(100% - 22px) here
   to leave room for the paperclip, but the paperclip is a sibling that already
   takes that room, so it was subtracted twice — and because a message box is
   sized to its own content, the percentage squeezed even short names
   ("sticky-note.jpg" lost 3px and became "sticky-note.j…"). Length is capped
   in JS instead, where it can be a number rather than a measurement. */
.cv-chat-doc {
    font-size: 15px;
}

/* Copper, the portal's hyperlink colour — these ARE links, and the green
   accent read as a button. Visited stays copper: a downloaded document is not
   a "read" link, and going purple would make half a conversation look broken.
   Spelled out because a bare `a:visited` rule anywhere (0,1,1) would
   out-specify a lone class (0,1,0) — and hover must come after it. */
a.cv-chat-doc {
    color: var(--cv-link);
    text-decoration: underline;
    text-underline-offset: 2px;
}

a.cv-chat-doc:visited {
    color: var(--cv-link);
}

a.cv-chat-doc:hover {
    color: var(--cv-link-dark);
}

/* Can break mid-name if a panel is genuinely too narrow — overflowing the
   conversation sideways would be worse than an ugly wrap, and the JS cap makes
   it rare enough to never see. */
.cv-chat-doc-name {
    overflow-wrap: anywhere;
}

/* Kept together, and never the part that gets cut. 15px like the name, not the
   13px secondary size — the whole line is one sentence, and "view only" is the
   part a reader most needs to catch, so it can't be the smallest thing there. */
.cv-chat-doc-size,
.cv-chat-doc-flag {
    color: var(--cv-muted);
    font-size: 15px;
    text-decoration: none;
    white-space: nowrap;
}

.cv-chat-doc-flag {
    margin-left: 5px;
}

/* Listed, not released. No colour change, no underline, no pointer. */
.cv-chat-doc--view {
    color: var(--cv-muted);
    cursor: default;
}

/* Gray italics, not a black bar: the accountants found the bar harsh sitting
   in a client's own conversation. The wording is deliberate — "removed as a
   security measure" is true of every reason this fires (archived, or hidden
   from the client), and it says the thing we want a client to take away. */
/* Plain inline text now, so it sits on the baseline beside the paperclip. */
.cv-chat-doc-redacted {
    font-size: 15px;
    font-style: italic;
    color: var(--cv-muted);
    cursor: help;
}

/* ---- Composer: the staged document ------------------------------------
   Picking a file stages it here; Send posts the document and the caption
   together as one message. */

.cv-chat-attaching {
    padding: 4px 14px 8px;
    font-size: 13px;
    color: var(--cv-muted);
}

.cv-chat-attaching.is-error {
    color: var(--cv-danger);
}

.cv-chat-staged {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    max-width: 100%;
    padding: 3px 4px 3px 10px;
    border: 1px solid var(--cv-border-strong);
    border-radius: 999px;
    background: var(--cv-card);
}

.cv-chat-staged-name {
    font-weight: 600;
    color: var(--cv-ink);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.cv-chat-staged-size {
    color: var(--cv-muted);
}

.cv-chat-staged-x {
    flex: 0 0 auto;
    width: 20px;
    height: 20px;
    padding: 0;
    border: 0;
    border-radius: 50%;
    background: transparent;
    color: var(--cv-muted);
    font-size: 17px;
    line-height: 1;
    cursor: pointer;
}

.cv-chat-staged-x:hover {
    background: var(--cv-bg);
    color: var(--cv-ink);
}

/* Shown beside a staged document whose name is over the display cap. */
.cv-chat-staged-warn {
    display: block;
    margin-top: 4px;
    color: var(--cv-muted);
    font-size: 13px;
}

/* ---- PIN entry + lock modal ------------------------------------------ */

.cv-modal-overlay {
    position: fixed;
    inset: 0;
    background: rgba(26, 31, 46, 0.5);
    z-index: 70;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 20px;
}

.cv-modal-overlay[hidden] {
    display: none;
}

.cv-modal-panel {
    position: relative;   /* anchors the close X */
    background: var(--cv-card);
    border-radius: 14px;
    box-shadow: 0 20px 60px rgba(26, 31, 46, 0.3);
    padding: 26px 24px;
    width: min(400px, 92vw);
    text-align: center;
}

/* Every modal's top-right close X. */
.cv-modal-close {
    position: absolute;
    top: 8px;
    right: 10px;
    padding: 4px 8px;
    background: none;
    border: 0;
    border-radius: 8px;
    font-size: 24px;
    line-height: 1;
    color: var(--cv-muted);
    cursor: pointer;
}

.cv-modal-close:hover {
    color: var(--cv-ink);
}

.cv-modal-panel h3 {
    font-size: 18px;
    margin-bottom: 6px;
}

.cv-modal-panel p {
    color: var(--cv-muted);
    font-size: 15px;
    margin-bottom: 14px;
}

/* ---- post-login unread-messages modal -------------------------------- */

.cv-unread-modal {
    position: relative;
}

.cv-unread-close {
    position: absolute;
    top: 10px;
    right: 12px;
    background: none;
    border: 0;
    font-size: 24px;
    line-height: 1;
    color: var(--cv-muted);
    cursor: pointer;
    padding: 4px;
}

.cv-unread-close:hover {
    color: var(--cv-ink);
}

.cv-unread-list {
    list-style: none;
    margin: 14px 0 18px;
    padding: 0;
}

.cv-unread-list li {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    padding: 8px 2px;
    border-bottom: 1px dashed var(--cv-border);
    font-size: 15px;
}

.cv-unread-list li:last-child {
    border-bottom: 0;
}

.cv-unread-name {
    flex: 1;
    text-align: left;
    font-weight: 600;
}

.cv-unread-avatar {
    position: relative;
    display: grid;
    place-items: center;
    flex: 0 0 auto;
    width: 32px;
    height: 32px;
    border-radius: 50%;
    color: #fff;
    font-size: 12px;
    font-weight: 600;
    letter-spacing: 0.02em;
    overflow: hidden;
    user-select: none;
}

.cv-unread-avatar img {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

/* The sign-in modal hangs near the top of the viewport, not centered. */
.cv-modal-overlay--top {
    align-items: flex-start;
    padding-top: 240px;
}

.cv-unread-count {
    background: rgba(184, 115, 51, 0.14);
    color: var(--cv-copper-dark);
    border-radius: 999px;
    font-size: 13px;
    font-weight: 600;
    padding: 1px 9px;
}

.cv-unread-more {
    color: var(--cv-muted);
    justify-content: center;
}

.cv-pin-badge {
    width: 44px;
    height: 44px;
    margin: 0 auto 10px;
    border-radius: 50%;
    background: rgba(52, 77, 47, 0.12);
    color: var(--cv-accent-dark);
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 18px;
}

.cv-pin-group {
    display: flex;
    gap: 10px;
    justify-content: center;
    margin: 10px 0 6px;
}

.cv-pin-digit {
    width: 52px;
    height: 56px;
    font: inherit;
    font-size: 24px;
    text-align: center;
    border: 1px solid var(--cv-border-strong);
    border-radius: 4px;
}

.cv-pin-digit:focus {
    border-color: var(--cv-accent);
    outline: 2px solid rgba(52, 77, 47, 0.32);
}

.cv-pin-msg {
    min-height: 20px;
    font-size: 13px;
    color: var(--cv-danger);
    margin-top: 6px;
}

.cv-pin-cancel {
    margin-top: 10px;
    background: none;
    border: 0;
    font: inherit;
    font-size: 15px;
    color: var(--cv-muted);
    cursor: pointer;
    padding: 8px 14px;
}

@keyframes cv-shake {
    0%, 100% { transform: translateX(0); }
    20%, 60% { transform: translateX(-6px); }
    40%, 80% { transform: translateX(6px); }
}

.cv-pin-shake {
    animation: cv-shake 0.35s ease;
}

/* ---- message flags (gold protected-content lock) ---------------------
   One icon by the timestamp covers every protected segment in the message:
   click reveals all (PIN if any are locked), click again re-protects. */

.cv-chat-flags {
    display: inline-flex;
    align-items: center;
    vertical-align: middle;
    margin: 0 5px;
    cursor: pointer;
    color: #daa520;
}

.cv-chat-flags .cv-icon {
    width: 17px;
    height: 17px;
    fill: none;
    stroke: currentColor;
}

.cv-chat-flags:hover {
    color: #b8860b;
}

/* ---- documents: toolbar, breadcrumbs, views -------------------------- */

.cv-doc-toolbar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    margin-bottom: 10px;
    flex-wrap: wrap;
}

.cv-crumbs {
    font-size: 15px;
    min-width: 0;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.cv-crumbs a {
    font-weight: 600;
}

.cv-crumbs .sep {
    color: var(--cv-muted);
    margin: 0 4px;
}

.cv-view-toggle {
    display: inline-flex;
    border: 1px solid var(--cv-border-strong);
    border-radius: 4px;
    overflow: hidden;
}

.cv-view-toggle button {
    border: 0;
    background: var(--cv-card);
    color: var(--cv-muted);
    padding: 7px 11px;
    cursor: pointer;
    display: inline-flex;
    align-items: center;
}

.cv-view-toggle button.is-active {
    background: var(--cv-accent);
    color: #fff;
}

.cv-doc-actions {
    display: flex;
    gap: 8px;
    flex-wrap: wrap;
}

.cv-doc-actions .cv-btn {
    display: inline-block;
    width: auto;
    /* Matches the staff page toolbars — same height, same 16px label. */
    padding: 12px 20px;
}

/* list view rows */
.cv-doc-row {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 10px 0;
    border-bottom: 1px solid var(--cv-border);
}

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

.cv-doc-icon {
    flex: 0 0 auto;
    width: 40px;
    height: 48px;
    display: flex;
    align-items: center;
    justify-content: center;
}

.cv-doc-fileinfo {
    min-width: 0;
    flex: 1;
    display: flex;
    flex-direction: column;
}

.cv-doc-filename {
    font-weight: 600;
    font-size: 16px;
    overflow-wrap: anywhere;
}

.cv-doc-meta {
    font-size: 13px;
    color: var(--cv-muted);
}

/* icon (grid) view */
.cv-doc-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(120px, 1fr));
    gap: 6px;
}

/* display:grid would otherwise defeat the hidden attribute the view
   toggle relies on — both views rendered at once. */
.cv-doc-grid[hidden] {
    display: none;
}

.cv-doc-tile {
    text-align: center;
    padding: 14px 8px 12px;
    border-radius: 4px;
    color: var(--cv-ink);
    display: block;
}

.cv-doc-tile:hover,
.cv-doc-tile:focus {
    background: var(--cv-bg);
    text-decoration: none;
    color: var(--cv-ink);
}

.cv-doc-tile .cv-doc-icon {
    margin: 0 auto 8px;
    width: 48px;
    height: 56px;
}

.cv-doc-tile-name {
    font-size: 13px;
    font-weight: 600;
    overflow-wrap: anywhere;
    line-height: 1.3;
}

.cv-doc-tile-meta {
    font-size: 11px;
    color: var(--cv-muted);
    margin-top: 2px;
}

/* file-type badge (pure CSS "icon": page shape + extension chip) */
.cv-fileicon {
    position: relative;
    width: 38px;
    height: 46px;
    background: var(--cv-card);
    border: 1.5px solid var(--cv-muted);
    border-radius: 5px 12px 5px 5px;
    display: inline-block;
}

.cv-fileicon::after {
    content: attr(data-ext);
    position: absolute;
    left: 50%;
    bottom: 5px;
    transform: translateX(-50%);
    font-size: 9px;
    font-weight: 700;
    letter-spacing: 0.04em;
    color: #fff;
    background: var(--cv-accent);
    border-radius: 3px;
    padding: 1px 4px;
    text-transform: uppercase;
}

/* Classic folder: darker back panel + top-left tab behind a lighter front
   with hairlines near the bottom (SVG so the shape stays crisp). */
.cv-fileicon--folder {
    width: 40px;
    height: 32px;
    border: 0;
    border-radius: 0;
    background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 64 50'%3E%3Cpath d='M3 10a5 5 0 0 1 5-5h15a4 4 0 0 1 3 1.4L30.5 11H56a5 5 0 0 1 5 5v4H3Z' fill='%239c5b26'/%3E%3Crect x='3' y='14' width='58' height='33' rx='5' fill='%23b87333'/%3E%3Cg stroke='%239c5b26' stroke-width='1.6'%3E%3Cline x1='9' y1='38' x2='55' y2='38'/%3E%3Cline x1='9' y1='41.5' x2='55' y2='41.5'/%3E%3C/g%3E%3C/svg%3E") center / contain no-repeat;
}

.cv-fileicon--folder::before,
.cv-fileicon--folder::after {
    content: none;
}

/* Uncategorized is where the client's own uploads land — blue, the same
   marker staff see in their tree. */
.cv-fileicon--folder-uncat {
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 64 50'%3E%3Cpath d='M3 10a5 5 0 0 1 5-5h15a4 4 0 0 1 3 1.4L30.5 11H56a5 5 0 0 1 5 5v4H3Z' fill='%232f5e94'/%3E%3Crect x='3' y='14' width='58' height='33' rx='5' fill='%235b8fc7'/%3E%3Cg stroke='%233d6da3' stroke-width='1.6'%3E%3Cline x1='9' y1='38' x2='55' y2='38'/%3E%3Cline x1='9' y1='41.5' x2='55' y2='41.5'/%3E%3C/g%3E%3C/svg%3E");
}

.cv-doc-tile .cv-fileicon--folder {
    width: 47px;
    height: 37px;
}

/* Upload modal file picker: the native input stretches invisibly over the
   row (it takes the click and anchors the required-bubble); the styled
   button and filename echo are the visible face — same as the staff side. */
.cv-filepick {
    position: relative;
    display: flex;
    align-items: center;
    gap: 12px;
    margin-bottom: 14px;
}

.cv-filepick input[type='file'] {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    opacity: 0;
    cursor: pointer;
}

.cv-filepick input[type='file']:focus-visible ~ .cv-btn {
    outline: 2px solid var(--cv-accent);
    outline-offset: 2px;
}

.cv-filepick .cv-btn {
    /* The visible "button" is a span — flex-center its label the way a
       real button element would. */
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: auto;
    margin: 0;
    flex: 0 0 auto;
}

/* Upload progress: real transfer for big files, ~3s sweep for small ones. */
.cv-upload-progress {
    height: 6px;
    border-radius: 999px;
    background: var(--cv-border);
    overflow: hidden;
    margin: 14px 0 2px;
}

.cv-upload-progress[hidden] {
    display: none;
}

.cv-upload-progress-fill {
    height: 100%;
    width: 0;
    border-radius: inherit;
    background: var(--cv-accent);
    transition: width 0.12s linear;
}

/* ---- invoices / billing ---------------------------------------------- */

.cv-invoice-row {
    display: flex;
    justify-content: space-between;
    gap: 12px;
    padding: 10px 0;
    border-bottom: 1px solid var(--cv-border);
    font-size: 16px;
}

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

.cv-status-pill {
    flex: 0 0 auto;
    font-size: 12px;
    font-weight: 600;
    padding: 4px 10px;
    border-radius: 999px;
    background: var(--cv-bg);
    color: var(--cv-muted);
    white-space: nowrap;
}

.cv-status-pill--paid { background: rgba(42, 169, 83, 0.12); color: #1e7c3e; }
.cv-status-pill--issued { background: rgba(52, 77, 47, 0.12); color: var(--cv-accent-dark); }
.cv-status-pill--past_due { background: rgba(229, 72, 77, 0.12); color: #9c2c31; }
.cv-status-pill--open { background: rgba(52, 77, 47, 0.12); color: var(--cv-accent-dark); }
.cv-status-pill--closed { background: rgba(42, 169, 83, 0.12); color: #1e7c3e; }

/* ---- tasks: subtasks + notes ----------------------------------------- */

.cv-subtasks {
    margin: 4px 0 6px 16px;
    border-left: 2px solid var(--cv-border);
    padding-left: 12px;
}

.cv-subtasks .cv-task {
    padding: 7px 0;
}

.cv-task-due {
    font-size: 12px;
    color: var(--cv-accent-dark);
}

.cv-task-due--overdue {
    color: var(--cv-danger);
    font-weight: 600;
}

.cv-task-notes {
    margin-top: 6px;
    font-size: 13px;
}

.cv-task-notes summary {
    cursor: pointer;
    color: var(--cv-accent-dark);
    font-weight: 600;
}

.cv-task-note-item {
    padding: 6px 0;
    border-bottom: 1px dashed var(--cv-border);
}

.cv-task-note-item:last-child {
    border-bottom: 0;
}

.cv-task-note-author {
    font-weight: 600;
    color: var(--cv-muted-dark);
}

.cv-note-form {
    display: flex;
    gap: 6px;
    margin-top: 8px;
}

.cv-note-form input {
    flex: 1;
    font: inherit;
    font-size: 13px;
    padding: 7px 10px;
    border: 1px solid var(--cv-border-strong);
    border-radius: 4px;
}

.cv-note-form .cv-btn {
    display: inline-block;
    width: auto;
    min-height: 34px;
    padding: 6px 12px;
    font-size: 13px;
}


/* ---- tasks: staff-style blocks inside the section cards --------------- */
/* Scoped to .cv-task-card so none of it touches the older .cv-task rules
   the dashboard still uses. */

.cv-task-card {
    position: relative;
    border: 1px solid var(--cv-border);
    border-radius: 4px;
    margin-bottom: 12px;
    background: var(--cv-card);
    padding: 0 14px 14px;
}

.cv-task-card:last-child { margin-bottom: 0; }
.cv-task-card[hidden] { display: none; }

/* Header bar: the same green as the staff card headers. Negative margins
   run it edge to edge through the block's padding. */
.cv-task-card .cv-task-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    flex-wrap: nowrap;
    margin: 0 -14px 12px;
    padding: 5px 12px;
    min-height: 48px;
    background: var(--cv-cardbar);
    border-bottom: 1px solid var(--cv-border);
    border-radius: 3px 3px 0 0;
}

.cv-task-card .cv-task-headline {
    display: flex;
    align-items: center;
    gap: 8px;
    flex: 1 1 auto;
    min-width: 0;
}

.cv-task-card .cv-task-title {
    font-weight: 700;
    font-size: 17px;
    color: var(--cv-ink);
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.cv-task-card--closed .cv-task-title {
    color: var(--cv-muted);
    text-decoration: line-through;
}

.cv-task-actions {
    display: flex;
    align-items: center;
    gap: 6px;
    flex: 0 0 auto;
    align-self: stretch;
}

/* The task's ACTION — a copper block capping the header bar's end (the
   negative margins swallow the bar's 5px/12px padding so it sits flush,
   square corners like the bar itself). White text, darker on hover. */
a.cv-task-actionbtn {
    align-self: stretch;
    display: flex;
    align-items: center;
    gap: 8px;
    margin: -5px -12px -5px 6px;
    padding: 0 18px;
    border-radius: 0;
    background: var(--cv-copper);
    color: #fff;
    font-weight: 600;
    font-size: 15px;
    white-space: nowrap;
}

a.cv-task-actionbtn .cv-icon {
    width: 15px;
    height: 15px;
    flex: 0 0 auto;
}

a.cv-task-actionbtn:hover,
a.cv-task-actionbtn:focus {
    background: var(--cv-copper-dark);
    color: #fff;
    text-decoration: none;
}

.cv-task-actions form { display: contents; }

.cv-task-card .cv-btn-link {
    padding: 4px 6px;
    min-height: 0;
    font-size: 17px;
    font-weight: 600;
    color: var(--cv-accent);
    text-decoration: none;
}

.cv-task-card .cv-btn-link:hover { text-decoration: underline; }

.cv-task-card .cv-task-facts {
    font-size: 17px;
    color: var(--cv-muted);
}

.cv-task-card .cv-task-facts + .cv-task-facts { margin-top: 2px; }

.cv-task-card .cv-task-desc {
    font-size: 17px;
    color: var(--cv-muted-dark);
    margin-top: 6px;
}

/* Status chips ride the assignee line. */
.cv-task-card .cv-task-chip,
/* Signed pill — closed BY A SIGNATURE, not merely closed. */
.cv-task-card .cv-task-signedpill {
    background: var(--cv-alert-success-bg);
    border: 1px solid var(--cv-alert-success-border);
    color: var(--cv-alert-success-ink);
}

.cv-task-card .cv-task-chip,
.cv-task-card .cv-task-closedpill,
.cv-task-card .cv-task-signedpill,
.cv-task-card .cv-task-pastdue {
    display: inline-block;
    margin-left: 8px;
    padding: 1px 9px;
    border-radius: 999px;
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    vertical-align: 1px;
}

.cv-task-card .cv-task-chip {
    background: var(--cv-accent);
    color: #fff;
}

.cv-task-card .cv-task-closedpill {
    background: var(--cv-alert-info-bg);
    border: 1px solid var(--cv-alert-info-border);
    color: var(--cv-alert-info-ink);
}

.cv-task-card .cv-task-pastdue {
    background: var(--cv-alert-error-bg);
    border: 1px solid var(--cv-alert-error-border);
    color: var(--cv-alert-error-ink);
    vertical-align: 4px;
}

/* Note thread. */
.cv-task-card .cv-task-notes-list {
    display: flex;
    flex-direction: column;
    gap: 10px;
    margin-top: 10px;
    padding: 11px 13px;
    background: var(--cv-bg);
    border-radius: 4px;
    font-size: 17px;
}

.cv-task-card .cv-task-note-row {
    display: flex;
    flex-direction: column;
    gap: 1px;
    padding: 0;
    border: 0;
}

.cv-task-card .cv-task-note-author {
    font-size: 16px;
    font-weight: 700;
    color: var(--cv-muted);
}

.cv-task-card .cv-task-note-body {
    display: -webkit-box;
    -webkit-line-clamp: 4;
    -webkit-box-orient: vertical;
    overflow: hidden;
    white-space: pre-line;
}

.cv-task-card .cv-task-note-body.is-expanded {
    display: block;
    -webkit-line-clamp: none;
}

.cv-clamp-toggle {
    align-self: flex-start;
    margin-top: 2px;
    border: 0;
    background: none;
    padding: 0;
    font: inherit;
    font-size: 15px;
    font-weight: 600;
    color: var(--cv-link);
    cursor: pointer;
}

.cv-clamp-toggle:hover { color: var(--cv-link-dark); text-decoration: underline; }

/* The reveal-on-demand note form. */
.cv-tasknote-form {
    margin-top: 10px;
    padding: 10px 12px;
    background: var(--cv-bg);
    border-radius: 4px;
}

.cv-tasknote-form[hidden] { display: none; }

.cv-tasknote-form textarea {
    width: 100%;
    font-family: inherit;
    padding: 11px 13px;
    min-height: 46px;
    font-size: 16px;
    line-height: 1.5;
    resize: none;
    overflow-y: hidden;
}

.cv-tasknote-form .cv-btn {
    width: auto;
    margin: 0;
}

.cv-charcount {
    float: right;
    font-weight: 500;
    font-size: 13px;
    color: var(--cv-muted);
    font-variant-numeric: tabular-nums;
}

.cv-charcount.is-near { color: var(--cv-alert-warning-ink); }

/* Subtasks: indented, with the elbow in the gutter pointing at the block. */
.cv-task-subs { padding-left: 36px; }
.cv-task-subs[hidden] { display: none; }
.cv-task-subs .cv-task-card { position: relative; }

.cv-task-elbow {
    position: absolute;
    left: -27px;
    top: 9px;
    color: var(--cv-muted);
    font-size: 24px;
    line-height: 1;
}

/* ---- timeline scroll panel ------------------------------------------- */
/* Scrollbar hidden on purpose — the View older / View newer pagers are the
   navigation (the wheel and touch still scroll). */

.cv-tl-panel {
    overflow-y: auto;
    overscroll-behavior: contain;
    scrollbar-width: none;          /* Firefox */
    -ms-overflow-style: none;
}

.cv-tl-panel::-webkit-scrollbar {
    display: none;                  /* Chrome/Safari */
}

.cv-tl-pager {
    position: sticky;
    z-index: 2;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 7px;
    width: 100%;
    border: 0;
    cursor: pointer;
    font: inherit;
    font-size: 16px;
    font-weight: 600;
    color: var(--cv-accent-dark);
    text-align: center;
}

.cv-tl-pager svg {
    flex: 0 0 auto;
}

.cv-tl-pager:hover {
    color: var(--cv-accent);
}

/* Each bar's -16px offset parks it over the card's own padding, so the
   padding here is the only thing between the label and the card edge: the
   bottom bar needs the extra 16px back or it reads as crammed. */
.cv-tl-pager--top {
    top: -16px;                     /* flush with the card's padding edge */
    padding: 12px 0;
    margin-bottom: 14px;
    border-bottom: 1px solid var(--cv-border);
    background: var(--cv-card);
}

.cv-tl-pager--bottom {
    bottom: -16px;
    padding: 12px 0 33px;
    margin-top: 14px;
    border-top: 1px solid var(--cv-border);
    background: var(--cv-card);
}

.cv-tl-pager[hidden] {
    display: none;
}

@media print {
    .cv-tl-panel {
        height: auto !important;
        overflow: visible;
    }
}


/* ---- documents: two-row file lines + folder counts ------------------- */

.cv-doc-dl {
    margin-left: auto;
    flex: 0 0 auto;
    min-width: 92px;
    text-align: center;
    font-size: 15px;
    font-weight: 600;
    color: var(--cv-ink);
    white-space: nowrap;
}

.cv-doc-count {
    font-weight: 400;
    color: var(--cv-muted);
}

@media (max-width: 560px) {
    .cv-doc-dl {
        display: none;   /* narrow phones: keep rows to name + meta */
    }
}

/* ---- documents: column headers above the file list ------------------- */
/* Folders list first; this header row sits between them and the files. */

.cv-doc-cols {
    display: flex;
    align-items: center;
    padding: 10px 0 6px 52px;   /* left inset lines up with the filenames */
    border-bottom: 1px solid var(--cv-border);
    font-size: 12px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--cv-muted);
}

.cv-doc-col-dl {
    margin-left: auto;
    min-width: 92px;
    text-align: center;
}

@media (max-width: 560px) {
    .cv-doc-col-dl {
        display: none;   /* matches the hidden per-row download label */
    }
}


/* ---- documents: name filter ------------------------------------------ */

.cv-search {
    font: inherit;
    font-size: 15px;
    font-weight: 500;
    padding: 9px 12px 9px 34px;
    min-height: 40px;
    border: 1px solid var(--cv-border-strong);
    border-radius: 4px;
    color: var(--cv-ink);
    background: var(--cv-card)
        url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Ccircle cx='7' cy='7' r='4.5' fill='none' stroke='%23353c49' stroke-width='1.8'/%3E%3Cline x1='10.5' y1='10.5' x2='14' y2='14' stroke='%23353c49' stroke-width='1.8' stroke-linecap='round'/%3E%3C/svg%3E")
        10px center / 16px 16px no-repeat;
}

.cv-search::placeholder {
    color: var(--cv-muted-dark);
    font-weight: 400;
}

.cv-search:focus {
    border-color: var(--cv-accent);
    outline: 2px solid rgba(52, 77, 47, 0.32);
    outline-offset: 0;
}

.cv-doc-search {
    flex: 1 1 160px;
    min-width: 140px;
}

.cv-task-search {
    display: block;
    width: 100%;
    margin-bottom: 8px;
}

.cv-doc-row[hidden],
.cv-doc-tile[hidden] {
    display: none;
}

/* flex would defeat the hidden attribute the task search relies on */
.cv-task[hidden] {
    display: none;
}

/* ---- screen lock ------------------------------------------------------ */


.cv-lockscreen {
    position: fixed;
    inset: 0;
    z-index: 100;
    background: rgba(252, 250, 244, 0.99);
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 20px;
}

.cv-lockscreen[hidden] {
    display: none;
}

.cv-lockscreen-panel {
    text-align: center;
    max-width: 340px;
}

.cv-lockscreen-panel h3 {
    font-size: 20px;
    margin-bottom: 6px;
}

.cv-lockscreen-panel p {
    color: var(--cv-muted);
    font-size: 15px;
    margin-bottom: 14px;
}

.cv-lockscreen .cv-pin-cancel {
    display: inline-block;
    text-decoration: none;
}


/* ---- two-step verification card -------------------------------------- */

.cv-mfa-actions {
    display: flex;
    gap: 8px;
    margin-top: 12px;
    flex-wrap: wrap;
}

.cv-mfa-actions .cv-btn {
    display: inline-block;
    width: auto;
    flex: 1 1 auto;
    min-height: 42px;
    padding: 10px 16px;
    font-size: 15px;
}

.cv-mfa-confirm {
    margin-top: 12px;
    display: flex;
    gap: 8px;
    align-items: flex-end;
}

.cv-mfa-confirm label {
    flex: 1;
    display: block;
}

.cv-mfa-confirm span {
    display: block;
    font-size: 15px;
    font-weight: 600;
    margin-bottom: 6px;
}

.cv-mfa-confirm input {
    width: 100%;
    font: inherit;
    font-size: 16px;
    padding: 10px 12px;
    border: 1px solid var(--cv-border-strong);
    border-radius: 4px;
}

.cv-mfa-confirm .cv-btn {
    display: inline-block;
    width: auto;
    flex: 0 0 auto;
    min-height: 44px;
    padding: 10px 18px;
}

.cv-mfa-confirm[hidden] {
    display: none;
}


/* ---- chat scroll pagers (same treatment as the timeline) -------------- */

.cv-chat-scrollwrap {
    position: relative;
    flex: 1 1 auto;
    min-height: 0;
    display: flex;
    flex-direction: column;
}

.cv-chat-scroll {
    scrollbar-width: none;
    -ms-overflow-style: none;
}

.cv-chat-scroll::-webkit-scrollbar {
    display: none;
}

.cv-chat-pager {
    position: absolute;
    left: 0;
    right: 0;
}

.cv-chat-pager--top {
    top: 0;
    padding: 10px 0 12px;
    border-bottom: 1px solid var(--cv-border);
    background: var(--cv-card);
    border-radius: 4px 4px 0 0;
}

.cv-chat-pager--bottom {
    bottom: 0;
    padding: 12px 0 10px;
    border-top: 1px solid var(--cv-border);
    background: var(--cv-card);
}


/* ---- documents: capped scroll area (timeline treatment) --------------- */

.cv-doc-scroll {
    overflow-y: auto;
    overscroll-behavior: contain;
    scrollbar-width: none;
    -ms-overflow-style: none;
}

.cv-doc-scroll::-webkit-scrollbar {
    display: none;
}

.cv-doc-pager--top {
    top: 0;
    padding: 10px 0 12px;
    margin-bottom: 10px;
    border-bottom: 1px solid var(--cv-border);
    background: var(--cv-card);
}

.cv-doc-pager--bottom {
    bottom: 0;
    padding: 12px 0 10px;
    margin-top: 10px;
    border-top: 1px solid var(--cv-border);
    background: var(--cv-card);
}


.cv-doc-dl--none {
    font-weight: 400;
    color: var(--cv-muted);
}

/* Upload destination note — clients no longer choose a folder. */
.cv-upload-dest {
    font-size: 15px;
    color: var(--cv-muted);
    margin-bottom: 10px;
}

/* ── Onboarding hub steps — pill + title lockup, centered, roomy ───────── */
.cv-onb-step {
    text-align: center;
    padding: 30px 32px;
    margin-bottom: 18px;
}

.cv-step-head {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 12px;
    margin: 0 0 14px;
}

.cv-step-title {
    font-size: 19px;
    font-weight: 600;
    color: var(--cv-ink);
}

/* Balanced, measured copy — no orphaned last words. */
.cv-onb-step p {
    max-width: 52ch;
    margin: 0 auto;
    font-size: 15px;
    text-wrap: balance;
}

.cv-onb-step .cv-btn {
    margin-top: 20px;
}

/* A gated step — visible so the road ahead reads, but clearly not yet
   (mirrors the task list's "unlocks when the task above it is complete"). */
.cv-onb-step--locked {
    opacity: 0.55;
}

/* The step-done pill riding the step title. */
.cv-step-done {
    display: inline-block;
    padding: 2px 10px;
    border-radius: 10px;
    font-size: 12px;
    font-weight: 700;
    letter-spacing: 0.4px;
    background: color-mix(in srgb, var(--cv-success) 18%, var(--cv-card));
    color: color-mix(in srgb, var(--cv-success) 60%, var(--cv-ink));
}

/* ── cvSweep + inline result note (shared look with the staff shell) ───── */
.cv-sweep {
    position: relative;
    height: 8px;
    margin: 0 0 12px;
    border-radius: 4px;
    overflow: hidden;
    background: var(--cv-accent);
}

.cv-sweep .cv-sweep-cover {
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    width: 100%;
    background: var(--cv-card);
    transition: width 2s ease-out;
}

.cv-zone-note {
    display: block;
    margin: 0 0 10px;
    font-size: 15px;
    font-weight: 600;
    color: var(--cv-accent);
}

.cv-zone-note:empty { display: none; }

.cv-zone-note.is-error { color: var(--cv-danger); }

/* Crowned cards: the 8px green top border that marks the onboarding
   surfaces — differentiates stacked section cards at a glance. */
.cv-card--crown {
    border-top: 8px solid var(--cv-shell-green);
}

/* Document viewer (client/_partials/doc-viewer): rasterized pages as
   images, so we own every pixel — no browser PDF plugin, no viewer
   chrome, and it renders on iOS. A one-page document sits at its exact
   natural height (image aspect == page aspect — a scrollbar is
   impossible); longer documents scroll inside a page-shaped frame. */
.cv-docviewer {
    padding: 0;
    overflow: hidden;
}

.cv-docviewer-pages img {
    display: block;
    width: 100%;
}

.cv-docviewer--scroll .cv-docviewer-pages {
    aspect-ratio: 8.5 / 11;
    overflow-y: auto;
}

.cv-docviewer--scroll .cv-docviewer-pages img + img {
    border-top: 4px solid var(--cv-border);
}

.cv-docviewer-actions {
    display: flex;
    gap: 10px;
    flex-wrap: wrap;
    margin: 0 0 16px;
}

.cv-docviewer-actions .cv-btn {
    flex: 1;
}

/* ── SSN scan: the warn-don't-block note + chat composer hint ─────────── */
.cv-ssn-note {
    margin: 8px 0 4px;
    padding: 8px 12px;
    border: 1px solid var(--cv-alert-warning-border);
    border-radius: 4px;
    background: var(--cv-alert-warning-bg);
    color: var(--cv-alert-warning-ink);
    font-size: 14px;
    line-height: 1.45;
}

.cv-chat-ssnhint {
    margin: 6px 0 0;
    padding: 7px 10px;
    border: 1px solid var(--cv-alert-warning-border);
    border-radius: 4px;
    background: var(--cv-alert-warning-bg);
    color: var(--cv-alert-warning-ink);
    font-size: 13.5px;
}

.cv-ssn-note a {
    color: inherit;
    font-weight: 600;
    text-decoration: underline;
}
.cv-ssn-note a:hover { color: var(--cv-ink); }

.cv-ssn-note .cv-ssn-actions {
    display: block;
    margin-top: 5px;
}

/* ── Onboarding Step 3: the tiny cart the ceremony collects ───────────── */
.cv-onb-cart {
    width: 100%;
    max-width: 460px;
    margin: 14px auto 0;
    border-collapse: collapse;
    font-size: 15px;
    text-align: left;
}

.cv-onb-cart td {
    padding: 7px 8px;
    border-bottom: 1px solid var(--cv-border);
}

.cv-onb-cart td.num {
    text-align: right;
    white-space: nowrap;
}

.cv-onb-cart tr.is-credit td {
    color: var(--cv-muted);
}

.cv-onb-cart tr.is-total td {
    font-weight: 700;
    border-bottom: 0;
}

/* ── Billing: payment methods + expiry warnings ───────────────────────── */
.cv-bill-warn {
    padding: 10px 14px;
    margin-bottom: 12px;
    border-left: 3px solid var(--cv-amber);
    background: color-mix(in srgb, var(--cv-amber) 8%, var(--cv-card));
    font-size: 15px;
}

.cv-bill-cards {
    list-style: none;
    margin: 0 0 12px;
    padding: 0;
}

.cv-bill-cards li {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 10px 0;
    border-bottom: 1px solid var(--cv-border);
    font-size: 15px;
}

.cv-bill-cards li:last-child { border-bottom: 0; }
.cv-bill-cards .cv-bill-cardname { flex: 1 1 auto; }


/* == Profile: the account-photo block (ported from the staff panel) ======= */
.cv-avatar-edit { display: flex; align-items: flex-start; gap: 22px; margin-top: 14px; flex-wrap: wrap; }
.cv-avatar-preview {
    position: relative; flex: 0 0 auto; width: 116px; height: 116px;
    border-radius: 50%; overflow: hidden; display: grid; place-items: center;
    color: #fff; font-size: 40px; font-weight: 600; letter-spacing: 0.5px; user-select: none;
}
.cv-avatar-preview img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.cv-avatar-side { flex: 1 1 260px; min-width: 0; }
.cv-avatar-actions { display: flex; flex-wrap: wrap; gap: 8px; margin: 12px 0 18px; }
.cv-avatar-actions .cv-btn { width: auto; }
.cv-swatch-label { font-size: 15px; font-weight: 500; margin-bottom: 8px; }
.cv-swatch-row { display: flex; flex-wrap: wrap; gap: 8px; }
.cv-swatch {
    width: 30px; height: 30px; padding: 0; border: 2px solid transparent; border-radius: 50%;
    cursor: pointer; box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.12);
}
.cv-swatch.is-active { border-color: var(--cv-ink); box-shadow: inset 0 0 0 2px #fff; }
.cv-swatch:focus-visible { outline: 2px solid var(--cv-accent); outline-offset: 2px; }
.cv-swatch-row.is-muted .cv-swatch { opacity: 0.38; filter: grayscale(0.55); cursor: default; }
.cv-swatch-note { margin: 8px 0 0; font-size: 15px; line-height: 1.45; color: var(--cv-muted); }
.cv-avatar-msg { margin-top: 10px; font-size: 13.5px; min-height: 19px; color: var(--cv-muted); }
.cv-avatar-msg.is-error { color: #b3261e; }
.cv-crop-panel { width: min(560px, 94vw); text-align: left; }
.cv-crop-stage { margin: 14px 0 16px; max-height: 56vh; overflow: hidden; background: #f4f2ec; border: 1px solid #e5e7eb; border-radius: 4px; }
.cv-crop-stage img { display: block; max-width: 100%; }
.cv-crop-actions { display: flex; justify-content: flex-end; gap: 10px; }
.cv-crop-actions .cv-btn { width: auto; }

/* -- vendored: Cropper.js v1.6.2 stylesheet (MIT, Chen Fengyuan) -- */
.cropper-container{-webkit-touch-callout:none;direction:ltr;font-size:0;line-height:0;position:relative;-ms-touch-action:none;touch-action:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.cropper-container img{backface-visibility:hidden;display:block;height:100%;image-orientation:0deg;max-height:none!important;max-width:none!important;min-height:0!important;min-width:0!important;width:100%}.cropper-canvas,.cropper-crop-box,.cropper-drag-box,.cropper-modal,.cropper-wrap-box{bottom:0;left:0;position:absolute;right:0;top:0}.cropper-canvas,.cropper-wrap-box{overflow:hidden}.cropper-drag-box{background-color:#fff;opacity:0}.cropper-modal{background-color:#000;opacity:.5}.cropper-view-box{display:block;height:100%;outline:1px solid #39f;outline-color:rgba(51,153,255,.75);overflow:hidden;width:100%}.cropper-dashed{border:0 dashed #eee;display:block;opacity:.5;position:absolute}.cropper-dashed.dashed-h{border-bottom-width:1px;border-top-width:1px;height:33.33333%;left:0;top:33.33333%;width:100%}.cropper-dashed.dashed-v{border-left-width:1px;border-right-width:1px;height:100%;left:33.33333%;top:0;width:33.33333%}.cropper-center{display:block;height:0;left:50%;opacity:.75;position:absolute;top:50%;width:0}.cropper-center:after,.cropper-center:before{background-color:#eee;content:" ";display:block;position:absolute}.cropper-center:before{height:1px;left:-3px;top:0;width:7px}.cropper-center:after{height:7px;left:0;top:-3px;width:1px}.cropper-face,.cropper-line,.cropper-point{display:block;height:100%;opacity:.1;position:absolute;width:100%}.cropper-face{background-color:#fff;left:0;top:0}.cropper-line{background-color:#39f}.cropper-line.line-e{cursor:ew-resize;right:-3px;top:0;width:5px}.cropper-line.line-n{cursor:ns-resize;height:5px;left:0;top:-3px}.cropper-line.line-w{cursor:ew-resize;left:-3px;top:0;width:5px}.cropper-line.line-s{bottom:-3px;cursor:ns-resize;height:5px;left:0}.cropper-point{background-color:#39f;height:5px;opacity:.75;width:5px}.cropper-point.point-e{cursor:ew-resize;margin-top:-3px;right:-3px;top:50%}.cropper-point.point-n{cursor:ns-resize;left:50%;margin-left:-3px;top:-3px}.cropper-point.point-w{cursor:ew-resize;left:-3px;margin-top:-3px;top:50%}.cropper-point.point-s{bottom:-3px;cursor:s-resize;left:50%;margin-left:-3px}.cropper-point.point-ne{cursor:nesw-resize;right:-3px;top:-3px}.cropper-point.point-nw{cursor:nwse-resize;left:-3px;top:-3px}.cropper-point.point-sw{bottom:-3px;cursor:nesw-resize;left:-3px}.cropper-point.point-se{bottom:-3px;cursor:nwse-resize;height:20px;opacity:1;right:-3px;width:20px}@media (min-width:768px){.cropper-point.point-se{height:15px;width:15px}}@media (min-width:992px){.cropper-point.point-se{height:10px;width:10px}}@media (min-width:1200px){.cropper-point.point-se{height:5px;opacity:.75;width:5px}}.cropper-point.point-se:before{background-color:#39f;bottom:-50%;content:" ";display:block;height:200%;opacity:0;position:absolute;right:-50%;width:200%}.cropper-invisible{opacity:0}.cropper-bg{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAAA3NCSVQICAjb4U/gAAAABlBMVEXMzMz////TjRV2AAAACXBIWXMAAArrAAAK6wGCiw1aAAAAHHRFWHRTb2Z0d2FyZQBBZG9iZSBGaXJld29ya3MgQ1M26LyyjAAAABFJREFUCJlj+M/AgBVhF/0PAH6/D/HkDxOGAAAAAElFTkSuQmCC")}.cropper-hide{display:block;height:0;position:absolute;width:0}.cropper-hidden{display:none!important}.cropper-move{cursor:move}.cropper-crop{cursor:crosshair}.cropper-disabled .cropper-drag-box,.cropper-disabled .cropper-face,.cropper-disabled .cropper-line,.cropper-disabled .cropper-point{cursor:not-allowed}

/* ── Privacy notice ──────────────────────────────────────────────────
   A standalone page: no portal furniture, because it renders with no
   session at all and a policy reads better on its own. Measure is the
   whole design here — this is a document, and a document that runs the
   full width of a monitor does not get read. */
.cv-policy-body {
    background: var(--cv-bg, #f7f4ed);
    margin: 0;
}

.cv-policy {
    max-width: 68ch;
    margin: 0 auto;
    padding: 48px 24px 96px;
    font-size: 16px;
    line-height: 1.65;
    color: var(--cv-ink, #1f2420);
}

.cv-policy-head { margin-bottom: 28px; }
.cv-policy-logo { height: 38px; width: auto; margin-bottom: 18px; }

.cv-policy h1 {
    font-family: "Source Serif 4", Georgia, serif;
    font-size: 34px;
    line-height: 1.15;
    margin: 0 0 4px;
    color: var(--cv-primary, #344d2f);
}

.cv-policy-eff { margin: 0; color: var(--cv-muted, #6b7268); font-size: 14px; }

.cv-policy h2 {
    font-family: "Source Serif 4", Georgia, serif;
    font-size: 21px;
    margin: 34px 0 8px;
    color: var(--cv-primary, #344d2f);
}

.cv-policy p { margin: 0 0 12px; }
.cv-policy ul { margin: 0 0 12px; padding-left: 20px; }
.cv-policy li { margin-bottom: 7px; }

.cv-policy-lede { font-size: 17.5px; color: var(--cv-muted, #4a5450); }

.cv-policy-dl { margin: 0 0 12px; }
.cv-policy-dl dt { font-weight: 600; margin-top: 12px; }
.cv-policy-dl dd { margin: 2px 0 0; }

/* The three "we don't" lines — the answer to what people actually worry
   about, so they get their own block rather than a bullet among bullets. */
.cv-policy-never {
    border-left: 3px solid var(--cv-accent, #b87333);
    padding: 10px 0 10px 16px;
    margin: 14px 0 4px;
}
.cv-policy-never p { margin: 0 0 4px; font-weight: 500; }
.cv-policy-never p:last-child { margin-bottom: 0; }

/* Shown only to someone the gate sent here. */
.cv-policy-callout {
    background: #fff;
    border: 1px solid var(--cv-border, #ded8ca);
    border-left: 3px solid var(--cv-primary, #344d2f);
    padding: 14px 18px;
    margin-bottom: 24px;
    border-radius: 3px;
}

.cv-policy-ack {
    margin-top: 36px;
    padding-top: 24px;
    border-top: 1px solid var(--cv-border, #ded8ca);
}
.cv-policy-ack .cv-btn { width: auto; display: inline-block; }
.cv-policy-ackhint { margin: 10px 0 0; font-size: 14px; color: var(--cv-muted, #6b7268); }

.cv-policy-back, .cv-policy-ackedon {
    margin-top: 32px;
    padding-top: 18px;
    border-top: 1px solid var(--cv-border, #ded8ca);
    font-size: 14.5px;
    color: var(--cv-muted, #6b7268);
}

/* ── Book an appointment (M365 plan Phase 4) ──────────────────────────────
   Three pages: what kind, when, done. Tokens throughout so the client
   portal's eventual dark mode needs nothing here. */

.cv-book-types {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
    gap: 14px;
    margin-bottom: 22px;
}

/* A whole card is the link, not a button inside it: the entire thing is one
   choice, and a click target the size of the choice is the point. */
.cv-book-type {
    display: flex;
    flex-direction: column;
    gap: 9px;
    padding: 18px 20px;
    background: var(--cv-card, #fff);
    border: 1px solid var(--cv-border, #ded8ca);
    border-radius: 4px;
    color: var(--cv-ink, #1e2637);
    transition: border-color .12s ease-out, transform .12s ease-out;
}

.cv-book-type:hover,
.cv-book-type:focus-visible {
    text-decoration: none;
    border-color: var(--cv-accent, #3f5f46);
    transform: translateY(-1px);
}

.cv-book-type-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 10px;
}

.cv-book-type-name { font-size: 17px; font-weight: 600; }

.cv-book-type-blurb {
    font-size: 14.5px;
    line-height: 1.5;
    color: var(--cv-muted, #6b7268);
}

.cv-book-type-go {
    font-size: 14px;
    font-weight: 600;
    color: var(--cv-link, #b87333);
}

.cv-back {
    display: inline-block;
    margin-bottom: 8px;
    font-size: 14.5px;
}

/* ── Times ─────────────────────────────────────────────────────────────── */

.cv-book-day { margin-bottom: 14px; }

.cv-book-slots {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    margin-top: 12px;
}

/* Wide enough for a tapped thumb, and tabular numerals so a column of times
   lines up rather than shuffling on the colon. */
.cv-book-slot {
    min-width: 92px;
    min-height: 42px;
    padding: 9px 14px;
    border: 1px solid var(--cv-border-strong, #c6ccd8);
    border-radius: 4px;
    background: var(--cv-card, #fff);
    font: inherit;
    font-size: 15px;
    font-variant-numeric: tabular-nums;
    color: var(--cv-ink, #1e2637);
    cursor: pointer;
}

.cv-book-slot:hover { border-color: var(--cv-accent, #3f5f46); }

/* Chosen state is border + weight + fill, never colour alone — the same rule
   the rest of the portal follows for anyone who cannot see the green. */
.cv-book-slot[aria-pressed="true"] {
    background: var(--cv-accent, #3f5f46);
    border-color: var(--cv-accent, #3f5f46);
    color: var(--cv-accent-contrast, #fff);
    font-weight: 600;
}

/* Sticks to the bottom of the screen once a time is chosen. The list runs to
   a fortnight of days, and a Book button you have to go and find is a booking
   that doesn't happen. */
.cv-book-confirm {
    margin-top: 18px;
    position: sticky;
    bottom: 12px;
    box-shadow: 0 -2px 18px rgba(30, 38, 55, .13);
    border: 1px solid var(--cv-accent, #3f5f46);
}

.cv-book-more {
    margin: 4px 0 18px;
    font-size: 15px;
}

/* On a short screen a sticky panel can eat the whole viewport; below that,
   let it scroll with the page rather than cover the times it is about. */
@media (max-height: 620px) {
    .cv-book-confirm { position: static; }
}

.cv-book-chosen {
    font-size: 17px;
    font-weight: 600;
    margin: 0 0 14px;
}

.cv-book-confirm .cv-btn { width: auto; display: inline-block; }

/* ── Done ──────────────────────────────────────────────────────────────── */

.cv-book-when {
    font-size: 19px;
    line-height: 1.45;
    margin: 0 0 14px;
}

.cv-book-again { width: auto; display: inline-block; }

/* ── cv-pill ───────────────────────────────────────────────────────────
   Ported from the staff bundle (sass/global/_base.scss) 2026-09-14, because
   the client portal never had it and every pill on the Book and Appointments
   pages was rendering as bare text. The two stylesheets are separate copies
   by design and they drift — anything meant for both has to be written twice,
   and this is the second time that has bitten.
   Tones: muted (inert), wait (in flight), ok (accent), success, danger. */
.cv-pill {
    display: inline-block;
    padding: 2px 9px;
    border-radius: 10px;
    font-size: 11px;
    font-weight: 700;
    letter-spacing: .4px;
    vertical-align: 1px;
    white-space: nowrap;
}

.cv-pill--muted {
    background: var(--cv-bg, #f3f2ee);
    color: var(--cv-muted-dark, #353c49);
    border: 1px solid var(--cv-border-strong, #c6ccd8);
}

.cv-pill--wait {
    background: color-mix(in srgb, #b87333 16%, var(--cv-card, #fff));
    color: #7a4a1f;
}

.cv-pill--ok {
    background: color-mix(in srgb, var(--cv-accent, #3f5f46) 16%, var(--cv-card, #fff));
    color: var(--cv-accent, #3f5f46);
}

.cv-pill--success {
    background: color-mix(in srgb, var(--cv-success, #2aa953) 18%, var(--cv-card, #fff));
    color: color-mix(in srgb, var(--cv-success, #2aa953) 60%, var(--cv-ink, #1e2637));
}

.cv-pill--danger {
    background: color-mix(in srgb, var(--cv-danger, #e5484d) 14%, var(--cv-card, #fff));
    color: color-mix(in srgb, var(--cv-danger, #e5484d) 70%, var(--cv-ink, #1e2637));
}

/* ── Your appointments ────────────────────────────────────────────────── */

.cv-appt {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    flex-wrap: wrap;
    padding: 14px 0;
    border-top: 1px solid var(--cv-border, #ded8ca);
}

.cv-appt:first-of-type { border-top: 0; }

.cv-appt-main {
    display: flex;
    flex-direction: column;
    gap: 2px;
    min-width: 0;
}

.cv-appt-type {
    font-size: 16.5px;
    font-weight: 600;
    display: flex;
    align-items: baseline;
    gap: 8px;
    flex-wrap: wrap;
}

.cv-appt-when { font-size: 15px; }

.cv-appt-mins {
    font-size: 13.5px;
    color: var(--cv-muted, #6b7268);
}

/* Struck through AND labelled — the pill carries the meaning for anyone who
   cannot see the line, and the line carries it for anyone skimming. */
.cv-appt.is-cancelled .cv-appt-when { text-decoration: line-through; }
.cv-appt.is-cancelled { opacity: .72; }
.cv-appt.is-past { opacity: .8; }

/* Cancelling emails everyone on the invitation. It should not look like the
   primary action on the page. */
.cv-appt-cancel {
    width: auto;
    min-height: 38px;
    padding: 8px 15px;
    font-size: 14.5px;
    background: transparent;
    color: var(--cv-danger, #e5484d);
    border: 1px solid var(--cv-danger, #e5484d);
}

.cv-appt-actions { margin: 0 0 18px; }

.cv-appt-book {
    width: auto;
    display: inline-block;
    min-height: 40px;
    padding: 10px 18px;
    font-size: 15px;
}

.cv-appt-next {
    font-size: 17px;
    line-height: 1.5;
    margin: 0 0 6px;
}

.cv-book-after {
    display: flex;
    align-items: center;
    gap: 16px;
    flex-wrap: wrap;
}

.cv-book-againlink { font-size: 15px; }

/* ── Paying for a consultation ─────────────────────────────────────────── */

.cv-book-type-meta {
    display: inline-flex;
    gap: 6px;
    flex-shrink: 0;
}

#cv-consult-element { margin: 14px 0 6px; }

.cv-consult-msg {
    margin: 10px 0;
    font-size: 15px;
    min-height: 1.4em;
}

#cv-consult-submit { width: auto; display: inline-block; }
