/* ==========================================================================
   RealVelach common styles
   One palette for the whole site: black page, white content cards, one red.
   Buttons and form controls are themed through MDB's own CSS variables, so
   hover / focus / active states never fall back to MDB's green or blue.
   ========================================================================== */

:root {
    /* The accent and the page: the colour theme («Системные настройки» → «Интерфейс», service/theme). These values are
       the classic theme, red on black; another theme redefines them in a <style> of the page (Palette.css), and
       PaletteTest keeps them equal to Palette.CLASSIC. */
    --rv-accent: #d32f2f;
    --rv-accent-rgb: 211, 47, 47;
    --rv-accent-hover: #b71c1c;
    --rv-accent-active: #8e1515;
    --rv-accent-on-dark: #ff6b6b;         /* the accent as text or outline on the page's colour (navbar, footers) */
    --rv-accent-on-dark-rgb: 255, 107, 107;
    --rv-page-bg: #000;
    --rv-page-bg-rgb: 0, 0, 0;
    --rv-surface-dark: #161616;

    /* The brand's pictures (fragments/brand.html: the navbar's logo, the landing's hero; GRAPHIC_DESIGN.md «Brand
       pictures»): the red and the dark of the pictures they were drawn from. A theme with «Логотип и значок в цветах
       темы» redefines them (Palette.Brand); PaletteTest keeps these equal to Palette.Brand.CLASSIC. */
    --rv-brand: #e6393b;
    --rv-brand-ground: #16171c;
    --rv-logo-edge: #7f1011;              /* the logo's flat shadow edge: the red at half its lightness */

    /* The signal red: errors, «Занят», conflicts, deletes. Never themed: a blue theme still warns in red. */
    --rv-danger: #d32f2f;
    --rv-danger-rgb: 211, 47, 47;
    --rv-danger-hover: #b71c1c;
    --rv-danger-active: #8e1515;
    --rv-danger-tint: rgba(var(--rv-danger-rgb), .08);
    --rv-danger-tint-strong: rgba(var(--rv-danger-rgb), .16);
    --rv-danger-text: var(--rv-danger);
    --rv-danger-text-hover: var(--rv-danger-hover);
    --rv-danger-text-active: var(--rv-danger-active);

    --rv-card-bg: #fff;
    --rv-text: #262626;
    --rv-text-muted: #5c636a;      /* 6:1 on white, at least 4.5:1 on the light greys and red tints of the app */
    --rv-border: #dee2e6;
    /* Roles without a value here (--rv-subtle-bg, --rv-line, --rv-text-2, --rv-text-faint, --rv-other-bg and
       --rv-ok/warn/danger/info-fg/bg/line, --rv-ai-fg) are used as var(--rv-role, #its light colour): the light look keeps
       each place's own shade, the dark mode below sets the role once. */

    /* MDB's body font (Roboto, assets/css/fonts.css), with system fonts of the same kind while it loads */
    --mdb-font-roboto: "Roboto", system-ui, -apple-system, "Segoe UI", "Helvetica Neue", Arial, sans-serif;

    --rv-radius: .5rem;
    --rv-navbar-height: 4rem;
}

/* ---------- Dark mode of the console ----------
   The staff's choice (navbar: Светлая / Тёмная / Как в системе, velach.js), only on /admin pages: layout.html sets
   data-mdb-theme="dark" on <html>, MDB turns its own parts (forms, tables, pop-ups, menus) dark and these blocks the app's
   tokens. */
:root[data-mdb-theme=dark] {
    --rv-text: #e6e6e6;
    --rv-text-2: #c9cdd1;
    --rv-text-muted: #a8aeb4;      /* 7:1 on the dark card */
    --rv-text-faint: #868c92;
    --rv-other-bg: #5a6068;

    --rv-danger-tint: rgba(var(--rv-danger-rgb), .2);
    --rv-danger-tint-strong: rgba(var(--rv-danger-rgb), .34);
    --rv-danger-text: #ff6b6b;
    --rv-danger-text-hover: #ff9a9a;
    --rv-danger-text-active: #ff6b6b;

    --rv-ok-fg: #7ad48a;
    --rv-ok-bg: rgba(46, 125, 50, .24);
    --rv-ok-line: #4caf50;
    --rv-warn-fg: #f2c45a;
    --rv-warn-bg: rgba(250, 178, 25, .16);
    --rv-warn-line: #d9a21b;
    --rv-danger-fg: #ff8a80;
    --rv-danger-bg: rgba(211, 47, 47, .2);
    --rv-danger-line: #e57373;
    --rv-info-fg: #8cb8f2;
    --rv-info-bg: rgba(42, 120, 214, .2);
    --rv-info-line: #4a86d0;
    --rv-ai-fg: #c4b5fd;
    --rv-ai: #c4b5fd;
    --rv-ai-tint: rgba(124, 58, 237, .22);
    --rv-ai-border: #7c5cd6;

    /* MDB's own surfaces (pop-ups, menus, inputs) in the colours of the cards */
    --mdb-body-color: var(--rv-text);
    --mdb-surface-bg: var(--rv-card-bg);
    --mdb-surface-color: var(--rv-text);
    --mdb-border-color: var(--rv-border);
}

/* Tokens made of the theme's two colours. Also on the preview of «Цвета сайта» (settings.html), which sets the picked
   colours on itself: a custom property is worked out where it is declared, so these are declared there again. */
:root, .theme-preview {
    --rv-accent-tint: rgba(var(--rv-accent-rgb), .08);
    --rv-accent-tint-strong: rgba(var(--rv-accent-rgb), .16);
    /* the accent as the colour of text: the same in light mode, lighter on the dark cards of the dark mode */
    --rv-accent-text: var(--rv-accent);
    --rv-accent-text-hover: var(--rv-accent-hover);
    --rv-accent-text-active: var(--rv-accent-active);
}

:root[data-mdb-theme=dark], [data-mdb-theme=dark] .theme-preview {
    /* the cards take a shade of the theme's page colour, so a blue theme gets bluish dark cards */
    --rv-card-bg: color-mix(in srgb, var(--rv-page-bg), #fff 11%);
    --rv-subtle-bg: color-mix(in srgb, var(--rv-page-bg), #fff 16%);
    --rv-border: color-mix(in srgb, var(--rv-page-bg), #fff 26%);
    --rv-line: color-mix(in srgb, var(--rv-page-bg), #fff 22%);
    --rv-accent-tint: rgba(var(--rv-accent-rgb), .2);
    --rv-accent-tint-strong: rgba(var(--rv-accent-rgb), .34);
    --rv-accent-text: var(--rv-accent-on-dark);
    --rv-accent-text-hover: color-mix(in srgb, var(--rv-accent-on-dark), #fff 30%);
    --rv-accent-text-active: var(--rv-accent-on-dark);
}

[data-mdb-theme=dark] .rc {
    --rc-free-bg: var(--rv-card-bg);
    --rc-busy-past: var(--rv-subtle-bg);
    --rc-closed: repeating-linear-gradient(-45deg, var(--rv-subtle-bg) 0 6px, var(--rv-card-bg) 6px 12px);
    --rc-past: rgba(0, 0, 0, .35);
}

[data-mdb-theme=dark] .doodle { --doodle-pale: rgba(255, 255, 255, .05); }

/* ---------- Page ---------- */

body {
    background-color: var(--rv-page-bg);
    color: var(--rv-text);
}

main {
    padding-top: calc(var(--rv-navbar-height) + 1.5rem);
    padding-bottom: 3rem;
}

/* The landing page starts with a full width carousel instead of the fixed navbar offset */
main.landing-main {
    padding-top: 2rem;
}

a {
    color: var(--rv-accent-text);
}

a:hover, a:focus {
    color: var(--rv-accent-text-hover);
}

/* White content card used on every page */
#main-info, .main-info {
    background: var(--rv-card-bg) !important;
    border-radius: var(--rv-radius);
}

/* Page title row: title on the left, page actions on the right */
.page-header {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: .75rem;
    margin-bottom: 1.5rem;
}

.page-header h1 {
    margin-bottom: 0;
}

/* A few sentences under the title of a page: what it is for and when to use it */
.page-intro {
    max-width: 52rem;
    margin: -.75rem 0 1.25rem;
    color: var(--rv-text-muted);
}

.page-intro p {
    margin-bottom: .5rem;
}

.page-intro p:last-child {
    margin-bottom: 0;
}

.page-lead {
    color: var(--rv-text-muted);
    margin-top: -.75rem;
    margin-bottom: 1.5rem;
}

/* ---------- Buttons ---------- */

.velach-btn {
    --mdb-btn-bg: var(--rv-accent);
    --mdb-btn-color: #fff;
    --mdb-btn-border-color: var(--rv-accent);
    --mdb-btn-hover-bg: var(--rv-accent-hover);
    --mdb-btn-hover-color: #fff;
    --mdb-btn-hover-border-color: var(--rv-accent-hover);
    --mdb-btn-focus-bg: var(--rv-accent-hover);
    --mdb-btn-focus-color: #fff;
    --mdb-btn-active-bg: var(--rv-accent-active);
    --mdb-btn-active-color: #fff;
    --mdb-btn-active-border-color: var(--rv-accent-active);
    --mdb-btn-disabled-bg: var(--rv-accent);
    --mdb-btn-disabled-color: #fff;
    --mdb-btn-disabled-border-color: var(--rv-accent);
    --mdb-btn-box-shadow: 0 4px 9px -4px rgba(var(--rv-accent-rgb), .45);
    --mdb-btn-hover-box-shadow: 0 8px 9px -4px rgba(var(--rv-accent-rgb), .3), 0 4px 18px 0 rgba(var(--rv-accent-rgb), .2);
    --mdb-btn-focus-box-shadow: var(--mdb-btn-hover-box-shadow);
    --mdb-btn-active-box-shadow: var(--mdb-btn-hover-box-shadow);
    background-color: var(--mdb-btn-bg);
    border-color: var(--mdb-btn-border-color);
    color: var(--mdb-btn-color);
    box-shadow: var(--mdb-btn-box-shadow);
}

.velach-btn:hover, .velach-btn:focus-visible {
    background-color: var(--mdb-btn-hover-bg);
    border-color: var(--mdb-btn-hover-border-color);
    color: var(--mdb-btn-hover-color);
    box-shadow: var(--mdb-btn-hover-box-shadow);
}

.velach-btn:focus {
    background-color: var(--mdb-btn-focus-bg);
    color: var(--mdb-btn-focus-color);
}

.velach-btn:active, .velach-btn.active {
    background-color: var(--mdb-btn-active-bg);
    border-color: var(--mdb-btn-active-border-color);
    color: var(--mdb-btn-active-color);
}

.velach-outline-btn {
    --mdb-btn-bg: transparent;
    --mdb-btn-color: var(--rv-accent-text);
    --mdb-btn-border-color: var(--rv-accent);
    --mdb-btn-hover-bg: var(--rv-accent-tint);
    --mdb-btn-hover-color: var(--rv-accent-text-hover);
    --mdb-btn-hover-border-color: var(--rv-accent-hover);
    --mdb-btn-focus-bg: var(--rv-accent-tint);
    --mdb-btn-focus-color: var(--rv-accent-text-hover);
    --mdb-btn-active-bg: var(--rv-accent-tint-strong);
    --mdb-btn-active-color: var(--rv-accent-text-active);
    --mdb-btn-active-border-color: var(--rv-accent-active);
    --mdb-btn-outline-border-color: var(--rv-accent);
    --mdb-btn-outline-hover-border-color: var(--rv-accent-hover);
    --mdb-btn-outline-focus-border-color: var(--rv-accent-hover);
    --mdb-btn-outline-active-border-color: var(--rv-accent-active);
    --mdb-btn-box-shadow: none;
    --mdb-btn-hover-box-shadow: none;
    --mdb-btn-focus-box-shadow: 0 0 0 .2rem rgba(var(--rv-accent-rgb), .2);
    --mdb-btn-active-box-shadow: none;
    background-color: var(--mdb-btn-bg);
    color: var(--mdb-btn-color);
    border: 2px solid var(--mdb-btn-border-color);
}

.velach-outline-btn:hover, .velach-outline-btn:focus-visible {
    background-color: var(--mdb-btn-hover-bg);
    border-color: var(--mdb-btn-hover-border-color);
    color: var(--mdb-btn-hover-color);
}

.velach-outline-btn:focus {
    background-color: var(--mdb-btn-focus-bg);
    color: var(--mdb-btn-focus-color);
}

.velach-outline-btn:active, .velach-outline-btn.active {
    background-color: var(--mdb-btn-active-bg);
    border-color: var(--mdb-btn-active-border-color);
    color: var(--mdb-btn-active-color);
}

/* Selected state of a group of outline buttons, e.g. the chart selector in the console */
.velach-outline-btn.active {
    background-color: var(--rv-accent);
    border-color: var(--rv-accent);
    color: #fff;
}

/* Same outline style on a dark background (navbar, landing) */
.velach-outline-btn.on-dark {
    --mdb-btn-color: var(--rv-accent-on-dark);
    --mdb-btn-border-color: var(--rv-accent-on-dark);
    --mdb-btn-hover-bg: rgba(var(--rv-accent-on-dark-rgb), .15);
    --mdb-btn-hover-color: #fff;
    --mdb-btn-hover-border-color: var(--rv-accent-on-dark);
    --mdb-btn-focus-bg: rgba(var(--rv-accent-on-dark-rgb), .15);
    --mdb-btn-focus-color: #fff;
    --mdb-btn-active-bg: rgba(var(--rv-accent-on-dark-rgb), .25);
    --mdb-btn-active-color: #fff;
    --mdb-btn-active-border-color: var(--rv-accent-on-dark);
}

/* Destructive actions: delete buttons in the tables and on detail pages */
.velach-danger-btn {
    --mdb-btn-bg: transparent;
    --mdb-btn-color: var(--rv-danger-text-active);
    --mdb-btn-hover-bg: var(--rv-danger-active);
    --mdb-btn-hover-color: #fff;
    --mdb-btn-focus-bg: var(--rv-danger-active);
    --mdb-btn-focus-color: #fff;
    --mdb-btn-active-bg: #6d0f0f;
    --mdb-btn-active-color: #fff;
    --mdb-btn-box-shadow: none;
    --mdb-btn-hover-box-shadow: none;
    --mdb-btn-focus-box-shadow: 0 0 0 .2rem rgba(var(--rv-danger-rgb), .25);
    --mdb-btn-active-box-shadow: none;
    background-color: var(--mdb-btn-bg);
    color: var(--mdb-btn-color);
    border: 2px solid var(--rv-danger-active);
}

.velach-danger-btn:hover, .velach-danger-btn:focus, .velach-danger-btn:focus-visible {
    background-color: var(--mdb-btn-hover-bg);
    border-color: var(--rv-danger-active);
    color: var(--mdb-btn-hover-color);
}

.velach-danger-btn:active {
    background-color: var(--mdb-btn-active-bg);
    color: #fff;
}

/* Small square icon buttons in table rows (edit / delete) */
.btn-icon {
    min-width: 2.5rem;
    padding: .375rem .625rem;
}

.table-actions {
    display: flex;
    flex-wrap: wrap;
    gap: .375rem;
}

.table-actions form {
    margin: 0;
}

/* ---------- Forms ---------- */

/* ==========================================================================
   Compact add / change forms (GRAPHIC_DESIGN.md, "Forms that add or change a record"):
   the page, its form and its context fit a 1366x650 browser window without scrolling.

   <main class="container compact-page">  … <h1> and actions in .page-header
   <form class="form-compact form-columns">      two columns from 992px: fields + buttons | rows / context
       <div class="form-main"> .field / .field-row … <div class="form-buttons"> </div>
       <div class="form-side"> sections of rows, attributes, a calendar </div>
   ========================================================================== */

.compact-page { padding-top: calc(var(--rv-navbar-height) + .75rem); padding-bottom: 1rem; }
.compact-page .page-header { margin-bottom: .75rem; }
.compact-page .page-header h1 { font-size: 1.6rem; }

.form-compact {
    display: flex;
    flex-direction: column;
    gap: .6rem;
}

.form-compact .form-control, .form-compact .form-select { padding-top: .3rem; padding-bottom: .3rem; }
.form-compact .input-group-text { padding-top: .3rem; padding-bottom: .3rem; }

/* A field: its label above, a hint below */
.field { min-width: 0; }

.field-label {
    display: block;
    margin-bottom: .2rem;
    font-size: .72rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: .04em;
    color: var(--rv-text-muted);
}

.field-hint {
    margin: .2rem 0 0;
    font-size: .8rem;
    color: var(--rv-text-muted);
}

/* The order form's suggestion of the usual brand spelling (add_service.js): noticed, but never in the way */
.brand-hint { color: var(--rv-info-fg, #184f95); }
.brand-hint[hidden] { display: none; }
.brand-hint .btn-link { font-size: inherit; text-transform: none; }

/* Fields side by side, wrapping on a narrow screen */
.field-row {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(9.5rem, 1fr));
    gap: .5rem;
}

.field-row[hidden], .field[hidden] { display: none; }

/* Fields and buttons on the left, rows or context on the right; one column below 992px with the buttons last */
.form-columns {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    grid-template-areas: "main" "side" "buttons";
    gap: .6rem 1.75rem;
    align-items: start;
}

.form-columns > .form-main { grid-area: main; display: flex; flex-direction: column; gap: .6rem; }
.form-columns > .form-side { grid-area: side; display: flex; flex-direction: column; gap: .6rem; min-width: 0; }
.form-columns > .form-buttons { grid-area: buttons; }

@media (min-width: 992px) {
    .form-columns {
        grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
        grid-template-areas: "main side" "buttons side";
        grid-template-rows: auto 1fr;
    }
    .form-columns.side-wide { grid-template-columns: minmax(0, 23rem) minmax(0, 1fr); }
    /* A long list of rows scrolls inside its column, so the form's fields and buttons stay on the screen */
    .form-columns > .form-side.scroll {
        max-height: calc(100vh - var(--rv-navbar-height) - 8.5rem);
        overflow-y: auto;
        padding-right: .25rem;
    }
}

.form-buttons { display: flex; flex-wrap: wrap; align-items: center; gap: .5rem; }
.form-buttons .form-error:empty { display: none; }

/* Summary box: what will be saved, in words, right above the buttons (the rent form, the price list editor) */
.rent-summary {
    padding: .45rem .75rem;
    border-radius: var(--rv-radius);
    background: var(--rv-subtle-bg, #f7f8f9);
    border-left: 4px solid var(--rv-border);
    font-size: .9rem;
}

.rent-summary.ok { border-left-color: var(--rv-ok-fg, #2e7d32); }
.rent-summary.warn { border-left-color: var(--rv-danger); background: var(--rv-danger-tint); }

.rent-summary-main { font-weight: 600; font-variant-numeric: tabular-nums; }
.rent-summary-sub { display: block; font-size: .8rem; color: var(--rv-text-muted); }

/* A form filled from an unsaved draft (velach.js, "drafts"): one line above the buttons, red when the record changed since */
.draft-bar {
    flex-basis: 100%;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .25rem .6rem;
    padding: .35rem .6rem;
    border-radius: var(--rv-radius);
    border-left: 4px solid var(--rv-border);
    background: var(--rv-subtle-bg, #f7f8f9);
    font-size: .85rem;
}
.draft-bar > i { color: var(--rv-text-muted); }
.draft-bar.warn { border-left-color: var(--rv-danger); background: var(--rv-danger-tint); }
.draft-bar.warn > i { color: var(--rv-danger-text); }
.draft-bar-text { flex: 1 1 14rem; }
.draft-bar .btn { padding: .15rem .6rem; }

/* A group of rows (works, parts, attributes): its title and an add button with a text */
.rows-section { display: flex; flex-direction: column; gap: .35rem; }

.rows-section-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: .5rem;
    padding-bottom: .25rem;
    border-bottom: 1px solid var(--rv-border);
}

.rows-section-head .field-label { margin: 0; }

.rows-add {
    padding: .15rem .6rem;
    border: 1px solid var(--rv-accent);
    border-radius: 2rem;
    background: var(--rv-card-bg);
    color: var(--rv-accent-text);
    font-size: .78rem;
    line-height: 1.3;
    cursor: pointer;
}

.rows-add:hover, .rows-add:focus-visible { background: var(--rv-accent-tint); }

/* "No rows yet": the text of data-empty while the list has no row */
[data-rows][data-empty]:not(:has([data-row]))::before {
    content: attr(data-empty);
    display: block;
    padding: .2rem 0;
    font-size: .8rem;
    color: var(--rv-text-muted);
}

/* Choice buttons: radios or checkboxes that look like chips (statuses, roles) */
.chips { display: flex; flex-wrap: wrap; gap: .3rem; }

.chip {
    display: inline-flex;
    align-items: center;
    gap: .3rem;
    margin: 0;
    padding: .3rem .75rem;
    border: 1px solid var(--rv-border);
    border-radius: 2rem;
    background: var(--rv-card-bg);
    color: var(--rv-text);
    font-size: .85rem;
    line-height: 1.3;
    cursor: pointer;
    transition: border-color .15s, background-color .15s, color .15s;
}

.chip:hover { border-color: var(--rv-accent); color: var(--rv-accent-text); }
.chip:has(input:checked) { background: var(--rv-accent); border-color: var(--rv-accent); color: #fff; }
.chip:has(input:focus-visible) { outline: 2px solid var(--rv-accent-tint-strong); outline-offset: 1px; }
.chip input { position: absolute; opacity: 0; width: 1px; height: 1px; pointer-events: none; }

/* A photo: the current one (or the new one, drawn by preprocess_img.js) next to the file input */
.image-field {
    display: grid;
    grid-template-columns: 4.5rem minmax(0, 1fr);
    align-items: center;
    gap: .6rem;
}

.image-preview {
    width: 4.5rem;
    height: 3.5rem;
    border: 1px solid var(--rv-border);
    border-radius: var(--rv-radius);
    background: var(--rv-subtle-bg, #f7f8f9);
    display: flex;
    align-items: center;
    justify-content: center;
    overflow: hidden;
    color: var(--rv-text-muted);
}

.image-preview img, .image-preview canvas { max-width: 100%; max-height: 100%; object-fit: contain; }
.image-preview canvas { width: auto !important; height: 100% !important; }
.image-preview:has(canvas) .image-current, .image-preview:has(canvas) .image-none,
.image-preview:has(img) .image-none { display: none; }

/* The editor of the landing page's texts: one card per section, the cards in columns */
.landing-sections { columns: 4 15rem; column-gap: .75rem; }
.landing-tabs { margin-bottom: .5rem; }
.landing-tabs .nav-link { padding: .4rem .9rem; font-size: .75rem; }

.landing-section {
    break-inside: avoid;
    margin: 0 0 .6rem;
    padding: .35rem .65rem .5rem;
    border: 1px solid var(--rv-border);
    border-radius: var(--rv-radius);
}

.landing-section legend { float: none; width: auto; margin: 0 0 .25rem; padding: 0; }
.landing-section .field + .field { margin-top: .3rem; }
.landing-section label { margin-bottom: .1rem !important; }
/* A photo of the landing in its section of «Главная страница» (admin/landing_images.js) */
.landing-image { break-inside: avoid; }
.landing-image-preview { display: block; width: 100%; height: 6.5rem; object-fit: cover; border-radius: var(--rv-radius); background: var(--rv-subtle-bg, #f1f3f5); }
.landing-image-preview[hidden] { display: none; }
.landing-image-drawing { position: relative; overflow: hidden; background: var(--rv-brand-ground); }
.landing-image-drawing .hero-art { position: absolute; inset: 0; width: 100%; height: 100%; filter: brightness(.7); }
.landing-image-actions { display: flex; flex-wrap: wrap; gap: .4rem; margin-top: .4rem; }
.landing-section textarea { resize: vertical; }

/* A simple form (a few fields, no rows): not wider than it needs to be */
.form-narrow { max-width: 38rem; }

/* Rows (works, parts, parameters) in a compact form: tighter than in .form-stack */
.form-compact .form-row-inline { gap: .35rem; margin-bottom: .3rem; }
.form-compact .form-row-inline > .form-control.narrow { flex: 0 1 5.5rem; }
.form-compact .form-row-inline > .row-number { min-width: 1.25rem; font-size: .85rem; }
.form-compact .form-row-group .form-error:empty { display: none; }
.form-compact .attribute-row { padding: .4rem 0; }
.form-compact .attribute-row .form-row-inline { margin-bottom: 0; }

/* Parameters of a part's category: a grid of labelled fields */
.attribute-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(11rem, 1fr));
    gap: .5rem .75rem;
    align-content: start;
}

.attribute-grid .form-data-input { margin: 0; }
.attribute-grid .attribute-error:empty { display: none; }
.attribute-grid[data-empty]::before {
    content: attr(data-empty);
    grid-column: 1 / -1;
    font-size: .8rem;
    color: var(--rv-text-muted);
}

/* Vertical form: one field per row, the same gap everywhere */
.form-stack {
    display: flex;
    flex-direction: column;
    align-items: stretch;
    gap: .625rem;
    max-width: 40rem;
}

.form-stack > .btn, .form-stack > div > .btn {
    align-self: flex-start;
    margin-top: .5rem;
}

.form-stack .form-data-input {
    margin: 0;
}

/* A row of inputs that belong together, e.g. one service line: description, price, remove button */
.form-row-inline {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .5rem;
    margin-bottom: .5rem;
}

.form-row-inline > .form-control {
    flex: 1 1 10rem;
    width: auto;
    /* an input's default minimum width is its text size, which kept the "narrow" price fields as wide as the others */
    min-width: 0;
}

.form-row-inline > .form-control.narrow {
    flex: 0 1 7rem;
}

.form-row-inline > .row-number {
    min-width: 1.75rem;
    color: var(--rv-text-muted);
}

/* "Услуги +", "Материалы +", "Расходы +" section headers on the service form */
.form-section-header {
    display: flex;
    align-items: center;
    gap: .75rem;
    margin: 1.25rem 0 .5rem;
    font-weight: 600;
}

.form-section-header .btn {
    margin: 0;
}

.form-data-input {
    margin: .4rem 0;
}

.form-control:focus, .form-select:focus {
    border-color: var(--rv-accent);
    box-shadow: 0 0 0 .2rem rgba(var(--rv-accent-rgb), .18);
}

.form-check-input:checked,
.form-check-input[type=checkbox]:checked,
.form-check-input[type=checkbox]:checked:focus,
.form-check-input:checked:focus {
    background-color: var(--rv-accent);
    border-color: var(--rv-accent);
}

.form-check-input:checked:focus:before {
    box-shadow: 0 0 0 13px var(--rv-accent);
}

.form-check-input:focus {
    border-color: var(--rv-accent);
    box-shadow: 0 0 0 .2rem rgba(var(--rv-accent-rgb), .18);
}

.form-check-input[type=radio]:checked:after {
    background-color: var(--rv-accent);
    border-color: var(--rv-accent);
}

.form-check-input[type=radio]:checked,
.form-check-input[type=radio]:checked:focus {
    background-color: var(--rv-card-bg);
}

/* Switches (form-switch), Material's way: a tinted track and a thumb in the accent. Without this the rule above made the
   track solid red while MDB kept its own blue thumb and focus ring. */
.form-switch .form-check-input:checked,
.form-switch .form-check-input[type=checkbox]:checked,
.form-switch .form-check-input[type=checkbox]:checked:focus {
    background-color: var(--rv-accent-tint-strong);
    border-color: transparent;
}

.form-switch .form-check-input:checked[type=checkbox]:after,
.form-switch .form-check-input:valid:checked[type=checkbox]:after {
    background-color: var(--rv-accent);
}

.form-switch .form-check-input:checked:focus:before {
    box-shadow: 3px -1px 0 13px rgba(var(--rv-accent-rgb), .18);
}

/* Error messages under form fields */
.form-error {
    display: block;
    color: var(--rv-danger-text-hover);
    font-size: .875rem;
}

.form-error:empty {
    display: none;
}

/* "Зачем?" / "Как это работает?": a small explanation button in the brand colour, so that it is noticed
   (console panels, the service form). Opens a pop-up with the explanation. */
.why-btn {
    display: inline-flex;
    align-items: center;
    gap: .25rem;
    padding: .1rem .5rem;
    border: 1px solid var(--rv-accent);
    border-radius: 2rem;
    background: var(--rv-card-bg);
    color: var(--rv-accent-text-hover);
    font-size: .75rem;
    font-weight: 600;
    line-height: 1.4;
    white-space: nowrap;
}

.why-btn:hover {
    background: var(--rv-accent);
    color: #fff;
}

/* The pop-up of a "Зачем?" / "Как это работает?" button */

.why-modal .modal-body section + section { margin-top: 1rem; }
.why-modal h6 { font-weight: 700; margin-bottom: .375rem; }
.why-modal h6 i { margin-right: .4rem; }
.why-modal p { margin-bottom: 0; }
.why-modal ul { margin-bottom: 0; padding-left: 1.25rem; }
.why-modal li + li { margin-top: .25rem; }
.why-modal .why-profit h6 i { color: var(--rv-ok-line, #0ca30c); }
.why-modal .why-fields { background: var(--rv-subtle-bg, #f6f6f4); border-radius: var(--rv-radius); padding: .625rem .875rem; }
.why-modal .why-fields h6 i { color: var(--rv-info-fg, #2a78d6); }
.why-modal .why-check h6 i { color: var(--rv-warn-fg, #b07800); }

/* Under a "Материалы" row: a new part's category and the purchase price of a part without purchases */
.part-extra {
    display: flex;
    flex-direction: column;
    gap: .375rem;
    margin: -.25rem 0 .625rem 2.25rem;
    padding: .5rem .75rem;
    border-left: 3px solid var(--rv-accent-tint-strong);
    background: var(--rv-subtle-bg, #fafafa);
    border-radius: 0 var(--rv-radius) var(--rv-radius) 0;
}

.part-extra[hidden] {
    display: none;
}

.part-extra-head {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: .75rem;
}

.part-extra-note {
    font-size: .8125rem;
    color: var(--rv-text-muted);
}

.part-extra-fields {
    display: flex;
    flex-wrap: wrap;
    gap: .5rem;
}

.part-extra-fields > .form-control.narrow {
    flex: 0 1 8rem;
}

.part-extra-fields > .form-select {
    flex: 1 1 14rem;
    width: auto;
    min-width: 0;
}

.part-extra-fields > [hidden] {
    display: none;
}

/* Mechanic, "Принят" and "Готов" of the service form: one row on wide screens */
.service-work-fields {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr));
    gap: .625rem;
}

.service-field {
    display: flex;
    flex-direction: column;
    gap: .2rem;
    margin: 0;
}

.service-field-label {
    font-size: .8125rem;
    color: var(--rv-text-muted);
}

.service-field[hidden] {
    display: none;
}

/* ---------- Tabs, tables, badges ---------- */

.nav-tabs .nav-link.active, .nav-tabs .nav-item.show .nav-link {
    color: var(--rv-accent-text);
    border-color: var(--rv-accent);
}

.nav-tabs .nav-link:hover {
    border-color: var(--rv-accent-tint-strong);
}

.table-hover > tbody > tr:hover > * {
    --mdb-table-bg-state: var(--rv-accent-tint);
    --mdb-table-accent-bg: var(--rv-accent-tint);
}

.status-badge {
    font-size: .8rem;
    font-weight: 600;
    padding: .35em .7em;
}

.status-badge.status-0 { background-color: var(--rv-subtle-bg, #e9ecef); color: var(--rv-text-2, #495057); }   /* accepted */
.status-badge.status-1 { background-color: var(--rv-warn-bg, #fff3cd); color: var(--rv-warn-fg, #7a5a00); }   /* in progress */
.status-badge.status-2 { background-color: var(--rv-ok-bg, #d1e7dd); color: var(--rv-ok-fg, #0f5132); }   /* done */

/* DataTables pagination and inputs in the brand colour */
.dt-paging .dt-paging-button.current,
.dt-paging .dt-paging-button.current:hover,
.dataTables_paginate .paginate_button.current,
.dataTables_paginate .paginate_button.current:hover {
    background: var(--rv-accent) !important;
    border-color: var(--rv-accent) !important;
    color: #fff !important;
}

/* MDB's hint under a field (rgba .75 grey, 4.2:1) in the muted text colour */
.form-text {
    color: var(--rv-text-muted);
}

.text-muted-rv {
    color: var(--rv-text-muted) !important;
}

/* ---------- Images ---------- */

.img-thumbnail {
    height: 10rem;
    margin-left: auto;
    margin-right: auto;
    display: block;
}

.img-text {
    display: grid;
    text-align: center;
}

.img-icon {
    background: transparent !important;
    max-height: 2rem;
    max-width: 2rem;
}

/* ---------- Navbar ---------- */

.velach-navbar {
    background-color: rgba(var(--rv-page-bg-rgb), .7) !important;
    backdrop-filter: blur(8px);
    padding: 0 !important;
    min-height: var(--rv-navbar-height);
}

.velach-navbar .navbar-brand .brand-logo {
    display: block;
    height: var(--rv-navbar-height);
    width: auto;
    aspect-ratio: 600 / 164;       /* the box of the picture it was drawn from */
}

/* ---------- The brand's pictures (fragments/brand.html): their colours are the --rv-brand / --rv-logo tokens ---------- */
.brand-logo { filter: brightness(.9); }   /* flat and a bit shaded, as the hero: full brightness was too loud */
.brand-logo .logo-face, .brand-logo .logo-line { fill: var(--rv-brand); }
.brand-logo .logo-edge { fill: var(--rv-logo-edge); }
.brand-logo .logo-sub { fill: #f4f4f4; }

.hero-art .hr { fill: var(--rv-brand); }
.hero-art .hg { fill: var(--rv-brand-ground); }
.hero-art .hrim { fill: none; stroke-width: 12; }
.hero-art .hrim-stop { stop-color: var(--rv-brand); }
.hero-art .htread { fill: none; stroke-width: 6; }
.hero-art .hshade { fill: none; stroke: #000; stroke-opacity: .28; }
.hero-art .hspokes { fill: none; stroke: var(--rv-brand-ground); stroke-width: 2.2; }
/* the flat parts (design/brand-images/tools/flatparts.py): every tone made of the ground, so a theme's dark tints them too */
.hero-art .hp-body { fill: var(--rv-brand-ground); }
.hero-art .hp-body-dark { fill: color-mix(in srgb, var(--rv-brand-ground), #000 15%); }   /* darker than the ground, as the cut-out */
.hero-art .hp-ridge { fill: color-mix(in srgb, var(--rv-brand-ground), #fff 10%); }
.hero-art .hp-ridge-top { fill: color-mix(in srgb, var(--rv-brand-ground), #fff 22%); }
.hero-art .hp-gloss { fill: color-mix(in srgb, var(--rv-brand-ground), #fff 50%); }

.velach-navbar .nav-link {
    color: rgba(255, 255, 255, .75);
}

.velach-navbar .nav-link:hover, .velach-navbar .nav-link:focus {
    color: #fff;
}

.velach-navbar .nav-link.active {
    color: #fff;
    box-shadow: inset 0 -2px 0 var(--rv-accent);
}

/* The login in the navbar: a pill that opens the personal cabinet (crown, login, gear) */
.velach-navbar .navbar-user {
    display: inline-flex;
    align-items: center;
    gap: .45rem;
    padding: .25rem .7rem .25rem .6rem;
    border: 1px solid rgba(255, 255, 255, .22);
    border-radius: 2rem;
    color: rgba(255, 255, 255, .85);
    font-size: .875rem;
    text-decoration: none;
    transition: background-color .15s, border-color .15s, color .15s;
}

.velach-navbar .navbar-user:hover,
.velach-navbar .navbar-user:focus-visible,
.velach-navbar .navbar-user.active {
    color: #fff;
    border-color: var(--rv-accent);
    background: rgba(var(--rv-accent-rgb), .18);
}

.velach-navbar .navbar-user:focus-visible { outline: 2px solid var(--rv-accent); outline-offset: 2px; }
.velach-navbar .navbar-user-go { font-size: .75rem; opacity: .7; }
.velach-navbar .navbar-user:hover .navbar-user-go { opacity: 1; }

.velach-navbar .navbar-user .fa-crown {
    color: var(--rv-accent-text);
    font-size: 1rem;
}

.velach-navbar .navbar-collapse {
    gap: .75rem;
}

/* The parts search of the admin navbar (layout.html, velach.js): a magnifier that widens into the field in the one-line menu */
.velach-navbar .navbar-search { display: flex; align-items: center; gap: .35rem; margin: 0; }
.velach-navbar .navbar-search-go { margin: 0; padding: .25rem .55rem; line-height: 1.2; flex: 0 0 auto; }
@media (min-width: 992px) {
    /* one line: the login, «Выход» and the magnifier never wrap under the menu */
    .velach-navbar .navbar-tools { flex-wrap: nowrap !important; }
    .velach-navbar .navbar-search { position: relative; z-index: 3; }
    /* the field slides out to the left over the menu, so opening it moves nothing */
    .velach-navbar .navbar-search input {
        position: absolute; right: calc(100% + .35rem); top: 50%; transform: translateY(-50%); z-index: 2;
        width: 0; min-width: 0; padding-left: 0; padding-right: 0; border-color: transparent; opacity: 0; pointer-events: none;
        box-shadow: 0 .25rem 1rem rgba(0, 0, 0, .5);
        transition: width .2s ease, opacity .15s ease, padding .2s ease;
    }
    .velach-navbar .navbar-search.open input,
    .velach-navbar .navbar-search:focus-within input {
        width: min(18rem, 50vw); padding-left: .6rem; padding-right: .6rem; border-color: var(--rv-accent); opacity: 1; pointer-events: auto;
        background-color: var(--rv-card-bg); color: var(--rv-text);
    }
    /* while it is open the login and «Выход» step aside: the field covers only the menu links */
    .velach-navbar .navbar-tools:has(.navbar-search.open, .navbar-search:focus-within) > :not(.navbar-search) { visibility: hidden; }
}
@media (min-width: 992px) and (max-width: 1199.98px) {
    /* small computer screens: the crown pill without the login (its title still names it), smaller gaps */
    .velach-navbar .navbar-user-name { display: none; }
    .velach-navbar .navbar-tools { gap: .5rem !important; }
    .velach-navbar .navbar-nav .nav-link { padding-left: .45rem; padding-right: .45rem; }
}
@media (min-width: 992px) and (prefers-reduced-motion: reduce) {
    .velach-navbar .navbar-search input { transition: none; }
}
@media (max-width: 991.98px) {
    /* the toggled admin menu: the field over its whole width */
    .velach-navbar .navbar-search { width: 100%; }
    .velach-navbar .navbar-search input { flex: 1 1 auto; }
    .velach-navbar.navbar-expand-lg .navbar-collapse { padding: 0 1rem 1rem; }
}

@media (max-width: 767.98px) {
    .velach-navbar .navbar-collapse {
        padding: 0 1rem 1rem;
    }
}

.velach-nav-dropdown {
    background-color: var(--rv-surface-dark);
    border: 1px solid #333;
    padding: .375rem 0;
}

.velach-nav-dropdown .dropdown-item {
    color: rgba(255, 255, 255, .85);
    padding: .5rem 1.25rem;
}

.velach-nav-dropdown .dropdown-item:hover, .velach-nav-dropdown .dropdown-item:focus {
    background-color: rgba(var(--rv-accent-rgb), .25);
    color: #fff;
}

.velach-nav-dropdown .dropdown-item.active {
    background-color: var(--rv-accent);
    color: #fff;
}

/* ---------- Footer (public pages) ---------- */

/* ---------- Admin footer: version and links, in the style of the public footer but one line ---------- */

/* With the admin footer the page is a column, so that the footer stays at the bottom of a short page */
body:has(> footer.admin-footer) {
    display: flex;
    flex-direction: column;
    min-height: 100vh;
}

body:has(> footer.admin-footer) > main {
    flex: 1 0 auto;
    width: 100%;
}

.admin-footer {
    background-color: var(--rv-surface-dark);
    border-top: 3px solid var(--rv-accent);
    color: rgba(255, 255, 255, .6);
    font-size: .8125rem;
    padding: .6rem 0;
}

.admin-footer-inner {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: .5rem 1.5rem;
    max-width: 1920px;
    margin: 0 auto;
    padding: 0 1rem;
}

.admin-footer a {
    color: rgba(255, 255, 255, .85);
    text-decoration: none;
}

.admin-footer a:hover, .admin-footer a:focus-visible {
    color: var(--rv-accent-on-dark);
}

.admin-footer-links {
    display: flex;
    flex-wrap: wrap;
    gap: .25rem 1.25rem;
}

.admin-footer-links i:first-child {
    margin-right: .35rem;
}

.velach-footer {
    background-color: var(--rv-surface-dark);
    color: rgba(255, 255, 255, .75);
    padding: 2.5rem 0 1.5rem;
    border-top: 3px solid var(--rv-accent);
}

.velach-footer h6 {
    color: #fff;
    text-transform: uppercase;
    letter-spacing: .05em;
    margin-bottom: .75rem;
}

.velach-footer a {
    color: rgba(255, 255, 255, .85);
    text-decoration: none;
}

.velach-footer a:hover {
    color: var(--rv-accent-on-dark);
}

.velach-footer .footer-social a {
    font-size: 1.75rem;
    margin-right: .75rem;
}

.velach-footer .footer-copy {
    border-top: 1px solid #2a2a2a;
    margin-top: 1.5rem;
    padding-top: 1rem;
    font-size: .8rem;
    color: rgba(255, 255, 255, .6);
    display: flex;
    flex-wrap: wrap;
    justify-content: space-between;
    gap: .5rem 1.5rem;
}

/* The staff's login: small and quiet, clients don't need it (the navbar has no «Вход» for guests) */
.velach-footer .footer-copy .footer-staff, .velach-footer .footer-copy .footer-privacy { color: rgba(255, 255, 255, .6); }
.velach-footer address { margin-bottom: 0; font-style: normal; }

/* ---------- navbar phone (public pages): next to the logo on a phone, at the right end of the one-line menu ---------- */
.velach-navbar .navbar-phone {
    display: inline-flex;
    align-items: center;
    gap: .45rem;
    margin-left: auto;
    margin-right: .75rem;
    min-height: 2rem;
    color: #fff;
    font-weight: 500;
    white-space: nowrap;
    text-decoration: none;
}

.velach-navbar .navbar-phone i { color: var(--rv-accent-text); }
.velach-navbar .navbar-phone:hover, .velach-navbar .navbar-phone:focus { color: var(--rv-accent-on-dark); }

@media (min-width: 768px) {
    /* after the menu (the public menu is one line from md) */
    .velach-navbar .navbar-phone { order: 1; margin-right: 0; margin-left: 1rem; }
}

/* phones: the logo, the number and the menu button don't fit one line, and a second line of the fixed navbar would cover
   the page's top: only the phone icon there, a round button that calls (the number is on the page, in the hero) */
@media (max-width: 575.98px) {
    .velach-navbar .navbar-phone-number { display: none; }
    .velach-navbar .navbar-phone {
        justify-content: center;
        width: 2.5rem;
        height: 2.5rem;
        border-radius: 50%;
        border: 1px solid rgba(255, 255, 255, .25);
        font-size: 1.1rem;
    }
}

/* 360px phones: the logo is 238px wide, the margins have to give way so the menu button stays on the line */
@media (max-width: 399.98px) {
    .velach-navbar .navbar-brand { margin-right: .25rem; }
    .velach-navbar .navbar-phone { margin-right: .35rem; }
}

/* Yandex Maps rating badge (fragments/footer.html :: rating): Yandex's 150×50 frame, enlarged so that «5,0» is as big as
   «Работаем без выходных» (1.5rem), and without its box: the contrast filter turns the box pure black (dark theme) or pure
   white (light theme), and the blend mode makes exactly that colour vanish into whatever is behind it. Yandex's own
   picture, unchanged otherwise: it keeps updating the rating by itself. */
.rating-badge {
    --rating-scale: 1.7;
    flex: 0 0 auto;
    width: calc(150px * var(--rating-scale));
    height: calc(50px * var(--rating-scale));
    overflow: hidden;
    line-height: 0;
}

.rating-badge iframe {
    border: 0;
    display: block;
    transform: scale(var(--rating-scale));
    transform-origin: 0 0;
    filter: contrast(1.6);
    mix-blend-mode: multiply;
}

.rating-badge-dark iframe { mix-blend-mode: screen; }

/* phones: the hero's texts are smaller there (1.25rem) */
@media (max-width: 575.98px) {
    .rating-badge { --rating-scale: 1.4; }
}

/* «Главная страница»: an on/off switch among the texts */
.landing-switch { margin: .15rem 0 .2rem; }

/* Landing texts edited in a textarea in the admin console: keep their line breaks. */
.landing-multiline {
    white-space: pre-line;
}

/* Category attribute rows: the value lists take a whole line under the attribute */
.form-row-inline > .form-select {
    flex: 0 1 12rem;
    width: auto;
}

.form-row-inline > .attr-options, .form-row-inline > .attr-exclusive {
    flex-basis: 100%;
}

.attribute-row {
    padding: .75rem 0;
    border-bottom: 1px solid var(--rv-border);
}

/* ---------- Data tables ---------- */
/* MDB's default cell padding (1rem 1.4rem) makes the 9-column admin tables wider than a laptop screen,
   so the last column ended up behind a horizontal scroll. Tighter cells and wrapping headers keep them in view. */
#main-info .table > :not(caption) > * > * {
    padding: .625rem .75rem;
}

#main-info .table > thead th {
    white-space: normal;
    vertical-align: bottom;
}

#main-info .table .table-actions {
    flex-wrap: nowrap;
}

#main-info .table .img-thumbnail {
    height: auto;
    max-height: 6rem;
    max-width: 6rem;
}

/* List pages: the table needs the width more than the card needs side padding */
@media (min-width: 768px) {
    #main-info.list-page {
        padding-left: 1.5rem !important;
        padding-right: 1.5rem !important;
    }
}

@media (min-width: 768px) and (max-width: 1199.98px) {
    #main-info.list-page {
        padding-left: 1rem !important;
        padding-right: 1rem !important;
    }
}

/* ---------- Details pop-up of the admin tables (fill_info_modal.js) ---------- */
.clickable-rows > tbody > tr {
    cursor: pointer;
}

.details-modal .modal-content {
    border: 0;
    border-radius: var(--rv-radius);
    color: var(--rv-text);
}

.details-modal .modal-header {
    align-items: center;
    border-bottom: 3px solid var(--rv-accent);
    padding: 1rem 1.5rem;
}

.details-modal .modal-title {
    font-size: 1.35rem;
    font-weight: 600;
    line-height: 1.25;
}

.details-modal .details-heading {
    min-width: 0;
}

.details-modal .details-subtitle {
    color: var(--rv-text-muted);
    font-size: .8rem;
    letter-spacing: .04em;
    text-transform: uppercase;
}

.details-modal .details-badge:empty {
    display: none;
}

.details-modal .btn-close {
    margin-left: auto;
}

.details-modal .modal-body {
    padding: 1.25rem 1.5rem 1.5rem;
    font-size: .975rem;
    line-height: 1.5;
}

.details-modal .modal-footer {
    padding: .75rem 1.5rem;
    background: var(--rv-subtle-bg, #fafafa);
}

/* Label / value pairs */
.details-fields {
    display: grid;
    grid-template-columns: minmax(8rem, 34%) 1fr;
    gap: .5rem 1.25rem;
    margin: 0;
}

.details-fields dt {
    color: var(--rv-text-muted);
    font-weight: 500;
}

.details-fields dd {
    margin: 0;
    overflow-wrap: anywhere;
}

@media (max-width: 575.98px) {
    .details-fields {
        grid-template-columns: 1fr;
        gap: 0;
    }

    .details-fields dd {
        margin-bottom: .625rem;
    }
}

.details-empty {
    color: var(--rv-text-faint, #adb5bd);
}

.details-section {
    margin-top: 1.5rem;
}

.details-section-title {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 1rem;
    margin-bottom: .625rem;
    padding-bottom: .375rem;
    border-bottom: 1px solid var(--rv-border);
    font-size: .8rem;
    font-weight: 700;
    letter-spacing: .05em;
    text-transform: uppercase;
    color: var(--rv-text);
}

.details-section-extra {
    font-weight: 400;
    letter-spacing: 0;
    text-transform: none;
    color: var(--rv-text-muted);
}

.details-table {
    font-size: .925rem;
}

.details-table > :not(caption) > * > * {
    padding: .45rem .5rem;
}

.details-table thead th {
    color: var(--rv-text-muted);
    font-weight: 500;
    border-bottom-width: 1px;
}

.details-table tfoot th {
    border-top: 2px solid var(--rv-border);
    border-bottom: 0;
    font-weight: 700;
}

.details-image {
    display: block;
    width: 100%;
    max-height: 16rem;
    object-fit: contain;
    background: var(--rv-subtle-bg, #f8f9fa);
    border: 1px solid var(--rv-border);
    border-radius: var(--rv-radius);
    padding: .5rem;
}

/* ---------- Admin lists: search, sort and paging on the server (fragments/table.html) ---------- */

.list-toolbar {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .625rem;
    margin-bottom: 1rem;
}

.list-search {
    position: relative;
    flex: 1 1 18rem;
    max-width: 32rem;
}

.list-search > .fa-search {
    position: absolute;
    left: .75rem;
    top: 50%;
    transform: translateY(-50%);
    color: var(--rv-text-muted);
    pointer-events: none;
}

.list-search > .form-control {
    padding-left: 2.25rem;
}

.list-status {
    width: auto;
    min-width: 10rem;
}

.list-size {
    display: flex;
    align-items: center;
    gap: .5rem;
    margin: 0 0 0 auto;
    color: var(--rv-text-muted);
    font-size: .875rem;
    white-space: nowrap;
}

.list-size .form-select {
    width: auto;
}

/* Search box and selects of the same height */
.list-toolbar .form-control,
.list-toolbar .form-select {
    min-height: 2.5rem;
}

/* While htmx loads the next page / search result */
#list {
    transition: opacity .15s ease;
}

#list.htmx-request {
    opacity: .55;
    pointer-events: none;
}

.sort-link {
    display: inline-flex;
    align-items: baseline;
    gap: .375rem;
    color: inherit;
    text-decoration: none;
}

.sort-link:hover, .sort-link:focus {
    color: var(--rv-accent-text);
}

.sort-link .fa-sort {
    color: var(--rv-text-faint, #ced4da);
}

.sort-link.sorted {
    color: var(--rv-accent-text);
}

.list-pager {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: .75rem;
    margin-top: 1rem;
}

.list-count {
    color: var(--rv-text-muted);
    font-size: .875rem;
}

.list-pager .page-link {
    color: var(--rv-text);
}

.list-pager .page-item.active .page-link {
    background-color: var(--rv-accent);
    border-color: var(--rv-accent);
    color: #fff;
}

.list-pager .page-link:focus {
    box-shadow: 0 0 0 .2rem var(--rv-accent-tint-strong);
}

.clickable-rows > tbody > tr:focus-visible {
    outline: 2px solid var(--rv-accent);
    outline-offset: -2px;
}

/* ---------- Notifications (velach.js Velach.toast) ---------- */

.velach-toasts {
    position: fixed;
    right: 1rem;
    bottom: 1rem;
    z-index: 2000;
    display: flex;
    flex-direction: column;
    gap: .5rem;
    max-width: min(26rem, calc(100vw - 2rem));
}

.velach-toast {
    padding: .75rem 1rem;
    border-radius: var(--rv-radius);
    background: var(--rv-card-bg);
    color: var(--rv-text);
    border-left: 4px solid var(--rv-accent);
    box-shadow: 0 .5rem 1.5rem rgba(0, 0, 0, .25);
    transition: opacity .4s ease;
}

.velach-toast-success {
    border-left-color: var(--rv-ok-line, #198754);
}

/* a client's Telegram message about an order the employee follows (telegram_notify.js) */
.velach-toast-info {
    border-left-color: #229ed9;
}

.velach-toast.hide {
    opacity: 0;
}

/* A missing value in the details pop-up: the cell stays empty and shows a dash */
.details-modal dd:empty::before,
.details-modal .details-table td:empty::before {
    content: "—";
    color: var(--rv-text-faint, #adb5bd);
}

/* ---------- Negative margin warning of the service form ---------- */

.details-modal .margin-warning-header {
    border-bottom-color: var(--rv-warn-line, #f0ad4e);
}

.margin-warning-header .fa-exclamation-triangle {
    color: var(--rv-warn-line, #d9822b);
}

.margin-table .margin-section {
    display: inline-block;
    min-width: 4.75rem;
    color: var(--rv-text-muted);
    font-size: .8rem;
    text-transform: uppercase;
    letter-spacing: .03em;
}

.margin-table .margin-detail {
    color: var(--rv-text-muted);
    font-size: .85rem;
}

.margin-table tr.margin-negative > td {
    background-color: var(--rv-danger-tint);
}

.margin-table tr.margin-negative > td:last-child {
    color: var(--rv-danger-text-hover);
}

.margin-table .margin-hint {
    margin-top: .25rem;
    color: var(--rv-danger-text-hover);
    font-weight: 600;
    font-size: .875rem;
}

/* On a phone small buttons get a finger-sized height (GRAPHIC_DESIGN.md: touch targets about 2rem) */
@media (max-width: 575.98px) {
    .why-btn, .rows-add, .chip { min-height: 2rem; }
}

/* Users list: the mechanic's pay, a number and «% от работ / ₽ в месяц» side by side (users_list.html) */
.pay-form { display: flex; gap: .25rem; min-width: 13rem; }
.pay-form .form-control { width: 6rem; }
.pay-form .form-select { width: auto; }

/* the Telegram badge of an order in the orders list and on the order page */
/* The orders list: a red circle with the client's unread Telegram messages next to the order number (telegram_notify.js) */
.tg-unread {
    display: inline-flex; align-items: center; justify-content: center; vertical-align: middle;
    min-width: 1.3rem; height: 1.3rem; padding: 0 .3rem; margin-left: .35rem; border-radius: 1rem;
    background: var(--rv-accent); color: #fff; font-size: .72rem; line-height: 1; text-decoration: none;
    box-shadow: 0 0 0 2px var(--rv-card-bg);
}
.tg-unread b { font-weight: 700; }
.tg-unread:hover, .tg-unread:focus-visible { background: var(--rv-accent-hover); color: #fff; }
.tg-unread[hidden] { display: none; }

/* The navbar: Telegram with the count of unread client messages and a menu of the orders */
.tg-nav-btn, .ui-mode-btn { position: relative; color: #fff; font-size: 1.25rem; line-height: 1; padding: .25rem .35rem; display: inline-block; }
.tg-nav-btn:hover, .tg-nav-btn:focus-visible { color: #cfe9f7; }
.ui-mode-btn:hover, .ui-mode-btn:focus-visible { color: var(--rv-accent-on-dark); }
.tg-dot {
    position: absolute; top: -.2rem; right: -.45rem; min-width: 1.15rem; height: 1.15rem; padding: 0 .25rem;
    border-radius: 1rem; background: var(--rv-accent); color: #fff; font-size: .68rem; font-weight: 700;
    display: inline-flex; align-items: center; justify-content: center; box-shadow: 0 0 0 2px #222;
}
.tg-dot[hidden] { display: none; }
.tg-nav-menu { min-width: 18rem; max-width: 24rem; }
.tg-nav-menu .dropdown-item { white-space: normal; }
.tg-nav-order { display: flex; justify-content: space-between; gap: .5rem; font-weight: 600; }
.tg-nav-order .tg-unread { margin-left: 0; box-shadow: none; }
.tg-nav-last { display: block; font-size: .78rem; color: var(--rv-text-muted); overflow-wrap: anywhere; }
.tg-nav-empty { color: var(--rv-text-muted); font-size: .875rem; }

/* «Следить» on the order and its Telegram page */
.tg-watch.on { background: var(--rv-accent-tint); }
.tg-count[hidden] { display: none; }

/* The order form: «Уведомить клиента в Telegram» under the status (add_service.html) */
.notify-switch { display: flex; align-items: center; flex-wrap: wrap; gap: .4rem; margin-top: .4rem; font-size: .875rem; cursor: pointer; }
.notify-switch .form-check-input { margin: 0; }
.notify-hint { color: var(--rv-text-muted); font-size: .8rem; }

/* The unread count on the order page's «Telegram» button */
.tg-count { background: #229ed9; color: #fff; border-radius: 1rem; padding: 0 .4rem; font-size: .75rem; margin-left: .35rem; }


/* ---------- guesses of the AI: one look everywhere (console suggestions, part form, weekly summary) ----------
   Violet, so that it reads neither as an error (red) nor as data: a guess is not data until a person accepts it. */
:root { --rv-ai: #5b21b6; --rv-ai-tint: #f3effe; --rv-ai-border: #c4b5fd; }
.ai-badge {
    display: inline-block;
    padding: 0 .4rem;
    border-radius: 1rem;
    background: var(--rv-ai-tint);
    color: var(--rv-ai);
    border: 1px solid var(--rv-ai-border);
    font-size: .72rem;
    font-weight: 500;
    line-height: 1.4;
    white-space: nowrap;
    vertical-align: middle;
}
.ai-filled { outline: 2px dashed var(--rv-ai-border); outline-offset: 1px; background-color: var(--rv-ai-tint) !important; }
.ai-hints {
    border: 1px dashed var(--rv-ai-border);
    background: var(--rv-ai-tint);
    border-radius: var(--rv-radius);
    padding: .6rem .8rem;
    margin-bottom: 1rem;
}
.ai-hints-title { font-size: .95rem; font-weight: 600; color: var(--rv-ai); margin: 0 0 .2rem; }
.ai-hints-note { font-size: .8rem; color: var(--rv-text-muted); margin: 0 0 .4rem; }
.ai-hints-list { list-style: none; margin: 0; padding: 0; }
.ai-hint { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: .25rem .75rem; padding: .25rem 0; }
.ai-hint + .ai-hint { border-top: 1px solid var(--rv-ai-border); }
.ai-hint-conf { font-size: .75rem; color: var(--rv-text-muted); margin-left: .35rem; }
.ai-hint-actions .btn { text-transform: none; margin: 0; }
.ai-hint-done { font-size: .8rem; color: var(--rv-ai); }
.ai-hint.applied .ai-hint-text { opacity: .7; }

/* ---------- The console's easter egg (doodles.js): an abstract bicycle picture in a free spot of a compact page's card,
   placed by the script (left / top), hidden when there's no free spot ---------- */
.compact-page #main-info { position: relative; }

.doodle-egg {
    position: absolute;
    width: 11rem;
    opacity: .6;
    transition: opacity .15s;
}

.doodle-egg:hover, .doodle-egg:focus-visible { opacity: 1; }

/* Text with the line breaks it was typed with (a multi-line description) */
.text-lines { white-space: pre-line; overflow-wrap: anywhere; }

/* A textarea with suggestions (velach.js, suggest): the list opens under the field, as a datalist does under an input */
.suggest-field { position: relative; }
.suggest-field > textarea { resize: none; max-height: 10rem; overflow-y: auto; }
.suggest-list {
    position: absolute;
    z-index: 1050;
    left: 0;
    right: 0;
    max-height: 14rem;
    overflow-y: auto;
    margin: 2px 0 0;
    padding: .25rem 0;
    list-style: none;
    background: var(--rv-card-bg);
    border: 1px solid var(--rv-border);
    border-radius: var(--rv-radius);
    box-shadow: 0 .5rem 1rem rgba(0, 0, 0, .12);
}
.suggest-list [role=option] {
    padding: .3rem .75rem;
    cursor: pointer;
    white-space: pre-line;
    overflow-wrap: anywhere;
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 2;
    line-clamp: 2;
    overflow: hidden;
}
.suggest-list [role=option]:hover { background: var(--rv-subtle-bg, #f4f4f2); }
.suggest-list [role=option][aria-selected=true] { background: var(--rv-accent-tint-strong); }

/* the model picker of the pages that ask a model (fragments/ai :: modelPicker) */
.ai-model-picker { display: inline-flex; align-items: center; gap: .35rem; margin: 0; color: var(--rv-ai, var(--rv-ai-fg, #5b21b6)); font-size: .8125rem; }
.ai-model-picker .form-select { width: auto; max-width: 18rem; font-size: .8125rem; }

/* ---------- navbar basket: the shop's basket next to the phone, with the number of items (shop/basket_store.js) ---------- */
.velach-navbar .navbar-basket {
    position: relative;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2.5rem;
    height: 2.5rem;
    margin-right: .5rem;
    color: #fff;
    font-size: 1.1rem;
    text-decoration: none;
}

.velach-navbar .navbar-basket:hover, .velach-navbar .navbar-basket:focus, .velach-navbar .navbar-basket.active { color: var(--rv-accent-on-dark); }

.velach-navbar .navbar-basket-count {
    position: absolute;
    top: .1rem;
    right: 0;
    min-width: 1.15rem;
    padding: 0 .3rem;
    border-radius: 1rem;
    background: var(--rv-accent);
    color: #fff;
    font-size: .7rem;
    font-weight: 600;
    line-height: 1.15rem;
    text-align: center;
}

@media (min-width: 768px) {
    /* after the phone, at the right end of the one-line menu */
    .velach-navbar .navbar-basket { order: 2; margin-right: 0; margin-left: .5rem; }
}

@media (max-width: 399.98px) {
    .velach-navbar .navbar-basket { width: 2rem; margin-right: .25rem; }
}

/* ---------- Breadcrumbs of the deeper public pages (fragments/layout :: crumbs) ---------- */
.crumbs ol { display: flex; flex-wrap: wrap; gap: .25rem; margin: 0 0 .75rem; padding: 0; list-style: none; font-size: .85rem; }
.crumbs li + li::before { content: "›"; margin-right: .25rem; color: var(--rv-text-muted); }
.crumbs span { color: var(--rv-text-muted); }

/* The footer's links to the services and the articles */
.velach-footer .footer-nav { display: flex; flex-wrap: wrap; gap: .25rem 1.25rem; margin-top: 1.25rem; font-size: .9rem; }

/* ---------- Cookie notice (fragments/layout.html, cookie_notice.js) ---------- */

/* A dark card at the bottom like the footer, over the page, so it shifts nothing; full width on phones */
.cookie-notice {
    position: fixed;
    left: 1rem;
    right: 1rem;
    bottom: 1rem;
    z-index: 1900;                 /* under the toasts */
    margin: 0 auto;
    max-width: 52rem;
    display: flex;
    align-items: center;
    gap: .75rem 1.25rem;
    padding: .9rem 1.1rem;
    border-radius: var(--rv-radius);
    background: var(--rv-surface-dark);
    color: rgba(255, 255, 255, .85);
    box-shadow: 0 8px 24px rgba(0, 0, 0, .35);
    font-size: .875rem;
    line-height: 1.4;
}
.cookie-notice[hidden] { display: none; }
.cookie-notice p { margin: 0; flex: 1; }
.cookie-notice a { color: #fff; text-decoration: underline; }
.cookie-notice .btn { flex-shrink: 0; }
@media (max-width: 575.98px) {
    .cookie-notice { left: .5rem; right: .5rem; bottom: .5rem; flex-direction: column; align-items: stretch; }
}
