/* Veridica public storefront and client portal — the "Constitua" design
 * language.
 *
 * A deliberately sparse, trust-first layout: a dark institutional band carries
 * the wordmark, the navigation and the page title; everything below sits on
 * paper, separated by hairlines instead of cards and shadows. Type is Geist at
 * a single optical weight range, display sizes are large and tightly tracked,
 * and the only saturated colour is an acid green used as a mark, never as text
 * on paper.
 *
 * Everything here is scoped to the `.vp-body` class that both storefront
 * shells put on <body> (templates/public/base_public.html and
 * templates/portal/base_portal.html). No staff page carries that class, so the
 * --vp-* tokens below — and the token re-scoping at the end of this file —
 * cannot reach the authenticated application. The --v-* tokens in
 * redesign.css are never edited there, only re-declared here.
 *
 * Order: font → tokens and base → skip link → shell → band and topbar →
 * buttons → product grid → orientation → process → detail → modals → scope
 * flow → portal blocks → footer → flash → shared-form harmonization →
 * hover states → breakpoints → reduced motion. */

/* == font ============================================================== */

@font-face {
    font-family: "Geist";
    src: url("../fonts/veridica/geist-latin-wght.woff2") format("woff2");
    font-weight: 100 900;
    font-style: normal;
    font-display: swap;
}

/* == tokens and base =================================================== */

.vp-body {
    /* Materials */
    --vp-ink: #151717;
    --vp-muted: #626461;
    --vp-paper: #f8f7f4;
    --vp-sunk: #ecece6;
    --vp-surface: #fff;

    /* Lines: `line` frames controls, `hairline` separates rows on paper,
       `rule` closes a grid, `grid-line` splits the product columns. */
    --vp-line: #9a9a94;
    --vp-hairline: #c6c7c1;
    --vp-rule: #a3a49f;
    --vp-grid-line: #3a3c3c;

    /* Action */
    --vp-acid: #c5e313;
    --vp-accent: #536b00;
    --vp-accent-hover: #384400;
    --vp-ring: #718900;
    --vp-progress: #8ca900;
    --vp-selected: #eff4da;

    /* Dark band */
    --vp-header: #191c1e;
    --vp-header-ink: #f9f9f6;
    --vp-header-muted: #d7d7d2;

    /* States. Not part of the prototype, which has no forms with errors and
       no order status; kept in the same --vp-* namespace so the portal never
       has to reach for a staff token. */
    --vp-error: #8c3a32;
    --vp-error-wash: #f8efed;
    --vp-warn: #7a5512;
    --vp-warn-wash: #f4efe2;

    /* Motion and type */
    --vp-ease-out: cubic-bezier(.23, 1, .32, 1);
    --vp-ease-in-out: cubic-bezier(.77, 0, .175, 1);
    --vp-sans: "Geist", ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;

    /* One measure for every full-width block. The breakpoints below narrow
       the gutter by redefining this single value. */
    --vp-shell-w: min(100% - 88px, 1360px);

    margin: 0;
    min-height: 100vh;
    min-width: 320px;
    display: flex;
    flex-direction: column;
    color: var(--vp-ink);
    background: var(--vp-paper);
    font-family: var(--vp-sans);
    font-size: 17px;
    line-height: 1.55;
    font-synthesis: none;
    text-rendering: optimizeLegibility;
    -webkit-font-smoothing: antialiased;
}

/* Controls are given the storefront face one by one rather than through a
   `.vp-body input { font: inherit }` catch-all: a class-plus-element selector
   like that outranks the single-class rules the shared document workbench
   relies on, and would resize every field on the portal's order form. */

.vp-main {
    flex: 1 0 auto;
}

/* == skip link ========================================================= */

.vp-skip {
    position: fixed;
    top: -60px;
    left: 16px;
    z-index: 60;
    padding: 11px 17px;
    border-radius: 2px;
    color: var(--vp-header-ink);
    background: var(--vp-header);
    font-family: var(--vp-sans);
    font-size: 15px;
    line-height: 1;
    text-decoration: none;
    transition: top 120ms ease;
}

.vp-skip:focus {
    top: 16px;
}

/* == shell ============================================================= */

.vp-shell {
    box-sizing: border-box;
    width: var(--vp-shell-w);
    margin-inline: auto;
}

/* == dark band: topbar, navigation, page intro ========================= */

.vp-band {
    color: var(--vp-header-ink);
    background: var(--vp-header);
}

/* The catalog wears the tall band; every other page gets the slim one, which
   is the topbar plus a compact title area. */
.vp-band--tall {
    min-height: 332px;
}

/* Both shells put `.vp-shell.vp-topbar` directly inside the dark band; the
   band paints the background, the topbar only lays out its children. */
.vp-topbar {
    color: var(--vp-header-ink);
    background: var(--vp-header);
}

.vp-band .vp-topbar {
    background: transparent;
}

.vp-band .vp-topbar {
    box-sizing: border-box;
    height: 112px;
    display: grid;
    grid-template-columns: auto 1fr auto;
    align-items: center;
    column-gap: 110px;
}

/* Signed out, the portal header has no third child — the wordmark and the
   navigation are all there is. The empty third track would still eat a column
   gap, holding the call to action off the right edge, so the track goes. */
.vp-band .vp-topbar:not(:has(> :nth-child(3))) {
    grid-template-columns: auto 1fr;
}

.vp-wordmark {
    position: relative;
    justify-self: start;
    padding: 6px 18px 6px 0;
    display: inline-block;
    color: #fff;
    font-size: 28px;
    font-weight: 500;
    letter-spacing: -.05em;
    line-height: 1;
    text-decoration: none;
    transition: opacity 140ms ease, transform 140ms var(--vp-ease-out);
}

/* The mark is a 7px acid square hung off the wordmark's top right corner —
   the only saturated element in the header. */
.vp-wordmark__mark {
    position: absolute;
    top: 7px;
    right: 4px;
    width: 7px;
    height: 7px;
    overflow: hidden;
    background: var(--vp-acid);
    text-indent: -99em;
}

.vp-wordmark__text {
    font: inherit;
    letter-spacing: inherit;
}

.vp-nav {
    height: 100%;
    display: flex;
    align-items: stretch;
    justify-content: flex-start;
    gap: 58px;
}

.vp-nav a,
.vp-topbar > .vp-nav__cta {
    position: relative;
    display: inline-flex;
    align-items: center;
    height: 100%;
    color: #f1f1ed;
    font-size: 17px;
    text-decoration: none;
    transition: color 140ms ease, transform 140ms var(--vp-ease-out);
}

.vp-nav a::after,
.vp-topbar > .vp-nav__cta::after {
    content: "";
    position: absolute;
    right: 0;
    bottom: 17px;
    left: 0;
    height: 2px;
    background: var(--vp-acid);
    transform: scaleX(0);
    transform-origin: left;
    transition: transform 180ms var(--vp-ease-out);
}

.vp-nav a.is-active,
.vp-nav a[aria-current] {
    color: var(--vp-acid);
}

.vp-nav a.is-active::after,
.vp-nav a[aria-current]::after,
.vp-nav__cta::after {
    transform: scaleX(1);
}

/* The right-hand call to action. It is either the last child of `.vp-nav`
   (portal, signed out) or a third grid child of the topbar (public shell);
   both land on the right. */
.vp-nav__cta {
    justify-self: end;
    margin-left: auto;
}

.vp-account {
    justify-self: end;
    display: flex;
    align-items: center;
    gap: 16px;
}

.vp-account__email {
    max-width: 26ch;
    overflow: hidden;
    color: var(--vp-header-muted);
    font-size: 15px;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.vp-account form {
    margin: 0;
}

.vp-account__logout {
    min-height: 40px;
    padding: 0 16px;
    border: 1px solid rgb(255 255 255 / 26%);
    border-radius: 2px;
    color: var(--vp-header-ink);
    background: transparent;
    font-family: var(--vp-sans);
    font-size: 15px;
    cursor: pointer;
    transition: color 140ms ease, background-color 140ms ease, border-color 140ms ease, transform 140ms var(--vp-ease-out);
}

.vp-intro {
    box-sizing: border-box;
    width: var(--vp-shell-w);
    margin-inline: auto;
    padding: 38px 0 46px;
}

.vp-intro h1 {
    max-width: 900px;
    margin: 0;
    font-size: clamp(30px, 3.2vw, 42px);
    font-weight: 400;
    letter-spacing: -.05em;
    line-height: 1.06;
    /* Product names are Swiss legal compounds ("Aktionärbindungsvereinbarung")
       that would otherwise push past a narrow viewport's edge. */
    hyphens: auto;
    overflow-wrap: break-word;
}

.vp-intro p {
    max-width: 720px;
    margin: 18px 0 0;
    color: var(--vp-header-muted);
    font-size: 17px;
    line-height: 1.55;
}

.vp-band--tall .vp-intro {
    padding: 45px 0 52px;
}

.vp-band--tall .vp-intro h1 {
    font-size: clamp(42px, 4vw, 59px);
    letter-spacing: -.055em;
    line-height: 1.04;
}

.vp-band--tall .vp-intro p {
    margin-top: 20px;
}

/* == buttons, links and kickers ======================================== */

.vp-body :focus-visible {
    outline: 2px solid var(--vp-accent);
    outline-offset: 4px;
}

/* Olive on near-black fails contrast, so the band focuses in acid. Declared
   after the paper ring so the tie on specificity falls this way. */
.vp-band :focus-visible,
.vp-topbar :focus-visible {
    outline-color: var(--vp-acid);
}

/* The catalog's primary affordance: an outlined square that inverts on
   hover, with the arrow sliding out of the right edge. */
.vp-cta {
    box-sizing: border-box;
    width: 285px;
    min-height: 58px;
    padding: 0 24px;
    border: 1px solid var(--vp-ink);
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    color: var(--vp-ink);
    background: transparent;
    font-family: var(--vp-sans);
    font-size: 17px;
    text-align: left;
    text-decoration: none;
    cursor: pointer;
    transition: color 160ms ease, background-color 160ms ease, border-color 160ms ease, transform 140ms var(--vp-ease-out);
}

.vp-cta svg,
.vp-orientation svg,
.vp-button svg {
    flex: 0 0 auto;
    width: 21px;
    height: 21px;
    transition: transform 180ms var(--vp-ease-out);
}

.vp-button {
    box-sizing: border-box;
    min-height: 48px;
    border: 1px solid transparent;
    border-radius: 2px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 36px;
    font-family: var(--vp-sans);
    font-size: 17px;
    text-align: center;
    text-decoration: none;
    cursor: pointer;
    transition: color 150ms ease, background-color 150ms ease, border-color 150ms ease, opacity 150ms ease, transform 140ms var(--vp-ease-out);
}

.vp-button--primary {
    padding: 0 21px;
    border-color: #1a1d1d;
    color: #fff;
    background: #1a1d1d;
}

.vp-button--primary:disabled,
.vp-button--primary[aria-disabled="true"] {
    opacity: .34;
    cursor: not-allowed;
    transform: none;
}

.vp-button--ghost {
    padding: 0 12px;
    border-color: transparent;
    color: #4e5150;
    background: transparent;
}

.vp-button--block {
    width: 100%;
}

.vp-textlink {
    color: var(--vp-accent);
    text-decoration: underline;
    text-decoration-color: rgb(83 107 0 / 35%);
    text-decoration-thickness: 1px;
    text-underline-offset: 4px;
    transition: color 140ms ease, text-decoration-color 140ms ease;
}

.vp-kicker {
    margin: 0 0 14px;
    color: #4e6800;
    font-size: 12px;
    font-weight: 600;
    letter-spacing: .13em;
    line-height: 1.3;
}

/* == product grid ====================================================== */

.vp-catalog {
    padding-bottom: clamp(40px, 6vw, 76px);
}

.vp-products {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    border-bottom: 1px solid var(--vp-rule);
    margin: 0;
    padding: 0;
    list-style: none;
}

.vp-product {
    box-sizing: border-box;
    min-height: 593px;
    padding: 74px 62px 52px 12px;
    display: flex;
    flex-direction: column;
}

.vp-product:nth-child(even) {
    padding-right: 18px;
    padding-left: 82px;
    border-left: 1px solid var(--vp-grid-line);
}

.vp-product:nth-child(n+3) {
    border-top: 1px solid var(--vp-grid-line);
}

/* A single published contract keeps the full measure instead of leaving half
   the grid empty. The modifier is set server-side, never with :has(). */
.vp-products--single {
    grid-template-columns: minmax(0, 1fr);
}

.vp-products--single .vp-product,
.vp-products--single .vp-product:nth-child(even) {
    padding: 74px 12px 52px;
    border-left: 0;
}

.vp-products--single .vp-product:nth-child(n+2) {
    border-top: 1px solid var(--vp-grid-line);
}

.vp-product__number {
    margin-bottom: 29px;
    color: var(--vp-muted);
    font-size: 16px;
}

.vp-product__copy h2 {
    max-width: 590px;
    margin: 0;
    font-size: clamp(34px, 3vw, 46px);
    font-weight: 400;
    letter-spacing: -.055em;
    line-height: 1.06;
    hyphens: auto;
    overflow-wrap: break-word;
}

/* The title is the link to the detail page: it is the crawlable path and the
   whole product without JavaScript. */
.vp-product__copy h2 a {
    color: inherit;
    text-decoration: none;
}

.vp-product__copy p {
    max-width: 470px;
    margin: 26px 0 0;
    color: var(--vp-muted);
    font-size: 17px;
    line-height: 1.55;
}

.vp-product__meta {
    margin-top: auto;
    padding-top: 62px;
}

.vp-product__meta p {
    position: relative;
    margin: 0 0 22px;
    padding-left: 50px;
    font-size: 17px;
    line-height: 1.35;
}

.vp-product__meta p::before {
    content: "";
    position: absolute;
    top: .66em;
    left: 0;
    width: 29px;
    height: 2px;
    background: var(--vp-acid);
}

.vp-product__action {
    margin-top: 45px;
}

.vp-priceline {
    display: flex;
    align-items: baseline;
    gap: 16px;
    margin-bottom: 18px;
}

.vp-priceline span,
.vp-priceline small {
    color: var(--vp-muted);
    font-size: 15px;
}

.vp-priceline strong {
    font-size: 33px;
    font-weight: 400;
    letter-spacing: -.04em;
    font-variant-numeric: tabular-nums;
}

/* == orientation row =================================================== */

.vp-orientation {
    min-height: 70px;
    display: flex;
    align-items: center;
    gap: 8px;
    color: var(--vp-muted);
    font-size: 15px;
}

.vp-orientation a {
    display: inline-flex;
    align-items: center;
    gap: 12px;
    color: var(--vp-accent);
    text-decoration: none;
    transition: color 140ms ease, transform 140ms var(--vp-ease-out);
}

.vp-orientation svg {
    color: currentColor;
}

/* == process ============================================================ */

.vp-processblock {
    padding: clamp(44px, 6vw, 72px) 0 clamp(40px, 6vw, 64px);
    border-top: 1px solid var(--vp-hairline);
}

.vp-processblock h2 {
    max-width: 570px;
    margin: 0;
    font-size: clamp(28px, 3vw, 38px);
    font-weight: 400;
    letter-spacing: -.045em;
    line-height: 1.08;
}

.vp-processlist {
    max-width: 780px;
    margin: 34px 0 0;
    padding: 0;
    border-top: 1px solid var(--vp-hairline);
    list-style: none;
}

.vp-processlist li {
    padding: 20px 0;
    border-bottom: 1px solid var(--vp-hairline);
    display: grid;
    grid-template-columns: 54px 1fr;
    gap: 12px;
}

.vp-processlist li > span {
    color: #687b12;
    font-size: 13px;
}

.vp-processlist strong {
    font-weight: 500;
}

.vp-processlist p {
    margin: 5px 0 0;
    color: var(--vp-muted);
    font-size: 16px;
    line-height: 1.45;
}

/* The detail page's own step list numbers itself, because its markup puts the
   title in <strong> and the copy in <span>. */
.vp-process {
    margin-top: clamp(32px, 5vw, 56px);
}

.vp-process h2 {
    margin: 0;
    font-size: clamp(24px, 2.4vw, 30px);
    font-weight: 400;
    letter-spacing: -.04em;
    line-height: 1.12;
}

.vp-process__list {
    counter-reset: vp-step;
    max-width: 780px;
    margin: 28px 0 0;
    padding: 0;
    border-top: 1px solid var(--vp-hairline);
    list-style: none;
}

.vp-process__list li {
    padding: 20px 0 20px 54px;
    border-bottom: 1px solid var(--vp-hairline);
    position: relative;
}

.vp-process__list li::before {
    counter-increment: vp-step;
    content: "0" counter(vp-step);
    position: absolute;
    top: 22px;
    left: 0;
    color: #687b12;
    font-size: 13px;
}

.vp-process__list strong {
    display: block;
    font-weight: 500;
}

.vp-process__list span {
    display: block;
    margin-top: 5px;
    color: var(--vp-muted);
    font-size: 16px;
    line-height: 1.45;
}

/* == detail page ======================================================= */

.vp-detail {
    padding: clamp(34px, 5vw, 62px) 0 0;
}

.vp-detail__grid {
    display: grid;
    grid-template-columns: 1fr;
    gap: clamp(28px, 4vw, 56px);
    align-items: start;
}

.vp-breadcrumb {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 10px;
    margin-bottom: 30px;
    color: var(--vp-muted);
    font-size: 14px;
}

.vp-breadcrumb a {
    color: var(--vp-muted);
    text-decoration: none;
    transition: color 140ms ease;
}

.vp-detail__title {
    max-width: 760px;
    margin: 0 0 26px;
    font-size: clamp(32px, 3.4vw, 46px);
    font-weight: 400;
    letter-spacing: -.055em;
    line-height: 1.06;
}

.vp-pricebox {
    padding: 30px 28px;
    border: 1px solid var(--vp-hairline);
    background: var(--vp-paper);
}

.vp-pricebox__label {
    margin: 0;
    color: var(--vp-muted);
    font-size: 15px;
}

.vp-pricebox__amount {
    margin: 6px 0 0;
    font-size: 33px;
    font-weight: 400;
    letter-spacing: -.04em;
    line-height: 1.1;
    font-variant-numeric: tabular-nums;
}

.vp-pricebox__note {
    margin: 14px 0 22px;
    color: var(--vp-muted);
    font-size: 15px;
    line-height: 1.5;
}

.vp-pricebox__facts {
    margin: 24px 0 0;
    padding: 0;
    border-top: 1px solid var(--vp-hairline);
    list-style: none;
}

.vp-pricebox__facts li {
    position: relative;
    padding: 13px 0 0 34px;
    color: var(--vp-muted);
    font-size: 15px;
    line-height: 1.4;
}

.vp-pricebox__facts li::before {
    content: "";
    position: absolute;
    top: 1.32em;
    left: 0;
    width: 19px;
    height: 2px;
    background: var(--vp-acid);
}

/* == prose, legal pages and empty states =============================== */

.vp-prose {
    max-width: 68ch;
    /* Legal copy carries unbroken tokens — mail addresses, URLs, statute
       names — that must wrap rather than widen a phone viewport. */
    hyphens: auto;
    overflow-wrap: anywhere;
}

.vp-prose p {
    margin: 0 0 20px;
    color: var(--vp-muted);
    font-size: 17px;
    line-height: 1.65;
}

.vp-prose h2 {
    margin: 42px 0 14px;
    font-size: clamp(22px, 2.2vw, 28px);
    font-weight: 400;
    letter-spacing: -.04em;
    line-height: 1.15;
}

.vp-prose h3 {
    margin: 28px 0 8px;
    font-size: 17px;
    font-weight: 500;
}

.vp-legal {
    padding: clamp(30px, 4vw, 52px) 0 clamp(48px, 8vw, 96px);
}

.vp-legal__meta {
    margin-top: 42px !important;
    padding-top: 18px;
    border-top: 1px solid var(--vp-hairline);
    color: var(--vp-muted) !important;
    font-size: 14px !important;
}

.vp-todo {
    padding: 13px 14px;
    border-left: 2px solid var(--vp-warn);
    color: var(--vp-warn) !important;
    background: var(--vp-warn-wash);
    font-size: 14px !important;
}

.vp-empty {
    padding: clamp(40px, 6vw, 72px) 28px;
    border: 1px solid var(--vp-hairline);
    background: var(--vp-paper);
}

.vp-empty h2 {
    margin: 0 0 12px;
    font-size: clamp(24px, 2.6vw, 32px);
    font-weight: 400;
    letter-spacing: -.045em;
    line-height: 1.1;
}

.vp-empty p {
    max-width: 52ch;
    margin: 0;
    color: var(--vp-muted);
    font-size: 16px;
}

.vp-empty__action {
    margin: 26px 0 0;
}

/* == modal system (native <dialog>) ==================================== */

/* `display` is left to the user agent so that the element keeps working as a
   dialog; the entry is animated with @starting-style and the exit with a
   [data-closing] attribute the script sets before close(). */
dialog.vp-modal {
    box-sizing: border-box;
    width: min(100%, 700px);
    max-width: min(100%, 700px);
    max-height: min(860px, calc(100dvh - 48px));
    margin: auto;
    padding: 54px;
    border: 1px solid #303334;
    border-radius: 4px;
    overflow-y: auto;
    color: var(--vp-ink);
    background: var(--vp-paper);
    box-shadow: 0 32px 100px rgb(0 0 0 / 22%);
    opacity: 1;
    transform: none;
    transition: opacity 220ms var(--vp-ease-out), transform 220ms var(--vp-ease-out);
}

@starting-style {
    dialog.vp-modal[open] {
        opacity: 0;
        transform: translateY(10px) scale(.985);
    }
}

dialog.vp-modal[data-closing] {
    opacity: 0;
    transform: translateY(4px) scale(.99);
    transition-duration: 130ms;
}

dialog.vp-modal::backdrop {
    background: rgb(8 10 10 / 58%);
    backdrop-filter: blur(3px);
    opacity: 1;
    transition: opacity 220ms var(--vp-ease-out);
}

@starting-style {
    dialog.vp-modal[open]::backdrop {
        opacity: 0;
    }
}

dialog.vp-modal[data-closing]::backdrop {
    opacity: 0;
    transition-duration: 130ms;
}

dialog.vp-modal:focus {
    outline: none;
}

/* The scope steps differ in height; a floor keeps the actions from jumping
   between questions. */
dialog.vp-modal:has(.vp-scope-flow),
dialog.vp-modal:has(.vp-scope-summary) {
    min-height: min(760px, calc(100dvh - 48px));
}

.vp-modal h2 {
    max-width: 570px;
    margin: 0;
    font-size: clamp(30px, 4vw, 44px);
    font-weight: 400;
    letter-spacing: -.045em;
    line-height: 1.08;
}

.vp-modal h2:focus {
    outline: none;
}

.vp-modal__copy {
    max-width: 570px;
    margin: 22px 0 32px;
    color: var(--vp-muted);
    font-size: 16px;
    line-height: 1.6;
}

.vp-modal__close {
    position: absolute;
    top: 20px;
    right: 20px;
    width: 38px;
    height: 38px;
    border: 1px solid #c8c8c2;
    border-radius: 50%;
    display: grid;
    place-items: center;
    color: var(--vp-ink);
    background: transparent;
    cursor: pointer;
    transition: color 140ms ease, background-color 140ms ease, transform 140ms var(--vp-ease-out);
}

.vp-modal__close svg {
    width: 18px;
    height: 18px;
}

.vp-modal__actions {
    margin-top: 34px;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
}

/* The page behind a top-layer dialog must not scroll away under it. */
.vp-body:has(dialog.vp-modal[open]) {
    overflow: hidden;
}

/* == scope flow ======================================================== */

.vp-scope-heading {
    padding-right: 30px;
}

.vp-scope-progress {
    width: 100%;
    height: 2px;
    margin: 30px 0 0;
    display: block;
    overflow: hidden;
    background: #dddcd6;
}

.vp-scope-progress span {
    display: block;
    width: 100%;
    height: 100%;
    background: var(--vp-progress);
    transform-origin: left;
    transition: none;
}

.vp-scope-hint {
    margin: 22px 0 26px;
    color: var(--vp-muted);
    font-size: 15px;
    line-height: 1.55;
}

.vp-scope-options {
    border-top: 1px solid var(--vp-hairline);
}

.vp-scope-option {
    box-sizing: border-box;
    width: 100%;
    min-height: 76px;
    padding: 17px 18px;
    border: 0;
    border-bottom: 1px solid var(--vp-hairline);
    display: flex;
    align-items: center;
    gap: 16px;
    text-align: left;
    background: transparent;
    cursor: pointer;
    transition: background-color 150ms ease, transform 130ms var(--vp-ease-out);
}

.vp-scope-option[data-selected="true"] {
    background: var(--vp-selected);
}

.vp-scope-option strong,
.vp-scope-option small {
    display: block;
}

.vp-scope-option strong {
    font-size: 15px;
    font-weight: 500;
}

.vp-scope-option small {
    margin-top: 4px;
    color: var(--vp-muted);
    font-size: 14px;
}

/* A real radio, painted: keyboard, form semantics and the radiogroup all keep
   working, only the box is redrawn. */
.vp-scope-radio {
    appearance: none;
    flex: 0 0 auto;
    width: 20px;
    height: 20px;
    border: 1px solid #686b69;
    border-radius: 50%;
    background: transparent;
    cursor: pointer;
    transition: border-color 140ms ease, box-shadow 140ms ease;
}

.vp-scope-option[data-selected="true"] .vp-scope-radio,
.vp-scope-radio:checked {
    border-color: var(--vp-ring);
    box-shadow: inset 0 0 0 4px var(--vp-selected), inset 0 0 0 10px var(--vp-ring);
}

/* The ring belongs on the whole row, not on the 20px control. */
.vp-scope-option:has(.vp-scope-radio:focus-visible) {
    outline: 2px solid var(--vp-accent);
    outline-offset: -2px;
}

.vp-scope-radio:focus-visible {
    outline: none;
}

.vp-scope-facts {
    margin-top: 30px;
    padding-block: 18px;
    border-block: 1px solid #c9cac5;
    display: flex;
    gap: 28px;
    color: #4e5150;
    font-size: 14px;
}

.vp-scope-facts span {
    display: inline-flex;
    align-items: center;
    gap: 9px;
}

.vp-scope-facts svg {
    flex: 0 0 auto;
    width: 18px;
    height: 18px;
    color: #5d7800;
}

.vp-scope-result-icon {
    width: 52px;
    height: 52px;
    margin-bottom: 28px;
    border-radius: 50%;
    display: grid;
    place-items: center;
    color: #182000;
    background: var(--vp-acid);
}

.vp-scope-result-icon svg {
    width: 24px;
    height: 24px;
}

/* == portal: page heads, request list and status ======================= */

.vp-portal {
    padding: clamp(34px, 5vw, 58px) 0 clamp(48px, 8vw, 96px);
}

.vp-portal__head {
    max-width: 760px;
    margin-bottom: 38px;
}

.vp-pagehead__title {
    margin: 0;
    font-size: clamp(30px, 3.2vw, 42px);
    font-weight: 400;
    letter-spacing: -.05em;
    line-height: 1.06;
}

.vp-pagehead__lead {
    max-width: 62ch;
    margin: 18px 0 0;
    color: var(--vp-muted);
    font-size: 17px;
    line-height: 1.6;
}

.vp-requests {
    max-width: 960px;
    margin: 0;
    padding: 0;
    border-top: 1px solid var(--vp-hairline);
    list-style: none;
}

.vp-request {
    padding: 22px 0;
    border-bottom: 1px solid var(--vp-hairline);
}

.vp-request__link {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    justify-content: space-between;
    gap: 16px;
    color: var(--vp-ink);
    text-decoration: none;
}

.vp-request__title {
    max-width: 46ch;
    font-size: clamp(21px, 2vw, 26px);
    font-weight: 400;
    letter-spacing: -.04em;
    line-height: 1.15;
}

.vp-request__status {
    display: inline-flex;
    align-items: center;
    padding: 5px 12px;
    border: 1px solid var(--vp-hairline);
    border-radius: 999px;
    color: var(--vp-muted);
    font-size: 13px;
    line-height: 1.3;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

/* Status colours: the warn tone means "waiting for the customer", the error
   tone means a stopped request. Anything unmapped stays neutral. */
.vp-request__status--draft,
.vp-request__status--pending_payment {
    border-color: rgb(122 85 18 / 40%);
    color: var(--vp-warn);
    background: var(--vp-warn-wash);
}

.vp-request__status--rejected,
.vp-request__status--refunded,
.vp-request__status--cancelled,
.vp-request__status--abandoned {
    border-color: rgb(140 58 50 / 40%);
    color: var(--vp-error);
    background: var(--vp-error-wash);
}

.vp-request__meta {
    display: block;
    margin-top: 8px;
    color: var(--vp-muted);
    font-size: 14px;
    font-variant-numeric: tabular-nums;
}

/* The detail head repeats the status as a standalone paragraph. */
p.vp-request__status {
    margin: 16px 0 0;
}

/* == portal: timeline ================================================== */

.vp-timeline {
    max-width: 960px;
    display: flex;
    flex-wrap: wrap;
    gap: 26px;
    margin: 0 0 38px;
    padding: 20px 0;
    border-block: 1px solid var(--vp-hairline);
    list-style: none;
}

.vp-timeline__step {
    display: flex;
    align-items: center;
    gap: 10px;
    color: var(--vp-muted);
    font-size: 14px;
    line-height: 1.3;
}

.vp-timeline__mark {
    flex: 0 0 auto;
    width: 10px;
    height: 10px;
    border: 1px solid currentColor;
    border-radius: 50%;
}

.vp-timeline__label {
    display: inline-block;
}

.vp-timeline__step--done {
    color: var(--vp-accent);
}

.vp-timeline__step--done .vp-timeline__mark {
    background: var(--vp-accent);
}

/* aria-current="step" and the --current modifier describe the same row; both
   are styled so the template never has to choose. */
.vp-timeline__step--current,
.vp-timeline__step[aria-current="step"] {
    color: var(--vp-ink);
    font-weight: 500;
}

.vp-timeline__step--current .vp-timeline__mark,
.vp-timeline__step[aria-current="step"] .vp-timeline__mark {
    border-color: var(--vp-ring);
    background: var(--vp-acid);
    box-shadow: 0 0 0 3px var(--vp-selected);
}

.vp-timeline__step--stopped {
    color: var(--vp-error);
}

.vp-timeline__step--stopped .vp-timeline__mark {
    background: var(--vp-error);
}

/* == portal: notices, summary and order head =========================== */

.vp-notice {
    max-width: 760px;
    margin-top: 32px;
    padding: 26px 26px 24px;
    border: 1px solid var(--vp-hairline);
    background: var(--vp-sunk);
}

.vp-notice__title {
    margin: 0 0 8px;
    font-size: 19px;
    font-weight: 500;
    letter-spacing: -.02em;
    line-height: 1.3;
}

.vp-notice p {
    margin: 0 0 14px;
    color: var(--vp-muted);
    font-size: 16px;
    line-height: 1.55;
}

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

.vp-notice--ready {
    border-color: var(--vp-ring);
    background: var(--vp-selected);
}

.vp-notice--rejected {
    border-color: rgb(140 58 50 / 40%);
    background: var(--vp-error-wash);
}

.vp-summary {
    max-width: 960px;
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
    gap: 24px 32px;
    margin: 38px 0 0;
    padding: 24px 0;
    border-block: 1px solid var(--vp-hairline);
}

.vp-summary dt {
    color: var(--vp-muted);
    font-size: 13px;
    font-weight: 600;
    letter-spacing: .04em;
}

.vp-summary dd {
    margin: 6px 0 0;
    font-size: 16px;
    line-height: 1.45;
}

.vp-summary__reference {
    font-size: 14px;
    font-variant-numeric: tabular-nums;
    word-break: break-all;
}

.vp-orderhead {
    margin-bottom: 22px;
}

.vp-orderhead__price {
    margin: 0;
    color: var(--vp-muted);
    font-size: 15px;
    font-variant-numeric: tabular-nums;
}

/* == portal: authentication and forms ================================== */

.vp-auth {
    max-width: 470px;
    margin: 0 auto;
    padding: clamp(8px, 2vw, 24px) 0 clamp(24px, 5vw, 48px);
}

.vp-auth__title {
    margin: 0;
    font-size: clamp(28px, 3vw, 38px);
    font-weight: 400;
    letter-spacing: -.05em;
    line-height: 1.06;
}

.vp-auth__lead {
    margin: 18px 0 34px;
    color: var(--vp-muted);
    font-size: 16px;
    line-height: 1.6;
}

.vp-auth__foot {
    margin: 26px 0 0;
    color: var(--vp-muted);
    font-size: 15px;
}

.vp-auth__note {
    margin: 8px 0 0;
    color: var(--vp-muted);
    font-size: 15px;
}

.vp-form {
    display: grid;
    gap: 22px;
    margin: 0;
}

.vp-form--inline {
    gap: 16px;
    margin-top: 18px;
}

.vp-field {
    display: grid;
    gap: 8px;
}

.vp-field label {
    font-size: 13px;
    font-weight: 600;
}

.vp-field input {
    box-sizing: border-box;
    width: 100%;
    height: 54px;
    padding: 0 16px;
    border: 1px solid #8c8d88;
    border-radius: 2px;
    color: var(--vp-ink);
    background: var(--vp-surface);
    font-family: var(--vp-sans);
    font-size: 16px;
    transition: border-color 140ms ease;
}

.vp-field input:focus {
    border-color: var(--vp-accent);
}

.vp-field__hint {
    margin: 0;
    color: var(--vp-muted);
    font-size: 14px;
}

.vp-field__error {
    margin: 0;
    color: var(--vp-error);
    font-size: 14px;
}

.vp-formerror {
    margin-bottom: 24px;
    padding: 13px 15px;
    border-left: 2px solid var(--vp-error);
    color: var(--vp-error);
    background: var(--vp-error-wash);
    font-size: 16px;
    line-height: 1.45;
}

/* The honeypot is removed from the visual and the accessibility tree but
   stays in the DOM, where an automated form filler will find it. */
.vp-trap {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
}

/* == footer ============================================================ */

.vp-footer {
    margin-top: clamp(48px, 8vw, 96px);
    padding: 30px 0 38px;
    border-top: 1px solid var(--vp-hairline);
    background: var(--vp-paper);
}

.vp-footer__inner {
    display: flex;
    flex-direction: column;
    gap: 14px;
}

.vp-footer__brand {
    margin: 0;
    font-size: 17px;
    letter-spacing: -.02em;
}

.vp-footer__nav {
    display: flex;
    flex-wrap: wrap;
    gap: 26px;
}

.vp-footer__nav a {
    color: var(--vp-muted);
    font-size: 15px;
    text-decoration: none;
    transition: color 140ms ease;
}

.vp-footer__legal {
    margin: 0;
    color: var(--vp-muted);
    font-size: 14px;
}

/* == flash messages ==================================================== */

/* The portal shows flashes through the shared `.v-flash` markup. Restyled
   here, in the storefront's own language, instead of in redesign.css. */
.vp-body .v-flash {
    max-width: 960px;
    margin-bottom: 22px;
    padding: 13px 15px;
    border-left: 2px solid var(--vp-ring);
    color: var(--vp-ink);
    background: var(--vp-selected);
    font: 400 16px/1.5 var(--vp-sans);
}

.vp-body .v-flash--error {
    border-left-color: var(--vp-error);
    color: var(--vp-error);
    background: var(--vp-error-wash);
}

.vp-body .v-flash--warning {
    border-left-color: var(--vp-warn);
    color: var(--vp-warn);
    background: var(--vp-warn-wash);
}

/* == portal: shared staff workbench harmonization (scoped to .vp-body ONLY) == */

/* The order form is the staff document workbench rendered inside the portal
   shell. Its markup is shared and asserted by tests, so nothing here touches
   layout, geometry, data attributes or error classes: only the --v-* token
   VALUES are re-declared for this subtree, plus three surface rules that
   square off the borrowed controls. */
.vp-body {
    --v-accent: #536b00;
    --v-accent-hover: #384400;
    --v-accent-wash: rgb(83 107 0 / 9%);
    --v-accent-mark: rgb(83 107 0 / 12%);
    --v-serif: var(--vp-sans);
    --v-sans: var(--vp-sans);
    --v-paper: #f8f7f4;
}

.vp-body .vd-btn {
    border-radius: 2px;
}

.vp-body .vd-input,
.vp-body .vd-textarea,
.vp-body .vd-select {
    border-color: #8c8d88;
    border-radius: 2px;
}

.vp-body .vd-input:focus,
.vp-body .vd-textarea:focus,
.vp-body .vd-select:focus {
    border-color: var(--vp-accent);
}

.vp-body .v-form-card {
    border: 1px solid var(--vp-hairline);
    box-shadow: none;
}

/* == end portal harmonization ========================================== */

/* == hover and press =================================================== */

/* Hover belongs to devices that can hover; a touch device would otherwise
   keep the hovered state after the tap. */
@media (hover: hover) and (pointer: fine) {
    .vp-wordmark:hover {
        opacity: .78;
    }

    .vp-nav a:hover {
        color: var(--vp-acid);
    }

    .vp-nav a:hover::after {
        transform: scaleX(1);
    }

    .vp-account__logout:hover {
        border-color: rgb(255 255 255 / 52%);
        background: rgb(255 255 255 / 8%);
    }

    .vp-cta:hover,
    .vp-button--primary:hover {
        color: var(--vp-paper);
        border-color: var(--vp-ink);
        background: var(--vp-ink);
    }

    .vp-cta:hover svg,
    .vp-button--primary:hover svg,
    .vp-orientation a:hover svg {
        transform: translateX(3px);
    }

    .vp-button--ghost:hover {
        color: var(--vp-ink);
        background: rgb(21 23 23 / 6%);
    }

    .vp-textlink:hover {
        color: var(--vp-accent-hover);
        text-decoration-color: currentColor;
    }

    .vp-product__copy h2 a:hover {
        text-decoration: underline;
        text-decoration-color: var(--vp-hairline);
        text-decoration-thickness: 1px;
        text-underline-offset: 8px;
    }

    .vp-orientation a:hover,
    .vp-breadcrumb a:hover,
    .vp-footer__nav a:hover {
        color: var(--vp-accent-hover);
    }

    .vp-request__link:hover .vp-request__title {
        text-decoration: underline;
        text-decoration-color: var(--vp-hairline);
        text-decoration-thickness: 1px;
        text-underline-offset: 6px;
    }

    .vp-scope-option:hover {
        background: #f0f0eb;
    }

    .vp-scope-option[data-selected="true"]:hover {
        background: var(--vp-selected);
    }

    .vp-modal__close:hover {
        background: #e7e7e1;
    }
}

/* Press feedback stays outside the hover query: a touch device gets it too. */
.vp-wordmark:active,
.vp-nav a:active,
.vp-account__logout:active,
.vp-cta:active,
.vp-button:active,
.vp-textlink:active,
.vp-orientation a:active,
.vp-modal__close:active {
    transform: scale(.97);
}

.vp-scope-option:active {
    transform: scale(.995);
}

.vp-button--primary:disabled:active,
.vp-button--primary[aria-disabled="true"]:active {
    transform: none;
}

/* == breakpoints ======================================================= */

/* Short laptop screens: the scope modal loses its generous padding before it
   loses its scroll position. */
@media (max-height: 800px) and (min-width: 561px) {
    dialog.vp-modal {
        padding: 34px 54px 28px;
    }

    dialog.vp-modal:has(.vp-scope-flow),
    dialog.vp-modal:has(.vp-scope-summary) {
        min-height: calc(100dvh - 48px);
    }

    .vp-scope-heading h2 {
        font-size: 36px;
        line-height: 1.04;
    }

    .vp-scope-progress {
        margin-top: 18px;
    }

    .vp-scope-hint {
        margin: 16px 0 18px;
    }

    .vp-scope-option {
        min-height: 58px;
        padding: 11px 18px;
    }

    .vp-modal__actions {
        margin-top: 20px;
    }
}

@media (max-width: 900px) {
    .vp-body {
        --vp-shell-w: min(100% - 40px, 1360px);
    }

    .vp-band--tall {
        min-height: 360px;
    }

    .vp-band .vp-topbar {
        height: auto;
        padding-top: 24px;
        grid-template-columns: 1fr auto;
        gap: 24px;
    }

    /* The navigation drops to its own row and the underline moves to the row
       edge, where it reads as a tab indicator. */
    .vp-nav {
        grid-column: 1 / -1;
        grid-row: 2;
        height: 58px;
        gap: 32px;
    }

    .vp-nav a::after {
        bottom: 0;
    }

    .vp-nav__cta {
        height: 50px;
    }

    .vp-intro {
        padding-top: 34px;
    }

    .vp-band--tall .vp-intro {
        padding-top: 40px;
    }

    .vp-products,
    .vp-products--single {
        grid-template-columns: minmax(0, 1fr);
    }

    .vp-product,
    .vp-product:nth-child(even),
    .vp-products--single .vp-product,
    .vp-products--single .vp-product:nth-child(even) {
        min-height: 500px;
        padding: 54px 8px 46px;
        border-left: 0;
    }

    .vp-product:nth-child(n+2),
    .vp-products--single .vp-product:nth-child(n+2) {
        border-top: 1px solid var(--vp-grid-line);
    }

    .vp-product__copy h2 {
        font-size: clamp(31px, 8vw, 43px);
    }

    .vp-cta {
        width: min(100%, 330px);
    }
}

@media (min-width: 720px) {
    .vp-footer__inner {
        flex-direction: row;
        align-items: baseline;
        justify-content: space-between;
        gap: 32px;
    }
}

/* Source order on the detail page is main → price box → process, so a phone
   meets the price and the call to action before the four steps. On a wide
   screen the price box moves into a rail spanning both rows. */
@media (min-width: 900px) {
    .vp-detail__grid {
        grid-template-columns: minmax(0, 1fr) 330px;
    }

    .vp-detail__main {
        grid-column: 1;
        grid-row: 1;
    }

    .vp-detail__rail {
        position: sticky;
        top: 32px;
        grid-column: 2;
        grid-row: 1 / span 2;
    }

    .vp-detail__process {
        grid-column: 1;
        grid-row: 2;
    }
}

@media (max-width: 560px) {
    .vp-body {
        --vp-shell-w: min(100% - 32px, 1360px);
    }

    .vp-band--tall {
        min-height: 390px;
    }

    .vp-wordmark {
        font-size: 24px;
    }

    .vp-nav {
        width: 100%;
        justify-content: space-between;
        gap: 14px;
    }

    .vp-nav a {
        font-size: 15px;
    }

    .vp-nav__cta {
        font-size: 14px;
    }

    .vp-intro h1,
    .vp-band--tall .vp-intro h1 {
        font-size: 40px;
    }

    .vp-intro p {
        font-size: 15px;
    }

    .vp-product,
    .vp-product:nth-child(even),
    .vp-products--single .vp-product,
    .vp-products--single .vp-product:nth-child(even) {
        min-height: 486px;
    }

    .vp-product__meta {
        padding-top: 45px;
    }

    .vp-product__meta p {
        padding-left: 40px;
        font-size: 15px;
    }

    .vp-product__action {
        margin-top: 32px;
    }

    .vp-priceline strong {
        font-size: 29px;
    }

    .vp-orientation {
        padding-block: 20px;
        align-items: flex-start;
        flex-direction: column;
    }

    .vp-account {
        gap: 10px;
    }

    .vp-account__email {
        max-width: 18ch;
        font-size: 13px;
    }

    /* Below 560px the dialog becomes a bottom sheet: full width, pinned to
       the bottom edge by an auto top margin, entering from below. */
    dialog.vp-modal {
        width: 100%;
        max-width: 100%;
        max-height: 92dvh;
        margin: 0 auto;
        margin-block-start: auto;
        padding: 48px 22px 28px;
        border-radius: 4px 4px 0 0;
    }

    @starting-style {
        dialog.vp-modal[open] {
            opacity: 0;
            transform: translateY(100%);
        }
    }

    .vp-modal h2 {
        font-size: 28px;
    }

    .vp-modal__actions,
    .vp-scope-facts {
        align-items: stretch;
        flex-direction: column;
    }

    .vp-modal__actions .vp-button {
        width: 100%;
    }

    .vp-modal__actions .vp-button--ghost {
        order: 2;
    }

    .vp-scope-facts {
        gap: 12px;
    }

    .vp-request__link {
        gap: 10px;
    }

    .vp-summary {
        grid-template-columns: minmax(0, 1fr);
    }
}

/* == reduced motion ==================================================== */

@media (prefers-reduced-motion: reduce) {
    .vp-wordmark,
    .vp-nav a,
    .vp-nav a::after,
    .vp-account__logout,
    .vp-cta,
    .vp-cta svg,
    .vp-button,
    .vp-button svg,
    .vp-textlink,
    .vp-orientation a,
    .vp-orientation svg,
    .vp-product__copy h2 a,
    .vp-breadcrumb a,
    .vp-footer__nav a,
    .vp-field input,
    .vp-scope-option,
    .vp-scope-radio,
    .vp-modal__close,
    dialog.vp-modal,
    dialog.vp-modal::backdrop {
        transform: none !important;
        transition-property: color, background-color, border-color, opacity, box-shadow;
        transition-duration: 100ms;
    }

    .vp-nav a.is-active::after,
    .vp-nav a[aria-current]::after,
    .vp-nav__cta::after {
        transform: scaleX(1) !important;
    }

    .vp-skip {
        transition: none;
    }

    /* The entry animations lose their travel; only the fade remains. */
    @starting-style {
        dialog.vp-modal[open] {
            opacity: 0;
            transform: none;
        }

        dialog.vp-modal[open]::backdrop {
            opacity: 0;
        }
    }

    dialog.vp-modal[data-closing] {
        transform: none !important;
        transition-duration: 100ms;
    }
}
