/* =============================================================================
   ONBOARDING COMPONENTS
   =============================================================================

   The walkthrough card and its step dots, the spotlight layer (cutout and
   arrow), the progress ring, the checklist tick, the getting-started
   checklist and its navigation ring, the send card, the peak and the client
   preview's strip. Markup: templates/macros/onboarding.html. Behaviour:
   static/js/controllers/esm/onboard_spotlight_controller.js,
   onboard_ring_controller.js, onboarding_checklist_controller.js,
   onboard_send_controller.js, client_preview_controller.js and _onboard.js.
   Linked on every page by base.html (the ring is in the navigation).

   Every onboarding surface follows docs/ONBOARDING_DESIGN_RULES.md. This file
   owns: V1 tokens only (no colour or easing literal; the css_literals ratchet
   holds it at zero), V2 the one gradient (the card), V4 contrast (measured in
   the Onboarding block of tokens/semantic.css), V5 48px targets, M1 to M6.

   Motion: every duration and distance below is multiplied by --onboard-motion
   on the element that animates (1 full, 0 reduced). A timing that skips the
   switch keeps moving for people who asked for less motion, so keep it.
   ========================================================================== */

/* ── The floor: how far a docked card sits above the bottom of the screen ──
   Clear of the web bottom nav below 992px; clear of the edge where there is
   no web nav (the native shells, whose tab bar ends the web view, and a nav
   dropped for the keyboard); in the corner the hidden Chip launcher leaves
   on desktop. One floor per context, so the two safe-area insets are never
   added together. The send card and the walkthrough card both dock on it. */
:root {
    --onboard-floor: calc(var(--mobile-nav-height) + var(--mobile-nav-safe-bottom) + var(--space-3));
}

@media (min-width: 992px) {
    :root {
        --onboard-floor: var(--space-6);
    }
}

html[data-hotwire-native],
body[data-keyboard-open] {
    --onboard-floor: calc(var(--space-3) + var(--safe-bottom));
}

/* A docked card arrives from the edge it docks to and goes back the way it
   came (M1 enter: 280ms ease-out, 28px; leave: 200ms ease-in, 14px).
   --onboard-rise is 1 for a card on the floor, -1 for one at the top.
   Reduced: a 150ms fade (M6). */
@keyframes onboard-rise-in {
    from {
        opacity: 0;
        transform: translateY(calc(var(--onboard-step-shift) * var(--onboard-rise, 1) * var(--onboard-motion)));
    }
}

@keyframes onboard-rise-out {
    to {
        opacity: 0;
        transform: translateY(calc(var(--onboard-step-shift) * 0.5 * var(--onboard-rise, 1) * var(--onboard-motion)));
    }
}

/* ── Layer: the stage the spotlight, arrow and card are drawn on ───────────
   Full screen and click-through, so a tap on the lit control reaches the real
   control. Over Bootstrap modals (1055), so a target inside the quote form
   can be lit; under toasts (1090). */
.onboard-layer {
    position: fixed;
    inset: 0;
    z-index: 1080;
    pointer-events: none;
}

/* ── Spotlight (W6, M2) ────────────────────────────────────────────────────
   One element: its own box is the lit cutout and a 200vmax spread shadow is
   the veil over everything else, so the hole and the dimming always move
   together. Placed by the onboard-spotlight controller through the
   --onboard-spot-* properties; the corner radius follows the target's. */
.onboard-spotlight {
    position: absolute;
    top: 0;
    left: 0;
    width: var(--onboard-spot-w, 0px);
    height: var(--onboard-spot-h, 0px);
    border-radius: var(--onboard-spot-r, var(--border-radius-lg));
    transform: translate(var(--onboard-spot-x, 0px), var(--onboard-spot-y, 0px));
    box-shadow:
        0 0 0 2px var(--onboard-accent),
        0 0 0 200vmax var(--onboard-veil);
    opacity: 0;
    /* The cutout's move scales with motion; its fade never goes to nothing,
       so with reduced motion the dimming still crossfades (M6). */
    transition-property: transform, width, height, border-radius, opacity;
    transition-duration:
        calc(var(--dur-onboard-spotlight) * var(--onboard-motion)),
        calc(var(--dur-onboard-spotlight) * var(--onboard-motion)),
        calc(var(--dur-onboard-spotlight) * var(--onboard-motion)),
        calc(var(--dur-onboard-spotlight) * var(--onboard-motion)),
        var(--dur-onboard-fade);
    transition-timing-function: var(--ease-decel);
}

.onboard-spotlight[data-shown] {
    opacity: 1;
}

/* A round control (the Chip button) gets a round cutout. */
.onboard-spotlight[data-shape="round"] {
    border-radius: 50%;
}

/* A control that is easy to miss (the detail banner's View Job and View
   Invoice): a thicker ring, and a pulse radiating from it in four rounds,
   in step with the arrow's extra nudges, then still (M3: never forever).
   Reduced motion keeps the thicker ring. */
.onboard-spotlight[data-emphasis] {
    box-shadow:
        0 0 0 4px var(--onboard-accent),
        0 0 0 200vmax var(--onboard-veil);
}

.onboard-spotlight[data-emphasis][data-shown]::after {
    position: absolute;
    inset: 0;
    border-radius: inherit;
    content: "";
    opacity: 0;
    animation: onboard-pulse calc(var(--dur-onboard-pulse) * var(--onboard-motion)) var(--ease-decel)
        calc(var(--dur-onboard-spotlight) * var(--onboard-motion)) 4;
}

@keyframes onboard-pulse {
    0% {
        box-shadow: 0 0 0 0 var(--onboard-accent);
        opacity: 1;
    }
    45%,
    100% {
        box-shadow: 0 0 0 var(--onboard-pulse-spread) var(--onboard-accent);
        opacity: 0;
    }
}

/* The veil alone, nothing lit: the offer card sits over a dimmed screen. */
.onboard-spotlight[data-veil] {
    box-shadow:
        0 0 0 0 transparent,
        0 0 0 200vmax var(--onboard-veil);
}

/* The first placement lands where it belongs instead of gliding in from the
   corner; only the fade-in runs. */
.onboard-spotlight[data-placing] {
    transition-property: opacity;
}

/* ── Arrow (W6, M3) ────────────────────────────────────────────────────────
   Drawn pointing down; positioned by its tip, the box's bottom centre, at
   (--onboard-arrow-x, --onboard-arrow-y). Below a target it turns over to
   point up. The cream halo keeps the orange stroke legible on the veil and on
   whatever is behind it. */
.onboard-arrow {
    position: absolute;
    top: 0;
    left: 0;
    width: 40px;
    height: 56px;
    color: var(--onboard-accent);
    transform:
        translate(
            calc(var(--onboard-arrow-x, 0px) - 50%),
            calc(var(--onboard-arrow-y, 0px) - 100%)
        )
        rotate(var(--onboard-arrow-turn, 0deg));
    transform-origin: 50% 100%;
    opacity: 0;
}

.onboard-arrow[data-side="below"] {
    --onboard-arrow-turn: 180deg;
}

.onboard-arrow[data-shown] {
    opacity: 1;
}

/* Moving between targets, the arrow waits for the cutout to arrive. */
.onboard-arrow[data-shown="after-move"] {
    --onboard-arrow-delay: calc(var(--dur-onboard-spotlight) * var(--onboard-motion));
}

.onboard-arrow svg {
    display: block;
    width: 100%;
    height: 100%;
    overflow: visible;
}

.onboard-arrow path {
    fill: none;
    stroke-linecap: round;
    stroke-linejoin: round;
    stroke-dasharray: 1;
    stroke-dashoffset: 0;
}

.onboard-arrow__halo path {
    stroke: var(--onboard-ink);
    stroke-width: 7;
}

.onboard-arrow__ink path {
    stroke: currentColor;
    stroke-width: 3.5;
}

/* Draws in over 200ms, shaft then head, then nudges toward the target twice
   and holds still. It never loops. */
.onboard-arrow[data-shown] .onboard-arrow__shaft {
    animation: onboard-draw calc(var(--dur-onboard-arrow-draw) * 0.65 * var(--onboard-motion))
        var(--ease-decel) var(--onboard-arrow-delay, 0ms) both;
}

.onboard-arrow[data-shown] .onboard-arrow__head {
    animation: onboard-draw calc(var(--dur-onboard-arrow-draw) * 0.35 * var(--onboard-motion))
        var(--ease-decel)
        calc(var(--onboard-arrow-delay, 0ms) + var(--dur-onboard-arrow-draw) * 0.65 * var(--onboard-motion))
        both;
}

.onboard-arrow[data-shown] svg {
    animation: onboard-nudge calc(var(--dur-onboard-arrow-nudge) * var(--onboard-motion)) var(--ease-standard)
        calc(var(--onboard-arrow-delay, 0ms) + var(--dur-onboard-arrow-draw) * var(--onboard-motion)) 2;
}

/* An easy-to-miss control's arrow nudges twice in each of the pulse's four
   rounds, instead of twice in all, then holds still. */
.onboard-arrow[data-emphasis][data-shown] svg {
    animation: onboard-nudge-round calc(var(--dur-onboard-pulse) * var(--onboard-motion)) var(--ease-standard)
        calc(var(--onboard-arrow-delay, 0ms) + var(--dur-onboard-arrow-draw) * var(--onboard-motion)) 4;
}

@keyframes onboard-nudge-round {
    0%,
    25%,
    50%,
    100% {
        transform: translateY(0);
    }
    12.5%,
    37.5% {
        transform: translateY(calc(var(--onboard-nudge-shift) * 1.5 * var(--onboard-motion)));
    }
}

/* Quiet: the arrow follows a target that moves field to field without
   drawing in or nudging again, so a fill reads as one gesture (M3). */
.onboard-arrow[data-shown="quiet"] {
    transition: transform calc(var(--dur-onboard-spotlight) * var(--onboard-motion)) var(--ease-decel);
}

.onboard-arrow[data-shown="quiet"] svg,
.onboard-arrow[data-shown="quiet"] path {
    animation: none;
}

@keyframes onboard-draw {
    from {
        stroke-dashoffset: 1;
    }
    to {
        stroke-dashoffset: 0;
    }
}

@keyframes onboard-nudge {
    50% {
        transform: translateY(calc(var(--onboard-nudge-shift) * var(--onboard-motion)));
    }
}

/* ── Card (V2, A1, A4) ─────────────────────────────────────────────────────
   The one surface allowed the gradient. In flow it is the offer card on the
   dashboard; inside the layer it docks to the half of the screen away from
   the target (placed by _onboard.js placeCard). */
.onboard-card {
    position: relative;
    max-width: 26rem;
    padding: var(--space-3) var(--space-5) var(--space-5);
    overflow: hidden;
    color: var(--onboard-ink);
    font-family: var(--font-family-base);
    background: var(--onboard-gradient);
    border-radius: var(--border-radius-xl);
    box-shadow:
        inset 0 0 0 1px var(--onboard-card-edge),
        var(--shadow-lg);
}

.onboard-layer .onboard-card {
    position: absolute;
    inset-inline: var(--space-3);
    bottom: var(--onboard-floor);
    margin-inline: auto;
    pointer-events: auto;
    transition: transform calc(var(--dur-onboard-step-in) * var(--onboard-motion)) var(--ease-decel);
}

.onboard-layer .onboard-card[data-placement="top"] {
    --onboard-rise: -1;
    top: calc(var(--space-3) + var(--safe-top));
    bottom: auto;
}

.onboard-layer .onboard-card[data-moving] {
    transition: none;
}

/* Arriving and leaving, it rises from the edge it docks to (onboard-rise). */
.onboard-layer .onboard-card[data-state="in"] {
    animation: onboard-rise-in
        calc(var(--dur-onboard-fade) + (var(--dur-onboard-step-in) - var(--dur-onboard-fade)) * var(--onboard-motion))
        var(--ease-decel) both;
}

.onboard-layer .onboard-card[data-state="out"] {
    pointer-events: none;
    animation: onboard-rise-out
        calc(var(--dur-onboard-fade) + (var(--dur-onboard-step-out) - var(--dur-onboard-fade)) * var(--onboard-motion))
        var(--ease-exit) both;
}

.onboard-card__head {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    min-height: 48px;
}

.onboard-card__louie {
    flex: none;
    width: 32px;
    height: auto;
}

/* Close (W4): a full 48px target, pulled into the corner so the icon lines up
   with the card's padding. Closing never asks "are you sure". */
.onboard-card__close {
    display: grid;
    place-items: center;
    flex: none;
    width: 48px;
    height: 48px;
    margin-inline: auto calc(var(--space-3) * -1);
    padding: 0;
    color: var(--onboard-ink);
    font-size: 1.125rem;
    background: transparent;
    border: 0;
    border-radius: var(--radius-pill);
}

.onboard-card__close:hover {
    background: var(--onboard-card-edge);
}

.onboard-card__close:focus-visible {
    outline: 2px solid var(--onboard-ink);
    outline-offset: -6px;
}

/* ── Step dots (W5): how long, and how far along ───────────────────────────
   The current step is the stretched orange pill; done steps are solid. */
.onboard-dots {
    display: flex;
    gap: 6px;
    margin: 0;
    padding: 0;
    list-style: none;
}

.onboard-dots > li {
    width: 8px;
    height: 8px;
    background: var(--onboard-dot-todo);
    border-radius: var(--radius-pill);
    transition-property: width, background-color;
    transition-duration: calc(var(--dur-onboard-step-in) * var(--onboard-motion));
    transition-timing-function: var(--ease-decel);
}

.onboard-dots > li[data-state="done"] {
    background: var(--onboard-ink);
}

.onboard-dots > li[data-state="current"] {
    width: 22px;
    background: var(--onboard-accent);
}

/* ── Step content and the slide between steps (M1) ─────────────────────────
   Leaving and entering steps share one grid cell, so they cross instead of
   queueing. Forward slides left; --onboard-dir turns it round for back. */
.onboard-card__viewport {
    --onboard-dir: 1;
    display: grid;
    margin-top: var(--space-1);
}

.onboard-card__viewport[data-direction="back"] {
    --onboard-dir: -1;
}

.onboard-card__viewport > * {
    grid-area: 1 / 1;
}

.onboard-card__viewport > [data-motion="enter"] {
    animation: onboard-step-in
        calc(var(--dur-onboard-fade) + (var(--dur-onboard-step-in) - var(--dur-onboard-fade)) * var(--onboard-motion))
        var(--ease-decel) both;
}

.onboard-card__viewport > [data-motion="leave"] {
    pointer-events: none;
    animation: onboard-step-out
        calc(var(--dur-onboard-fade) + (var(--dur-onboard-step-out) - var(--dur-onboard-fade)) * var(--onboard-motion))
        var(--ease-exit) both;
}

@keyframes onboard-step-in {
    from {
        opacity: 0;
        transform: translateX(calc(var(--onboard-step-shift) * var(--onboard-motion) * var(--onboard-dir)));
    }
}

@keyframes onboard-step-out {
    to {
        opacity: 0;
        transform: translateX(calc(var(--onboard-step-shift) * var(--onboard-motion) * var(--onboard-dir) * -1));
    }
}

.onboard-step__eyebrow,
.onboard-send__saved {
    margin: 0 0 var(--space-1);
    font-size: 0.875rem;
    font-weight: 600;
}

.onboard-step__title {
    margin: 0;
    color: inherit;
    font-family: var(--font-family-heading);
    font-size: 1.375rem;
    font-weight: 700;
    line-height: 1.2;
    letter-spacing: -0.01em;
}

.onboard-step__body {
    margin: var(--space-2) 0 0;
    font-size: 1.0625rem;
    line-height: 1.45;
}

/* ── Actions (A1, V5) ──────────────────────────────────────────────────────
   One cream primary that fills the row, one quiet text action beside it. */
.onboard-card__actions {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    margin-top: var(--space-5);
}

.onboard-action,
.onboard-action-quiet {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--space-2);
    min-height: 48px;
    font-size: 1rem;
    border: 0;
    border-radius: var(--radius-pill);
    transition: transform var(--dur-fast) var(--ease-standard);
}

.onboard-action {
    flex: 1 1 auto;
    padding: 0 var(--space-6);
    color: var(--onboard-action-ink);
    font-weight: 700;
    background: var(--onboard-action-bg);
}

.onboard-action-quiet {
    padding: 0 var(--space-4);
    color: var(--onboard-ink);
    font-weight: 600;
    background: transparent;
}

.onboard-action-quiet:hover {
    background: var(--onboard-card-edge);
}

.onboard-action:active,
.onboard-action-quiet:active,
.onboard-send .onboard-checklist__action:active {
    transform: scale(var(--press-scale));
}

.onboard-action:focus-visible,
.onboard-action-quiet:focus-visible,
.onboard-send .onboard-checklist__action:focus-visible,
.onboard-send:focus-visible {
    outline: 2px solid var(--onboard-accent);
    outline-offset: 3px;
}

/* ── Progress ring (F2, F3, M4) ────────────────────────────────────────────
   Fills toward the goal the moment an item ticks; at the end the count gives
   way to a check. --sm is the navigation size and carries no count. */
.onboard-ring {
    position: relative;
    display: inline-grid;
    flex: none;
    place-items: center;
    width: 48px;
    height: 48px;
}

.onboard-ring--sm {
    width: 28px;
    height: 28px;
}

.onboard-ring--lg {
    width: 64px;
    height: 64px;
}

.onboard-ring svg {
    width: 100%;
    height: 100%;
    overflow: visible;
}

.onboard-ring__track,
.onboard-ring__fill {
    fill: none;
    stroke-width: 3.5;
}

.onboard-ring__track {
    stroke: var(--onboard-ring-track);
}

.onboard-ring--on-dark .onboard-ring__track {
    stroke: var(--onboard-ring-track-on-dark);
}

.onboard-ring__fill {
    stroke: var(--onboard-accent);
    transition: stroke-dashoffset calc(var(--dur-onboard-ring) * var(--onboard-motion)) var(--ease-decel);
}

.onboard-ring__check {
    fill: none;
    stroke: var(--onboard-accent);
    stroke-width: 3;
    stroke-linecap: round;
    stroke-linejoin: round;
    stroke-dasharray: 1;
    stroke-dashoffset: 1;
    transition: stroke-dashoffset calc(var(--dur-onboard-tick) * var(--onboard-motion)) var(--ease-decel);
}

/* The check waits for the ring to close before it draws. */
.onboard-ring[data-complete] .onboard-ring__check {
    stroke-dashoffset: 0;
    transition-delay: calc(var(--dur-onboard-ring) * var(--onboard-motion));
}

/* Placed at the value it last showed, without moving, before it fills to
   the new one (onboard_ring_controller.js). */
.onboard-ring[data-instant] .onboard-ring__fill,
.onboard-ring[data-instant] .onboard-ring__check,
.onboard-ring[data-instant] .onboard-ring__count {
    transition: none;
}

.onboard-ring__count {
    position: absolute;
    color: var(--text-primary);
    font-family: var(--font-family-heading);
    font-size: 0.8125rem;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
    transition: opacity calc(var(--dur-onboard-tick) * var(--onboard-motion)) var(--ease-exit);
}

.onboard-ring--lg .onboard-ring__count {
    font-size: 1rem;
}

.onboard-ring--on-dark .onboard-ring__count {
    color: var(--onboard-ink);
}

.onboard-ring[data-complete] .onboard-ring__count {
    opacity: 0;
}

/* ── Checklist tick (F1, M4) ───────────────────────────────────────────────
   To do is an outline; the next item's outline is the accent; done fills
   green and the check draws in. A tick already done on page load renders done
   without drawing: these are transitions, not animations, on purpose. */
.onboard-tick {
    display: inline-grid;
    flex: none;
    place-items: center;
    width: 28px;
    height: 28px;
    color: var(--onboard-ink);
    background: transparent;
    border-radius: var(--radius-pill);
    box-shadow: inset 0 0 0 2px var(--secondary-color);
    transition-property: background-color, box-shadow;
    transition-duration: calc(var(--dur-onboard-tick) * var(--onboard-motion));
    transition-timing-function: var(--ease-decel);
}

.onboard-tick[data-next] {
    box-shadow: inset 0 0 0 2px var(--onboard-accent);
}

.onboard-tick[data-done] {
    background: var(--primary-color);
    box-shadow: inset 0 0 0 2px var(--primary-color);
}

.onboard-tick svg {
    width: 18px;
    height: 18px;
}

.onboard-tick path {
    fill: none;
    stroke: currentColor;
    stroke-width: 2.75;
    stroke-linecap: round;
    stroke-linejoin: round;
    stroke-dasharray: 1;
    stroke-dashoffset: 1;
    transition: stroke-dashoffset calc(var(--dur-onboard-tick) * var(--onboard-motion)) var(--ease-decel);
}

.onboard-tick[data-done] path {
    stroke-dashoffset: 0;
}

/* ── Getting-started checklist (F1 to F3, A1, A3, V4, V5) ──────────────────
   Ring and title, what is done collapsed to one line, the next item open
   with its why and its one action, the rest a 48px row each. All text is
   --text-primary (V4: 7:1, no grey); weight and size carry the hierarchy.
   Inside the navigation ring's menu it drops the card frame. */
.onboard-checklist {
    margin-bottom: var(--space-6);
    padding: var(--space-4) var(--space-4) var(--space-2);
    color: var(--text-primary);
}

.onboard-checklist[data-leaving],
.onboard-send-fold[data-folding] > .onboard-send {
    pointer-events: none;
    transform-origin: 100% 0;
    animation: onboard-checklist-leave
        calc(var(--dur-onboard-fade) + (var(--dur-onboard-step-out) - var(--dur-onboard-fade)) * var(--onboard-motion))
        var(--ease-exit) both;
}

/* Put away toward its top corner: the ring the checklist becomes, the close
   the send card was closed from. */
@keyframes onboard-checklist-leave {
    to {
        opacity: 0;
        transform: translateY(calc(var(--onboard-step-shift) * -0.5 * var(--onboard-motion)))
            scale(calc(1 - 0.06 * var(--onboard-motion)));
    }
}

.onboard-checklist__head {
    display: flex;
    align-items: center;
    gap: var(--space-3);
}

.onboard-checklist__heading {
    flex: 1 1 auto;
    min-width: 0;
}

.onboard-checklist__title {
    margin: 0;
    color: inherit;
    font-family: var(--font-family-heading);
    font-size: 1.1875rem;
    font-weight: 700;
    line-height: 1.2;
}

.onboard-checklist__meta {
    margin: var(--space-1) 0 0;
    font-size: 0.875rem;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
}

.onboard-checklist__close {
    display: grid;
    place-items: center;
    width: 48px;
    height: 48px;
    margin-inline-end: calc(var(--space-3) * -1);
    padding: 0;
    color: var(--text-primary);
    font-size: 1.0625rem;
    background: transparent;
    border: 0;
    border-radius: var(--radius-pill);
}

.onboard-checklist__close:hover {
    background: var(--bg-secondary);
}

.onboard-checklist__close:focus-visible,
.onboard-checklist__row:focus-visible,
.onboard-checklist__ask:focus-visible {
    outline: 2px solid var(--onboard-accent);
    outline-offset: 2px;
}

.onboard-checklist__done {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-2) var(--space-4);
    margin: var(--space-3) 0;
    padding: 0;
    list-style: none;
}

.onboard-checklist__done > li {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    font-size: 0.9375rem;
    font-weight: 600;
}

.onboard-checklist__done .onboard-tick,
.onboard-send__saved .onboard-tick {
    width: 20px;
    height: 20px;
}

.onboard-checklist__done .onboard-tick svg,
.onboard-send__saved .onboard-tick svg {
    width: 14px;
    height: 14px;
}

.onboard-checklist__items {
    display: grid;
    gap: var(--space-1);
    margin: 0;
    padding: 0;
    list-style: none;
}

/* The next item: the one with words of why and an action (A1). Its tick
   lines up with the rows' ticks below. */
.onboard-checklist__next {
    display: grid;
    grid-template-columns: 28px minmax(0, 1fr);
    gap: var(--space-3);
    padding: var(--space-4) var(--space-3);
}

/* "This one next": a breath of the accent over the surface, with its edge.
   One owner for the checklist's next item and the send card. */
.onboard-checklist__next,
.onboard-send {
    background: var(--onboard-next-bg);
    border-radius: var(--border-radius-lg);
    box-shadow: inset 0 0 0 1px var(--onboard-next-edge);
}

.onboard-checklist__item-title {
    margin: var(--space-1) 0 0;
    font-size: 1.0625rem;
    font-weight: 700;
    line-height: 1.3;
}

.onboard-checklist__why {
    margin: var(--space-1) 0 var(--space-3);
    font-size: 1rem;
    line-height: 1.45;
}

.onboard-checklist__action {
    width: 100%;
    min-height: 48px;
    font-weight: 700;
    border-radius: var(--radius-pill);
}

.onboard-checklist__row {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    width: 100%;
    min-height: 48px;
    padding: 0 var(--space-3);
    color: var(--text-primary);
    font: inherit;
    font-weight: 600;
    text-align: start;
    text-decoration: none;
    background: transparent;
    border: 0;
    border-radius: var(--border-radius-lg);
}

.onboard-checklist__row:hover {
    color: var(--text-primary);
    background: var(--bg-secondary);
}

.onboard-checklist__row > .bi {
    margin-inline-start: auto;
    font-size: 0.875rem;
}

.onboard-checklist__help {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0 var(--space-1);
    margin: var(--space-2) 0 0;
    padding: 0 var(--space-3);
    font-size: 0.9375rem;
}

/* The checklist's Ask Chip button and the quiet Ask Chip link
   (macros/ask_chip.html) read as the same link. */
.onboard-checklist__ask,
.ask-chip {
    min-height: 48px;
    padding: 0 var(--space-1);
    color: var(--primary-color);
    font: inherit;
    font-weight: 700;
    text-decoration: underline;
    text-underline-offset: 0.2em;
    background: transparent;
    border: 0;
}

/* ── Navigation ring (F3) ──────────────────────────────────────────────────
   The dismissed checklist, small, beside the bell in the desktop bar and the
   mobile bell row; it opens the same checklist as a menu. It arrives once,
   when the dismiss stream draws it, and sits still on every page after. */
.onboard-nav-ring {
    display: flex;
    align-items: center;
}

.onboard-nav-ring__toggle {
    display: grid;
    place-items: center;
    width: 48px;
    height: 48px;
    padding: 0;
    background: transparent;
    border: 0;
    border-radius: var(--radius-pill);
}

.notification-bell-mobile .onboard-nav-ring__toggle {
    background: var(--primary-color);
}

.onboard-nav-ring__toggle:hover,
.onboard-nav-ring__toggle[aria-expanded="true"] {
    background: var(--onboard-card-edge);
}

.notification-bell-mobile .onboard-nav-ring__toggle:hover,
.notification-bell-mobile .onboard-nav-ring__toggle[aria-expanded="true"] {
    background: var(--primary-hover);
}

.onboard-nav-ring__toggle:focus-visible {
    outline: 2px solid var(--onboard-ink);
    outline-offset: -4px;
}

.onboard-nav-ring[data-arriving] .onboard-nav-ring__toggle {
    animation: onboard-ring-arrive
        calc(var(--dur-onboard-fade) + (var(--dur-onboard-step-in) - var(--dur-onboard-fade)) * var(--onboard-motion))
        var(--ease-decel) var(--dur-onboard-step-out) both;
}

@keyframes onboard-ring-arrive {
    from {
        opacity: 0;
        transform: scale(calc(1 - 0.4 * var(--onboard-motion)));
    }
}

.onboard-nav-ring__menu {
    width: min(22rem, calc(100vw - var(--space-4)));
    padding: 0;
    overflow: hidden;
    border-radius: var(--border-radius-xl);
}

.onboard-nav-ring__menu .onboard-checklist {
    margin: 0;
    padding-bottom: var(--space-2);
}

/* ── Send card (A1, A4, A5, V4, V5, M1, M4, M6) ─────────────────────────────
   A business's first quote, followed straight away by its one next step:
   send it. The checklist's next item lifted out and set under the thumb, so
   it brings no new look: its surface (grouped with .onboard-checklist__next),
   title, Bottle Green action, close and quiet link are the checklist's own
   classes. Never the gradient (V2); every word is --text-primary (V4). This
   block adds the grid, the saved line, the action's cell, the two placements
   and their motion. */
.onboard-send {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    grid-template-areas:
        "title   close"
        "actions actions";
    column-gap: var(--space-2);
    margin: 0;
    padding: var(--space-4) var(--space-5) var(--space-5);
    color: var(--text-primary);
    font-family: var(--font-family-base);
}

/* What the success toast used to say, at the eyebrow's size, beside the
   checklist's done tick at its done-list size (both grouped above). The tick
   draws in once the card has landed (M4). */
.onboard-send__saved {
    grid-area: saved;
    display: flex;
    align-items: center;
    gap: var(--space-2);
}

.onboard-send > .onboard-checklist__title {
    grid-area: title;
}

/* Close: the checklist's 48px control in the top-right corner. The negative
   block margins keep its box from heightening the first line, so its icon
   sits on that line and 8px or more stay clear above the action (V5). */
.onboard-send > .onboard-checklist__close {
    grid-area: close;
    align-self: start;
    margin-block: calc(var(--space-3) * -1);
}

/* New words take a line's place: out, new words, in. What a tap says on the
   client preview's strip. */
.onboard-client-strip__line {
    transition: opacity calc(var(--dur-onboard-fade) * var(--onboard-motion)) var(--ease-decel);
}

.onboard-client-strip__line[data-swapping] {
    opacity: 0;
    transition-timing-function: var(--ease-exit);
}

.onboard-send__actions {
    grid-area: actions;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-1) var(--space-2);
    margin-top: var(--space-5);
}

/* The client preview's way in (onboard_client_preview_link): the checklist's
   quiet text action, as a link on its own 48px row under the card's pill or
   the checklist item's action. */
.onboard-client-link {
    display: inline-flex;
    align-items: center;
    justify-content: center;
}

.onboard-client-link:hover {
    color: var(--primary-color);
}

.onboard-send__actions > .onboard-client-link {
    flex: 1 0 100%;
}

.onboard-checklist__also {
    display: flex;
    width: 100%;
    margin-top: var(--space-1);
}

/* While the send card is up it carries the way in, so the checklist's copy
   steps aside (A1). */
body[data-onboard-prompt] .onboard-checklist [data-client-preview-link] {
    display: none;
}

/* The action's cell grows along the row, and its grid stretches the action
   to the cell's width. */
.onboard-send__cell {
    display: grid;
    flex: 1 1 auto;
}

/* The checklist's pill with its icon and a press. */
.onboard-send .onboard-checklist__action {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--space-2);
    transition: transform calc(var(--dur-fast) * var(--onboard-motion)) var(--ease-standard);
}

/* While the send card is up, the checklist's own next action steps down to
   an outline, so the screen keeps one filled primary (A1). */
body[data-onboard-prompt] .onboard-checklist .onboard-checklist__action {
    color: var(--primary-color);
    background-color: transparent;
    border-color: var(--primary-color);
}

/* ── After a save: docked over the bottom navigation, never blocking ───────
   A non-modal dialog (F3, W2c): the page under it stays live and any
   navigation takes it away. It docks on --onboard-floor. Over the nav
   (1000); under the More menu (1050), modals (1055), the walkthrough layer
   (1080) and toasts. */
.onboard-send[data-surface="after_save"] {
    position: fixed;
    z-index: 1035;
    inset: auto var(--space-3) var(--onboard-floor);
    grid-template-areas:
        "saved   close"
        "title   close"
        "why     why"
        "actions actions";
    width: auto;
    max-width: 26rem;
    max-height: calc(100dvh - var(--onboard-floor) - var(--safe-top) - var(--space-3));
    margin: 0 auto;
    overflow-y: auto;
    border: 0;
    box-shadow:
        inset 0 0 0 1px var(--onboard-next-edge),
        var(--shadow-lg);
}

/* An author display beats the browser's own dialog:not([open]) rule. */
.onboard-send[data-surface="after_save"]:not([open]) {
    display: none;
}

@media (min-width: 992px) {
    .onboard-send[data-surface="after_save"] {
        inset: auto var(--space-6) var(--onboard-floor) auto;
        width: 22rem;
    }
}

/* Hidden until the create sheet has closed, then it rises from the edge the
   sheet went down to and goes back the way it came (onboard-rise). */
.onboard-send[data-state="waiting"] {
    visibility: hidden;
}

.onboard-send[data-state="in"] {
    animation: onboard-rise-in
        calc(var(--dur-onboard-fade) + (var(--dur-onboard-step-in) - var(--dur-onboard-fade)) * var(--onboard-motion))
        var(--ease-decel) both;
}

.onboard-send[data-state="out"] {
    pointer-events: none;
    animation: onboard-rise-out
        calc(var(--dur-onboard-fade) + (var(--dur-onboard-step-out) - var(--dur-onboard-fade)) * var(--onboard-motion))
        var(--ease-exit) both;
}

/* ── On the quote page: in flow under Quote Actions ─────────────────────────
   The wrapper always renders (the repaint target) and owns no margin: the
   container's 24px is above it, the next section's below. When the card is
   closed, or its quote handed to the sender, the wrapper's one row folds shut
   so the cards below glide up into its place (200ms ease-in). Reduced: the
   card fades first, then the gap closes in one step (M6). */
.onboard-send-fold {
    display: grid;
    grid-template-rows: 1fr;
    transition: grid-template-rows calc(var(--dur-onboard-step-out) * var(--onboard-motion)) var(--ease-exit)
        calc(var(--dur-onboard-fade) * (1 - var(--onboard-motion)));
}

/* Where focus waits once a closed card has gone: a reading position, not a
   control. */
.onboard-send-fold:focus {
    outline: none;
}

.onboard-send-fold > .onboard-send {
    min-height: 0;
}

.onboard-send-fold[data-folding] {
    grid-template-rows: 0fr;
    overflow: hidden;
}

/* With no card, a plain block: an empty grid box stops the container's 24px
   and the next section's collapsing into one, doubling the gap under Quote
   Actions. It stays in the page, focusable, as the repaint target. */
.onboard-send-fold:not(:has(> *)) {
    display: block;
}

/* From md the in-flow card is one row: its words, the action at its own
   width, the close. No 700px-wide pill. */
@media (min-width: 768px) {
    .onboard-send[data-surface="quote_page"] {
        grid-template-columns: minmax(0, 1fr) auto auto;
        grid-template-areas: "title actions close";
        align-items: center;
        column-gap: var(--space-4);
        padding-block-end: var(--space-4);
    }

    /* The way in stacks under the pill, at the pill's width. */
    .onboard-send[data-surface="quote_page"] > .onboard-send__actions {
        flex-direction: column;
        align-items: stretch;
        margin-top: 0;
    }

    .onboard-send[data-surface="quote_page"] > .onboard-send__actions > .onboard-client-link {
        flex: none;
    }

    .onboard-send[data-surface="quote_page"] .onboard-checklist__action {
        width: auto;
        padding-inline: var(--space-6);
    }

    .onboard-send[data-surface="quote_page"] > .onboard-checklist__close {
        align-self: center;
        margin-block: 0;
    }
}

/* ── The peak (W7, M5, M6) ─────────────────────────────────────────────────
   The one celebration: the owner's first sight of a quote as its client will
   see it. A cream disc pops, a Bottle Green check draws on it and eight
   Ironbark sparks shoot out and are gone: 800ms in all, no modal, no sound.
   Every part's delay plus duration is a share of --dur-onboard-peak, the
   latest ending at exactly 1.0, all times --onboard-motion. Reduced motion
   (M6) zeroes them, so fill-mode both lands on the still check at once. At
   rest (no data-peak) it is that still check. */
.onboard-peak {
    display: inline-grid;
    flex: none;
    width: 48px;
    height: 48px;
}

.onboard-peak svg {
    width: 100%;
    height: 100%;
    overflow: visible;
    transition: opacity var(--dur-onboard-fade) var(--ease-decel);
}

.onboard-peak__disc {
    fill: var(--onboard-ink);
    transform-box: fill-box;
    transform-origin: center;
}

.onboard-peak__check,
.onboard-peak__ray {
    fill: none;
    stroke-linecap: round;
    stroke-linejoin: round;
    stroke-dasharray: 1;
}

.onboard-peak__check {
    stroke: var(--onboard-band);
    stroke-width: 3;
    stroke-dashoffset: 0;
}

.onboard-peak__ray {
    stroke: var(--onboard-accent);
    stroke-width: 2.5;
    stroke-dashoffset: 1;
    opacity: 0;
}

/* Waiting for the server's answer: nothing shows. With no answer in three
   peak lengths (no script, a lost request) the still check shows by itself;
   under reduced motion at once. */
.onboard-peak[data-peak="waiting"] svg {
    opacity: 0;
    animation: onboard-peak-reveal 0s calc(var(--dur-onboard-peak) * 3 * var(--onboard-motion)) forwards;
}

.onboard-peak[data-peak="play"] svg {
    transition: none;
}

.onboard-peak[data-peak="play"] .onboard-peak__disc {
    animation: onboard-peak-pop calc(var(--dur-onboard-peak) * 0.25 * var(--onboard-motion)) var(--ease-overshoot) both;
}

.onboard-peak[data-peak="play"] .onboard-peak__check {
    animation: onboard-draw calc(var(--dur-onboard-peak) * 0.3125 * var(--onboard-motion)) var(--ease-decel)
        calc(var(--dur-onboard-peak) * 0.1875 * var(--onboard-motion)) both;
}

.onboard-peak[data-peak="play"] .onboard-peak__ray {
    animation: onboard-peak-spark calc(var(--dur-onboard-peak) * 0.625 * var(--onboard-motion)) var(--ease-decel)
        calc(var(--dur-onboard-peak) * 0.375 * var(--onboard-motion)) both;
}

@keyframes onboard-peak-reveal {
    to {
        opacity: 1;
    }
}

@keyframes onboard-peak-pop {
    from {
        opacity: 0;
        transform: scale(calc(1 - 0.6 * var(--onboard-motion)));
    }
}

@keyframes onboard-peak-spark {
    from {
        opacity: 1;
        stroke-dashoffset: 1;
    }

    50% {
        opacity: 1;
        stroke-dashoffset: 0;
    }

    to {
        opacity: 0;
        stroke-dashoffset: -1;
    }
}

/* ── The client preview's strip (A1, A4, V4, V5) ───────────────────────────
   Last on the client's page as the owner sees it (quote_public_view.html),
   held at the bottom of the screen until the page's end brings it to rest
   there: whose view this is, the peak, and the one way back, under the thumb.
   The flat band, never the gradient, whose glow would take the line under
   7:1 (V2, V4). It has no arrival motion: a page-check swap repaints it, and
   that must not show. */
.onboard-client-strip {
    position: sticky;
    bottom: calc(var(--space-3) + var(--safe-bottom));
    z-index: 2;
    display: grid;
    grid-template-columns: 48px minmax(0, 1fr);
    grid-template-areas:
        "peak line"
        "peak back";
    column-gap: var(--space-3);
    align-items: center;
    max-width: 26rem;
    margin: var(--space-4) auto 0;
    padding: var(--space-3) var(--space-4);
    color: var(--onboard-ink);
    font-family: var(--font-family-base);
    background: var(--onboard-band);
    border-radius: var(--border-radius-lg);
    box-shadow: var(--shadow-lg);
}

.onboard-client-strip > .onboard-peak {
    grid-area: peak;
}

.onboard-client-strip__line {
    grid-area: line;
    margin: 0;
    font-size: 1rem;
    font-weight: 600;
    line-height: 1.4;
}

/* The quiet action, its words lined up with the line's. */
.onboard-client-strip__back {
    grid-area: back;
    justify-self: start;
    margin-inline-start: calc(var(--space-4) * -1);
    text-decoration: none;
}

.onboard-client-strip__back:hover {
    color: var(--onboard-ink);
}

/* From md one row, as wide as its words, so the line does not wrap. */
@media (min-width: 768px) {
    .onboard-client-strip {
        grid-template-columns: 48px minmax(0, 1fr) auto;
        grid-template-areas: "peak line back";
        width: fit-content;
        max-width: 100%;
    }

    .onboard-client-strip__back {
        margin-inline-start: 0;
    }
}

/* ── The walkthrough (W1 to W7) ────────────────────────────────────────────
   A non-modal <dialog> whose only child is the fixed layer, so every UA
   dialog style is reset: it takes no space and makes no stacking context,
   and the layer keeps its own position and z-index. Only its open attribute
   is ever toggled (walkthrough_controller.js), which also works in WebViews
   without HTMLDialogElement. */
dialog.walkthrough {
    position: static;
    inset: auto;
    width: auto;
    height: auto;
    max-width: none;
    max-height: none;
    margin: 0;
    padding: 0;
    overflow: visible;
    color: inherit;
    background: none;
    border: 0;
}

dialog.walkthrough:not([open]) {
    display: none;
}

/* The offer and the end card carry no step dots and no close (W4, W5); their
   own display rules would otherwise beat [hidden]. */
.walkthrough .onboard-dots[hidden],
.walkthrough .onboard-card__close[hidden] {
    display: none;
}

/* A first tap outside the lit control: the card shakes once, side to side,
   and its nudge line says how to carry on or leave (walkthrough_controller.js
   _warn). Reduced motion keeps the line and drops the shake. */
.walkthrough__nudge {
    margin: var(--space-3) 0 0;
    padding-top: var(--space-3);
    font-size: 0.9375rem;
    font-weight: 600;
    line-height: 1.4;
    border-top: 1px solid var(--onboard-card-edge);
}

.walkthrough__nudge [hidden] {
    display: none;
}

.onboard-layer .onboard-card[data-nudged] {
    animation: onboard-shake calc(var(--dur-onboard-arrow-nudge) * var(--onboard-motion)) var(--ease-standard);
}

@keyframes onboard-shake {
    20%,
    60% {
        translate: calc(var(--onboard-nudge-shift) * -1 * var(--onboard-motion)) 0;
    }
    40%,
    80% {
        translate: calc(var(--onboard-nudge-shift) * var(--onboard-motion)) 0;
    }
}

/* What the client gets, inside the card (_walkthrough_preview.js): the PDF's
   pages, the email or the text, on white as the client sees it, scrolling
   within the card so its words and Next stay put. */
.walkthrough__preview {
    max-height: 45vh;
    margin-top: var(--space-3);
    overflow: auto;
    color: var(--c-neutral-900);
    background: var(--c-neutral-000);
    border-radius: var(--border-radius-lg);
    -webkit-overflow-scrolling: touch;
}

.walkthrough__preview:empty {
    min-height: 8rem;
}

.walkthrough__preview--zoom {
    cursor: zoom-in;
}

/* Under a PDF or email preview: how to see it full size. A touch screen
   taps; a pointer that hovers clicks. */
.walkthrough__zoom-hint {
    display: inline-flex;
    gap: var(--space-2);
    align-items: center;
    min-height: 48px;
    padding: 0;
    color: inherit;
    font-size: 0.875rem;
    background: none;
    border: 0;
    opacity: 0.85;
}

.walkthrough__zoom-hint--hover {
    display: none;
}

@media (hover: hover) and (pointer: fine) {
    .walkthrough__zoom-hint--touch {
        display: none;
    }

    .walkthrough__zoom-hint--hover {
        display: inline;
    }
}

/* The preview at its own size (walkthrough_controller.js _openZoom), over
   everything the walkthrough shows: a dimmed edge and an X, the document
   scrolling inside. */
.walkthrough-zoom {
    position: fixed;
    inset: 0;
    z-index: 1090;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: calc(var(--space-3) + var(--safe-top)) var(--space-3) calc(var(--space-3) + var(--safe-bottom));
    background: var(--onboard-veil);
    animation: onboard-zoom-in calc(var(--dur-onboard-step-in) * var(--onboard-motion)) var(--ease-decel) both;
}

.walkthrough-zoom[hidden] {
    display: none;
}

.walkthrough-zoom__sheet {
    position: relative;
    display: flex;
    flex-direction: column;
    width: min(100%, 56rem);
    height: 100%;
    overflow: hidden;
    color: var(--c-neutral-900);
    background: var(--c-neutral-000);
    border-radius: var(--border-radius-lg);
    box-shadow: var(--shadow-lg);
}

.walkthrough-zoom__body {
    flex: 1;
    min-height: 0;
    overflow: auto;
    -webkit-overflow-scrolling: touch;
}

.walkthrough-zoom__body canvas {
    display: block;
    width: 100%;
    height: auto;
}

.walkthrough-zoom__body .walkthrough-message__email {
    height: calc(100% - 3rem);
}

.walkthrough-zoom__close {
    position: absolute;
    top: var(--space-2);
    right: var(--space-2);
    z-index: 1;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 48px;
    height: 48px;
    color: var(--onboard-ink);
    background: var(--onboard-band);
    border: 0;
    border-radius: 50%;
    box-shadow: var(--shadow-lg);
}

@keyframes onboard-zoom-in {
    from {
        opacity: 0;
        scale: calc(1 - 0.04 * var(--onboard-motion));
    }
}

.walkthrough__preview canvas {
    display: block;
    width: 100%;
    height: auto;
}

.walkthrough-message__subject {
    margin: 0;
    padding: var(--space-3);
    font-size: 0.9375rem;
    font-weight: 700;
    border-bottom: 1px solid var(--c-neutral-200);
}

.walkthrough-message__email {
    display: block;
    width: 100%;
    height: 40vh;
    border: 0;
}

/* In the card the email is a picture to tap: a tap inside a frame stays in
   the frame's own document and never reaches walkthrough#zoom on the box. The
   full-size view (.walkthrough-zoom__body) keeps it live, to scroll. */
.walkthrough__preview .walkthrough-message__email {
    pointer-events: none;
}

.walkthrough-message__phone {
    margin: 0;
    padding: var(--space-2) var(--space-3) 0;
    font-size: 0.875rem;
    font-weight: 700;
    text-align: center;
}

.walkthrough-message__bubble {
    max-width: 85%;
    margin: var(--space-2) var(--space-3) var(--space-3);
    padding: var(--space-2) var(--space-3);
    white-space: pre-wrap;
    overflow-wrap: anywhere;
    background: var(--c-neutral-200);
    border-radius: var(--border-radius-lg);
}

/* The link the last step lights: thumb-sized (V5). It sits inside the card,
   which paints over the spotlight's ring and arrow, so it carries its own
   accent ring and the easy-to-miss pulse, four rounds then still (M3). */
.walkthrough-message__bubble a {
    position: relative;
    display: inline-block;
    padding: var(--space-2);
    color: var(--c-bottle-700);
    font-weight: 700;
    text-decoration: underline;
    border-radius: var(--border-radius-sm);
    box-shadow: 0 0 0 2px var(--onboard-accent);
}

.walkthrough-message__bubble a::after {
    position: absolute;
    inset: 0;
    border-radius: inherit;
    content: "";
    opacity: 0;
    animation: onboard-pulse calc(var(--dur-onboard-pulse) * var(--onboard-motion)) var(--ease-decel)
        calc(var(--dur-onboard-spotlight) * var(--onboard-motion)) 4;
}

/* The demo's "name your business", inline in the end card's sentence; the
   padding widens its tap area without moving the line. */
.walkthrough__link {
    margin-block: calc(var(--space-3) * -1);
    padding: var(--space-3) 0;
    color: inherit;
    font: inherit;
    font-weight: 700;
    text-decoration: underline;
    text-underline-offset: 0.2em;
    background: none;
    border: 0;
}

/* The way in and back: an Ask Chip style link with a play mark, and the
   quiet step counter when it resumes. */
.walkthrough-line {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    text-decoration: none;
}

.walkthrough-line__words {
    text-decoration: underline;
    text-underline-offset: 0.2em;
}

/* The counter stays one piece; on a narrow card the words wrap instead. Set
   apart by size and weight, never grey: all checklist text is full contrast (V4). */
.walkthrough-line__step {
    color: var(--text-primary);
    font-size: 0.875rem;
    font-weight: 400;
    white-space: nowrap;
}

/* The suggestion the fill is about to pick, held long enough to read. */
/* Mixed with white, not the theme surface: the suggestion list is white with
   dark text in every theme (address_autocomplete.js). */
.address-autocomplete-item[data-onboard-pick] {
    background: color-mix(in srgb, var(--onboard-accent) 10%, rgb(var(--c-ink-white)));
    box-shadow: inset 3px 0 0 var(--onboard-accent);
}

/* The walkthrough's sample quote, said beside its status in a list row and on
   the detail banner: the "this one next" breath, so it reads as onboarding,
   not as a workflow status. */
.onboard-sample {
    display: inline-flex;
    align-items: center;
    margin-inline-start: var(--space-2);
    padding: var(--space-1) var(--space-2);
    color: var(--text-primary);
    font-size: 0.75rem;
    font-weight: 600;
    line-height: 1;
    vertical-align: middle;
    background: var(--onboard-next-bg);
    border-radius: var(--radius-pill);
    box-shadow: inset 0 0 0 1px var(--onboard-next-edge);
}

/* The phone-app offer (onboard_app_offer): the checklist's row, padded as
   its help lines are, and the end card's block under its words. The badges
   are the store-line composite (components/store_badges.css); only their
   gap above is set here. */
.onboard-app {
    margin: var(--space-3) 0 0;
}

.onboard-checklist .onboard-app {
    padding: 0 var(--space-3);
}

.onboard-app__title {
    margin: 0;
    font-weight: 700;
}

.onboard-app__why {
    margin: 0;
}

.onboard-app .onboard-app__stores {
    margin-top: var(--space-2);
    justify-content: flex-start;
}

.onboard-app__dismiss {
    margin-top: var(--space-1);
}

/* The PWA line: only an installed home-screen app is told the store app is better. */
.onboard-app__pwa {
    display: none;
}

@media (display-mode: standalone) {
    .onboard-app__pwa {
        display: inline;
    }
}

/* The quiet Ask Chip line under an empty list or an error (macros/ask_chip.html).
   Muted lead; the link shares the checklist ask's rule, centred in its tap target. */
.ask-chip-line {
    margin: var(--space-3) 0 0;
    color: var(--text-muted);
    text-align: center;
}

.ask-chip {
    display: inline-flex;
    align-items: center;
}
