/** Repair Center — Đăng ký sửa chữa online (module 5). PLACEHOLDER form — see template.php. */
.vnt39-rc-booking { padding: 20px; background: #f7f7f8; }
.vnt39-rc-booking .container { padding: 0; }
/* Solid — dashed border is this design's language for an EMPTY/placeholder
 * state (e.g. matched-services' "chưa chọn gì" box above this one on the
 * page). This card is a real, filled form, not a placeholder, so it stays
 * solid like every other real card (.vnt39-rc-warranty__card, etc.) —
 * dashed here would visually mislabel it as an empty state. (Was changed
 * to dashed for a round of "match the two side-by-side cards' border"
 * requests, then rolled back once the dashed-as-placeholder convention
 * became clear — see repair-center.css for the two-column layout these
 * sit in.) */
.vnt39-rc-booking__card { min-width: 0; border: 1px solid #e5e7eb; border-radius: 10px; padding: 22px; background: #fff; }
.vnt39-rc-booking__head { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; margin-bottom: 10px; }
/* Flatsome's base CSS sets a blanket `h1,h2,h3,h4,h5,h6{width:100%}` —
 * that alone was pushing the tag beside this h2 onto its own line
 * despite flex-wrap having plenty of room. width:auto lets the h2 size
 * to its own text again, the way a normal flex item would. */
.vnt39-rc-booking__head h2 { width: auto; margin: 0; color: #111318; font-size: 19px; font-weight: 800; }
.vnt39-rc-booking__head-text { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; flex: 1 1 auto; min-width: 0; }
.vnt39-rc-booking__tag { border-radius: 999px; padding: 5px 11px; background: #f0faf3; color: #155209; font-size: 11px; font-weight: 700; letter-spacing: .02em; }
/* Desktop: no accordion — chevron hidden, header not clickable-looking,
 * form always shown. The collapse/expand behaviour below is mobile-only
 * (see media query), matching the mockup: only the mobile view collapses
 * this module by default. */
.vnt39-rc-booking__chevron { display: none; flex-shrink: 0; width: 20px; height: 20px; color: #a30d1b; transition: transform .2s ease; }
/* Mobile collapse is a JS-measured max-height (see script.js) — plain
 * block on desktop, nothing special needed here; body-inner (wrapping the
 * form+success panel together, see template.php) is a leftover from an
 * earlier grid-template-rows 0fr↔1fr attempt that turned out not to
 * render correctly in testing (see script.js's comment) and is harmless
 * to leave in place. */
/* Tighter rhythm than before — gap between rows and label-to-input gap
 * were both wider than they needed to be, stretching the whole section
 * taller than the mockup for no real reason. */
.vnt39-rc-booking__form { display: grid; gap: 7px; }
.vnt39-rc-booking__form[hidden] { display: none; }
.vnt39-rc-booking__row { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 14px; }
/* HOTFIX — FIELD LABEL + REQUIRED/ERROR UX, section 8 audit turned up a
 * pre-existing bug: same author-style-beats-UA-default gotcha as the Brand
 * field's `label[hidden]` override a few lines down, just never applied to
 * `.row` — WITHOUT this, the return address row's `hidden` attribute
 * (template.php's `data-vnt39-return-wrap hidden`) did nothing at all, so
 * it rendered `display:grid` and stayed VISIBLE even while "Giống địa chỉ
 * trên" was checked (confirmed via computed style: `display:grid` with
 * `hidden` still true). Not something this hotfix's own field-heading/
 * error-placement changes introduced — caught only because section 8
 * explicitly required testing the checked/unchecked toggle end to end. */
.vnt39-rc-booking__row[hidden] { display: none; }
/* Thiết bị/Model/Lỗi sit in one row in the mockup, not paired 2+2 with
 * "Lỗi" dropped to its own full-width row. Step 3 adds a 4th field
 * (Brand) that only exists for some devices — auto-fit instead of a
 * hardcoded repeat(3/4, …) means this row reflows correctly whether
 * Brand's <label> is hidden or shown, with no JS-driven class swap and no
 * horizontal overflow at any width (wraps to 2 rows instead). */
.vnt39-rc-booking__row--fields { grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); }
.vnt39-rc-booking__form label,
.vnt39-rc-booking__full { display: flex; min-width: 0; flex-direction: column; gap: 3px; color: #344054; font-size: 13px; font-weight: 600; }
/* `.vnt39-rc-booking__form label { display:flex }` above wins over the
 * browser's own default `[hidden]{display:none}` UA rule (author styles
 * beat user-agent styles regardless of specificity) — without this, the
 * Brand field's `hidden` attribute would do nothing and it would always
 * show, even for iPhone/MacBook. Same class of bug as the Flatsome leaks
 * elsewhere on this page, just from this module's own CSS instead. */
.vnt39-rc-booking__form label[hidden] { display: none; }
/* Label text + the required "*" used to be two bare siblings inside a
 * flex-direction:column label — a flex container wraps loose text in its
 * own anonymous box, so the label and the "*" ended up as two separate
 * flex ITEMS and stacked on their own lines instead of sitting on one
 * line. Wrapping both in one span makes them a single flex item again;
 * the "*" itself goes red like a normal required-field marker. */
/* HOTFIX — FIELD LABEL + REQUIRED/ERROR UX. Every required field's label
 * row is now `.field-heading` (label-text on the left, inline error on the
 * right) sitting ABOVE the input/select as ONE extra flex item inside the
 * existing `.vnt39-rc-booking__form label{display:flex;flex-direction:
 * column}` — `.label-text` itself is its own nested flex row so "Mã bưu
 * điện" + "*" can NEVER be split onto two lines by the outer column layout
 * (the exact bug this hotfix fixes — see template.php's history). Error
 * text is a sibling flex item that wraps to its own line via flex-wrap
 * when the row is too narrow (auto-fit columns, phone widths) — no
 * separate breakpoint needed, `justify-content:space-between` degrades to
 * flex-start on its own once the error is alone on line 2. */
.vnt39-rc-booking__field-heading { display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; column-gap: 12px; row-gap: 2px; }
.vnt39-rc-booking__label-text { display: flex; flex-wrap: nowrap; align-items: center; gap: 4px; white-space: nowrap; }
.vnt39-rc-booking__label-text em,
.vnt39-rc-booking__consent em { color: #a30d1b; font-style: normal; }
.vnt39-rc-booking__form input,
.vnt39-rc-booking__form select,
.vnt39-rc-booking__form textarea { min-width: 0; border: 1px solid #d0d5dd; border-radius: 7px; padding: 8px 12px; background: #fff; font-family: inherit; line-height: 1.4; font-size: 14px; color: #111318; }
.vnt39-rc-booking__form textarea { resize: vertical; }
/* HOTFIX — inline field error: red border on the control itself + a short
 * message in its `.field-heading` row, NOT the form-level error banner
 * (approved "Không hiện lỗi này ở đầu form"). `.is-invalid` toggled by
 * script.js only once a field has been touched (blur/change) and found
 * invalid, or on a failed submit — never on page load. Covers every
 * control type a required field in this form can be (text/email/select),
 * plus a distinct outline treatment for the consent checkbox below since
 * checkboxes have no visible border to redden. */
.vnt39-rc-booking__form input.is-invalid,
.vnt39-rc-booking__form select.is-invalid,
.vnt39-rc-booking__form textarea.is-invalid { border-color: #a30d1b; }
.vnt39-rc-booking__form input.is-invalid:focus,
.vnt39-rc-booking__form select.is-invalid:focus,
.vnt39-rc-booking__form textarea.is-invalid:focus { outline: none; border-color: #a30d1b; box-shadow: 0 0 0 3px rgba(163, 13, 27, .16); }
.vnt39-rc-booking__consent input.is-invalid { outline: 2px solid #a30d1b; outline-offset: 2px; border-radius: 3px; }
.vnt39-rc-booking__field-error { margin: 0; color: #a30d1b; font-size: 11.5px; font-weight: 600; line-height: 1.3; }
.vnt39-rc-booking__field-error[hidden] { display: none; }
/* Consent's error sits right under the checkbox row instead of inside a
 * `.field-heading` (the consent row isn't `.vnt39-rc-booking__form label`'s
 * column layout — it's its own flex row, see `.vnt39-rc-booking__consent`
 * further down), so it needs its own small top offset here. */
.vnt39-rc-booking__field-error--consent { display: block; margin-top: -4px; }
/* Native <select> chrome (-webkit-appearance:menulist) ignores author
 * padding and renders its own text box — reset appearance so it behaves
 * like a plain box exactly like the text inputs beside it, then redraw
 * the dropdown arrow ourselves since appearance:none also removes that.
 *
 * That alone still clipped the value's top edge — Flatsome's own base
 * CSS sets a blanket `select{height:2.507em}` (confirmed by reading
 * flatsome.css directly), which at THIS select's 14px font-size resolves
 * to 35px — shorter than the 10px+10px padding plus 19.6px line-height
 * it actually needs (~41.6px), so the option text overflowed past the
 * box's own top edge instead of fitting inside it. height:auto lets the
 * box size itself from padding+line-height like a normal element,
 * instead of Flatsome's em-relative fixed height. */
.vnt39-rc-booking__form select { height: auto; appearance: none; -webkit-appearance: none; -moz-appearance: none; padding-right: 34px; background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23667085' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E"); background-repeat: no-repeat; background-position: right 10px center; background-size: 16px; }
/* Step 3: Model/Lỗi/Dịch vụ start with no options until a prior field is
 * answered (script.js disables them then, same locked-step idea as
 * model-issue-wizard's own disabled steps). */
.vnt39-rc-booking__form select:disabled { cursor: not-allowed; background-color: #f7f7f8; color: #98a2b3; }
/* Step 3 success panel — replaces the form in place after a mock submit
 * (no DB/API, see template.php); same card padding as the form so the
 * card's own size doesn't visibly jump. */
.vnt39-rc-booking__success { display: flex; flex-direction: column; align-items: flex-start; gap: 6px; padding: 8px 0 4px; }
/* Same author-style-beats-UA-default gotcha as the Brand field's label
 * above — this rule's own `display:flex` would otherwise defeat its own
 * `hidden` attribute. */
.vnt39-rc-booking__success[hidden] { display: none; }
.vnt39-rc-booking__success-icon { display: grid; place-items: center; width: 44px; height: 44px; margin-bottom: 4px; border-radius: 50%; background: #eef8f1; color: #155209; }
.vnt39-rc-booking__success-icon .vnt39-rc-icon { width: 22px; height: 22px; }
.vnt39-rc-booking__success b { color: #111318; font-size: 17px; font-weight: 800; }
.vnt39-rc-booking__success p { margin: 0; color: #667085; font-size: 13.5px; line-height: 1.5; }
.vnt39-rc-booking__success-reset { margin-top: 6px; border: 1.5px solid #d0d5dd; border-radius: 7px; padding: 9px 16px; background: #fff; color: #344054; font-size: 13.5px; line-height: 1.3; font-weight: 700; cursor: pointer; }
.vnt39-rc-booking__success-reset:hover { border-color: #a30d1b; color: #a30d1b; }
.vnt39-rc-booking__consent { display: flex; align-items: flex-start; gap: 8px; color: #667085; font-size: 12.5px; font-weight: 500; }
.vnt39-rc-booking__consent input { flex-shrink: 0; margin-top: 3px; }
/* Same red-required-asterisk treatment as the label-text fields above,
 * just not reusing that class since this one isn't a <label>'s own
 * heading text — it's the consent sentence itself. */
.vnt39-rc-booking__consent em { color: #a30d1b; font-style: normal; }
.vnt39-rc-booking__submit { display: flex; align-items: center; justify-content: center; gap: 8px; margin-top: 4px; border: 0; border-radius: 8px; padding: 13px; background: #a30d1b; color: #fff; font-size: 15px; line-height: 1.2; font-weight: 700; cursor: pointer; }
.vnt39-rc-booking__submit .vnt39-rc-icon { width: 18px; height: 18px; }
.vnt39-rc-booking__submit:hover { background: #8f0b18; }
.vnt39-rc-booking__submit:disabled { opacity: .6; cursor: not-allowed; }
/* STEP B6 — real submit's error state (invalid field, rate-limited, network
 * failure): plain inline text above the fields, same red as the rest of
 * this form's own accent, no icon/animation — kept as quiet as the
 * `required` validation errors the browser itself would show. */
.vnt39-rc-booking__error { margin: 0 0 4px; color: #a30d1b; font-size: 13px; font-weight: 600; }
.vnt39-rc-booking__error[hidden] { display: none; }

/* FINAL HOTFIX+UX PACK, approved "E." — price/info box beside the Dịch vụ
 * select. Fixed-ish width on desktop (not a 50/50 split with the select —
 * the select needs the room, this box only ever holds a price + one short
 * meta line), stacks full-width below the select at the same breakpoint
 * every other two-column row here already stacks at. */
.vnt39-rc-booking__row--service { grid-template-columns: minmax(0, 1fr) minmax(150px, 200px); align-items: end; }
.vnt39-rc-booking__price-box { display: flex; flex-direction: column; gap: 2px; min-width: 0; border: 1px solid #eee0e1; border-radius: 7px; padding: 8px 12px; background: #faf5f5; }
.vnt39-rc-booking__price-box-label { color: #98a2b3; font-size: 11px; font-weight: 600; text-transform: uppercase; letter-spacing: .02em; }
.vnt39-rc-booking__price-box-amount { color: #98a2b3; font-size: 15px; font-weight: 700; line-height: 1.3; }
/* "Đã chọn" state — burgundy, heavier, bigger (approved "màu burgundy/dark
 * red, font-weight 700/800, nổi bật") — toggled via this modifier class in
 * script.js, not two separate elements swapped in/out. */
.vnt39-rc-booking__price-box.is-priced .vnt39-rc-booking__price-box-amount { color: #a30d1b; font-size: 19px; font-weight: 800; }
.vnt39-rc-booking__price-box-meta { color: #667085; font-size: 11.5px; font-weight: 600; }
.vnt39-rc-booking__price-box-meta[hidden] { display: none; }
/* Dịch vụ giá 0 (Kiểm tra & chẩn đoán...) — script.js chỉ hiện dòng này
 * khi selected.price_raw === 0, không gắn riêng Device/Model nào. */
.vnt39-rc-booking__price-box-note { color: #a30d1b; font-size: 11px; font-weight: 700; line-height: 1.35; }
.vnt39-rc-booking__price-box-note[hidden] { display: none; }

@media (max-width: 549px) {
	.vnt39-rc-booking__row--service { grid-template-columns: minmax(0, 1fr); }
}

@media (max-width: 849px) {
	.vnt39-rc-booking { padding: 16px; }
	.vnt39-rc-booking__row { grid-template-columns: minmax(0, 1fr); }
	/* Mobile mockup: this module is collapsed by default, header row is
	 * tappable to expand/collapse. script.js measures scrollHeight and
	 * sets max-height inline (a plain grid-template-rows 0fr↔1fr didn't
	 * render correctly in testing — see script.js's comment); overflow +
	 * transition here are the only two things CSS still owns. */
	/* nowrap + align-items:flex-start on the OUTER head — the head-text
	 * child still wraps title/tag onto their own lines internally, but
	 * without this the row itself would wrap once title+tag take the
	 * full width at phone widths, dropping the chevron onto its own line
	 * instead of keeping it pinned top-right of the header. */
	.vnt39-rc-booking__head { flex-wrap: nowrap; align-items: flex-start; cursor: pointer; margin-bottom: 0; }
	.vnt39-rc-booking__chevron { margin-top: 2px; }
	.vnt39-rc-booking__chevron { display: inline-flex; transform: rotate(90deg); }
	.vnt39-rc-booking__head[aria-expanded="true"] .vnt39-rc-booking__chevron { transform: rotate(-90deg); }
	.vnt39-rc-booking__body { overflow: hidden; transition: max-height .3s ease; }
	.vnt39-rc-booking__head[aria-expanded="true"] + .vnt39-rc-booking__body { margin-top: 14px; }
}

.vnt39-rc-booking__success .vnt39-rc-booking__success-code { margin-top: 2px; color: #111318; font-size: 14px; font-weight: 600; }
.vnt39-rc-booking__success-code strong { color: #a30d1b; font-size: 15px; letter-spacing: .02em; user-select: all; }
.vnt39-rc-booking__success .vnt39-rc-booking__success-code[hidden] { display: none; }

/* ---- UX-02 --------------------------------------------------------------------------------------------------------------------------------
 * 1. The consent / "giống địa chỉ" rows are <label>s, so `.vnt39-rc-booking__form label { flex-direction: column }` (0,1,1) beat
 *    `.vnt39-rc-booking__consent { display:flex }` (0,1,0) and stacked the checkbox ABOVE its text. One more class lifts the row rule over it.
 * 2. Phones/tablets: 16px fields (iOS Safari zooms the page into anything smaller), 44px touch targets, a checkbox that is a real target. */
.vnt39-rc-booking { scroll-margin-top: 12px; }
.vnt39-rc-booking__form label.vnt39-rc-booking__consent { flex-direction: row; align-items: flex-start; gap: 10px; }
.vnt39-rc-booking__consent input[type="checkbox"] { flex-shrink: 0; width: 20px; height: 20px; margin: 1px 0 0; }
@media (max-width: 849px) {
	.vnt39-rc-booking__form input:not([type="checkbox"]):not([type="radio"]),
	.vnt39-rc-booking__form select,
	.vnt39-rc-booking__form textarea { font-size: 16px; min-height: 44px; }
	.vnt39-rc-booking__form textarea { min-height: 96px; }
	.vnt39-rc-booking__form label.vnt39-rc-booking__consent { min-height: 44px; padding: 8px 0; font-size: 14px; }
	.vnt39-rc-booking__consent input[type="checkbox"] { width: 22px; height: 22px; margin-top: 0; }
	.vnt39-rc-booking__submit { min-height: 48px; font-size: 16px; }
	.vnt39-rc-booking__head { min-height: 44px; }
	.vnt39-rc-booking__success-reset { min-height: 44px; }
}
