﻿/* ── The guided wizard's chrome ────────────────────────────────────────────────────────────────────
   Shared, not scoped. Two pages wear this look — the job wizard and the quote wizard — and a guided
   flow that drifts apart between them would be worse than a stylesheet that is global: the whole point
   of the design is that answering "what needs doing?" and "what are we quoting for?" feel like the same
   act. Every rule is prefixed wz- and nothing else in the app uses that prefix.

   The accent is passed in per page as --dom (a trade's colour on a job, the app's primary on a quote),
   so the same rules theme themselves to whatever is being built.

   Linked from each page's <HeadContent>, and from the MAUI head's index.html — <HeadContent> is a no-op
   inside the BlazorWebView, so a page that only did the former would render unstyled on device.
   ─────────────────────────────────────────────────────────────────────────────────────────────────── */

.wz {
    position: relative;
    min-height: 100%;
    padding-bottom: 5rem;
    --wz-border: var(--ty-color-border, #e7ebf0);
    --wz-border-soft: var(--ty-color-border-soft, #eef1f4);
    --wz-text: var(--ty-color-text, #1c2128);
    --wz-muted: var(--ty-color-text-muted, #8a95a1);
}

/* ── Header ── */
.wz-head {
    display: flex;
    align-items: center;
    gap: .5rem;
    padding: .8rem 1.1rem;
    border-bottom: 1px solid var(--wz-border);
    position: sticky;
    top: 0;
    z-index: 5;
}

.wz-crumb {
    display: inline-flex;
    align-items: center;
    gap: .35rem;
    border: 0;
    background: transparent;
    color: var(--wz-muted);
    font-weight: 600;
    font-size: .85rem;
    padding: 0;
    cursor: pointer;
}
.wz-crumb:hover { color: var(--dom); }
.wz-sep { color: var(--ty-color-border-strong, #c2cad3); font-size: .65rem; }

.wz-domico {
    width: 28px; height: 28px; border-radius: 9px;
    display: inline-flex; align-items: center; justify-content: center;
    color: var(--ty-color-primary-contrast, #fff); font-size: .85rem; flex: none;
}
.wz-title { font-weight: 800; font-size: 1rem; }

.wz-seg {
    display: inline-flex; background: var(--ty-color-surface-sunken, #f1f2f4);
    border-radius: 10px; padding: 4px; gap: 3px;
}
.wz-seg button {
    border: 0; background: transparent; color: var(--wz-muted);
    font-weight: 700; font-size: .78rem; padding: .4rem .8rem; border-radius: 7px; cursor: pointer;
}
.wz-seg button.on { background: var(--dom); color: var(--ty-color-primary-contrast, #fff); }

.wz-errbar {
    display: flex; align-items: center; gap: .5rem;
    padding: .6rem 1.1rem; background: var(--ty-color-danger-soft, #fdecec); color: var(--ty-color-danger-ink, #b32121); font-weight: 600; font-size: .82rem;
}

/* Both wizards' "entered without a customer" safety net is the SHARED <CustomerPickerDialog>
   (Components/CustomerPickerDialog.razor + its own scoped CSS), not a picker drawn here — so the .wz-pick*
   / .wz-cust* rules that used to sit at this spot are gone. One dialog, one stylesheet, one behaviour. */

/* ── Panel grid (the record behind) ── */
.wz-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
    gap: .8rem;
    padding: 1.1rem;
}
.wz-panel {
    border: 2px solid var(--wz-border-soft); border-radius: 13px; padding: .85rem .9rem;
    background: var(--ty-color-surface, #fff); transition: border-color .15s, box-shadow .15s, opacity .15s;
}
.wz-panel.current { border-color: var(--dom); box-shadow: 0 0 0 3px color-mix(in srgb, var(--dom) 16%, transparent); cursor: pointer; }
.wz-panel.done { border-color: color-mix(in srgb, var(--dom) 34%, var(--wz-border-soft)); background: color-mix(in srgb, var(--dom) 3%, var(--ty-color-surface, #fff)); cursor: pointer; }
.wz-panel.skipped { border-color: var(--ty-color-warning-border, #f2d9a4); background: var(--ty-color-surface-subtle, #f6f8fa); cursor: pointer; }
.wz-panel.pending { opacity: .7; cursor: pointer; }

.wz-phead { display: flex; align-items: center; gap: .5rem; }
.wz-pico { width: 30px; height: 30px; border-radius: 8px; display: inline-flex; align-items: center; justify-content: center; flex: none; }
.wz-ptitle { font-weight: 800; flex: 1 1 auto; min-width: 0; }

.wz-preq, .wz-popt {
    font-size: .62rem; font-weight: 800; text-transform: uppercase; letter-spacing: .03em;
    padding: .12rem .45rem; border-radius: 999px;
}
.wz-preq { color: var(--ty-color-danger-ink, #b32121); background: var(--ty-color-danger-soft, #fdecec); }
.wz-popt { color: var(--ty-color-text-muted, #57606a); background: var(--ty-color-surface-sunken, #f3f5f8); }

.wz-pstate { margin-left: auto; display: inline-flex; align-items: center; gap: .28rem; font-size: .62rem; font-weight: 800; padding: .18rem .5rem; border-radius: 999px; }
.wz-pstate--current { color: var(--ty-color-info-ink, #1457b0); background: var(--ty-color-info-soft, #eaf2fd); }
.wz-pstate--done { color: var(--ty-color-success-ink, #1a7f37); background: var(--ty-color-success-soft, #e6f6ea); }
.wz-pstate--skipped { color: var(--ty-color-warning-ink, #9a5b00); background: var(--ty-color-warning-soft, #fdf1dd); }
.wz-pstate--pending { color: var(--ty-color-text-subtle, #8a95a1); background: var(--ty-color-surface-3, #eef1f4); }

.wz-pval {
    margin-top: .55rem; background: var(--ty-color-surface, #fff); border: 1px solid var(--wz-border);
    border-radius: 9px; padding: .5rem .65rem; font-weight: 700; font-size: .85rem;
    display: flex; align-items: center; gap: .45rem; color: var(--wz-text);
}
.wz-pval--empty { color: var(--ty-color-text-subtle, #8a95a1); font-weight: 500; border-style: dashed; }

/* ── Full-form inline field ── */
.wz-full { margin-top: .55rem; }
.wz-chips { display: flex; gap: .35rem; flex-wrap: wrap; margin-top: .5rem; }
.wz-chip { border: 0; border-radius: 999px; font-weight: 700; font-size: .72rem; padding: .35rem .7rem; cursor: pointer; }

.wz-freq { display: flex; align-items: center; gap: .4rem; flex-wrap: wrap; margin-top: .3rem; }
.wz-freq-lbl { font-weight: 800; }
.wz-freq-n { width: 4.5rem; flex: none; }
.wz-freq-u { width: 6.5rem; flex: none; }
.wz-freq-cur { font-weight: 700; color: var(--dom); }
.wz-freq--sheet { margin-top: .8rem; }

/* ── Multi-field panels — a trade's secondary fields (Electrician's Scope, Plumber's Fault, Solar's
   System), rendered by JobFieldKind the same way Full-form always has, either stacked in the grid tile
   or beneath the guided sheet's tap-to-answer primary field. ── */
.wz-full-field { margin-top: .6rem; }
.wz-full-field .wz-full-flabel { display: block; font-weight: 700; font-size: .68rem; letter-spacing: .02em; text-transform: uppercase; color: var(--wz-muted); margin-bottom: .25rem; }
.wz-extra-fields { display: flex; flex-direction: column; gap: .8rem; margin-top: .9rem; padding-top: .9rem; border-top: 1px dashed var(--wz-border-soft); }
.wz-extra-field .wz-extra-label { display: block; font-weight: 800; font-size: .78rem; color: var(--wz-text); margin-bottom: .3rem; }

/* ── A step's secondary controls ──────────────────────────────────────────────────────────────────
   A field asked for BESIDE the big question used to be raw Bootstrap (.form-control-sm) sitting under
   the wizard's own rounded, thick-bordered answer buttons — a company name and a start date that
   looked like they belonged to a different application. These give a secondary field the same clothes
   as everything else in the sheet: the .wz-f input treatment above (the fields carry .wz-f), a select
   that reads as a choice, and the app's OWN calendar/clock rather than the browser's grey drop-down. */

.wz-pick { position: relative; display: flex; align-items: center; }
.wz-select {
    width: 100%; appearance: none;
    padding-right: 2.4rem !important;   /* room for the chevron */
    cursor: pointer;
}
.wz-select:disabled { cursor: default; opacity: .7; }
/* The chevron is drawn rather than left to the platform: appearance:none removes the native arrow, and a
   select with no arrow is indistinguishable from a text box — which is exactly the confusion this replaced. */
.wz-pick-arr { position: absolute; right: .85rem; pointer-events: none; font-size: .8rem; color: var(--ty-color-border-strong, #c2cad3); }
/* The chosen option's own glyph, so a picked answer reads like the tap-to-answer buttons above it. */
.wz-pick-lead { position: absolute; left: .85rem; pointer-events: none; font-size: 1rem; }
.wz-select.has-lead { padding-left: 2.5rem !important; }

/* "Pick a date…" — the same shape as the answer buttons above it, opening the app's own calendar in
   place. A native date input cannot be themed, cannot be sized for a gloved hand, and looks nothing
   like the picker the primary step of this very wizard opens. */
.wz-datebtn {
    display: flex; align-items: center; gap: .6rem; width: 100%; text-align: left; cursor: pointer;
    border: 2px solid var(--ty-color-border, #e7ebf0); border-radius: 11px;
    background: var(--ty-color-surface, #fff); color: var(--ty-color-text, #1c2128);
    font-weight: 600; font-size: .9rem; padding: .65rem .75rem;
    transition: border-color .12s, color .12s;
}
.wz-datebtn:hover { border-color: var(--dom); }
.wz-datebtn-arr { color: var(--ty-color-border-strong, #c2cad3); margin-left: auto; }
.wz-cal--inline { margin-top: .6rem; }
.wz-extra-go { margin-top: 1rem; }

@media (min-width: 48rem) {
    .wz-datebtn { font-size: 1rem; padding: .8rem .9rem; }
}

/* ── Guide-me FAB ── */
/* "Guide me" rides the shell's corner-FAB rail (app.css: --ty-fab-*) rather than a hand-picked offset: it
   sits in the messages column but one row UP, clear of the messages and quick-add "+" buttons beneath it.
   It used to sit at bottom: 5.5rem (88px), straight through the 72–124px band those two now occupy — hence
   the overlap. Stacked above rather than shifted left because this is a wide pill; moving it left would
   still have crossed the "+". */
.wz-fab {
    position: fixed;
    right: var(--ty-fab-inset, 1.25rem);
    bottom: calc(var(--ty-fab-bottom, 4.5rem) + var(--ty-fab-size, 3.25rem) + var(--ty-fab-gap, .75rem));
    z-index: 1048;
    border: 0; border-radius: 999px; color: var(--ty-color-primary-contrast, #fff); font-weight: 800;
    padding: .75rem 1.3rem; box-shadow: 0 12px 30px color-mix(in srgb, var(--dom) 45%, transparent); cursor: pointer;
}

/* ── Wizard sheet (centered modal) ── */
.wz-scrim {
    position: fixed; inset: 0; z-index: 1060;
    background: rgba(var(--ty-color-overlay-rgb, 12, 18, 28), .45); display: flex; align-items: center; justify-content: center;
    padding: 1.25rem; backdrop-filter: blur(2px);
}
.wz-sheet {
    width: min(640px, 100%); background: var(--ty-color-surface, #fff); border-radius: 20px;
    box-shadow: 0 30px 70px -20px rgba(var(--ty-shadow-rgb, 12, 18, 28), .5); overflow: hidden;
    display: flex; flex-direction: column;
    /* dvh, with vh as the fallback for anything that doesn't know it. On a handset the on-screen keyboard
       does NOT shrink vh, so a sheet sized in vh keeps its full height while the keyboard covers the bottom
       third of it — and the step's Continue sits underneath, unreachable. That matters more now that a form
       step focuses its first field on arrival, which opens that keyboard immediately. */
    max-height: 88vh;
    max-height: 88dvh;
}
.wz-sheet-top { color: var(--ty-color-primary-contrast, #fff); padding: 1.1rem 1.2rem 1.2rem; position: relative; }
.wz-sheet-x { position: absolute; top: .9rem; right: 1rem; cursor: pointer; opacity: .85; font-size: .95rem; }
.wz-sheet-x:hover { opacity: 1; }
.wz-sheet-eyebrow { font-size: .68rem; font-weight: 700; text-transform: uppercase; letter-spacing: .05em; opacity: .85; }
.wz-sheet-q { font-weight: 800; font-size: 1.35rem; margin-top: .3rem; }
.wz-prog { display: flex; gap: .3rem; margin-top: .85rem; }
.wz-prog span { height: 5px; flex: 1 1 0; border-radius: 3px; background: color-mix(in srgb, var(--ty-color-primary-contrast, #fff) 30%, transparent); }
.wz-prog span.past { background: color-mix(in srgb, var(--ty-color-primary-contrast, #fff) 70%, transparent); }
.wz-prog span.on { background: var(--ty-color-surface, #fff); }

.wz-sheet-body { padding: 1.1rem 1.2rem; overflow-y: auto; }
.wz-opts { display: flex; flex-direction: column; gap: .6rem; }
.wz-opt {
    display: flex; align-items: center; gap: .8rem; width: 100%;
    padding: .9rem 1rem; border: 2px solid var(--wz-border); border-radius: 14px; background: var(--ty-color-surface, #fff);
    cursor: pointer; text-align: left; font-weight: 700; font-size: .95rem;
    transition: transform .1s, box-shadow .1s, border-color .1s;
}
.wz-opt:hover { transform: translateY(-1px); box-shadow: 0 0 0 3px color-mix(in srgb, currentColor 18%, transparent); }
.wz-opt i { font-size: 1.05rem; }
.wz-opt-arr { color: var(--ty-color-border-strong, #c2cad3); margin-left: auto; }
.wz-opt--custom { color: var(--wz-muted); border-style: dashed; margin-top: .6rem; }

/* An option's own row, so a selected catalogue option can carry a rename pencil beside it without nesting
   a second button inside the tap-to-answer one. */
.wz-opt-row { display: flex; align-items: stretch; gap: .4rem; }
.wz-opt-row .wz-opt { flex: 1 1 auto; }
.wz-opt-editbtn {
    flex: none; display: inline-flex; align-items: center; justify-content: center; width: 2.6rem;
    border: 2px solid var(--wz-border); border-radius: 14px; background: var(--ty-color-surface, #fff);
    color: var(--wz-muted); cursor: pointer;
}
.wz-opt-editbtn:hover { color: var(--dom); border-color: color-mix(in srgb, var(--dom) 40%, var(--wz-border)); }

/* A round's (or similar catalogue option's) usual day — separate from its name, never baked into it. */
.wz-opt-badge {
    flex: none; font-size: .72rem; font-weight: 700; color: var(--wz-muted);
    background: var(--ty-color-surface-sunken, #f3f5f8); border-radius: 999px; padding: .15rem .55rem;
}

/* The "+ Add …" / rename box: the option tile itself, opened up. It keeps .wz-opt's shape, padding, weight
   and icon, swaps the label for a borderless input, and grows two round actions on the right — so the list
   never changes gear while a name is typed. The tile is lit in the trade colour (currentColor) and pops in. */
.wz-opt--edit {
    cursor: default;
    border-color: currentColor;
    border-style: solid;
    padding-right: .55rem;
    box-shadow: 0 0 0 4px color-mix(in srgb, currentColor 14%, transparent);
    animation: wz-opt-pop .18s cubic-bezier(.2, .9, .3, 1.4);
}
.wz-opt--edit:hover { transform: none; box-shadow: 0 0 0 4px color-mix(in srgb, currentColor 14%, transparent); }
.wz-opt--edit > i { color: currentColor; }
.wz-opt-input {
    flex: 1 1 auto; min-width: 0;
    border: 0; outline: 0; background: transparent;
    font: inherit; font-weight: 700; font-size: .95rem; line-height: 1.5;
    padding: 0;
}
.wz-opt-input::placeholder { color: var(--wz-muted); font-weight: 600; }
.wz-opt-act {
    flex: none; display: inline-flex; align-items: center; justify-content: center;
    width: 2.25rem; height: 2.25rem; border-radius: 999px;
    border: 2px solid var(--wz-border); background: var(--ty-color-surface, #fff);
    color: var(--wz-muted); font-size: 1rem; cursor: pointer;
    transition: transform .1s, box-shadow .1s;
}
.wz-opt-act:hover { transform: scale(1.08); }
.wz-opt-act:focus-visible { outline: 2px solid currentColor; outline-offset: 2px; }
.wz-opt-act--ok { border-color: transparent; color: var(--ty-color-primary-contrast, #fff); }
.wz-opt-act--ok:hover { filter: brightness(1.08); }
.wz-opt-act:disabled { opacity: .5; pointer-events: none; }
@keyframes wz-opt-pop { from { transform: scale(.97); opacity: .6; } }
@media (prefers-reduced-motion: reduce) { .wz-opt--edit { animation: none; } }

.wz-custom { display: flex; gap: .55rem; margin-top: .8rem; }
.wz-custom input { flex: 1; }

.wz-skipnote {
    margin-top: .8rem; display: flex; gap: .5rem; align-items: flex-start;
    background: var(--ty-color-warning-soft, #fdf1dd); color: var(--ty-color-warning-ink, #9a5b00); border-radius: 10px; padding: .6rem .75rem; font-size: .8rem; line-height: 1.5;
}

.wz-sheet-foot { display: flex; align-items: center; gap: .5rem; margin-top: 1.1rem; }
.wz-btng {
    display: inline-flex; align-items: center; border: 1px solid var(--wz-border);
    background: var(--ty-color-surface, #fff); color: var(--wz-text); font-weight: 700; font-size: .82rem;
    padding: .45rem .85rem; border-radius: 9px; cursor: pointer;
}
.wz-btng:hover { background: var(--ty-color-surface-sunken, #f8fafc); }
.wz-btng.off { opacity: .4; pointer-events: none; }
.wz-btng--ghost { border: none; color: var(--wz-muted); }

.wz-revrow {
    display: flex; align-items: center; gap: .55rem;
    padding: .55rem .25rem; border-bottom: 1px solid var(--wz-border-soft); font-size: .9rem;
}
.wz-rev-title { font-weight: 700; }
.wz-rev-val { margin-left: auto; font-weight: 600; text-align: right; }

.min-w-0 { min-width: 0; }

@media (max-width: 640px) {
    .wz-head { flex-wrap: wrap; }
}

/* ── Roomier on tablet and desktop ────────────────────────────────────────────────────────────────
   The sheet is sized for a phone held one-handed, which leaves the same small card marooned in the
   middle of a laptop screen — the answer buttons in particular are the whole interaction and were
   reading as cramped. From tablet up everything steps up a size; the phone layout is untouched.

   62rem matches the jobs/customers list breakpoint, so the app changes shape at one width. */
@media (min-width: 48rem) {
    .wz-sheet { width: min(880px, 100%); max-height: 90vh; max-height: 90dvh; }

    .wz-sheet-top { padding: 1.5rem 1.75rem 1.6rem; }
    .wz-sheet-eyebrow { font-size: .74rem; }
    .wz-sheet-q { font-size: 1.75rem; }
    .wz-prog span { height: 7px; }

    .wz-sheet-body { padding: 1.5rem 1.75rem; }
    .wz-opts { gap: .75rem; }

    /* The tap targets: taller, larger type, bigger glyph. */
    .wz-opt { padding: 1.15rem 1.25rem; font-size: 1.05rem; border-radius: 16px; }
    .wz-opt i { font-size: 1.25rem; }

    .wz-skipnote { font-size: .86rem; padding: .75rem .9rem; }
    .wz-sheet-foot { margin-top: 1.4rem; }
    .wz-btng { font-size: .9rem; padding: .55rem 1rem; }
}

@media (min-width: 62rem) {
    .wz-sheet { width: min(1020px, 100%); }
    .wz-sheet-q { font-size: 1.95rem; }
    .wz-opt { padding: 1.3rem 1.4rem; font-size: 1.1rem; }
}

/* A step that draws a MAP takes the extra width and height it needs. Placing a pin is a "which of these two
   roofs" judgement, and the wizard's own comfortable reading width is nowhere near enough of the street to
   make it — so the address step, and only the address step, opens wider than the rest of the flow. */
@media (min-width: 62rem) {
    .wz-sheet--wide { width: min(1240px, 100%); max-height: 94vh; max-height: 94dvh; }
}

/* ── The date/time picker ─────────────────────────────────────────────────────────────────────────
   The "When" step's custom entry is a native date input. At the default control size the calendar
   glyph is a few pixels across, which is a poor target with a gloved hand, and the browser sizes its
   drop-down calendar relative to the field. Growing the field grows the picker with it. */
.wz-custom input[type="date"],
.wz-custom input[type="time"] {
    font-size: 1rem;
    padding: .7rem .85rem;
}

@media (min-width: 48rem) {
    .wz-custom { gap: .75rem; margin-top: 1rem; }
    .wz-custom input { font-size: 1.05rem; padding: .85rem 1rem; }

    .wz-custom input[type="date"],
    .wz-custom input[type="time"] {
        font-size: 1.15rem;
        padding: .95rem 1.1rem;
    }

    /* Chromium sizes the calendar indicator off the font size; nudging it up again makes the target
       comfortable without stretching the field. */
    .wz-custom input[type="date"]::-webkit-calendar-picker-indicator,
    .wz-custom input[type="time"]::-webkit-calendar-picker-indicator {
        transform: scale(1.5);
        margin-left: .5rem;
        cursor: pointer;
    }

    /* The full-form (non-guided) mode uses the compact controls; match them up too. */
    .wz-full input[type="date"] { font-size: 1rem; padding: .55rem .7rem; }
    .wz-full input[type="date"]::-webkit-calendar-picker-indicator { transform: scale(1.3); cursor: pointer; }
}

/* ── The calendar's slot in the sheet ──────────────────────────────────────────────────────────────
   Full width so the day grid gets the whole sheet to spread across — the reason for replacing the
   native drop-down in the first place. */
.wz-cal { margin-top: .8rem; }

@media (min-width: 48rem) {
    .wz-cal { margin-top: 1rem; }
}

/* ── The panel cards behind the sheet ──────────────────────────────────────────────────────────────
   Sized for a phone, which leaves them small and tightly packed on a laptop where there is room to
   spare. From tablet up the cards, their icons, titles and answer chips all step up, and the grid
   gives each card more minimum width so the answers don't wrap. Phone layout is untouched. */
@media (min-width: 48rem) {
    .wz-grid {
        grid-template-columns: repeat(auto-fill, minmax(360px, 1fr));
        gap: 1.1rem;
        padding: 1.5rem;
    }

    .wz-panel { border-radius: 16px; padding: 1.15rem 1.2rem; }
    .wz-phead { gap: .65rem; }
    .wz-pico { width: 38px; height: 38px; border-radius: 10px; font-size: 1.1rem; }
    .wz-ptitle { font-size: 1.08rem; }
    .wz-pstate { font-size: .68rem; padding: .24rem .6rem; }
    .wz-preq, .wz-popt { font-size: .68rem; padding: .16rem .55rem; }

    .wz-pval {
        margin-top: .75rem; border-radius: 11px; padding: .7rem .85rem;
        font-size: .98rem; gap: .55rem;
    }
}

@media (min-width: 62rem) {
    .wz-grid { grid-template-columns: repeat(auto-fill, minmax(400px, 1fr)); gap: 1.25rem; }
    .wz-panel { padding: 1.3rem 1.35rem; }
    .wz-pico { width: 42px; height: 42px; }
    .wz-ptitle { font-size: 1.15rem; }
    .wz-pval { font-size: 1.05rem; padding: .8rem .95rem; }
}

/* The preset that is the current answer — so coming back to a step shows what was chosen. */
.wz-opt--on {
    border-color: currentColor;
    background: color-mix(in srgb, currentColor 8%, var(--ty-color-surface, #fff));
    box-shadow: 0 0 0 2px color-mix(in srgb, currentColor 16%, transparent);
}
.wz-opt--on .wz-opt-arr { color: currentColor; }

/* ── The review step ───────────────────────────────────────────────────────────────────────────────
   This is the last thing read before committing a job, and every row on it is a decision the user is
   confirming — so the rows, the footer and above all "Book it" carry more weight than the small
   button they inherited from Bootstrap's btn-sm. */
.wz-book {
    display: inline-flex; align-items: center; justify-content: center;
    border: 0; border-radius: 12px; cursor: pointer;
    padding: .8rem 1.4rem; font-weight: 800; font-size: 1rem;
    box-shadow: 0 6px 16px rgba(var(--ty-shadow-rgb, 12, 18, 28), .16);
    transition: transform .1s, box-shadow .1s, filter .1s;
}
.wz-book:hover:not(:disabled) { filter: brightness(1.06); transform: translateY(-1px); }
.wz-book:disabled { opacity: .65; cursor: default; box-shadow: none; }

@media (min-width: 48rem) {
    /* The confirmation rows. */
    .wz-revrow { padding: .8rem .3rem; font-size: 1.02rem; gap: .7rem; }
    .wz-revrow i { font-size: 1.15rem; }
    .wz-rev-title { font-size: 1.02rem; }
    .wz-rev-val { font-size: 1.02rem; }

    /* The footer actions — "Back", "Edit the form", "Book it". */
    .wz-sheet-foot { gap: .65rem; margin-top: 1.5rem; }
    .wz-btng { font-size: .95rem; padding: .7rem 1.15rem; border-radius: 11px; }
    .wz-book { padding: .9rem 1.7rem; font-size: 1.08rem; border-radius: 13px; }
}

@media (min-width: 62rem) {
    .wz-revrow { padding: .9rem .35rem; font-size: 1.08rem; }
    .wz-rev-title, .wz-rev-val { font-size: 1.08rem; }
    .wz-btng { font-size: 1rem; padding: .75rem 1.25rem; }
    .wz-book { padding: .95rem 1.9rem; font-size: 1.15rem; }
}

/* On a phone the three actions would otherwise crowd; let them wrap and give Book it the full width. */
@media (max-width: 30rem) {
    .wz-sheet-foot { flex-wrap: wrap; }
    .wz-book { flex: 1 1 100%; margin-top: .5rem; }
}

/* ── The "Where" step: the shared address component inside the wizard ──────────────────────────── */
.wz-addr { display: flex; flex-direction: column; gap: .6rem; width: 100%; text-align: left; }
.wz-addr--sheet { margin-top: .25rem; }
.wz-addr-actions { display: flex; align-items: center; gap: .5rem; flex-wrap: wrap; }
.wz-addr-reset { align-self: flex-start; }

/* The address step is the one step taller than any sheet: a full address form AND a map worth placing a pin
   on. It therefore scrolls — so its forward action rides the bottom of the scroll area rather than sitting
   below the map where nobody scrolling the map would find it. */
.wz-addr--sheet .wz-addr-actions {
    position: sticky;
    bottom: 0;
    z-index: 2;
    padding: .6rem 0 .2rem;
    background: var(--ty-color-surface, #fff);
    box-shadow: 0 -10px 14px -12px rgba(var(--ty-shadow-rgb, 12, 18, 28), .5);
}

/* ── The shared <TyWizard> host ────────────────────────────────────────────────────────────────────
   Everything above is the look the job and quote wizards established; these are the few pieces the
   generalized host adds so expenses, team and vehicles can wear the same clothes.

   The difference between those two pages and this component is WHERE the flow lives. A job or a quote
   is a page you navigate to, so it owns the viewport. An expense, a team member or a van is added
   from a list you are standing on, so the wizard arrives OVER that list (.wz-overlay) or INSIDE a
   drawer's tab (.wz--embedded) and has to size itself to whatever it was dropped into.
   ─────────────────────────────────────────────────────────────────────────────────────────────── */

/* Adding from a list: the wizard takes the screen, above the shell but below the sheet's own scrim. */
.wz-overlay {
    position: fixed;
    inset: 0;
    z-index: 1055;
    overflow-y: auto;
    background: var(--ty-color-surface-subtle, #f6f8fa);
}
.wz-overlay .wz-head { background: var(--ty-color-surface, #fff); }

/* Editing inside a drawer: no viewport of its own, no bottom rail to clear, and one column of cards. */
.wz--embedded { min-height: 0; padding-bottom: 0; }
.wz--embedded .wz-grid { padding: 0; gap: .7rem; grid-template-columns: 1fr; }

@media (min-width: 48rem) {
    .wz--embedded .wz-grid { padding: 0; gap: .9rem; grid-template-columns: 1fr; }
}

/* "Guide me" is fixed to the shell's FAB rail on a page that owns the screen. Embedded, there is no
   rail to ride and a fixed pill would float over whatever else is on screen — so it sits in the flow. */
.wz-fab--inline {
    position: static;
    display: block;
    width: 100%;
    margin-top: 1rem;
    box-shadow: none;
}

/* ── The step's controls ───────────────────────────────────────────────────────────────────────────
   A step hands over real editors, so the wizard only supplies the frame: a stack of labelled fields
   that reads the same in a panel card as it does in the sheet. */
.wz-sheet-fields { display: flex; flex-direction: column; gap: .9rem; }

.wz-fields { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 11rem), 1fr)); gap: .75rem; }
.wz-f { display: flex; flex-direction: column; gap: .3rem; min-width: 0; }
.wz-f > label, .wz-flabel {
    font-size: .72rem; font-weight: 800; text-transform: uppercase; letter-spacing: .03em;
    color: var(--ty-color-text-muted, #57606a);
}
.wz-f--wide { grid-column: 1 / -1; }
.wz-fhint { font-size: .76rem; color: var(--ty-color-text-subtle, #8a95a1); }
.wz-ferr { font-size: .78rem; font-weight: 700; color: var(--ty-color-danger-ink, #b32121); }

/* A step's own controls (the customer-form's --nc-fld look, generalized): every plain input/select/textarea
   a wizard step drops into .wz-f, .wz-fields or .wz-sheet-fields gets the same rounded, thick-bordered box
   as the customer and address forms — never bare Bootstrap .form-control. Reaches into OptionSelect's
   <select> too (a global stylesheet, not scoped CSS, so no ::deep is needed to cross that boundary).
   Wrapped in :where() (zero specificity) so the money field's own border-radius/alignment overrides below
   — a real conflict, since .wz-money's input is also inside a .wz-f — still win on source order alone. */
:where(.wz-f, .wz-fields, .wz-sheet-fields) input:not([type="radio"]):not([type="checkbox"]),
:where(.wz-f, .wz-fields, .wz-sheet-fields) select,
:where(.wz-f, .wz-fields, .wz-sheet-fields) textarea {
    width: 100%; background: var(--ty-color-surface, #fff); border: 2px solid var(--ty-color-border, #e7ebf0);
    border-radius: 11px; padding: .65rem .75rem; font-weight: 600; font-size: .9rem;
    color: var(--ty-color-text, #1c2128); outline: none;
}
:where(.wz-f, .wz-fields, .wz-sheet-fields) input:focus,
:where(.wz-f, .wz-fields, .wz-sheet-fields) select:focus,
:where(.wz-f, .wz-fields, .wz-sheet-fields) textarea:focus {
    border-color: var(--dom, var(--ty-color-primary, #1E6FD9)); box-shadow: none;
}
:where(.wz-f, .wz-fields, .wz-sheet-fields) input.is-invalid,
:where(.wz-f, .wz-fields, .wz-sheet-fields) select.is-invalid,
:where(.wz-f, .wz-fields, .wz-sheet-fields) textarea.is-invalid { border-color: var(--ty-color-danger, #dc3545); }
:where(.wz-f, .wz-fields, .wz-sheet-fields) textarea { resize: vertical; min-height: 4.5rem; }

/* A money field reads as money: the currency is furniture, not something to type. */
.wz-money { display: flex; align-items: stretch; }
.wz-money > span {
    display: inline-flex; align-items: center; padding: 0 .7rem; font-weight: 800;
    color: var(--ty-color-text-muted, #57606a);
    background: var(--ty-color-surface-sunken, #f3f5f8);
    border: 1px solid var(--ty-color-border, #e7ebf0); border-right: 0;
    border-radius: 8px 0 0 8px;
}
.wz-money > input { border-radius: 0 8px 8px 0; text-align: right; font-weight: 700; }

/* A computed total the user reads rather than fills in — never an input that looks editable. */
.wz-readout {
    display: flex; align-items: baseline; gap: .4rem;
    background: var(--ty-color-surface-sunken, #f3f5f8); border-radius: 9px; padding: .55rem .7rem;
    font-weight: 800; font-size: 1.05rem; color: var(--ty-color-text, #1c2128);
}
.wz-readout small { font-weight: 700; font-size: .72rem; color: var(--ty-color-text-muted, #57606a); }

/* An on/off decision, as a card that says what it means rather than a bare switch. */
.wz-switch {
    display: flex; align-items: center; gap: .7rem; width: 100%; text-align: left;
    border: 2px solid var(--ty-color-border, #e7ebf0); border-radius: 12px;
    background: var(--ty-color-surface, #fff); padding: .7rem .85rem; cursor: pointer;
}
.wz-switch--on { border-color: currentColor; background: color-mix(in srgb, currentColor 7%, var(--ty-color-surface, #fff)); }
.wz-switch i:first-child { font-size: 1.1rem; }
.wz-switch-txt { display: flex; flex-direction: column; min-width: 0; flex: 1 1 auto; }
.wz-switch-t { font-weight: 800; font-size: .92rem; color: var(--ty-color-text, #1c2128); }
.wz-switch-s { font-size: .76rem; color: var(--ty-color-text-muted, #57606a); }
.wz-switch-state { margin-left: auto; font-size: 1.2rem; }

/* The sheet's forward action. "Next" is the button pressed most in the whole flow — it earns the same
   weight the review step's Save carries, not the outline of a secondary. */
.wz-next {
    display: inline-flex; align-items: center; border: 0; border-radius: 10px; cursor: pointer;
    font-weight: 800; font-size: .88rem; padding: .55rem 1.1rem;
    box-shadow: 0 4px 12px rgba(var(--ty-shadow-rgb, 12, 18, 28), .14);
}
.wz-next:hover { filter: brightness(1.06); }

/* The per-step complaint, inside the sheet rather than on the page behind it. */
.wz-errbar--sheet { margin-top: .8rem; border-radius: 10px; padding: .55rem .75rem; }

/* Review rows jump back to their step — the fastest way to fix the one thing that is wrong. */
.wz-revrow--tap { cursor: pointer; }
.wz-revrow--tap:hover { background: var(--ty-color-surface-sunken, #f8fafc); }
.wz-rev-edit { color: var(--ty-color-border-strong, #c2cad3); font-size: .85rem; margin-left: .5rem; }

@media (min-width: 48rem) {
    .wz-sheet-fields { gap: 1.1rem; }
    .wz-fields { gap: .9rem; }
    .wz-next { font-size: .95rem; padding: .7rem 1.35rem; border-radius: 11px; }
}

/* A chip that IS the current answer. The chips are flat by design — a ring rather than a fill keeps the
   row readable when several are on screen and one of them is chosen. */
.wz-chip--on {
    box-shadow: inset 0 0 0 2px currentColor;
    font-weight: 800;
}

/* ── A form step ──────────────────────────────────────────────────────────────────────────────────
   A step whose fields are all plain typed values (a first name beside a surname, an email beside a
   phone) is one FORM, not a tap-to-answer question with the rest demoted to small boxes underneath —
   see JobWizardPanelState.UsesFieldForm. It reuses .wz-fields/.wz-f (the shared step-field kit above)
   unchanged, so every input on it is the same control the rest of the app draws; these few rules only
   give it room to breathe inside the sheet and mark which of them is required. */
.wz-fields--step { margin-top: .25rem; }
.wz-fields--step .wz-f > label { font-size: .74rem; }

/* The one thing a two-up form has to say that a one-question step never had to: which of them is
   compulsory. Colour alone would not carry it, hence the glyph. */
.wz-req-star { color: var(--ty-color-danger, #dc3545); font-weight: 900; margin-left: .15rem; }

@media (min-width: 48rem) {
    /* Two comfortable columns rather than four thin ones: two fields is what these steps actually hold,
       and a name box that fits a name reads better than one that fits the grid. */
    .wz-fields--step { grid-template-columns: repeat(auto-fit, minmax(min(100%, 16rem), 1fr)); gap: 1rem; }
    .wz-fields--step input, .wz-fields--step textarea { font-size: 1rem; padding: .8rem .9rem; }
}

/* A JobFieldKind.Custom step's own component — the host draws the panel chrome around it, the component
   draws everything inside. Not scoped: DynamicComponent renders across a component boundary, so a
   module-scoped .razor.css never reaches in here — every Custom step's own styling hook lives in this ONE
   shared sheet instead of each module inventing its own copy. */
.wz-custom-step { margin-top: .4rem; }

/* A capability panel (Documents…) embedded inside a Custom step — e.g. the Projects survey step's own
   Documents panel, exactly the "SoJobEditor" embed idiom used on a finished record's own detail page. */
.wz-panel-embed {
    margin-top: 14px;
    border-top: 1px solid var(--ty-color-border, #eaecef);
    padding-top: 10px;
}

.wz-panel-embed-title {
    font-weight: 600;
    margin-bottom: 6px;
}
