/* Self-hosted (static/fonts/) rather than a Google Fonts CDN call, so
   guest-facing pages make no third-party request at load time - see
   static/fonts/*-LICENSE.txt for the SIL Open Font License terms. Single
   variable-weight file per family covers the whole weight range used
   below, so browsers without variable-font support simply skip it and
   fall back to the next stack entry instead of loading a mismatched weight. */
@font-face {
    font-family: "Inter";
    src: url("/fonts/InterVariable.woff2") format("woff2-variations");
    font-weight: 100 900;
    font-style: normal;
    font-display: swap;
}

@font-face {
    font-family: "Source Serif 4";
    src: url("/fonts/SourceSerif4Variable-Roman.woff2") format("woff2-variations");
    font-weight: 200 900;
    font-style: normal;
    font-display: swap;
}

:root {
    --color-bg: #f5f4ed;
    --color-surface: #fdfcfa;
    --color-text: #3d3929;
    --color-muted: #83827d;
    --color-border: #e8e4d9;
    --color-primary: #cc785c;
    --color-primary-hover: #b35f45;
    --color-success: #3d6a5b;
    --color-success-bg: #e6ede9;
    --color-error: #bf4a3d;
    --color-error-bg: #fbeae7;
    --color-pending: #8a5a00;
    --color-pending-bg: #f7ecd9;
    --color-neutral-bg: #eae8e0;
    /* Catalog/Ministry-lookup area accent - kept distinct from
       --color-primary (booking/stay actions) so nav buttons read as
       belonging to different functional areas at a glance. */
    --color-catalog: #4a6f8c;
    --color-catalog-hover: #3a5a72;
    --color-catalog-bg: rgba(74, 111, 140, 0.1);
    --radius: 12px;
    --font-sans: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
    --font-serif: "Source Serif 4", ui-serif, Georgia, "Times New Roman", serif;
}

* { box-sizing: border-box; }

body {
    margin: 0;
    font-family: var(--font-sans);
    background: var(--color-bg);
    color: var(--color-text);
    line-height: 1.5;
}

.page {
    max-width: 640px;
    margin: 0 auto;
    padding: 2.5rem 1.25rem;
}

.card {
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    padding: 2rem;
    box-shadow: 0 1px 2px rgba(45, 42, 38, 0.04), 0 1px 10px rgba(45, 42, 38, 0.03);
}

h1 { font-family: var(--font-serif); font-size: 1.85rem; font-weight: 500; letter-spacing: -0.02em; margin-top: 0; margin-bottom: 0.6rem; }
h2 { font-family: var(--font-serif); font-size: 1.15rem; font-weight: 500; letter-spacing: -0.01em; margin-bottom: 0.5rem; }

fieldset {
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    margin: 0 0 1.5rem;
    padding: 1rem 1.25rem 1.25rem;
}

legend { padding: 0 0.4rem; font-weight: 600; color: var(--color-muted); }

label {
    display: block;
    font-size: 0.9rem;
    font-weight: 500;
    margin-bottom: 0.35rem;
    margin-top: 0.9rem;
}

.required-marker { color: var(--color-error); margin-left: 0.2rem; }
html[dir="rtl"] .required-marker { margin-left: 0; margin-right: 0.2rem; }

.required-hint {
    font-size: 0.85rem;
    color: var(--color-muted);
    margin: 0 0 1rem;
}

input, select {
    width: 100%;
    padding: 0.55rem 0.7rem;
    border: 1px solid var(--color-border);
    border-radius: 8px;
    font-size: 1rem;
    background: var(--color-surface);
}

/* Checkboxes aren't a stacked full-width field - the rule above is
   written for text/select inputs and would otherwise stretch a
   checkbox's hit area to the full row width, pushing its label text
   away from the visible box. */
input[type="checkbox"] {
    width: auto;
    padding: 0;
}

input:focus, select:focus {
    outline: 2px solid var(--color-primary);
    outline-offset: 1px;
}

/* Autocomplete combobox (nationality/country/city on the guest form) -
   see combobox.js. The popup is positioned relative to this wrapper so
   it floats over whatever follows in the form instead of pushing it down. */
.combobox {
    position: relative;
}

.combobox-input {
    padding-right: 2.2rem;
}

html[dir="rtl"] .combobox-input {
    padding-right: 0.7rem;
    padding-left: 2.2rem;
}

.combobox-toggle {
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    width: 2.2rem;
    display: flex;
    align-items: center;
    justify-content: center;
    background: none;
    border: none;
    margin: 0;
    padding: 0;
    cursor: pointer;
}

html[dir="rtl"] .combobox-toggle {
    right: auto;
    left: 0;
}

.combobox-toggle::before {
    content: '';
    width: 0;
    height: 0;
    border-left: 5px solid transparent;
    border-right: 5px solid transparent;
    border-top: 6px solid var(--color-muted);
    transition: transform 0.15s ease;
}

.combobox-toggle.is-open::before {
    transform: rotate(180deg);
}

.combobox-list {
    position: absolute;
    z-index: 20;
    top: calc(100% + 4px);
    left: 0;
    right: 0;
    max-height: 220px;
    overflow-y: auto;
    margin: 0;
    padding: 0.3rem;
    list-style: none;
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: 8px;
    box-shadow: 0 6px 16px rgba(0, 0, 0, 0.15);
}

.combobox-list[hidden] {
    display: none;
}

.combobox-option {
    padding: 0.5rem 0.6rem;
    border-radius: 6px;
    cursor: pointer;
    font-size: 0.95rem;
}

.combobox-option mark {
    background: none;
    color: inherit;
    font-weight: 700;
}

.combobox-hint {
    padding: 0.5rem 0.6rem;
    color: var(--color-muted);
    font-size: 0.85rem;
}

.combobox-option.is-active,
.combobox-option:hover {
    background: var(--color-neutral-bg);
}

/* Narrower than the shared full-width input rule above, and centered -
   the login card itself keeps its usual width, only the fields inside
   it shrink. Labels get the same width/centering so their text lines up
   with the left edge of the field below it, as it did at full width.
   The checkbox is excluded: it's not a stacked full-width field like
   the others, it sits inline next to its own label text. */
.login-form input:not([type="checkbox"]),
.login-form label {
    width: 80%;
    margin-left: auto;
    margin-right: auto;
}

.login-form input:not([type="checkbox"]) {
    display: block;
}

.login-form .checkbox-label {
    display: flex;
    align-items: center;
    gap: 0.5rem;
}

/* Login page only - wider than the shared .page so the illustration
   panel has room inside the card next to the form. Scoped to this
   modifier class rather than changing .page/.card, which every other
   admin/guest page also relies on. */
.page-login {
    max-width: 780px;
}

/* Stays list only - wider than the shared .page so its 7-column table
   fits without .table-scroll kicking in on typical desktop widths, even
   for rows whose actions column renders two icon buttons plus captions
   (e.g. a failed Ministry submission: "Correct data" + "Retry submission").
   Scoped to this modifier class for the same reason as .page-login. */
.page-stays {
    max-width: 1240px;
}

/* .card's own padding/border/background stay, but padding is zeroed and
   moved onto .login-content instead, so .login-visual can sit flush
   against the card's edges (top/bottom/left) and be clipped to its
   rounded corners via overflow:hidden below - a uniform card padding
   would otherwise leave a visible gap around the image. */
.login-card {
    display: flex;
    align-items: stretch;
    padding: 0;
    overflow: hidden;
}

.login-visual {
    flex: 0 0 38%;
    background: var(--color-primary);
}

.login-visual img {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.login-content {
    flex: 1 1 auto;
    min-width: 0;
    padding: 2rem;
}

/* Mirrors .card > h1:first-child - the heading is no longer a direct
   child of .card now that .login-content wraps it. */
.login-content > h1:first-child {
    padding-bottom: 0.85rem;
    margin-bottom: 1.25rem;
    border-bottom: 1px solid var(--color-border);
}

/* Below this width there's no room for the image to sit next to the
   form without squeezing it - drop the illustration and let the card
   go back to a normal single-column layout instead of the two panels
   getting cramped or misaligned. */
@media (max-width: 620px) {
    .login-visual {
        display: none;
    }
}

button, .button {
    display: inline-block;
    margin-top: 1.5rem;
    padding: 0.65rem 1.4rem;
    background: var(--color-primary);
    color: white;
    border: none;
    border-radius: 8px;
    font-size: 1rem;
    font-weight: 500;
    cursor: pointer;
    text-decoration: none;
    transition: opacity 0.15s ease, background-color 0.15s ease;
}

/* Translucent rather than a solid color swap: for the outlined
   .button-secondary variant especially, a solid fill on hover left its
   already-orange text nearly illegible against the same solid orange
   background. */
button:hover, .button:hover { opacity: 0.85; }

.button-secondary {
    background: transparent;
    color: var(--color-primary);
    border: 1px solid var(--color-primary);
}

.button-secondary:hover {
    background-color: rgba(204, 120, 92, 0.1);
    opacity: 1;
}

/* Darker outline than .button-secondary, for an action next to it that
   should read as more final/cautionary (e.g. "Close link" sitting next
   to "Copy link" in the bookings list) without going as far as a red
   danger color. */
.button-dark {
    background: transparent;
    color: var(--color-text);
    border: 1px solid var(--color-text);
}

.button-dark:hover {
    background-color: rgba(61, 57, 41, 0.1);
    opacity: 1;
}

/* Catalog/Ministry-lookup area's themed button variant - see
   --color-catalog above. */
.button-catalog {
    background: transparent;
    color: var(--color-catalog);
    border: 1px solid var(--color-catalog);
}

.button-catalog:hover {
    background-color: var(--color-catalog-bg);
    opacity: 1;
}

.error-list {
    background: var(--color-error-bg);
    color: var(--color-error);
    border-radius: 6px;
    padding: 0.75rem 1rem;
    margin: 1rem 0;
    font-size: 0.9rem;
}

.field-error {
    color: var(--color-error);
    font-size: 0.82rem;
    margin-top: 0.25rem;
}

.muted { color: var(--color-muted); font-size: 0.9rem; }

/* Guest demographic data on the read-only stay-details view reads as
   visually secondary to the stay-level card above it - same gray already
   used for field labels (.muted), just applied to the whole block so the
   values match too (issue #52). */
.guest-detail { color: var(--color-muted); }

/* Amber, same convention as .modal-header - a blank optional guest field
   (issue #52) reads as a warning without going as far as the red used
   for .status-FAILED/REJECTED errors elsewhere. */
.not-answered {
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
    color: var(--color-pending);
}

table { width: 100%; border-collapse: collapse; margin-top: 1rem; }
th, td { text-align: left; padding: 0.6rem 0.5rem; border-bottom: 1px solid var(--color-border); font-size: 0.9rem; }
th { color: var(--color-muted); font-weight: 600; }

/* Lets a wide table (e.g. the guest review table) scroll horizontally
   on narrow screens instead of squeezing its columns unreadably. */
.table-scroll { overflow-x: auto; }

/* Bookings list month/year stepper (issue #43) - two stacked rows (year,
   month), each a centered "prev value next" row reusing the same
   .button-icon/.button-icon-wrap/.button-icon-caption pattern as the
   row-action icons above, rather than inventing a second hover-caption
   style. An arrow's wrapping .button-icon-wrap is toggled `hidden` by
   JS (stays-list.html) rather than merely disabled, matching the issue's
   "only rendered when there's an adjacent year/month with bookings" -
   there's deliberately no dead/disabled arrow state. It stays invisible
   rather than removed from the row's layout though (see .stepper-arrow
   below) so the year and month values line up vertically no matter
   which arrows either row is missing. Reused as-is (single .stepper row)
   for the stay-details guest stepper (issue #46) - see slide-stepper.js
   for the slide transition shared by both. */
.period-selector {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.4rem;
    margin-bottom: 1.25rem;
}

.stepper {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0.75rem;
}

.stepper-value {
    min-width: 8rem;
    text-align: center;
    font-weight: 600;
}

/* :not(:last-child)/:not(:first-child) keep these scoped to the two-row
   year/month layout they were written for - a single-row stepper (the
   stay-details guest stepper, issue #46) is simultaneously first and
   last child, and without the guard would get both rules at once
   (enlarged *and* muted) instead of the plain default styling that
   actually suits a single row. */
.stepper:first-child:not(:last-child) .stepper-value { font-size: 1.1rem; }
.stepper:last-child:not(:first-child) .stepper-value { color: var(--color-muted); }

/* Any panel driven by slidePanel() (slide-stepper.js) - #stays-panel (the
   same .table-scroll wrapping the bookings table, issue #43) and
   #guest-panel (stay-details.html, issue #46) - is animated in place on
   stepper navigation: it slides its current content out one side then the
   freshly-swapped-in content in from the other, direction matching
   next/previous. transform/opacity are toggled via inline style rather
   than swapped CSS classes so the JS can pick the exit/enter side per
   click without a class for every direction combination. */
.slide-panel { will-change: transform; }

/* error.html - centered so the icon reads as the visual anchor of the
   page instead of sitting off to the side of left-aligned text. */
.error-card { text-align: center; }

.error-icon {
    font-size: 2.5rem;
    color: var(--color-error);
    margin: 0 0 1rem;
}

/* Hidden outside the mobile breakpoint below so hovering a top-nav
   button (which already shows its text label there) doesn't also pop
   up a redundant caption repeating the same text. */
.top-nav .button-icon-caption { display: none; }

@media (max-width: 480px) {
    .page { padding: 1.5rem 1rem; }
    .card { padding: 1.25rem; }
    .login-content { padding: 1.25rem; }

    /* Bookings list (issue #37): collapse to Title/Status/Actions,
       hiding Airbnb ref./Check-in/Check-out/Guests, which are still
       reachable via the "View details" row action. */
    .page-stays table th:nth-child(n+2):nth-child(-n+5),
    .page-stays table td:nth-child(n+2):nth-child(-n+5) {
        display: none;
    }

    /* Collapse the top-nav buttons to icon-only, reusing the same
       hover/focus caption pattern as the row-action icons below. */
    .top-nav .button-icon-wrap .button-label { display: none; }
    .top-nav .button-icon-wrap .icon { margin-right: 0; }
    .top-nav .button-icon-wrap > a,
    .top-nav .button-icon-wrap > form > button {
        padding: 0.4rem;
        width: 2.1rem;
        height: 2.1rem;
        display: inline-flex;
        align-items: center;
        justify-content: center;
    }
    .top-nav .button-icon-caption { display: block; }
}

/* white-space:nowrap keeps multi-word statuses (e.g. "PENDING HOST
   VALIDATION") on one line - without it, a squeezed table column wraps
   the text across several lines and the pill's rounded shape collapses
   into a tall oval instead of the containing .table-scroll taking over,
   which is the whole point of that container (see its own comment). */
.status-badge {
    display: inline-block;
    padding: 0.15rem 0.5rem;
    border-radius: 999px;
    font-size: 0.78rem;
    font-weight: 600;
    white-space: nowrap;
}
.status-OPEN { background: var(--color-success-bg); color: var(--color-success); }
.status-SUBMITTED { background: var(--color-success-bg); color: var(--color-success); }
.status-CLOSED, .status-EXPIRED, .status-CANCELLED { background: var(--color-neutral-bg); color: var(--color-muted); }
.status-PENDING, .status-PENDING_HOST_VALIDATION { background: var(--color-pending-bg); color: var(--color-pending); }
.status-FAILED, .status-REJECTED { background: var(--color-error-bg); color: var(--color-error); }

.link-box {
    display: flex;
    gap: 0.5rem;
    margin-top: 1rem;
}
.link-box input { flex: 1; font-family: monospace; font-size: 0.85rem; }

.top-nav {
    display: flex;
    flex-wrap: wrap;
    justify-content: space-between;
    align-items: center;
    gap: 0.6rem 1rem;
    margin-bottom: 1.5rem;
    padding-bottom: 1.1rem;
    border-bottom: 1px solid var(--color-border);
}

/* The shared button/.button rule carries a 1.5rem margin-top meant for
   buttons stacked below a form field - left unset here, it pushes these
   buttons visibly low against the heading text next to them, even with
   align-items:center on the flex row above. */
.top-nav a,
.top-nav button {
    margin-top: 0;
}

/* Same title/content separation as .top-nav, for the simpler pages that
   render an <h1> directly in the card with no nav row alongside it. */
.card > h1:first-child {
    padding-bottom: 0.85rem;
    margin-bottom: 1.25rem;
    border-bottom: 1px solid var(--color-border);
}

/* Inline nav-button icon set (see fragments/common.html :: icon) - sized
   off font-size so it scales with whatever button it's placed in, and
   inherits currentColor so it automatically matches each themed button
   (.button, .button-secondary, .button-catalog, .button-dark, ...). */
.icon {
    display: inline-flex;
    vertical-align: -0.15em;
    margin-right: 0.4rem;
}

.icon svg {
    width: 1em;
    height: 1em;
}

/* Payment type icon on the stay-details view (fragments/common.html ::
   icon('payment-*')) - bumped up from the surrounding text size so it
   reads as a quick-glance icon rather than disappearing into the line,
   same approach as .modal-header .icon. */
.payment-type-icon .icon {
    font-size: 2em;
}

/* Nationality/country-of-residence flag emoji on the read-only
   stay-details view - bumped up from the surrounding text size so it
   reads as a quick-glance icon rather than disappearing into the line
   (issue #52). */
.flag-icon {
    font-size: 1.75em;
    vertical-align: middle;
    line-height: 1;
}

/* Icon-only row actions (bookings list) - each row shows a different
   subset of these depending on stay/Ministry status, so a fixed
   icon-only size keeps every row the same height regardless of which
   ones are present, instead of long/short text labels bouncing the row
   layout around (see issue #9). The caption is hidden until hover/focus
   so the action stays discoverable without permanently costing row
   space; aria-label on the button itself carries the accessible name so
   the (aria-hidden) caption is purely visual. */
/* contain: layout keeps the caption's absolute-positioned box (wider
   than the icon button it's centered on) from counting toward the
   scrollable overflow of ancestors up to .table-scroll - without it,
   any row with 2+ actions triggers a horizontal scrollbar with nothing
   new to scroll to, since the caption stays invisible until hover
   either way. Doesn't clip the caption's rendering, so it still shows
   in full on hover/focus. */
.button-icon-wrap {
    position: relative;
    display: inline-flex;
    align-items: center;
    contain: layout;
}

/* Without this, the [hidden] attribute the stepper JS toggles on a
   wrap with no adjacent year/month to jump to (stays-list.html) loses
   to the display:inline-flex rule above - same specificity, and an
   author rule beats the UA stylesheet's own [hidden] { display:none }
   regardless of source order. */
.button-icon-wrap[hidden] {
    display: none;
}

/* Overrides the display:none above for the stepper's own arrows only
   (.stepper-arrow, stays-list.html) - visibility:hidden instead keeps
   the wrap's box in the flex row, so a hidden arrow leaves an
   empty-but-same-size gap rather than letting .stepper's
   justify-content:center recenter the row around fewer buttons. That's
   what keeps the year value sitting directly above the month value
   regardless of which arrows either row is missing. */
.button-icon-wrap.stepper-arrow[hidden] {
    display: inline-flex;
    visibility: hidden;
    pointer-events: none;
}

.button-icon {
    margin: 0;
    padding: 0.4rem;
    width: 2.1rem;
    height: 2.1rem;
    display: inline-flex;
    align-items: center;
    justify-content: center;
}

.button-icon .icon {
    margin-right: 0;
}

.button-icon-caption {
    position: absolute;
    bottom: calc(100% + 0.4rem);
    left: 50%;
    transform: translateX(-50%);
    background: var(--color-text);
    color: var(--color-surface);
    font-size: 0.75rem;
    font-weight: 500;
    white-space: nowrap;
    padding: 0.3rem 0.55rem;
    border-radius: 6px;
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.15s ease;
    z-index: 5;
}

.button-icon-wrap:hover .button-icon-caption,
.button-icon-wrap:focus-within .button-icon-caption {
    opacity: 1;
}

.lang-switcher {
    display: flex;
    justify-content: flex-end;
    margin-bottom: 0.75rem;
}

.lang-switcher select {
    width: auto;
    padding: 0.25rem 0.5rem;
    font-size: 0.78rem;
    transition: background-color 0.15s ease;
}

.lang-switcher select:hover {
    background-color: rgba(204, 120, 92, 0.1);
}

.visually-hidden {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
}

.progress-counter {
    font-size: 0.9rem;
    color: var(--color-primary);
    margin: 0 0 0.75rem;
}

.photo-fields {
    display: flex;
    flex-direction: column;
    gap: 1.5rem;
    margin-top: 0.9rem;
}

.photo-field {
    display: flex;
    flex-direction: column;
}

.photo-preview { max-width: 320px; }

.photo-field label { margin-top: 0; }

.photo-preview {
    aspect-ratio: 4 / 3;
    margin: 0.5rem 0 0.6rem;
    border: 1px dashed var(--color-border);
    border-radius: var(--radius);
    background: var(--color-bg);
    display: flex;
    align-items: center;
    justify-content: center;
    overflow: hidden;
}

.photo-preview img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.photo-preview-placeholder {
    color: var(--color-muted);
    font-size: 0.82rem;
    text-align: center;
    padding: 0.5rem;
}

.photo-upload-row {
    display: flex;
    align-items: center;
    gap: 0.5rem;
}

.photo-remove-button {
    margin-top: 0;
    padding: 0.55rem 0.9rem;
    font-size: 0.85rem;
    line-height: 1.2;
    white-space: nowrap;
}

/* The native file input's own "No file chosen" text duplicates the
   photo-preview placeholder above it, so the input itself is visually
   hidden (kept focusable/tabbable, unlike display:none) and a <label>
   styled as a button drives it instead - clicking or activating the
   label opens the file picker via the for/id association. */
.photo-file-input {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}

.photo-upload-button {
    /* The global `label` rule (margin-top/margin-bottom for form field
       labels) would otherwise leak onto this label-styled-as-button,
       throwing off its vertical centering next to .photo-remove-button
       in the flex row - zero it out explicitly rather than relying on
       .photo-field label's margin-top:0, which doesn't touch bottom. */
    margin: 0;
    display: inline-block;
    padding: 0.55rem 1rem;
    background: var(--color-primary);
    color: white;
    border: 1px solid transparent;
    border-radius: 8px;
    font-size: 0.85rem;
    font-weight: 500;
    line-height: 1.2;
    transition: opacity 0.15s ease;
    cursor: pointer;
    transition: background-color 0.15s ease;
}

.photo-upload-button:hover { opacity: 0.85; }

/* Forwards the hidden input's keyboard focus ring onto the visible
   label-button, since the input itself is clipped out of view. */
.photo-file-input:focus-visible + .photo-upload-button {
    outline: 2px solid var(--color-primary);
    outline-offset: 2px;
}

.legal-notice {
    font-size: 0.85rem;
    color: var(--color-muted);
    background: var(--color-bg);
    border-left: 3px solid var(--color-primary);
    padding: 0.75rem 1rem;
    margin: 1rem 0 1.5rem;
}

/* Mirror the accent border for right-to-left languages (Arabic) */
html[dir="rtl"] .legal-notice {
    border-left: none;
    border-right: 3px solid var(--color-primary);
}

.review-photo-thumb {
    max-width: 160px;
    max-height: 160px;
    cursor: zoom-in;
}

html[dir="rtl"] .lang-switcher {
    justify-content: flex-start;
}

/* Confirmation modal (e.g. "delete booking" on the stays list) - native
   <dialog> rather than a hand-rolled overlay, so Escape-to-close and
   focus trapping come for free; only the box itself needs styling, the
   browser handles centering and the ::backdrop dimming. */
.modal {
    max-width: 420px;
    width: 90%;
    padding: 1.75rem;
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    background: var(--color-surface);
    color: var(--color-text);
    box-shadow: 0 1px 2px rgba(45, 42, 38, 0.04), 0 1px 10px rgba(45, 42, 38, 0.03);
}

.modal::backdrop {
    background: rgba(61, 57, 41, 0.5);
}

.modal-header {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    margin-bottom: 0.75rem;
}

/* Amber, same as .status-PENDING - reads as "warning" without going as
   far as the red used for .status-FAILED/REJECTED errors elsewhere. */
.modal-header .icon {
    margin-right: 0;
    font-size: 1.4rem;
    color: var(--color-pending);
}

.modal-header h2 {
    margin: 0;
    color: var(--color-pending);
}

.modal-message {
    margin: 0 0 1.5rem;
    font-size: 0.95rem;
}

.modal-actions {
    display: flex;
    justify-content: flex-end;
    gap: 0.6rem;
}

.modal-actions button {
    margin-top: 0;
}
