/* Shared classes: the single definition of every element both NiceGUI and React pages draw. They work on plain HTML
   elements (a <button>, a <span>); a Quasar or MUI element that carries one only needs the small framework adapter in
   wf_quasar.css (NiceGUI) or wf_mui.css (React) on top. Colours come only from wf_tokens.css. What each element is for
   and which class draws it: docs/webform_design.md, "Shared classes". Loaded on every page. The values are the CRUD
   pages' own, so moving an element onto these classes does not change how it looks.

   Backgrounds and text colours of buttons are !important: a Quasar button carries Quasar's own !important colour
   classes (bg-primary, text-white), which they have to beat. */

/* ---------- Buttons: 34px, 6px corners, solid fill, a darker 1px border, no capitals, no shadow ---------- */
.wfc-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    height: 34px;
    min-height: 34px;
    min-width: auto;
    padding: 0 10px;
    border: 1px solid transparent;
    border-radius: 6px;
    font-family: Manrope, sans-serif;
    font-size: 13px;
    font-weight: 600;
    color: #ffffff;
    white-space: nowrap;
    text-transform: none;
    cursor: pointer;
    box-sizing: border-box;
}

.wfc-btn:focus-visible { outline: none; }
.wfc-btn:disabled { opacity: 0.45; cursor: default; }
.wfc-btn svg { flex-shrink: 0; }

/* Two classes, so a colour beats the older one-class button rules it may still meet */
.wfc-btn.wfc-btn-create  { background: var(--wf-heading) !important; border-color: var(--wf-heading-border); color: #ffffff !important; }
.wfc-btn.wfc-btn-primary { background: var(--wf-primary) !important; border-color: var(--wf-primary-border); color: #ffffff !important; }
.wfc-btn.wfc-btn-save    { background: var(--wf-save) !important; border-color: var(--wf-save-border); color: #ffffff !important; }
.wfc-btn.wfc-btn-draft   { background: var(--wf-draft) !important; border-color: var(--wf-draft-border); color: #ffffff !important; }
.wfc-btn.wfc-btn-edit    { background: var(--wf-edit) !important; border-color: var(--wf-edit-border); color: #ffffff !important; }
.wfc-btn.wfc-btn-delete  { background: var(--wf-delete) !important; border-color: var(--wf-delete-border); color: #ffffff !important; }
.wfc-btn.wfc-btn-danger  { background: var(--wf-danger) !important; border-color: var(--wf-danger-border); color: #ffffff !important; }
.wfc-btn.wfc-btn-back    { background: var(--wf-back) !important; border-color: var(--wf-back-border); color: #ffffff !important; }
.wfc-btn.wfc-btn-cancel  { background: #ffffff !important; border-color: var(--wf-cancel-border); color: var(--wf-text) !important; }
/* A flat action on the content: no border or fill, a coral icon beside a dark label (a signature's "Clear") */
.wfc-btn.wfc-btn-flat    { min-width: 0; padding: 0 8px; border-color: transparent; background: transparent !important; color: var(--wf-text) !important; }
.wfc-btn-flat svg { color: var(--wf-accent); }

/* Smaller buttons inside a detail area (Edit, Delete next to a role name) */
.wfc-btn-sm { height: 30px; min-height: 30px; padding: 0 10px; gap: 5px; font-size: 12.5px; }

/* A button of a modal: a little wider, so Cancel and the action read as a pair */
.wfc-btn-modal { min-width: 84px; padding: 0 14px; }

/* An icon alone is a square as high as its row's buttons; on a phone header buttons are 36px squares */
.wfc-btn-icon { width: 34px; padding: 0; }
.wfc-btn-sm.wfc-btn-icon { width: 30px; }
.wfc-btn-phone { width: 36px; height: 36px; min-height: 36px; padding: 0; }

/* Outline actions on a holder row: Disable is coral, Enable is green, both the same width */
.wfc-btn.wfc-btn-outline { height: 28px; min-height: 28px; min-width: 76px; padding: 0 10px; background: #ffffff !important; font-size: 12.5px; }
.wfc-btn.wfc-btn-outline-coral { border-color: var(--wf-accent); color: var(--wf-accent-text) !important; }
.wfc-btn.wfc-btn-outline-green { border-color: var(--wf-save); color: var(--wf-save-text) !important; }

/* ---------- Hover and keyboard focus: the overlay Quasar puts on its buttons and tabs (q-focus-helper) ----------
   A layer of the element's own text colour, lightened and darkened a little as Quasar does, shown at 15% on hover and
   22% on keyboard focus. Quasar elements draw it themselves; this gives plain HTML elements the same. */
.wfc-btn:not(.q-btn),
.wfc-icon-action:not(.q-btn),
.wfc-flat-action,
.wfc-modal-close:not(.q-btn),
.wfc-seg-item:not(.q-tab) {
    position: relative;
}

.wfc-btn:not(.q-btn)::after,
.wfc-icon-action:not(.q-btn)::after,
.wfc-flat-action::after,
.wfc-modal-close:not(.q-btn)::after,
.wfc-seg-item:not(.q-tab)::after {
    content: '';
    position: absolute;
    inset: 0;
    border-radius: inherit;
    background: linear-gradient(rgba(255, 255, 255, 0.4), rgba(255, 255, 255, 0.4)), linear-gradient(rgba(0, 0, 0, 0.1), rgba(0, 0, 0, 0.1)), currentColor;
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.4s var(--wf-hover-easing);
}

@media (hover: hover) {
    .wfc-btn:not(.q-btn):hover:not(:disabled)::after,
    .wfc-icon-action:not(.q-btn):hover:not(:disabled)::after,
    .wfc-flat-action:hover:not(:disabled)::after,
    .wfc-modal-close:not(.q-btn):hover::after,
    .wfc-seg-item:not(.q-tab):hover:not(:disabled)::after {
        opacity: 0.15;
    }
}

.wfc-btn:not(.q-btn):focus-visible::after,
.wfc-icon-action:not(.q-btn):focus-visible::after,
.wfc-flat-action:focus-visible::after,
.wfc-modal-close:not(.q-btn):focus-visible::after,
.wfc-seg-item:not(.q-tab):focus-visible::after {
    opacity: 0.22;
}

/* The click ripple Quasar draws on its buttons and tabs, for the same plain HTML elements: commonreact/wfRipple.js adds
   it on React pages, with Quasar's sizes and timings. */
.wfc-add-bar:not(.q-btn) {
    position: relative;
}

.wfc-ripple {
    position: absolute;
    inset: 0;
    z-index: 0;
    overflow: hidden;
    border-radius: inherit;
    color: inherit;
    pointer-events: none;
    contain: strict;
}

.wfc-ripple-inner {
    position: absolute;
    top: 0;
    left: 0;
    border-radius: 50%;
    background: currentColor;
    color: inherit;
    opacity: 0;
    pointer-events: none;
    will-change: transform, opacity;
}

.wfc-ripple-inner-enter { transition: transform 0.225s var(--wf-ripple-easing), opacity 0.1s var(--wf-ripple-easing); }
.wfc-ripple-inner-leave { transition: opacity 0.25s var(--wf-ripple-easing); }

/* ---------- Coral actions: what changes the content (add, remove) ---------- */

/* Remove (and any other icon action on content): a flat coral square, at least 32px, no border and no fill */
.wfc-icon-action {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    min-width: 32px;
    min-height: 32px;
    padding: 0;
    border: 0;
    border-radius: 6px;
    background: transparent;
    color: var(--wf-accent);
    cursor: pointer;
}
.wfc-icon-action:focus-visible { outline: none; }
.wfc-icon-action:disabled { opacity: 0.4; cursor: default; }
.wfc-icon-action-sm { min-width: 26px; min-height: 26px; border-radius: 5px; }
.wfc-icon-action-xs { min-width: 18px; min-height: 18px; border-radius: 4px; }

/* An add action inside a block: coral icon, dark label, no fill or border */
.wfc-flat-action {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    height: 32px;
    padding: 0 10px;
    border: 0;
    border-radius: 6px;
    background: transparent;
    font: 600 13.5px Manrope, sans-serif;
    color: var(--wf-text);
    cursor: pointer;
}
.wfc-flat-action svg { color: var(--wf-accent); }
.wfc-flat-action:focus-visible { outline: none; }
.wfc-flat-action:disabled { opacity: 0.45; cursor: default; }

/* The bar that ends a list: full width, light coral, solid coral on hover. Full width says "a new container goes here" */
.wfc-add-bar {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    width: 100%;
    height: 26px;
    min-height: 26px;
    margin: 0;
    padding: 0 10px;
    border: 1px solid var(--wf-accent-light-border);
    border-radius: 6px;
    background: var(--wf-accent-light);
    font-family: Manrope, sans-serif;
    font-size: 13px;
    font-weight: 700;
    color: var(--wf-text);
    cursor: pointer;
    box-sizing: border-box;
    transition: background-color 0.12s, border-color 0.12s, color 0.12s;
}
.wfc-add-bar svg { color: var(--wf-accent); transition: color 0.12s; }
.wfc-add-bar:focus-visible { outline: none; background: var(--wf-accent); border-color: var(--wf-accent); color: #ffffff; }
.wfc-add-bar:focus-visible svg { color: #ffffff; }
.wfc-add-bar:disabled { opacity: 0.45; cursor: default; }
/* Only where there is a real pointer: on a touch screen the hover look would stay on after a tap */
@media (hover: hover) {
    .wfc-add-bar:hover:not(:disabled) { background: var(--wf-accent); border-color: var(--wf-accent); color: #ffffff; }
    .wfc-add-bar:hover:not(:disabled) svg { color: #ffffff; }
}
@media (max-width: 768px) {
    .wfc-add-bar { height: 34px; min-height: 34px; font-size: 13.5px; }
}

/* ---------- Shapes: a circle shows a kind, a 6px rectangle names it ---------- */
.wfc-kind {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    width: 20px;
    height: 20px;
    border-radius: 50%;
}
.wfc-kind-sm { width: 18px; height: 18px; }

.wfc-tag {
    display: inline-flex;
    flex: 0 0 auto;
    align-items: center;
    justify-content: center;
    gap: 4px;
    height: 18px;
    padding: 0 5px;
    border-radius: 6px;
    font-family: Manrope, sans-serif;
    font-size: 10px;
    font-weight: 700;
    line-height: 1;
    white-space: nowrap;
    box-sizing: border-box;
}
/* With a border one step darker than its fill (the list page's and approval panel's role tags) */
.wfc-tag-outlined { border: 1px solid; }

/* The colour of a kind, for its circle and its tag alike */
.wfc-c-system    { background: var(--wf-kind-system-bg);    color: var(--wf-kind-system-fg); }
.wfc-c-custom    { background: var(--wf-kind-custom-bg);    color: var(--wf-kind-custom-fg); }
.wfc-c-scoped    { background: var(--wf-kind-scoped-bg);    color: var(--wf-kind-scoped-fg);    border-color: var(--wf-kind-scoped-border); }
.wfc-c-unscoped  { background: var(--wf-kind-unscoped-bg);  color: var(--wf-kind-unscoped-fg); }
.wfc-c-external  { background: var(--wf-kind-external-bg);  color: var(--wf-kind-external-fg); }
.wfc-c-approvals { background: var(--wf-kind-approvals-bg); color: var(--wf-kind-approvals-fg); }
/* A state that needs doing (Unregistered): the warning notice's colours */
.wfc-c-warning   { background: var(--wf-notice-warning-bg);  color: var(--wf-notice-warning-icon); border-color: var(--wf-notice-warning-border); }

/* A scope (or similar value) as a small grey tag, optionally with its own coral remove */
.wfc-value-tag {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    height: 22px;
    padding: 0 7px;
    border-radius: 5px;
    background: var(--wf-tint);
    color: var(--wf-tag-text);
    font: 600 11.5px Manrope, sans-serif;
    white-space: nowrap;
}
.wfc-value-tag:has(.wfc-icon-action) { padding-right: 3px; }

/* A chosen value inside a picker (selected scopes) */
.wfc-chip {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    height: 26px;
    padding: 0 6px 0 8px;
    border: 1px solid var(--wf-tint-border);
    border-radius: 6px;
    background: var(--wf-tint);
    font: 600 12.5px Manrope, sans-serif;
    color: var(--wf-heading);
}

.wfc-code { font: 12px ui-monospace, Consolas, monospace; color: var(--wf-label); }

/* Unsaved changes: a red dot on the top-right corner of the Save button, ringed in the colour behind it. Its text
   ("Unsaved changes") is not drawn: it is there for screen readers and tests, the tooltip shows it on hover */
.wfc-unsaved-badge {
    position: absolute;
    top: -5px;
    right: -5px;
    z-index: 1;
    width: 13px;
    height: 13px;
    border-radius: 50%;
    background: var(--wf-unsaved);
    box-shadow: 0 0 0 2px var(--wf-unsaved-ring, var(--wf-header-bg));
    font-size: 0;
    line-height: 0;
    color: transparent;
    overflow: hidden;
}
.wfc-modal-footer .wfc-unsaved-badge { --wf-unsaved-ring: var(--wf-card-bg); }

.wfc-status { display: inline-flex; align-items: center; gap: 6px; font: 600 13px Manrope, sans-serif; }
.wfc-status::before { content: ''; width: 8px; height: 8px; border-radius: 50%; background: currentColor; }
.wfc-status-active   { color: var(--wf-save-text); }
.wfc-status-disabled { color: var(--wf-label); }

/* A person's picture or initials */
.wfc-avatar {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    width: 22px;
    height: 22px;
    border-radius: 50%;
    background: var(--wf-header-bg);
    color: var(--wf-heading);
    font: 700 9.5px Manrope, sans-serif;
}
.wfc-avatar-everyone { background: var(--wf-kind-unscoped-bg); color: var(--wf-kind-unscoped-fg); }

/* A person in a list they can be removed from: one dense white chip holding the picture, name, user ID and remove */
.wfc-person-chip {
    display: flex;
    align-items: center;
    gap: 7px;
    min-width: 0;
    height: 32px;
    padding: 0 2px 0 5px;
    /* The field border and a faint shadow keep the chip apart from a white body (option C, 2026-10-22) */
    border: 1px solid var(--wf-field-border);
    border-radius: 6px;
    background: var(--wf-card-bg);
    box-shadow: 0 1px 2px rgba(16, 24, 40, 0.06);
    box-sizing: border-box;
}
.wfc-person-chip .wfc-icon-action { margin-left: auto; }
@media (max-width: 599px) {
    .wfc-person-chip { height: 36px; }
    .wfc-person-chip .wfc-icon-action-sm { min-width: 32px; min-height: 32px; }
}

/* ---------- Page header: the tint band with a 3px line (navy here; CRUD colours it per page) ---------- */
.wfc-page-header {
    display: flex;
    flex-direction: row;
    align-items: center;
    justify-content: space-between;
    row-gap: 10px;
    min-height: 53px;
    padding: 8px 16px;
    border-bottom: 3px solid var(--wf-heading);
    background: var(--wf-header-bg);
    box-sizing: border-box;
    overflow: hidden;
}
@media (max-width: 768px) {
    .wfc-page-header { min-height: 55px; padding: 8px; row-gap: 0; }
}

.wfc-page-title {
    flex: 0 1 auto;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-family: Manrope, sans-serif;
    font-size: 18px;
    font-weight: 700;
    line-height: 34px;
    color: var(--wf-heading);
}

/* The module's navbar icon before the page title (an <img> of the bucket SVG). brightness(0) first turns any colour
   the SVG has (some are blue) to black, then the rest turns black into --wf-heading; without it a coloured icon comes
   out in its opposite colour. A CSS mask would take the token directly, but the bucket sends no CORS headers */
.wfc-page-icon {
    flex: 0 0 auto;
    width: 22px;
    height: 22px;
    object-fit: contain;
    filter: brightness(0) invert(14%) sepia(26%) saturate(971%) hue-rotate(174deg) brightness(128%);
}
@media (max-width: 768px) {
    .wfc-page-icon { width: 20px; height: 20px; }
}

/* ---------- Panels and bands ---------- */
.wfc-panel {
    border: 1px solid var(--wf-card-border);
    border-radius: 8px;
    background: var(--wf-card-bg);
    overflow: hidden;
}

/* The header band of a panel (bucket, repeat group): tint, at least 44px */
.wfc-band {
    display: flex;
    align-items: center;
    gap: 10px;
    min-height: 44px;
    padding: 0 6px 0 8px;
    background: var(--wf-tint);
}

/* ---------- Custom pages (GenericModule): platform panels on a flush page (docs/webform_design.md, "Custom pages") ---------- */
/* The content under .wfc-page-header and the summary strip: panels 20px apart */
.wfc-page-body {
    display: flex;
    flex-direction: column;
    gap: 20px;
    width: 100%;
    padding: 20px 24px 32px;
    box-sizing: border-box;
    font-family: Manrope, sans-serif;
    color: var(--wf-text);
}
@media (max-width: 768px) {
    .wfc-page-body { padding: 14px 8px 24px; gap: 14px; }
}

/* Main column and a 360px side panel (an order, a summary); one column under 1000px */
.wfc-split { display: grid; grid-template-columns: minmax(0, 1fr) 360px; gap: 20px; align-items: start; }
@media (max-width: 1000px) {
    .wfc-split { grid-template-columns: minmax(0, 1fr); }
}

/* Summary strip: the page's key facts in one row under the header, divided by thin lines */
.wfc-strip {
    display: flex;
    align-items: stretch;
    padding: 16px 24px;
    background: var(--wf-card-bg);
    border-bottom: 1px solid var(--wf-card-border);
    font-family: Manrope, sans-serif;
}
.wfc-fact { display: flex; flex-direction: column; justify-content: center; gap: 2px; min-width: 0; padding: 0 28px; border-left: 1px solid var(--wf-card-border); }
.wfc-fact:first-child { padding-left: 0; border-left: 0; }
.wfc-fact-label { font-size: 12.5px; font-weight: 600; line-height: 18px; color: var(--wf-label); }
.wfc-fact-value { font-size: 16px; font-weight: 700; line-height: 24px; color: var(--wf-text); font-variant-numeric: tabular-nums; }
.wfc-fact-figure { font-size: 22px; font-weight: 800; line-height: 26px; color: var(--wf-heading); font-variant-numeric: tabular-nums; }
.wfc-fact-note { max-width: 320px; font-size: 12.5px; line-height: 18px; color: var(--wf-label); }
@media (max-width: 768px) {
    .wfc-strip { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px 16px; padding: 12px 8px; }
    .wfc-fact { padding: 0; border-left: 0; }
    .wfc-fact:has(.wfc-fact-note) { grid-column: 1 / -1; }
}

/* Panels on a custom page: the platform panel (.wfc-panel) with a titled band. A band holding a title gets the page's
   16px inset; its caption and actions sit at its right */
.wfc-band:has(> .wfc-band-title) { padding: 0 8px 0 16px; }
.wfc-band-icon { flex-shrink: 0; font-size: 18px; width: 18px; height: 18px; color: var(--wf-heading); }
.wfc-band-title { flex-shrink: 0; font: 700 14px/20px Manrope, sans-serif; color: var(--wf-heading); }
.wfc-band-caption { min-width: 0; margin-left: auto; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 12.5px; color: var(--wf-label); }
.wfc-band-actions { display: flex; align-items: center; gap: 8px; margin-left: auto; }
.wfc-band-caption + .wfc-band-actions { margin-left: 12px; }
@media (max-width: 768px) {
    .wfc-band-caption { display: none; }
}

/* What a panel holds: free content (body), selectable rows, a table flush to its edges, and a footer for its action */
.wfc-panel-body { display: flex; flex-direction: column; gap: 8px; padding: 16px; }
.wfc-panel-row { display: flex; align-items: center; gap: 16px; padding: 14px 16px; border-top: 1px solid var(--wf-row-line); }
.wfc-panel-row[aria-selected="true"] { background: var(--wf-primary); border-top-color: var(--wf-primary); color: #ffffff; }
.wfc-panel-row[aria-selected="true"] .wfc-caption { color: var(--wf-selection-subtext); }
.wfc-panel-row[aria-selected="true"] .wfc-figure,
.wfc-panel-row[aria-selected="true"] .wfc-subheading { color: #ffffff; }
.wfc-panel > .wfc-table { border: 0; border-radius: 0; }
.wfc-panel > .wfc-table th, .wfc-panel > .wfc-table td { padding-left: 16px; padding-right: 16px; }
.wfc-panel-foot { display: flex; flex-direction: column; gap: 8px; padding: 16px; border-top: 1px solid var(--wf-row-line); }

/* Label and value pairs inside a panel (account details, a record's facts) */
.wfc-kv { display: grid; grid-template-columns: minmax(120px, max-content) minmax(0, 1fr); margin: 0; font-family: Manrope, sans-serif; }
.wfc-kv > dt, .wfc-kv > dd { margin: 0; padding: 10px 16px; border-top: 1px solid var(--wf-row-line); }
.wfc-kv > dt:first-of-type, .wfc-kv > dt:first-of-type + dd { border-top: 0; }
.wfc-kv > dt { font-size: 12.5px; font-weight: 600; line-height: 20px; color: var(--wf-label); }
.wfc-kv > dd { font-size: 14px; line-height: 20px; color: var(--wf-text); overflow-wrap: anywhere; }
@media (max-width: 599px) {
    .wfc-kv { grid-template-columns: minmax(0, 1fr); }
    .wfc-kv > dd { padding-top: 0; border-top: 0; }
}

/* Nothing to show yet: centred in the panel, an icon on a tint circle, a title and a hint (App Permissions' empty role) */
.wfc-empty { display: flex; flex-direction: column; align-items: center; gap: 6px; padding: 32px 16px; text-align: center; font-family: Manrope, sans-serif; }
.wfc-empty-icon { display: flex; align-items: center; justify-content: center; width: 44px; height: 44px; margin-bottom: 4px; border-radius: 50%; background: var(--wf-tint); color: var(--wf-heading); font-size: 22px; }
.wfc-empty-title { font-size: 14px; font-weight: 700; color: var(--wf-text); }
.wfc-empty-hint { max-width: 360px; font-size: 12.5px; line-height: 18px; color: var(--wf-label); }

/* Text on a custom page: body text (a field value's size), a heading inside a panel, one big number */
.wfc-text { font: 15px/22px Manrope, sans-serif; color: var(--wf-text); }
.wfc-subheading { font: 700 14px/20px Manrope, sans-serif; color: var(--wf-text); }
.wfc-figure { font: 800 30px/1.15 Manrope, sans-serif; color: var(--wf-heading); font-variant-numeric: tabular-nums; }

/* Tier columns (plans, packages): side by side inside one panel, split by hairlines, stacking when narrow. The chosen
   tier's head takes the main selection fill */
.wfc-tiers { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); }
.wfc-tier { display: flex; flex-direction: column; min-width: 0; box-shadow: -1px 0 0 var(--wf-row-line), 0 -1px 0 var(--wf-row-line); }
.wfc-tier-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; min-height: 40px; padding: 0 24px; border-bottom: 1px solid var(--wf-row-line); }
.wfc-tier-name { font: 700 15px/22px Manrope, sans-serif; color: var(--wf-heading); }
.wfc-tier-tag { font-size: 12.5px; font-weight: 600; color: var(--wf-selection-subtext); }
.wfc-tier-body { display: flex; flex: 1 1 auto; flex-direction: column; gap: 14px; padding: 20px 24px 24px; }
.wfc-tier-body > .wfc-btn:last-child, .wfc-tier-body > .wfc-tier-end:last-child { width: 100%; margin-top: auto; }
.wfc-tier-end { text-align: center; line-height: 34px; }
.wfc-tier[aria-selected="true"] { background: var(--wf-readonly-bg); }
.wfc-tier[aria-selected="true"] > .wfc-tier-head { background: var(--wf-primary); border-bottom-color: var(--wf-primary); }
.wfc-tier[aria-selected="true"] .wfc-tier-name { color: #ffffff; }
.wfc-price { display: flex; align-items: baseline; flex-wrap: wrap; gap: 4px; }
/* The list price a discounted price replaces, struck through after the figure */
.wfc-price-was { font: 14px Manrope, sans-serif; color: var(--wf-label); text-decoration: line-through; }
@media (max-width: 768px) {
    .wfc-tier-head { padding: 0 16px; }
    .wfc-tier-body { padding: 16px; }
}

/* A list of what something includes: a green check before each line */
.wfc-checklist { display: flex; flex-direction: column; gap: 8px; margin: 0; padding: 0; list-style: none; font: 14px/20px Manrope, sans-serif; color: var(--wf-text); }
.wfc-checklist > li { display: flex; align-items: flex-start; gap: 8px; }
.wfc-checklist > li::before { content: ''; flex-shrink: 0; width: 10px; height: 5px; margin: 5px 3px 0; border: solid var(--wf-save-border); border-width: 0 0 2.5px 2.5px; transform: rotate(-45deg); }

/* The row a select's menu shows when there is nothing to pick ("No options available", "No matches") */
.wfc-select-empty { font-family: Manrope, sans-serif; font-size: 14px; color: var(--wf-label); }

/* Plan comparison: the tier columns (.wfc-tier) over one row per feature, a tick where a tier includes it and nothing where
   it doesn't. One grid: a label column, then a column per tier (--wfc-compare-tiers, set by the page). A row is
   display: contents, so its cells sit in the grid. On a phone each label takes its own line over the tiers' cells */
.wfc-compare { display: grid; grid-template-columns: minmax(200px, 300px) repeat(var(--wfc-compare-tiers, 4), minmax(0, 1fr)); font-family: Manrope, sans-serif; }
.wfc-compare-corner { display: flex; flex-direction: column; justify-content: flex-end; gap: 4px; padding: 16px; }
.wfc-compare > .wfc-tier { box-shadow: inset 1px 0 0 var(--wf-card-border); }
.wfc-compare .wfc-tier-head { padding: 0 16px; }
.wfc-compare .wfc-tier-body { gap: 6px; padding: 16px; }
.wfc-compare .wfc-figure { font-size: 24px; }
.wfc-compare .wfc-tier-summary { min-height: 40px; margin-bottom: 8px; }
.wfc-compare-row { display: contents; }
.wfc-compare-group { grid-column: 1 / -1; padding: 10px 16px; border-top: 1px solid var(--wf-card-border); background: var(--wf-readonly-bg); font-size: 13px; font-weight: 700; line-height: 18px; color: var(--wf-heading); }
.wfc-compare-label { padding: 12px 16px; border-top: 1px solid var(--wf-row-line); font-size: 14px; line-height: 20px; color: var(--wf-text); }
.wfc-compare-cell { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 2px; min-width: 0; min-height: 45px; padding: 6px 10px; box-sizing: border-box; border-top: 1px solid var(--wf-row-line); box-shadow: inset 1px 0 0 var(--wf-card-border); text-align: center; }
.wfc-compare-cell[data-chosen="true"] { background: var(--wf-readonly-bg); }
.wfc-compare-value { font-size: 14px; font-weight: 600; line-height: 20px; color: var(--wf-text); }
.wfc-compare-note { font-size: 12.5px; line-height: 17px; color: var(--wf-primary-text); }
/* The tick: the checklist's check, larger */
.wfc-compare-tick { display: block; width: 13px; height: 7px; margin-bottom: 4px; border: solid var(--wf-save-border); border-width: 0 0 3px 3px; transform: rotate(-45deg); }
@media (max-width: 768px) {
    .wfc-compare { grid-template-columns: repeat(var(--wfc-compare-tiers, 4), minmax(0, 1fr)); }
    .wfc-compare-corner { grid-column: 1 / -1; padding: 10px 12px; }
    .wfc-compare-corner:empty { display: none; }
    .wfc-compare-corner + .wfc-tier { box-shadow: none; }
    .wfc-compare .wfc-tier-head { flex-wrap: wrap; justify-content: center; min-height: 36px; padding: 4px; text-align: center; }
    .wfc-compare .wfc-tier-name { font-size: 13px; }
    .wfc-compare .wfc-tier-body { align-items: center; padding: 10px 4px 8px; text-align: center; }
    .wfc-compare .wfc-price { flex-direction: column; align-items: center; gap: 0; }
    .wfc-compare .wfc-figure { font-size: 16px; }
    .wfc-compare .wfc-price-was { font-size: 12px; }
    .wfc-compare .wfc-tier-summary { display: none; }
    .wfc-compare .wfc-tier-body > .wfc-btn { height: auto; min-height: 44px; padding: 4px; white-space: normal; line-height: 1.2; }
    .wfc-compare .wfc-tier-end { font-size: 12px; line-height: 1.25; }
    .wfc-compare-group { padding: 8px 12px; }
    .wfc-compare-label { grid-column: 1 / -1; padding: 8px 12px 0; font-size: 13px; line-height: 18px; }
    .wfc-compare-cell { min-height: 34px; padding: 2px 4px 6px; border-top: 0; box-shadow: none; }
    .wfc-compare-value { font-size: 12px; line-height: 16px; }
    .wfc-compare-note { font-size: 11px; line-height: 14px; }
}

/* Usage against a limit (clock-ins this month, sites): a label row over a blue bar; amber from 80%, red over the limit.
   Never the coral progress bar, which means "working" */
.wfc-meter { display: flex; flex-direction: column; gap: 6px; font-family: Manrope, sans-serif; }
.wfc-meter-label { display: flex; justify-content: space-between; gap: 12px; font-size: 12.5px; font-weight: 600; color: var(--wf-label); }
.wfc-meter-value { color: var(--wf-text); font-variant-numeric: tabular-nums; }
.wfc-meter-track { height: 8px; border-radius: 4px; background: var(--wf-tint); overflow: hidden; }
.wfc-meter-fill { height: 100%; max-width: 100%; border-radius: 4px; background: var(--wf-primary); }
.wfc-meter[data-level="warning"] .wfc-meter-fill { background: var(--wf-notice-warning-icon); }
.wfc-meter[data-level="over"] .wfc-meter-fill { background: var(--wf-error); }
.wfc-meter[data-level="over"] .wfc-meter-value { color: var(--wf-error); }

/* Equal tiles that wrap: as many 240px-or-wider columns as fit */
.wfc-tiles { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 16px; width: 100%; }

/* A grid of people's photos (face registrations): a square photo, or a grey blank with a tag on its corner, over the
   name and user ID, with an optional icon action at the right */
.wfc-photo-tiles { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 12px; width: 100%; }
.wfc-photo-tile {
    display: flex;
    flex-direction: column;
    min-width: 0;
    border: 1px solid var(--wf-card-border);
    border-radius: 8px;
    background: #ffffff;
    overflow: hidden;
    font-family: Manrope, sans-serif;
}
.wfc-photo-tile-img {
    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;
    aspect-ratio: 1;
    background: var(--wf-readonly-bg);
    color: var(--wf-icon-muted);
    font-size: 56px;
}
.wfc-photo-tile-img img { display: block; width: 100%; height: 100%; object-fit: cover; }
.wfc-photo-tile-img .wfc-tag { position: absolute; top: 8px; left: 8px; }
.wfc-photo-tile-foot { display: flex; align-items: center; gap: 4px; padding: 8px 6px 8px 10px; border-top: 1px solid var(--wf-card-border); }
.wfc-photo-tile-text { flex: 1; min-width: 0; }
.wfc-photo-tile-name { overflow: hidden; font-size: 13.5px; font-weight: 700; line-height: 18px; color: var(--wf-text); text-overflow: ellipsis; white-space: nowrap; }
.wfc-photo-tile-sub { overflow: hidden; font-size: 12px; line-height: 16px; color: var(--wf-label); text-overflow: ellipsis; white-space: nowrap; }
@media (max-width: 599px) { .wfc-photo-tiles { grid-template-columns: repeat(auto-fill, minmax(130px, 1fr)); gap: 8px; } }

/* A read-only table of a few rows (payments, an invoice, usage by month): the data table's look on plain HTML. Inside a
   panel it runs flush to the panel's edges */
.wfc-table {
    width: 100%;
    border-collapse: separate;
    border-spacing: 0;
    border: 1px solid var(--wf-card-border);
    border-radius: 8px;
    overflow: hidden;
    font: 14px/20px Manrope, sans-serif;
    color: var(--wf-text);
}
.wfc-table th {
    padding: 8px 12px;
    background: var(--wf-readonly-bg);
    border-bottom: 1px solid var(--wf-card-border);
    text-align: left;
    font-size: 12.5px;
    font-weight: 600;
    color: var(--wf-label);
    white-space: nowrap;
}
.wfc-table td { padding: 9px 12px; border-bottom: 1px solid var(--wf-row-line); }
.wfc-table tr:last-child td,
.wfc-table tr:has(+ .wfc-table-total) td { border-bottom: 0; }
.wfc-table .wfc-num { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
.wfc-table tr.wfc-table-total td { border-top: 1px solid var(--wf-card-border); background: var(--wf-readonly-bg); font-weight: 700; }

/* RETIRED, kept only so the attendance Billing page renders until it is rebuilt on the classes above; delete them then.
   Never use them on a new page: cards are for CRUD forms, custom pages use panels */
.wfc-card { width: 100%; min-width: 0; background: var(--wf-card-bg); border: 1px solid var(--wf-card-border); border-radius: 10px; box-shadow: 0 1px 2px rgba(16, 24, 40, 0.05); box-sizing: border-box; overflow: hidden; font-family: Manrope, sans-serif; color: var(--wf-text); }
.wfc-card-band { display: flex; align-items: center; gap: 10px; padding: 11px 24px; background: var(--wf-header-bg); border-bottom: 1px solid var(--wf-card-border); font-size: 15px; font-weight: 700; line-height: 22px; color: var(--wf-heading); }
.wfc-card-body { display: flex; flex-direction: column; gap: 12px; padding: 24px; }
.wfc-card-band + .wfc-card-body { padding-top: 20px; }
.wfc-band:has(+ .wfc-panel-body):not(:has(> .wfc-band-title)) { padding: 0 16px; }
.wfc-panel[aria-selected="true"] { border-color: var(--wf-primary); }
.wfc-panel[aria-selected="true"] > .wfc-band,
.wfc-panel[aria-selected="true"] > .wfc-band .wfc-subheading { background: var(--wf-primary); color: #ffffff; }
.wfc-panel[aria-selected="true"] > .wfc-band .wfc-caption { color: var(--wf-selection-subtext); }

/* ---------- Notice rows: a tinted fill, a matching border and a coloured icon ---------- */
.wfc-notice {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    width: 100%;
    box-sizing: border-box;
    padding: 12px;
    border: 1px solid;
    border-radius: 6px;
    font-family: Manrope, sans-serif;
}
.wfc-notice-icon { flex-shrink: 0; font-size: 20px; }
.wfc-notice-content { display: flex; flex-direction: column; gap: 2px; flex: 1 1 0; min-width: 0; }
.wfc-notice-title { font-size: 14px; font-weight: 700; line-height: 20px; color: var(--wf-text); }
.wfc-notice-text { font-size: 13px; line-height: 20px; color: var(--wf-notice-text); white-space: pre-wrap; overflow-wrap: anywhere; }
.wfc-notice-error   { background: var(--wf-notice-error-bg);   border-color: var(--wf-notice-error-border); }
.wfc-notice-success { background: var(--wf-notice-success-bg); border-color: var(--wf-notice-success-border); }
.wfc-notice-warning { background: var(--wf-notice-warning-bg); border-color: var(--wf-notice-warning-border); }
.wfc-notice-info    { background: var(--wf-notice-info-bg);    border-color: var(--wf-notice-info-border); }
.wfc-notice-error .wfc-notice-icon   { color: var(--wf-notice-error-icon); }
.wfc-notice-success .wfc-notice-icon { color: var(--wf-notice-success-icon); }
.wfc-notice-warning .wfc-notice-icon { color: var(--wf-notice-warning-icon); }
.wfc-notice-info .wfc-notice-icon    { color: var(--wf-primary); }

/* ---------- Tabs: a white pill with a faint shadow; on a tint track when they are views of one thing ---------- */
.wfc-seg {
    display: inline-flex;
    gap: 2px;
    padding: 3px;
    border-radius: 8px;
    background: var(--wf-tint);
    max-width: 100%;
    box-sizing: border-box;
}
.wfc-seg-strong { background: var(--wf-tab-strip-line); }    /* on the header band, where the light track would vanish */

/* Tabs that do not fit never spill out of their track: the track scrolls sideways inside itself, as the CRUD form tabs'
   row does (a swipe on a phone, the wheel or a drag on a desktop, no scroll bar), and the selected tab is brought into
   view. Quasar's q-tabs scroll by themselves. */
.wfc-seg:not(.q-tabs) {
    overflow-x: auto;
    overflow-y: hidden;
    overscroll-behavior-x: contain;
    scroll-padding-inline: 3px;    /* a tab scrolled into view keeps the track's own 3px at the edge */
    scrollbar-width: none;
}
.wfc-seg:not(.q-tabs)::-webkit-scrollbar { display: none; }
.wfc-seg:not(.q-tabs) > .wfc-seg-item { flex-shrink: 0; }
/* Filling its row (a phone): the tabs share the width while they fit, and scroll once they do not */
.wfc-seg-fill { display: flex; width: 100%; }
.wfc-seg-fill > .wfc-seg-item { flex: 1 0 auto; }

.wfc-seg-item {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    min-height: 32px;
    padding: 0 12px;
    border: 0;
    border-radius: 6px;
    background: transparent;
    font-family: Manrope, sans-serif;
    font-size: 13px;
    font-weight: 600;
    color: var(--wf-tab-text);
    text-transform: none;
    cursor: pointer;
    box-sizing: border-box;
}
.wfc-seg-item:not(.q-tab) { white-space: nowrap; }
.wfc-seg-item[aria-selected="true"],
.wfc-seg-item[aria-checked="true"] {
    background: #ffffff;
    font-weight: 700;
    color: var(--wf-heading);
    box-shadow: 0 1px 2px rgba(16, 24, 40, 0.12);
}
.wfc-seg-item:focus-visible { outline: none; }
.wfc-seg-item:disabled { opacity: 0.45; cursor: default; }
@media (max-width: 768px) {
    .wfc-seg-item { min-height: 34px; padding: 0 14px; }
}
/* Compact: inside a card (the approval panel's Timeline / Path) */
.wfc-seg-compact .wfc-seg-item { min-height: 28px; height: 28px; padding: 0 14px; }

/* Switching tabs: the old panel slides out while the new one slides in from its tab's side, across the full width.
   The same slide, duration and easing as Quasar's animated q-tab-panels on the CRUD pages ("Tabs" in the spec).
   "next" = a tab further right was picked. */
@keyframes wfc-in-from-right { from { transform: translate3d(100%, 0, 0); } to { transform: none; } }
@keyframes wfc-in-from-left  { from { transform: translate3d(-100%, 0, 0); } to { transform: none; } }
@keyframes wfc-out-to-left   { from { transform: none; } to { transform: translate3d(-100%, 0, 0); } }
@keyframes wfc-out-to-right  { from { transform: none; } to { transform: translate3d(100%, 0, 0); } }
.wfc-panel-enter-next { animation: wfc-in-from-right var(--wf-tab-slide-duration) var(--wf-tab-slide-easing); }
.wfc-panel-enter-prev { animation: wfc-in-from-left var(--wf-tab-slide-duration) var(--wf-tab-slide-easing); }
.wfc-panel-leave-next { animation: wfc-out-to-left var(--wf-tab-slide-duration) var(--wf-tab-slide-easing) forwards; }
.wfc-panel-leave-prev { animation: wfc-out-to-right var(--wf-tab-slide-duration) var(--wf-tab-slide-easing) forwards; }

/* ---------- Main selection: the one item a page shows out of the list beside it ---------- */
.wfc-select-row {
    display: grid;
    align-items: center;
    width: 100%;
    border: 0;
    border-radius: 6px;
    background: transparent;
    text-align: left;
    font-family: Manrope, sans-serif;
    color: var(--wf-text);
    cursor: pointer;
    box-sizing: border-box;
}
.wfc-select-row:hover { background: rgba(66, 101, 146, 0.07); }
.wfc-select-row:focus-visible { outline: none; box-shadow: var(--wf-focus-ring); }
.wfc-select-name { font-size: 14px; font-weight: 600; color: var(--wf-text); }
.wfc-select-sub  { font-size: 12px; color: var(--wf-label); }
.wfc-select-row[aria-selected="true"] { background: var(--wf-primary); }
.wfc-select-row[aria-selected="true"] .wfc-select-name { font-weight: 700; color: #ffffff; }
.wfc-select-row[aria-selected="true"] .wfc-select-sub  { color: var(--wf-selection-subtext); }

/* A side panel's items as white cards with a thin border, 4px apart, on the panel's grey */
.wfc-select-card { background: var(--wf-card-bg); border: 1px solid var(--wf-card-border); }
.wfc-select-card:hover:not([aria-selected="true"]) { background: var(--wf-card-bg); border-color: var(--wf-field-border); }
.wfc-select-card[aria-selected="true"] { border-color: var(--wf-primary); }

/* An option inside a dropdown or menu keeps the light fill */
.wfc-option-selected { background: var(--wf-option-selected); }

/* ---------- Inputs (plain HTML; Quasar and MUI fields take the same look through their adapters) ---------- */
.wfc-input {
    width: 100%;
    height: 40px;
    padding: 0 12px;
    border: 1px solid var(--wf-field-border);
    border-radius: 6px;
    background: var(--wf-card-bg);
    font: 15px Manrope, sans-serif;
    color: var(--wf-text);
    outline: none;
    box-sizing: border-box;
}
textarea.wfc-input { height: auto; padding: 10px 12px; font-size: 14px; line-height: 21px; resize: vertical; }
.wfc-input:focus { border-color: var(--wf-primary); box-shadow: var(--wf-focus-ring); }
.wfc-input[aria-invalid="true"] { border-color: var(--wf-error); }
.wfc-input::placeholder { color: var(--wf-placeholder); }
.wfc-input:disabled, .wfc-input[readonly] { background: var(--wf-readonly-bg); }

.wfc-search {
    display: flex;
    align-items: center;
    gap: 8px;
    height: 34px;
    padding: 0 10px;
    border: 1px solid var(--wf-field-border);
    border-radius: 6px;
    background: #ffffff;
    box-sizing: border-box;
    color: var(--wf-icon-muted);
}
.wfc-search:focus-within { border-color: var(--wf-primary); box-shadow: var(--wf-focus-ring); }
.wfc-search input {
    flex: 1;
    min-width: 0;
    border: 0;
    outline: 0;
    background: transparent;
    font: 13.5px Manrope, sans-serif;
    color: var(--wf-text);
}
.wfc-search input::placeholder { color: var(--wf-placeholder); }

/* The x that clears a filled search box */
.wfc-search-clear {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    width: 24px;
    height: 24px;
    margin-right: -4px;
    padding: 0;
    border: 0;
    border-radius: 5px;
    background: transparent;
    color: var(--wf-icon-muted);
    cursor: pointer;
}
.wfc-search-clear:hover { background: var(--wf-tint); color: var(--wf-text); }

/* ---------- Search menu (React SearchMenu): a dropdown whose search box filters its options as you type ---------- */
.wfc-pick {
    display: flex;
    flex-direction: column;
    max-height: min(420px, calc(100vh - 32px));
    margin-top: 4px;
    border: 1px solid var(--wf-card-border);
    border-radius: 8px;
    background: var(--wf-card-bg);
    box-shadow: var(--wf-menu-shadow);
    overflow: hidden;
    font-family: Manrope, sans-serif;
    box-sizing: border-box;
}
.wfc-pick > .wfc-search { flex-shrink: 0; margin: 8px; }
.wfc-pick-list { flex: 1 1 auto; min-height: 0; overflow-y: auto; padding: 0 4px 4px; }
.wfc-pick-option {
    display: flex;
    align-items: center;
    gap: 10px;
    width: 100%;
    min-height: 36px;
    padding: 0 10px;
    border: 0;
    border-radius: 6px;
    background: transparent;
    text-align: left;
    font: 14px Manrope, sans-serif;
    color: var(--wf-text);
    cursor: pointer;
}
.wfc-pick-option > span { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.wfc-pick-sub { display: block; overflow: hidden; text-overflow: ellipsis; font-size: 12px; color: var(--wf-label); }
.wfc-pick-option[aria-selected="true"] { background: var(--wf-option-selected); font-weight: 700; }
.wfc-pick-option[data-active="true"] { background: rgba(66, 101, 146, 0.1); }    /* the hovered or arrowed-to option: a shade darker than the selected one */
.wfc-pick-empty { padding: 4px 12px 12px; font-size: 13px; color: var(--wf-label); }
@media (max-width: 768px) {
    .wfc-pick-option { min-height: 44px; }
}

/* ---------- Phone field (static/js/wf_phone_field.js): a country box with the flag and calling code, then the number.
   .wfc-phone is the form field (40px, the number is a .wfc-input); .wfc-phone-cell the same inside a table row ---------- */
.wfc-phone { display: flex; gap: 8px; width: 100%; min-width: 0; font-family: Manrope, sans-serif; }
/* The country box keeps one width whatever it shows (no code, "+1" or "+968"); the longest code fits beside the caret */
.wfc-phone-country {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    flex: 0 0 95px;
    width: 95px;
    height: 40px;
    padding: 0 2px 0 10px;
    border: 1px solid var(--wf-field-border);
    border-radius: 6px;
    background: var(--wf-card-bg);
    font: 15px Manrope, sans-serif;
    color: var(--wf-text);
    text-align: left;
    cursor: pointer;
    box-sizing: border-box;
}
.wfc-phone-country:disabled { background: var(--wf-readonly-bg); color: var(--wf-text); cursor: default; }
.wfc-phone-country:disabled .wfc-phone-caret { display: none; }
@media (hover: hover) {
    .wfc-phone-country:hover:not(:disabled) { border-color: var(--wf-primary); }
}
.wfc-phone-country:focus-visible,
.wfc-phone-country[aria-expanded="true"] { outline: none; border-color: var(--wf-primary); box-shadow: var(--wf-focus-ring); }
.wfc-phone:has(.wfc-phone-number[aria-invalid="true"]) .wfc-phone-country { border-color: var(--wf-error); }
.wfc-phone-flag { flex-shrink: 0; width: 16px; height: 12px; }
.wfc-phone-noflag { flex-shrink: 0; width: 16px; height: 12px; border-radius: 2px; background: var(--wf-row-line); }
.wfc-phone-flag[hidden], .wfc-phone-noflag[hidden] { display: none; }
.wfc-phone-code { flex: 1 1 0; min-width: 0; overflow: hidden; font-variant-numeric: tabular-nums; white-space: nowrap; }
.wfc-phone-code:empty::before { content: 'Code'; color: var(--wf-placeholder); }
.wfc-phone-caret { flex-shrink: 0; color: var(--wf-icon-muted); }
.wfc-phone-number { flex: 1 1 0; min-width: 0; font-variant-numeric: tabular-nums; }

/* In a table row: no outline of its own, the code on the grey of a read-only cell, marked as a whole while wrong */
.wfc-phone-cell { gap: 0; height: 100%; min-height: 26px; align-items: stretch; }
.wfc-phone-cell .wfc-phone-country {
    flex: 0 0 78px;
    width: 78px;
    height: auto;
    gap: 4px;
    padding: 0 0 0 8px;
    border: 0;
    border-right: 1px solid var(--wf-row-line);
    border-radius: 0;
    background: var(--wf-readonly-bg);
    font: 600 12.5px Manrope, sans-serif;
}
.wfc-phone-cell .wfc-phone-country:disabled { background: transparent; }
.wfc-phone-cell .wfc-phone-country:focus-visible,
.wfc-phone-cell .wfc-phone-country[aria-expanded="true"] { box-shadow: inset 0 0 0 1.5px var(--wf-primary); }
.wfc-phone-cell .wfc-phone-flag,
.wfc-phone-cell .wfc-phone-noflag { width: 14px; height: 10px; }
.wfc-phone-cell .wfc-phone-number {
    height: auto;
    padding: 0 8px;
    border: 0;
    border-radius: 0;
    outline: 0;
    background: transparent;
    font: 13px Manrope, sans-serif;
    color: var(--wf-text);
}
.wfc-phone-cell .wfc-phone-number:focus:not([readonly]) { background: var(--wf-card-bg); box-shadow: inset 0 0 0 1.5px var(--wf-primary); }
.wfc-phone-cell[aria-invalid="true"] { box-shadow: inset 0 0 0 1.5px var(--wf-error); background: var(--wf-notice-error-bg); }

/* The country list: a dropdown with a search box; one at a time on a page */
.wfc-phone-menu {
    position: fixed;
    z-index: 2147483647;
    display: flex;
    flex-direction: column;
    max-width: calc(100vw - 24px);
    overflow: hidden;
    border: 1px solid var(--wf-card-border);
    border-radius: 10px;
    background: var(--wf-card-bg);
    box-shadow: var(--wf-menu-shadow);
    font-family: Manrope, sans-serif;
    color: var(--wf-text);
    box-sizing: border-box;
}
.wfc-phone-menu-search { flex-shrink: 0; padding: 8px; border-bottom: 1px solid var(--wf-row-line); }
.wfc-phone-list { flex: 1 1 auto; min-height: 0; overflow-y: auto; }
.wfc-phone-option {
    display: flex;
    align-items: center;
    gap: 8px;
    width: 100%;
    min-height: 38px;
    padding: 0 12px;
    border: 0;
    border-bottom: 1px solid var(--wf-row-line);
    background: transparent;
    font: 14px Manrope, sans-serif;
    color: var(--wf-text);
    text-align: left;
    cursor: pointer;
}
.wfc-phone-option[hidden] { display: none; }
.wfc-phone-option img { flex-shrink: 0; width: 16px; height: 12px; }
.wfc-phone-option-code { min-width: 44px; font-weight: 600; color: var(--wf-label); font-variant-numeric: tabular-nums; }
.wfc-phone-option-name { flex: 1 1 0; min-width: 0; }
.wfc-phone-option[data-active="true"],
.wfc-phone-option[aria-selected="true"] { background: var(--wf-option-selected); }
.wfc-phone-option[aria-selected="true"] { font-weight: 600; }
@media (hover: hover) {
    .wfc-phone-option:hover { background: var(--wf-option-selected); }
}
.wfc-phone-option:focus-visible { outline: none; background: var(--wf-option-selected); }
.wfc-phone-empty { padding: 10px 12px; font-size: 14px; color: var(--wf-label); }
.wfc-phone-empty[hidden] { display: none; }
@media (max-width: 599px) {
    .wfc-phone-option { min-height: 44px; }
}

.wfc-label { font: 600 12.5px/18px Manrope, sans-serif; color: var(--wf-label); }
.wfc-required { color: var(--wf-error); }
.wfc-caption { font: 12.5px Manrope, sans-serif; color: var(--wf-label); }

/* ---------- Modal: white card, navy header with the title and a close button, body, footer of buttons ---------- */
.wfc-modal-card {
    display: flex;
    flex-direction: column;
    overflow: hidden;
    border-radius: var(--wf-modal-radius);
    box-shadow: var(--wf-modal-shadow);
    background: var(--wf-card-bg);
    font-family: Manrope, sans-serif;
    color: var(--wf-text);
    box-sizing: border-box;
}
/* The browser blends a clipped rounded corner with what lies behind it, so the card's white showed as a hairline
   round the navy header's top corners. Behind those corners the card is navy too. */
.wfc-modal-card:has(> .wfc-modal-header:first-child) {
    background: linear-gradient(var(--wf-heading), var(--wf-heading)) top / 100% calc(var(--wf-modal-radius) + 2px) no-repeat, var(--wf-card-bg);
}

.wfc-modal-header {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-shrink: 0;
    min-height: 44px;
    padding: 0 6px 0 16px;
    border-bottom: 1px solid var(--wf-heading-border);
    background: var(--wf-heading);
    box-sizing: border-box;
}
.wfc-modal-title {
    flex: 1 1 0;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-family: Manrope, sans-serif;
    font-size: 15px;
    font-weight: 700;
    line-height: 22px;
    color: #ffffff;
}
.wfc-modal-close {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    width: 32px;
    min-width: 32px;
    height: 32px;
    min-height: 32px;
    padding: 0;
    border: 0;
    border-radius: 6px;
    background: transparent;
    color: var(--wf-modal-close);
    cursor: pointer;
}
.wfc-modal-close:focus-visible { outline: none; }
.wfc-modal-close:disabled, .wfc-modal-close.disabled { opacity: 0.35 !important; }

.wfc-modal-body {
    display: flex;
    flex-direction: column;
    gap: 12px;
    flex: 1 1 auto;
    min-height: 0;
    overflow-x: hidden;    /* scrolls up and down only: nothing inside may shift the whole body sideways */
    overflow-y: auto;
    padding: 16px;
    font-family: Manrope, sans-serif;
    font-size: 14px;
    line-height: 21px;
    color: var(--wf-text);
    box-sizing: border-box;
}
/* The footer's own top padding is the gap between the text and the buttons */
.wfc-modal-body:has(+ .wfc-modal-footer:not(:empty)) { padding-bottom: 4px; }

.wfc-modal-footer {
    display: flex;
    flex-wrap: wrap;
    justify-content: flex-end;
    align-items: center;
    gap: 8px;
    flex-shrink: 0;
    padding: 12px 16px 16px;
    box-sizing: border-box;
}
.wfc-modal-footer:empty { display: none; }

/* A body that scrolls gets a line above its footer */
.wfc-modal-divided .wfc-modal-body:has(+ .wfc-modal-footer:not(:empty)) { padding-bottom: 16px; }
.wfc-modal-divided .wfc-modal-footer { padding: 12px 16px; border-top: 1px solid var(--wf-card-border); }

/* Motion, as Quasar's dialog: the card zooms in from the centre and back out, and pulses when the page behind it is
   clicked (a modal never closes that way). Quasar draws these on its own dialogs; React pages set the classes. */
@keyframes wfc-modal-in  { from { opacity: 0; transform: scale3d(0, 0, 1); } to { opacity: 1; transform: none; } }
@keyframes wfc-modal-out { from { opacity: 1; transform: none; } to { opacity: 0; transform: scale3d(0, 0, 1); } }
@keyframes wfc-modal-shake { 0% { transform: scale(1); } 50% { transform: scale(1.04); } 100% { transform: scale(1); } }
.wfc-modal-enter { animation: wfc-modal-in var(--wf-modal-duration) var(--wf-modal-easing); }
.wfc-modal-leave { animation: wfc-modal-out var(--wf-modal-duration) var(--wf-modal-easing) forwards; }
.wfc-modal-shake { animation: wfc-modal-shake var(--wf-shake-duration) var(--wf-shake-easing); }

@media (max-width: 599px) {
    .wfc-modal-close { width: 40px; min-width: 40px; height: 40px; min-height: 40px; }
    .wfc-modal-header { padding-right: 2px; }
    /* The footer's buttons share the width; a label never gets cut, so a button that doesn't fit moves to the next row */
    .wfc-modal-footer .wfc-btn-modal { flex: 1 1 0; height: 40px; min-height: 40px; min-width: max-content; padding: 0 8px; }
    .wfc-modal-footer .wfc-btn-modal.wfc-btn-flat { flex: 0 0 auto; }
    /* Buttons inside the body are as high as the footer's */
    .wfc-modal-body .wfc-btn-modal { height: 40px; min-height: 40px; }
}

/* ---- Progress bar: coral, cut into slanted sections, always moving so a bar that stands still never looks stuck ---- */

.wfc-progress {
    flex-shrink: 0;
    width: 100%;
    height: 12px;
    border-radius: 6px;
    background: var(--wf-row-line);
    overflow: hidden;
}

.wfc-progress-fill,
.wfc-busy-strip {
    position: relative;
    height: 100%;
    border-radius: 6px;
    overflow: hidden;
    background-color: var(--wf-accent);
    background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.32) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.32) 50%, rgba(255, 255, 255, 0.32) 75%, transparent 75%, transparent);
    background-size: 20px 20px;
    animation: wfc-progress-stripes 0.8s linear infinite;
}

.wfc-progress-fill {
    transition: width 0.3s ease;
}

/* The highlight that sweeps across the fill */
.wfc-progress-fill::after,
.wfc-busy-strip::after {
    content: '';
    position: absolute;
    top: 0;
    left: 0;
    width: 40%;
    height: 100%;
    background: linear-gradient(90deg, rgba(255, 255, 255, 0), rgba(255, 255, 255, 0.5), rgba(255, 255, 255, 0));
    animation: wfc-progress-sheen 1.8s ease-in-out infinite;
}

.wfc-progress-count {
    font-size: 13px;
    line-height: 18px;
    color: var(--wf-label);
    font-variant-numeric: tabular-nums;
}

@keyframes wfc-progress-stripes {
    from { background-position: 0 0; }
    to { background-position: 20px 0; }
}

@keyframes wfc-progress-sheen {
    from { transform: translateX(-100%); }
    to { transform: translateX(250%); }
}

/* ---- Busy indicator: a line of text over a strip of the progress bar's moving stripes. Never a circular spinner.
   CRUD (ngh.busy_indicator) and the React pages draw it ---- */

.wfc-busy {
    display: flex;
    flex-direction: column;
    gap: 10px;
    width: 100%;
    font-family: 'Manrope', sans-serif;
}

.wfc-busy-text {
    font-size: 14px;
    font-weight: 600;
    line-height: 21px;
    color: var(--wf-text);
}

.wfc-busy-hint {
    margin-top: -6px;
    font-size: 13px;
    line-height: 18px;
    color: var(--wf-label);
}

.wfc-busy-strip {
    flex-shrink: 0;
    width: 100%;
    height: 10px;
    border-radius: 5px;
}

/* The card round a busy indicator standing alone (saving, approving, restoring a draft, loading a map): sized to its
   text, at least 210px and at most a dialog's 560px. In a q-dialog on CRUD; in a .wfc-busy-layer on the React pages */
.wfc-busy-card {
    width: max-content;
    min-width: 210px;
    max-width: min(560px, 100%);
    padding: 14px 16px 16px;
    border: 1px solid var(--wf-card-border);
    border-radius: 10px;
    background: var(--wf-card-bg);
    box-shadow: var(--wf-modal-shadow);
    box-sizing: border-box;
}

/* Centres a busy card over the region it fills (its parent is positioned). Clicks pass through unless data-dim is set,
   which dims the region and blocks it until the wait is over */
.wfc-busy-layer {
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 16px;
    z-index: 1150;
    pointer-events: none;
}
.wfc-busy-layer[data-dim="true"] { background: var(--wf-backdrop); pointer-events: auto; }

/* Reduced motion: nothing slides. The sections stand still and the bar slowly fades lighter and darker instead, so it
   still never looks stuck */
@media (prefers-reduced-motion: reduce) {
    .wfc-progress-fill,
    .wfc-busy-strip {
        animation: wfc-progress-breathe 2.4s ease-in-out infinite;
    }

    .wfc-progress-fill::after,
    .wfc-busy-strip::after {
        display: none;
    }
}

@keyframes wfc-progress-breathe {
    0%, 100% { opacity: 1; }
    50% { opacity: 0.5; }
}
