/* * Public booking page. * * The customer's appearance settings come as CSS variables in style attributes * (Colors::style in src/backend/color.rs, Appearance::banner_style in src/backend/data.rs), * so nothing here is generated. The rules are scoped by .public-page, which wraps the public * route and the preview in the appearance settings; the admin portal keeps its own colours. * They override the colours that the vendor template hard-codes, and they set everything * that assets/css/dark.css sets, so the preview looks the same in both admin themes. ******************************************************************************/ .public-page { --rz-primary: #696cff; --rz-bg: #f5f5f9; --rz-card: #ffffff; --rz-text: #566a7f; --rz-on-primary: #ffffff; --rz-scheme: light; /* Shades derived from the settings */ --rz-body: color-mix(in srgb, var(--rz-text) 89%, var(--rz-card)); --rz-muted: color-mix(in srgb, var(--rz-text) 50%, var(--rz-card)); --rz-border: color-mix(in srgb, var(--rz-text) 22%, var(--rz-card)); --rz-primary-hover: color-mix(in srgb, var(--rz-primary) 90%, var(--rz-on-primary)); --rz-primary-shadow: color-mix(in srgb, var(--rz-primary) 40%, transparent); min-height: 100vh; color: var(--rz-body); background-color: var(--rz-bg); color-scheme: var(--rz-scheme); } /* Preview in the appearance settings */ .public-page.public-preview { min-height: 0; border: 1px solid var(--rz-border); border-radius: 0.5rem; overflow: hidden; } /* Typography */ .public-page h1, .public-page h2, .public-page h3, .public-page h4, .public-page h5, .public-page h6 { color: var(--rz-text); } .public-page a { color: var(--rz-primary); } .public-page a:hover { color: var(--rz-primary-hover); } /* Cards and dialogs */ .public-page .card { background-color: var(--rz-card); border-color: var(--rz-border); box-shadow: 0 2px 6px 0 rgba(67, 89, 113, 0.12); } .public-page .modal-content { color: var(--rz-body); background-color: var(--rz-card); box-shadow: 0 2px 20px 0 rgba(67, 89, 113, 0.45); } /* Forms */ .public-page .form-label, .public-page .form-check-label { color: var(--rz-text); } .public-page .form-control { color: var(--rz-body); background-color: var(--rz-card); border-color: var(--rz-border); } .public-page .form-control::placeholder { color: var(--rz-muted); } .public-page .form-control:focus { color: var(--rz-body); background-color: var(--rz-card); border-color: var(--rz-primary); box-shadow: 0 0 0.25rem 0.05rem color-mix(in srgb, var(--rz-primary) 10%, transparent); } .public-page .form-check-input:not(:checked) { background-color: var(--rz-card); border-color: var(--rz-border); } .public-page .form-check-input:focus { border-color: var(--rz-primary); box-shadow: 0 2px 4px 0 var(--rz-primary-shadow); } .public-page .form-check-input:checked { background-color: var(--rz-primary); border-color: var(--rz-primary); box-shadow: 0 2px 4px 0 var(--rz-primary-shadow); } /* Buttons */ .public-page .btn-primary { color: var(--rz-on-primary); background-color: var(--rz-primary); border-color: var(--rz-primary); box-shadow: 0 0.125rem 0.25rem 0 var(--rz-primary-shadow); } .public-page .btn-primary:hover, .public-page .btn-primary:focus { color: var(--rz-on-primary); background-color: var(--rz-primary-hover); border-color: var(--rz-primary-hover); } .public-page .btn-outline-secondary { color: var(--rz-body); border-color: var(--rz-muted); } .public-page .btn-outline-secondary:hover, .public-page .btn-outline-secondary:focus { color: var(--rz-card); background-color: var(--rz-body); border-color: var(--rz-body); } /* Time slots: a hidden checkbox followed by its label */ .public-page .btn-outline-primary { color: var(--rz-primary); border-color: var(--rz-primary); background: transparent; } .public-page .btn-outline-primary:hover, .public-page .btn-check:checked + .btn-outline-primary { color: var(--rz-on-primary); background-color: var(--rz-primary); border-color: var(--rz-primary); box-shadow: 0 0.125rem 0.25rem 0 var(--rz-primary-shadow); } .public-page .btn-check:focus + .btn-outline-primary { border-color: var(--rz-primary-hover); } /* Captcha */ .public-page .leptos-captcha { color: var(--rz-body); } /* Banner: the image (or a strip in the primary colour) with an optional logo and the title. The fallbacks are for the form embedded in the admin portal, outside of .public-page. */ .public-banner { --rz-banner-current-height: var(--rz-banner-height, 100px); display: flex; align-items: center; justify-content: var(--rz-banner-justify, flex-start); gap: 1rem; height: var(--rz-banner-current-height); padding: 0 30px; overflow: hidden; background-color: var(--rz-primary, #696cff); background-image: linear-gradient(rgba(0, 0, 0, var(--rz-banner-dim, 0)), rgba(0, 0, 0, var(--rz-banner-dim, 0))), var(--rz-banner-image, none); background-size: cover; background-position: var(--rz-banner-position, center); } .public-banner-logo { flex: none; height: calc(var(--rz-banner-current-height) * 0.6); max-width: 40%; object-fit: contain; } /* Two classes, to win over the heading colour above */ .public-banner .public-banner-title { min-width: 0; margin: 0; font-size: x-large; color: var(--rz-banner-title, #ffffff); text-shadow: 0 1px 3px rgba(0, 0, 0, 0.35); } .public-banner-text { padding: 10px; } @media (min-width: 1200px) { .public-banner { --rz-banner-current-height: var(--rz-banner-height-wide, 200px); } .public-banner .public-banner-title { font-size: xxx-large; } } /* The preview is narrow whatever the width of the window. Clicking into its banner sets the part of the image that stays visible, the mark shows it. */ .public-preview .public-banner { --rz-banner-current-height: var(--rz-banner-height, 100px); position: relative; cursor: crosshair; } .public-preview .public-banner .public-banner-title { font-size: x-large; } .public-banner-focus { position: absolute; width: 14px; height: 14px; border: 2px solid #ffffff; border-radius: 50%; box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.6); transform: translate(-50%, -50%); pointer-events: none; }