/* ============ DESIGN TOKENS ============ */
:root {
    --primary: #0F4C81;
    --primary-dark: #0a3b66;
    --primary-light: #E5EEF7;
    --accent: #00A6A6;
    --bg: #F4F6FA;
    --surface: #FFFFFF;
    --text: #1F2937;
    --muted: #6B7280;
    --border: #E5E7EB;
    --border-strong: #D1D5DB;
    --success: #059669;
    --success-bg: #D1FAE5;
    --danger: #DC2626;
    --danger-bg: #FEE2E2;
    --warning: #D97706;
    --warning-bg: #FEF3C7;
    --shadow-sm: 0 1px 2px rgba(15, 23, 42, 0.06);
    --shadow-md: 0 4px 12px rgba(15, 23, 42, 0.08);
    --shadow-lg: 0 12px 32px rgba(15, 23, 42, 0.12);
    --radius: 12px;
    --radius-sm: 8px;
    --radius-lg: 16px;
}

/* ============ RESET ============ */
*, *::before, *::after { box-sizing: border-box; }
* { margin: 0; padding: 0; }
html, body { height: 100%; }
/* The scrollbar's space stays reserved while a dialog locks the page, so the
   page does not jump sideways when the customer signature opens and closes. */
html { scrollbar-gutter: stable; }
body {
    font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
                 "Helvetica Neue", Arial, sans-serif;
    font-size: 15px;
    line-height: 1.5;
    color: var(--text);
    background: var(--bg);
    -webkit-font-smoothing: antialiased;
    -webkit-tap-highlight-color: transparent;
    /* Nothing may extend past the viewport on a phone. Anything genuinely
       wider (a data table) gets its own scroll container instead. */
    overflow-x: hidden;
}
/* Long service numbers, e-mail addresses and Croatian street names must wrap
   rather than push the layout sideways. `break-word` rather than `anywhere`:
   it only splits a word that cannot fit on a line by itself, so ordinary text
   still breaks between words. */
h1, h2, h3, p, dd, dt, td, th, li, strong, span, a { overflow-wrap: break-word; }
/* Set while a modal or the scanner is open. */
body.is-locked { overflow: hidden; }
a { color: var(--primary); text-decoration: none; }
a:hover { text-decoration: underline; }
button { font-family: inherit; cursor: pointer; }
img { max-width: 100%; display: block; }
fieldset { border: none; }
legend { padding: 0; }

/* ============ LAYOUT ============ */
.page-center {
    min-height: 100vh;
    display: grid;
    place-items: center;
    padding: 16px;
    background:
      radial-gradient(circle at 20% 0%, rgba(15, 76, 129, 0.10), transparent 60%),
      radial-gradient(circle at 80% 100%, rgba(0, 166, 166, 0.08), transparent 50%),
      var(--bg);
}
.page {
    min-height: 100vh;
    background: var(--bg);
}

/* ============ APP HEADER ============ */
.app-header {
    background: linear-gradient(135deg, var(--primary) 0%, var(--primary-dark) 100%);
    color: #fff;
    position: sticky;
    top: 0;
    z-index: 50;
    box-shadow: var(--shadow-md);
}
.app-header__inner {
    max-width: 720px;
    margin: 0 auto;
    padding: 14px 16px;
    display: flex;
    align-items: center;
    gap: 12px;
}
.app-header__title { flex: 1; min-width: 0; }
.app-header h1 { font-size: 17px; font-weight: 600; line-height: 1.2; }
.app-header__brand {
    display: inline-flex;
    align-items: center;
    /* The logo is small, but the link around it is a navigation target. */
    min-height: 44px;
    padding: 4px 0;
    border-radius: 8px;
    transition: opacity 0.15s;
}
.app-header__brand:hover { opacity: 0.85; text-decoration: none; }
.app-header__back {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    /* 44px is the smallest reliable one-handed target. */
    width: 44px;
    height: 44px;
    margin-left: -8px;
    color: #fff;
    border-radius: 8px;
    transition: background 0.15s;
}
.app-header__back:hover { background: rgba(255,255,255,0.15); text-decoration: none; }
.logo { max-width: 140px; height: auto; }
/* Das Logo ist weiss und sitzt auf dem dunkelblauen Header — es braucht
   keine weisse Kachel mehr darunter. */
.logo--small { max-width: 76px; flex-shrink: 0; }
.icon { display: inline-block; vertical-align: middle; flex-shrink: 0; }

.app-main {
    max-width: 720px;
    margin: 0 auto;
    padding: 16px;
    display: flex;
    flex-direction: column;
    gap: 16px;
}
.app-footer {
    max-width: 720px;
    margin: 0 auto;
    padding: 24px 16px 32px;
    text-align: center;
    color: var(--muted);
    font-size: 13px;
}
/* Legal links are rarely tapped but must still be reachable one-handed. */
.app-footer a { color: var(--muted); display: inline-block; padding: 8px 4px; }

/* ============ CARDS ============ */
.card {
    background: var(--surface);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-md);
    overflow: hidden;
}
.card--narrow { max-width: 460px; width: 100%; }
.card--wide { max-width: 760px; width: 100%; }
.card-header {
    padding: 28px 24px 20px;
    background: linear-gradient(135deg, var(--primary) 0%, var(--primary-dark) 100%);
    color: #fff;
    text-align: center;
}
.card-header--danger { background: var(--danger); }
.card-header h1 { font-size: 22px; font-weight: 600; margin-top: 8px; }
.card-header .subtitle { color: rgba(255,255,255,0.85); margin-top: 6px; font-size: 14px; }
.card-header .logo { margin: 0 auto 8px; max-width: 110px; }
.card-body { padding: 24px; }
.card-footer {
    padding: 16px 24px;
    background: #FAFBFC;
    border-top: 1px solid var(--border);
    text-align: center;
    font-size: 14px;
    color: var(--muted);
}
.card-footer a { color: var(--muted); }

/* ============ CHIPS ============ */
.chip {
    display: inline-block;
    background: rgba(255, 255, 255, 0.18);
    border: 1px solid rgba(255, 255, 255, 0.28);
    color: #fff;
    padding: 4px 12px;
    border-radius: 999px;
    font-size: 13px;
    font-weight: 500;
    margin-top: 10px;
}
.chip--ghost {
    background: rgba(255, 255, 255, 0.18);
    margin-top: 4px;
}

/* ============ FORM ============ */
.form-section {
    border-top: 1px solid var(--border);
    padding: 20px 0;
}
.form-section:first-of-type { border-top: none; padding-top: 4px; }
.form-section legend {
    font-size: 13px;
    font-weight: 600;
    color: var(--primary);
    text-transform: uppercase;
    letter-spacing: 0.04em;
    margin-bottom: 14px;
}
.form-group { margin-bottom: 14px; }
.form-group:last-child { margin-bottom: 0; }
.form-group label {
    display: block;
    font-size: 13px;
    font-weight: 500;
    color: var(--text);
    margin-bottom: 6px;
}
.form-row {
    display: grid;
    /* minmax(0, …): a column may shrink below its content's natural width.
       With plain 1fr, Safari lets a time field's built-in width push the
       column wider than half the row. */
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 12px;
    margin-bottom: 14px;
}
.form-row:last-child { margin-bottom: 0; }
/* Fields side by side share one bottom line. On a narrow phone one label can
   wrap to two lines ("Završetak / odlazak") while its neighbour does not;
   the inputs used to follow their labels and sit at different heights. */
.form-row > .form-group {
    display: flex;
    flex-direction: column;
    justify-content: flex-end;
    min-width: 0;
    margin-bottom: 0;
}
/* Date and time fields look and measure like every other input. iOS Safari
   otherwise centres the value, draws an empty field lower than a filled one
   and gives it its own minimum width. */
.form-group input[type="time"],
.form-group input[type="date"],
.form-group input[type="datetime-local"] {
    -webkit-appearance: none;
    appearance: none;
    display: block;
    min-width: 0;
    min-height: 50px;
    line-height: 1.4;
    text-align: left;
}
.form-group input[type="time"]::-webkit-date-and-time-value,
.form-group input[type="date"]::-webkit-date-and-time-value,
.form-group input[type="datetime-local"]::-webkit-date-and-time-value {
    text-align: left;
    min-height: 1.4em;
}
.form-group input,
.form-group select,
.form-group textarea {
    width: 100%;
    padding: 12px 14px;
    font-size: 16px;
    font-family: inherit;
    color: var(--text);
    background: #fff;
    border: 1.5px solid var(--border);
    border-radius: var(--radius-sm);
    transition: border-color 0.15s, box-shadow 0.15s;
}
.form-group input:focus,
.form-group select:focus,
.form-group textarea:focus {
    outline: none;
    border-color: var(--primary);
    box-shadow: 0 0 0 3px rgba(15, 76, 129, 0.15);
}
.form-group textarea { resize: vertical; min-height: 64px; }
.req { color: var(--danger); }
.muted { color: var(--muted); }
.small { font-size: 12px; }

/* ============ BUTTONS ============ */
.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    padding: 12px 20px;
    font-size: 15px;
    font-weight: 600;
    border: none;
    border-radius: var(--radius-sm);
    cursor: pointer;
    transition: transform 0.12s, box-shadow 0.12s, background 0.12s;
}
.btn:active { transform: translateY(1px); }
.btn--full { width: 100%; }
.btn--lg { padding: 16px 22px; font-size: 16px; }
.btn--primary {
    background: linear-gradient(135deg, var(--primary), var(--primary-dark));
    color: #fff;
    box-shadow: var(--shadow-sm);
}
.btn--primary:hover { box-shadow: var(--shadow-md); }
.btn--primary:disabled {
    opacity: 0.6;
    cursor: not-allowed;
    transform: none;
}
.btn--ghost {
    background: var(--primary-light);
    color: var(--primary);
}
.btn--ghost:hover { background: #d8e6f3; }
/* The second of two equal choices (Intervencija next to the monthly service):
   as big and as tappable, but visibly not the default. */
.btn--secondary {
    background: var(--surface);
    color: var(--primary-dark);
    border: 2px solid var(--primary);
}
.btn--secondary:hover { background: var(--primary-light); }
.running-card--fresh { border-color: var(--success); box-shadow: var(--shadow-md); }
.btn--danger { background: var(--danger); color: #fff; }
.link {
    background: none;
    border: none;
    color: var(--primary);
    font-size: 13px;
    padding: 0;
    cursor: pointer;
    font-weight: 500;
}
.link:hover { text-decoration: underline; }

/* ============ ALERT ============ */
.alert {
    padding: 12px 14px;
    border-radius: var(--radius-sm);
    font-size: 14px;
    margin-bottom: 14px;
}
.alert--danger { background: var(--danger-bg); color: var(--danger); }
.alert--success { background: var(--success-bg); color: var(--success); }
.alert--warning { background: var(--warning-bg); color: var(--warning); }
.hidden { display: none !important; }
.text-center { text-align: center; }

/* ============ ELEVATOR INFO ============ */
.elevator-info {
    background: var(--primary-light);
    border-left: 4px solid var(--primary);
    padding: 14px 16px;
    border-radius: var(--radius-sm);
    margin-bottom: 14px;
}
.elevator-info dl { display: grid; grid-template-columns: 120px 1fr; gap: 4px 12px; font-size: 14px; }
.elevator-info dt { color: var(--muted); font-weight: 500; }
.elevator-info dd { color: var(--text); font-weight: 600; }
.elevator-info .address { grid-column: 1 / -1; padding-top: 8px; border-top: 1px solid rgba(15, 76, 129, 0.15); margin-top: 4px; }
.elevator-info .address dt { margin-bottom: 4px; }

/* ============ HISTORY ============ */
.history {
    margin-top: 12px;
    display: flex;
    flex-direction: column;
    gap: 8px;
}
.history__item {
    background: #FAFBFC;
    border: 1px solid var(--border);
    border-left: 3px solid var(--primary);
    padding: 10px 12px;
    border-radius: var(--radius-sm);
    font-size: 13px;
}
.history__item strong { color: var(--text); }
.history__item .muted { font-size: 12px; }

/* ============ MATERIALS ============ */
/* One row per material (static/js/materials.js): what, how much, in which
   unit. On a phone the description gets the whole first line and quantity,
   unit and the remove button share the second; from 600px everything sits on
   one line. */
.material-list { display: flex; flex-direction: column; gap: 8px; margin-bottom: 10px; }
.material-row {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr) 44px;
    grid-template-areas:
        "desc desc desc"
        "qty  unit remove"
        "other other other";
    gap: 8px;
    padding: 10px;
    background: #FAFBFC;
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    align-items: center;
}
.material-row [data-field="description"] { grid-area: desc; }
.material-row [data-field="quantity"]    { grid-area: qty; }
.material-row [data-field="unit"]        { grid-area: unit; }
.material-row .material-row__remove      { grid-area: remove; }
.material-row .material-row__other       { grid-area: other; }
.material-row input,
.material-row select {
    /* min-width: 0 — an input's intrinsic minimum size is what pushed this row
       past the edge of a 320px screen. */
    min-width: 0;
    width: 100%;
    height: 46px;
    padding: 0 12px;
    border: 1.5px solid var(--border);
    border-radius: var(--radius-sm);
    font-size: 16px;
    font-family: inherit;
    color: var(--text);
    background: #fff;
}
.material-row select { padding-right: 6px; }
.material-row input:focus,
.material-row select:focus { outline: none; border-color: var(--primary); box-shadow: 0 0 0 3px rgba(15, 76, 129, 0.12); }
.material-row__remove {
    width: 44px;
    height: 44px;
    border: none;
    background: var(--danger-bg);
    color: var(--danger);
    border-radius: var(--radius-sm);
    font-size: 20px;
    line-height: 1;
}
.material-row__other[hidden] { display: none; }
@media (min-width: 600px) {
    .material-row {
        grid-template-columns: minmax(0, 1fr) 110px 150px 44px;
        grid-template-areas:
            "desc qty unit remove"
            ".    .   other .";
    }
}

/* ============ GPS PILL ============ */
.gps-pill {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    background: #F3F4F6;
    color: var(--muted);
    padding: 6px 12px;
    border-radius: 999px;
    font-size: 13px;
}
.gps-pill__dot {
    width: 8px; height: 8px; border-radius: 50%;
    background: var(--muted);
}
.gps-pill.is-ok { background: var(--success-bg); color: var(--success); }
.gps-pill.is-ok .gps-pill__dot { background: var(--success); }
.gps-pill.is-error { background: var(--warning-bg); color: var(--warning); }
.gps-pill.is-error .gps-pill__dot { background: var(--warning); }

/* ============ SIGNATURE ============ */
.signature { margin-bottom: 16px; }
.signature:last-child { margin-bottom: 0; }
.signature__head {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 6px;
}
.signature__head label { font-size: 13px; font-weight: 500; }
/* "Obriši" is hit with a thumb while holding the phone — it needs real area. */
.signature__head .link { padding: 12px 10px; margin: -12px -10px; }
.signature-pad {
    display: block;
    width: 100%;
    /* The canvas carries a 600px drawing buffer; it must never widen its box. */
    max-width: 100%;
    height: 180px;
    background: #fff;
    border: 1.5px dashed var(--border-strong);
    border-radius: var(--radius-sm);
    cursor: crosshair;
    touch-action: none;
}

/* ============ PHOTO UPLOAD ============ */
.photo-add {
    display: flex;
    align-items: center;
    gap: 14px;
    padding: 14px 16px;
    background: var(--primary-light);
    border: 2px dashed var(--primary);
    border-radius: var(--radius-sm);
    cursor: pointer;
    transition: background 0.15s, transform 0.1s;
    user-select: none;
}
.photo-add:hover { background: #d8e6f3; }
.photo-add:active { transform: scale(0.99); }
.photo-add__icon { font-size: 28px; line-height: 1; }
.photo-add strong { color: var(--primary); font-size: 14px; }
.photo-preview {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(96px, 1fr));
    gap: 8px;
    margin-top: 12px;
}
.photo-thumb {
    position: relative;
    aspect-ratio: 1 / 1;
    border-radius: var(--radius-sm);
    overflow: hidden;
    background: #f3f4f6;
    box-shadow: var(--shadow-sm);
}
.photo-thumb img {
    width: 100%; height: 100%; object-fit: cover; display: block;
}
.photo-thumb__remove {
    position: absolute;
    top: 4px;
    right: 4px;
    width: 26px;
    height: 26px;
    border: none;
    border-radius: 50%;
    background: rgba(0,0,0,0.6);
    color: #fff;
    font-size: 16px;
    line-height: 1;
    cursor: pointer;
    display: grid;
    place-items: center;
}
.photo-thumb__remove:hover { background: var(--danger); }

/* ============ CONSENT ============ */
.consent {
    display: flex;
    gap: 12px;
    background: var(--warning-bg);
    border: 1px solid #FCD34D;
    padding: 14px;
    border-radius: var(--radius-sm);
    font-size: 13px;
    line-height: 1.5;
    cursor: pointer;
}
.consent input[type="checkbox"] {
    width: 24px; height: 24px;
    margin-top: 1px;
    flex-shrink: 0;
    accent-color: var(--primary);
}

/* ============ OVERLAY (success) ============ */
.overlay {
    position: fixed;
    inset: 0;
    background: rgba(15, 23, 42, 0.55);
    display: grid;
    place-items: center;
    z-index: 100;
    padding: 16px;
    animation: fade-in 0.2s;
}
.overlay__card {
    background: #fff;
    border-radius: var(--radius-lg);
    padding: 32px 24px;
    text-align: center;
    max-width: 380px;
    width: 100%;
    box-shadow: var(--shadow-lg);
    animation: pop-in 0.3s cubic-bezier(0.34, 1.56, 0.64, 1);
}
.overlay__card h2 { margin: 16px 0 4px; font-size: 22px; color: var(--success); }
.overlay__actions { display: flex; flex-direction: column; gap: 8px; margin-top: 20px; }
.report-number {
    font-size: 28px;
    font-weight: 700;
    letter-spacing: 0.05em;
    color: var(--primary);
    background: var(--primary-light);
    padding: 10px 20px;
    border-radius: var(--radius-sm);
    display: inline-block;
    margin: 4px 0 12px;
}
.check-circle {
    width: 80px; height: 80px;
    margin: 0 auto;
    background: var(--success-bg);
    border-radius: 50%;
    display: grid;
    place-items: center;
}
.check-circle svg { width: 48px; height: 48px; fill: none; stroke: var(--success); stroke-width: 4; stroke-linecap: round; stroke-linejoin: round; }

/* ============ LEGAL PAGES ============ */
.legal { font-size: 15px; line-height: 1.7; }
.legal h2 { font-size: 17px; color: var(--primary); margin: 24px 0 8px; }
.legal h2:first-child { margin-top: 0; }
.legal p { margin-bottom: 12px; }
.legal ul { margin: 8px 0 16px 24px; }
.legal li { margin-bottom: 4px; }
.callout {
    padding: 14px 16px;
    border-radius: var(--radius-sm);
    margin: 16px 0;
    font-size: 14px;
}
.callout--info {
    background: var(--primary-light);
    border-left: 4px solid var(--primary);
}
.kv-list {
    display: grid;
    grid-template-columns: 120px 1fr;
    gap: 4px 12px;
    background: #FAFBFC;
    padding: 12px 16px;
    border-radius: var(--radius-sm);
    margin: 8px 0 16px;
}
.kv-list dt { color: var(--muted); font-weight: 500; }
.kv-list dd { font-weight: 600; }

/* ============ HOME HUB ============ */
.hero-card {
    background: #fff;
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-md);
    padding: 28px 24px;
    text-align: center;
}
.hero-card h2 {
    font-size: 22px;
    color: var(--primary);
    margin-bottom: 6px;
}
.hero-card p { margin-bottom: 20px; }
.btn-emoji { font-size: 22px; margin-right: 6px; }
.manual-entry { text-align: left; }
.manual-entry[open] .manual-form { padding: 0 16px 16px; }
.manual-entry .muted { padding: 0 16px 12px; }
.manual-entry summary {
    color: var(--primary);
    font-size: 15px;
    cursor: pointer;
    font-weight: 600;
    text-align: center;
    /* Full-height tap target: this is a one-handed control. */
    min-height: 52px;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 6px 16px;
    list-style: none;
}
.manual-entry summary::-webkit-details-marker { display: none; }
.manual-entry summary::marker { content: none; }
.manual-entry[open] summary { margin-bottom: 10px; }
.manual-form {
    display: flex;
    gap: 8px;
}
.manual-form input {
    flex: 1;
    padding: 12px 14px;
    border: 1.5px solid var(--border);
    border-radius: var(--radius-sm);
    font-size: 16px;
}
.manual-form input:focus { outline: none; border-color: var(--primary); }

.scanner-region {
    margin-top: 18px;
    text-align: left;
}
.scanner-region.hidden { display: none; }
#qr-reader {
    border-radius: var(--radius-sm);
    overflow: hidden;
    background: #000;
}
.scanner-actions {
    margin-top: 10px;
    display: flex;
    justify-content: center;
}

.quick-cards {
    display: grid;
    gap: 12px;
}
.quick-card {
    background: #fff;
    border-radius: var(--radius);
    box-shadow: var(--shadow-sm);
    padding: 16px 18px;
    display: flex;
    align-items: center;
    gap: 14px;
    color: var(--text);
    transition: transform 0.12s, box-shadow 0.15s;
}
.quick-card:hover {
    text-decoration: none;
    transform: translateY(-1px);
    box-shadow: var(--shadow-md);
}
.quick-card__icon {
    width: 48px;
    height: 48px;
    background: var(--primary-light);
    color: var(--primary);
    border-radius: 12px;
    display: grid;
    place-items: center;
    flex-shrink: 0;
}
.quick-card strong { display: block; color: var(--text); }
.quick-card__arrow {
    margin-left: auto;
    color: var(--primary);
    display: inline-flex;
    align-items: center;
}
.quick-card--placeholder { opacity: 0.6; cursor: default; }
.quick-card--placeholder:hover { transform: none; box-shadow: var(--shadow-sm); }

/* ============ MISC ============ */
.dot { margin: 0 6px; opacity: 0.4; }
.subtitle { color: var(--muted); }
.skeleton { background: linear-gradient(90deg, #f0f0f0 25%, #e0e0e0 50%, #f0f0f0 75%); background-size: 200% 100%; animation: shimmer 1.5s infinite; }

/* ============ ANIMATIONS ============ */
@keyframes fade-in { from { opacity: 0; } to { opacity: 1; } }
@keyframes pop-in { from { transform: scale(0.9); opacity: 0; } to { transform: scale(1); opacity: 1; } }
@keyframes shimmer { 0% { background-position: 200% 0; } 100% { background-position: -200% 0; } }

/* ============ RESPONSIVE ============ */
@media (max-width: 520px) {
    .form-row { grid-template-columns: minmax(0, 1fr); }
    /* Short values (times, first/last name) stay paired — stacking them just
       adds scrolling without making anything easier to hit. */
    .form-row--tight { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .card-header { padding: 24px 20px 18px; }
    .card-body { padding: 20px 18px; }
    .app-header h1 { font-size: 16px; }
    .elevator-info dl { grid-template-columns: 100px 1fr; font-size: 13px; }
}

/* =========================================================================
   FIELD-SERVICE UI
   Everything below is mobile-first: base rules target a 320px phone and the
   media queries only ever add space, never take it away.
   ========================================================================= */

/* ---- Header action (logout etc.) ---- */
.app-header__action {
    margin-left: auto;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 44px;
    height: 44px;
    color: #fff;
    border-radius: 10px;
}
.app-header__action:hover { background: rgba(255,255,255,0.15); text-decoration: none; }

/* Signing out is a word, not a padlock: a technician handing the phone to a
   colleague has to find it without guessing what a symbol means. */
.app-header__user {
    display: block;
    font-size: 15px;
    font-weight: 600;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.app-header__logout {
    margin-left: auto;
    flex-shrink: 0;
    display: inline-flex;
    align-items: center;
    min-height: 44px;
    padding: 0 14px;
    color: #fff;
    font-size: 14px;
    font-weight: 600;
    border: 1px solid rgba(255,255,255,0.45);
    border-radius: 10px;
}
.app-header__logout:hover { background: rgba(255,255,255,0.15); text-decoration: none; }

/* ---- Primary action tiles ---- */
.action-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 12px;
}
.action-tile {
    /* 96px keeps the target comfortably above the 44px minimum even with
       gloves on, which is the actual use case. */
    min-height: 96px;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 8px;
    padding: 14px 10px;
    background: var(--surface);
    border: 1.5px solid var(--border);
    border-radius: var(--radius-lg);
    color: var(--text);
    font: inherit;
    box-shadow: var(--shadow-sm);
    transition: transform 0.12s, box-shadow 0.12s;
}
.action-tile:active { transform: scale(0.98); }
.action-tile__icon { color: var(--primary); display: inline-flex; }
.action-tile__label { font-size: 15px; font-weight: 600; text-align: center; }
.action-tile--primary {
    background: linear-gradient(135deg, var(--primary), var(--primary-dark));
    border-color: transparent;
    color: #fff;
}
.action-tile--primary .action-tile__icon { color: #fff; }

/* ---- Monthly summary ---- */
.summary-card {
    background: var(--surface);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-md);
    padding: 18px;
}
.summary-card__head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 10px;
    margin-bottom: 14px;
}
.summary-card__head h2 { font-size: 16px; font-weight: 600; }
.summary-card__figures {
    /* 64px is the narrowest that still fits all four figures on one row at
       320px — wrapping one of them alone below the others reads as an error. */
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(64px, 1fr));
    gap: 10px;
}
.figure { display: flex; flex-direction: column; gap: 2px; }
.figure__value { font-size: 26px; font-weight: 700; line-height: 1.1; color: var(--text); }
.figure__label {
    font-size: 11px;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--muted);
    font-weight: 600;
}
.figure--open .figure__value { color: var(--primary); }
.figure--overdue .figure__value { color: var(--danger); }

.progress {
    margin-top: 14px;
    height: 6px;
    border-radius: 999px;
    background: var(--border);
    overflow: hidden;
}
.progress__bar { height: 100%; background: var(--success); border-radius: 999px; }

/* ---- City groups ---- */
.city-list { display: flex; flex-direction: column; gap: 10px; }
.city {
    background: var(--surface);
    border-radius: var(--radius);
    box-shadow: var(--shadow-sm);
    overflow: hidden;
}
.city__head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    padding: 16px;
    min-height: 56px;
    cursor: pointer;
    list-style: none;
    font-weight: 600;
}
.city__head::-webkit-details-marker { display: none; }
.city__name { font-size: 16px; }
.city__meta { display: inline-flex; align-items: center; gap: 6px; flex-shrink: 0; }
.city__chevron {
    color: var(--muted);
    display: inline-flex;
    transition: transform 0.18s;
}
.city[open] .city__chevron { transform: rotate(90deg); }
.city__items {
    display: flex;
    flex-direction: column;
    gap: 10px;
    padding: 0 12px 12px;
}

.tag {
    display: inline-block;
    min-width: 26px;
    text-align: center;
    padding: 3px 9px;
    border-radius: 999px;
    font-size: 12px;
    font-weight: 700;
}
.tag--open { background: var(--primary-light); color: var(--primary); }
.tag--overdue { background: var(--danger-bg); color: var(--danger); }

/* ---- Lift card ---- */
.lift-card {
    border: 1px solid var(--border);
    border-left: 4px solid var(--primary);
    border-radius: var(--radius-sm);
    padding: 14px;
    display: flex;
    flex-direction: column;
    gap: 12px;
    background: #fff;
}
.lift-card--overdue { border-left-color: var(--danger); }
.lift-card__no {
    font-size: 17px;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
}
.lift-card__address { color: var(--text); font-size: 14px; margin-top: 2px; }
.lift-card__status {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
    margin-top: 8px;
}
/* The primary action gets the full width of the card — squeezing three
   buttons onto one line made "Pokreni servis" wrap onto two lines. */
.lift-card__actions {
    display: grid;
    grid-template-columns: 1fr auto;
    gap: 8px;
}
.lift-card__cta { grid-column: 1 / -1; }
.lift-card__actions .btn { min-height: 48px; white-space: nowrap; }
.btn--icon { padding: 12px; flex-shrink: 0; }

/* ---- Status pills ---- */
.status {
    display: inline-block;
    padding: 4px 10px;
    border-radius: 999px;
    font-size: 12px;
    font-weight: 700;
    letter-spacing: 0.02em;
    text-transform: uppercase;
    white-space: nowrap;
}
.status--open { background: var(--primary-light); color: var(--primary); }
.status--done { background: var(--success-bg); color: var(--success); }
.status--overdue { background: var(--danger-bg); color: var(--danger); }
.status--skipped { background: #F3F4F6; color: var(--muted); }
.status--off { background: #F3F4F6; color: var(--muted); }
.status-label { font-size: 13px; color: var(--muted); }

/* ---- Lift detail page ---- */
.lift-hero {
    background: var(--surface);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-md);
    padding: 18px;
}
.lift-hero__address { font-size: 18px; font-weight: 600; line-height: 1.35; }
.lift-hero__customer { font-size: 14px; margin-top: 4px; }
.lift-hero__status {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    flex-wrap: wrap;
    margin-top: 14px;
    padding-top: 14px;
    border-top: 1px solid var(--border);
}

.lift-actions { display: flex; flex-direction: column; gap: 10px; }
.lift-actions__row { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.lift-actions__row .btn { min-height: 52px; }
.btn--xl { padding: 18px 22px; font-size: 17px; min-height: 56px; }
.btn:disabled { opacity: 0.5; cursor: not-allowed; }

/* ---- Sticky primary action ---- */
.page--sticky-cta { padding-bottom: 96px; }
.sticky-cta {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 60;
    padding: 10px 16px calc(10px + env(safe-area-inset-bottom));
    background: rgba(255, 255, 255, 0.94);
    backdrop-filter: blur(8px);
    border-top: 1px solid var(--border);
    box-shadow: 0 -4px 16px rgba(15, 23, 42, 0.06);
}
/* The button sits in a centred column the width of the page content. It used
   to be a direct child with `margin: 0 auto`, which does nothing on an
   inline-flex element — on a desktop the 720px button hugged the left edge. */
.sticky-cta__inner {
    display: flex;
    flex-direction: column;
    width: 100%;
    max-width: 720px;
    margin: 0 auto;
}
.sticky-cta > .btn { display: flex; width: 100%; max-width: 720px; margin: 0 auto; }
.sticky-cta__inner .btn { width: 100%; }
.sticky-cta__hint { text-align: center; margin-top: 4px; min-height: 16px; }
@media (min-width: 760px) {
    /* On a desktop a 720px-wide button reads as a banner, not a button. */
    .sticky-cta__inner, .sticky-cta > .btn { max-width: 440px; }
}
/* Variant used on the lift page: the same action already sits inline near the
   top, so the bar slides in only once that button has scrolled out of view. */
.sticky-cta--auto {
    transform: translateY(120%);
    transition: transform 0.2s ease;
}
.sticky-cta--auto.is-visible { transform: none; }
@media (prefers-reduced-motion: reduce) {
    .sticky-cta--auto { transition: none; }
}

/* ---- Generic lists ---- */
.section-title {
    font-size: 12px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--muted);
    margin-bottom: 12px;
}
.data-list { display: flex; flex-direction: column; }
.data-list__row {
    display: grid;
    grid-template-columns: minmax(0, 40%) minmax(0, 60%);
    gap: 10px;
    padding: 10px 0;
    border-bottom: 1px solid var(--border);
    font-size: 14px;
}
.data-list__row:last-child { border-bottom: none; }
.data-list dt { color: var(--muted); }
.data-list dd { font-weight: 600; text-align: right; }

.period-list { list-style: none; display: flex; flex-direction: column; }
.period-list__item {
    display: grid;
    grid-template-columns: 1fr auto;
    gap: 6px 10px;
    align-items: center;
    padding: 10px 0;
    border-bottom: 1px solid var(--border);
}
.period-list__item:last-child { border-bottom: none; }
.period-list__label { font-weight: 600; font-size: 14px; }
.period-list__by { grid-column: 1 / -1; }

.plain-list { list-style: none; display: flex; flex-direction: column; }
.plain-list__item {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    padding: 12px 0;
    border-bottom: 1px solid var(--border);
}
.plain-list__item:last-child { border-bottom: none; }
.plain-list__meta {
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    gap: 4px;
    flex-shrink: 0;
}

/* ---- Notices ---- */
.notice {
    display: flex;
    gap: 10px;
    align-items: flex-start;
    padding: 12px 14px;
    border-radius: var(--radius-sm);
    font-size: 13.5px;
    line-height: 1.5;
    margin-top: 14px;
}
.notice svg { flex-shrink: 0; margin-top: 1px; }
.notice--info { background: var(--primary-light); color: var(--primary-dark); }
.notice--warn { background: var(--warning-bg); color: #92400E; }
.alert--info { background: var(--primary-light); color: var(--primary-dark); }

/* ---- Context bar on the report form ---- */
.context-bar {
    display: flex;
    align-items: center;
    gap: 12px;
    background: var(--surface);
    border-radius: var(--radius);
    box-shadow: var(--shadow-sm);
    padding: 14px 16px;
}
.context-bar__main { min-width: 0; flex: 1; }
.context-bar__action {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 44px;
    height: 44px;
    border-radius: 10px;
    background: var(--primary-light);
    color: var(--primary);
    flex-shrink: 0;
}

/* ---- Choice pills (service type) ---- */
.choice-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
.choice { position: relative; display: block; }
.choice input {
    position: absolute;
    opacity: 0;
    width: 100%;
    height: 100%;
    margin: 0;
    cursor: pointer;
}
.choice span {
    display: flex;
    align-items: center;
    justify-content: center;
    text-align: center;
    min-height: 56px;
    padding: 10px 12px;
    border: 1.5px solid var(--border);
    border-radius: var(--radius-sm);
    background: #fff;
    font-size: 14px;
    font-weight: 500;
    line-height: 1.3;
    transition: border-color 0.12s, background 0.12s, color 0.12s;
}
.choice input:checked + span {
    border-color: var(--primary);
    background: var(--primary-light);
    color: var(--primary);
    font-weight: 700;
}
.choice input:focus-visible + span {
    outline: 2px solid var(--primary);
    outline-offset: 2px;
}

/* ---- Planned service vs. intervention ----
   The two kinds of work are billed and counted differently, so they are two
   visually separate blocks rather than six interchangeable pills. A technician
   in a hurry has to be able to see which half they are tapping in. */
.kind-choice { display: flex; flex-direction: column; gap: 14px; }
.kind-choice__group {
    border: 1px solid var(--border);
    border-left: 4px solid var(--border-strong);
    border-radius: var(--radius-sm);
    padding: 12px;
    background: #fff;
}
.kind-choice__group--regular { border-left-color: var(--primary); }
.kind-choice__group--intervention { border-left-color: var(--warning); }
.kind-choice__legend {
    margin: 0;
    font-size: 13px;
    font-weight: 700;
    letter-spacing: 0.04em;
    text-transform: uppercase;
}
.kind-choice__group--regular .kind-choice__legend { color: var(--primary); }
.kind-choice__group--intervention .kind-choice__legend { color: var(--warning); }
.kind-choice__hint { margin: 2px 0 10px; }
/* One pill on its own must not stretch to half the row and look like a
   half-finished pair. */
.kind-choice__group--regular .choice-grid { grid-template-columns: 1fr; }

.kind-banner {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 6px;
    margin: 12px 0 0;
    padding: 10px 12px;
    border-radius: var(--radius-sm);
    background: var(--primary-light);
    color: var(--primary);
    font-size: 14px;
}
.kind-banner__label { color: var(--muted); }
.kind-banner[data-kind="INTERVENTION"] {
    background: var(--warning-bg);
    color: var(--warning);
}

/* ---- The kind of work, as a tag ----
   Used in every list and history so the planned/unplanned distinction can be
   read without parsing the sentence around it. Colour is a second cue only;
   the word itself always says which one it is. */
.kind-tag {
    display: inline-block;
    padding: 2px 8px;
    border-radius: 999px;
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 0.03em;
    white-space: nowrap;
    vertical-align: middle;
}
.kind-tag--regular      { background: var(--primary-light); color: var(--primary); }
.kind-tag--intervention { background: var(--warning-bg);    color: var(--warning); }
.kind-tag--unknown      { background: #F3F4F6;              color: var(--muted); }

/* ---- Customer confirmation ---- */
.confirm-summary {
    display: flex;
    align-items: center;
    gap: 12px;
    margin-top: 12px;
    padding: 12px 14px;
    background: var(--success-bg);
    color: var(--success);
    border-radius: var(--radius-sm);
}
.confirm-summary > div { flex: 1; min-width: 0; }
/* A long name, or one typed without spaces, wraps inside the box. */
.confirm-summary .muted { overflow-wrap: anywhere; }
/* Once confirmed, the box stands where the button was — no extra gap. */
.hidden + .confirm-summary { margin-top: 0; }
.confirm-summary__icon { display: inline-flex; flex-shrink: 0; }
.confirm-summary .link { color: var(--success); flex-shrink: 0; }

.confirm-facts { display: flex; flex-direction: column; gap: 8px; margin-bottom: 16px; }
.confirm-facts > div {
    display: grid;
    grid-template-columns: minmax(0, 96px) 1fr;
    gap: 10px;
    font-size: 14px;
}
.confirm-facts dt { color: var(--muted); }
.confirm-facts dd { font-weight: 600; }
.confirm-statement {
    padding: 12px 14px;
    background: var(--bg);
    border-radius: var(--radius-sm);
    font-size: 14px;
    line-height: 1.5;
    margin-bottom: 16px;
}

/* ---- Modal (bottom sheet on phones, centred card on desktop) ---- */
.modal {
    position: fixed;
    inset: 0;
    /* Follow the visible part of the screen when the keyboard is up (ui.js). */
    top: var(--vv-top, 0px);
    bottom: auto;
    height: var(--vv-height, 100%);
    overscroll-behavior: contain;
    z-index: 200;
    background: rgba(15, 23, 42, 0.55);
    display: flex;
    align-items: flex-end;
    justify-content: center;
    animation: fade-in 0.15s;
}
.modal__sheet {
    background: #fff;
    width: 100%;
    max-width: 560px;
    max-height: min(94dvh, var(--vv-height, 94dvh));
    border-radius: var(--radius-lg) var(--radius-lg) 0 0;
    display: flex;
    flex-direction: column;
    animation: sheet-up 0.22s cubic-bezier(0.2, 0.8, 0.3, 1);
}
.modal__head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    padding: 18px 18px 12px;
    border-bottom: 1px solid var(--border);
}
.modal__head h2 { font-size: 18px; font-weight: 700; }
.modal__close {
    width: 40px;
    height: 40px;
    border: none;
    background: #F3F4F6;
    border-radius: 50%;
    font-size: 24px;
    line-height: 1;
    color: var(--muted);
    flex-shrink: 0;
}
.modal__body {
    padding: 18px;
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
    flex: 1;
}
.modal__foot {
    display: flex;
    gap: 10px;
    padding: 14px 18px calc(14px + env(safe-area-inset-bottom));
    border-top: 1px solid var(--border);
    background: #FAFBFC;
}
.modal__foot .btn { flex: 1; min-height: 52px; }
.signature-pad--large { height: 220px; }

@keyframes sheet-up { from { transform: translateY(24px); opacity: 0.6; } to { transform: none; opacity: 1; } }

/* ---- Scanner overlay ---- */
.scan {
    position: fixed;
    inset: 0;
    z-index: 300;
    background: #000;
    display: flex;
    flex-direction: column;
}
.scan__stage { position: absolute; inset: 0; overflow: hidden; }
.scan__video { width: 100%; height: 100%; object-fit: cover; }
.scan__canvas { display: none; }
.scan__reticle {
    position: absolute;
    top: 50%;
    left: 50%;
    width: min(72vw, 300px);
    aspect-ratio: 1 / 1;
    transform: translate(-50%, -55%);
    border: 3px solid rgba(255, 255, 255, 0.9);
    border-radius: 20px;
    box-shadow: 0 0 0 100vmax rgba(0, 0, 0, 0.45);
}
.scan__bar {
    position: relative;
    z-index: 2;
    padding: 16px;
    display: flex;
    gap: 10px;
}
.scan__bar--top {
    padding-top: calc(16px + env(safe-area-inset-top));
    justify-content: space-between;
}
.scan__bar--bottom {
    margin-top: auto;
    flex-direction: column;
    align-items: stretch;
    padding-bottom: calc(20px + env(safe-area-inset-bottom));
}
.scan__icon-btn {
    width: 48px;
    height: 48px;
    border: none;
    border-radius: 50%;
    background: rgba(0, 0, 0, 0.55);
    color: #fff;
    font-size: 26px;
    line-height: 1;
}
.scan__icon-btn.is-on { background: #fff; color: #111; }
.scan__status {
    color: #fff;
    text-align: center;
    font-size: 15px;
    line-height: 1.45;
    text-shadow: 0 1px 3px rgba(0, 0, 0, 0.7);
    min-height: 44px;
}
.scan__status--error { color: #FCA5A5; }
.scan__status--ok { color: #6EE7B7; }
.scan__link {
    background: none;
    border: none;
    color: #fff;
    text-decoration: underline;
    font-size: 14px;
    padding: 14px;
}

/* ---- Empty states ---- */
.empty-state { padding: 32px 20px; text-align: center; }
.empty-state__icon {
    width: 64px;
    height: 64px;
    margin: 0 auto 14px;
    display: grid;
    place-items: center;
    border-radius: 50%;
    background: var(--success-bg);
    color: var(--success);
}
.empty-state__icon--warn { background: var(--warning-bg); color: var(--warning); }
.empty-state h2, .empty-state h3 { font-size: 18px; margin-bottom: 6px; }
.empty-state__actions { display: flex; flex-direction: column; gap: 8px; margin-top: 18px; }

/* ---- Tablet and up ---- */
@media (min-width: 640px) {
    .action-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .choice-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
    .modal { align-items: center; padding: 20px; }
    .modal__sheet { border-radius: var(--radius-lg); max-height: 90dvh; }
    .lift-card {
        flex-direction: row;
        align-items: center;
        justify-content: space-between;
    }
    .lift-card__main { min-width: 0; flex: 1; }
    /* With room to spare the three actions sit side by side again. */
    .lift-card__actions {
        flex-shrink: 0;
        display: flex;
        align-items: center;
    }
    .lift-card__cta { grid-column: auto; }
}

/* ============ LOGIN TABS ============ */
.login-tabs {
    display: flex;
    border-bottom: 1px solid var(--border);
    margin: 0 1.25rem;
}
.login-tabs__tab {
    flex: 1;
    background: none;
    border: none;
    padding: 14px 12px;
    font-size: 14px;
    font-weight: 500;
    color: var(--muted);
    border-bottom: 2px solid transparent;
    transition: color 0.15s, border-color 0.15s;
}
.login-tabs__tab:hover {
    color: var(--text);
}
.login-tabs__tab.is-active {
    color: var(--primary);
    border-bottom-color: var(--primary);
}
.login-form.is-hidden {
    display: none;
}

/* =========================================================================
   SERVICE FLOW — scanning, running services, work orders
   Added with the QR gate. Mobile-first like everything above it: the base
   rules target a 320px phone and the media queries only add space.
   ========================================================================= */

/* ---- Overflow guards ----------------------------------------------------
   Two rules that prevent almost every case of a phone scrolling sideways: a
   grid or flex child defaults to min-width:auto and therefore refuses to
   shrink below its longest word, and a long address or part number has no
   break opportunity of its own. Fixing it here means each component does not
   have to remember to. */
.app-main > * { max-width: 100%; }
.lift-card__main,
.order-card__meta,
.plain-list__text,
.context-bar__main,
.running-card { min-width: 0; }
.lift-card__address,
.order-card__title,
.order-card__desc,
.data-list dd,
.plain-list__text { overflow-wrap: anywhere; }

/* Any table wide enough to need it scrolls inside its own box rather than
   dragging the whole page sideways.

   The negative margin that used to "bleed" this box out to its card's edges is
   gone: `.card` clips its overflow, so the matching padding was never visible,
   and the box measured 36px wider than the viewport on a 320px phone — which
   is what makes a page pan sideways and leaves the fixed action bar looking
   off-centre. Inside a card the container is now exactly as wide as the card. */
.table-scroll {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    max-width: 100%;
}

/* ---- The one way in ---- */
.scan-cta { display: flex; flex-direction: column; gap: 6px; }
.scan-cta__hint { text-align: center; margin: 0; }

.scan__hint {
    color: rgba(255, 255, 255, 0.82);
    font-size: 13px;
    text-align: center;
    margin: 0 0 6px;
}

/* ---- The gate on the lift page ---- */
.gate-card {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: 22px 18px;
    text-align: center;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 10px;
    box-shadow: var(--shadow-sm);
}
.gate-card[data-highlight] { border-color: var(--warning); }
.gate-card__icon {
    width: 56px;
    height: 56px;
    border-radius: 16px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    background: var(--primary-light);
    color: var(--primary);
}
.gate-card__title { font-size: 17px; font-weight: 600; margin: 0; }
.gate-card__text { margin: 0; font-size: 14px; line-height: 1.5; }
.gate-card__text--alert { color: var(--warning); font-weight: 600; }
.gate-card .btn { width: 100%; margin-top: 4px; }
.gate-card--admin { text-align: left; align-items: stretch; }

/* ---- A service with the clock running ---- */
.running-list { display: flex; flex-direction: column; gap: 10px; }
.running-card {
    background: var(--surface);
    border: 1px solid var(--success);
    border-left-width: 4px;
    border-radius: var(--radius);
    padding: 16px;
    display: flex;
    flex-direction: column;
    gap: 10px;
    box-shadow: var(--shadow-sm);
}
.running-card--link { text-decoration: none; color: inherit; }
.running-card--link:hover { text-decoration: none; box-shadow: var(--shadow-md); }
.running-card__head {
    display: flex;
    align-items: center;
    gap: 8px;
    font-size: 15px;
}
.running-card__dot {
    width: 9px;
    height: 9px;
    border-radius: 50%;
    background: var(--success);
    flex-shrink: 0;
    animation: pulse-dot 2s ease-in-out infinite;
}
@keyframes pulse-dot { 50% { opacity: 0.35; } }
@media (prefers-reduced-motion: reduce) {
    .running-card__dot { animation: none; }
}
.running-card__address, .running-card__time { margin: 0; font-size: 14px; }
.running-card__time { font-variant-numeric: tabular-nums; }
.running-card__cta {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    color: var(--primary);
    font-weight: 600;
    font-size: 14px;
}
.running-card__facts {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 10px;
    margin: 0;
}
.running-card__facts dt {
    font-size: 11px;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--muted);
}
.running-card__facts dd {
    margin: 2px 0 0;
    font-size: 17px;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
}
.running-card .btn { width: 100%; }

/* ---- Measured working time on the report form ---- */
.time-strip {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 4px;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: 12px;
    box-shadow: var(--shadow-sm);
}
.time-strip__item {
    display: flex;
    flex-direction: column;
    gap: 2px;
    min-width: 0;
    text-align: center;
}
.time-strip__label {
    font-size: 10.5px;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--muted);
}
.time-strip__value {
    font-size: 15px;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
}

/* ---- Contact details of a lift ----
   Label above value on a phone (names and company names are long), label
   beside value from 560px. The call button is the thing actually used. */
.contact-card {
    background: var(--surface);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-sm);
    padding: 16px 18px;
    display: flex;
    flex-direction: column;
    gap: 10px;
}
.contact-card .section-title { margin-bottom: 0; }
.contact-list { display: flex; flex-direction: column; margin: 0; }
.contact-list__row {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: 1px;
    padding: 8px 0;
    border-bottom: 1px solid var(--border);
    font-size: 14px;
}
.contact-list__row:last-child { border-bottom: none; }
.contact-list dt { color: var(--muted); font-size: 12px; }
.contact-list dd { margin: 0; font-weight: 600; overflow-wrap: anywhere; white-space: pre-line; }
.contact-card__call { min-height: 48px; }
@media (min-width: 560px) {
    .contact-list__row { grid-template-columns: 160px minmax(0, 1fr); gap: 12px; align-items: baseline; }
    .contact-list dt { font-size: 13px; }
}

/* ---- Intervention time on the report form ----
   Typed by the technician; the line under the two fields says back the exact
   duration it works out to, before anybody signs for it. */
.duration-line {
    display: flex;
    align-items: baseline;
    flex-wrap: wrap;
    gap: 4px 10px;
    margin: 4px 0 0;
    padding: 10px 12px;
    border-radius: var(--radius-sm);
    background: var(--bg);
    font-size: 14px;
}
.duration-line__label {
    font-size: 11px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--muted);
}
.duration-line strong { font-variant-numeric: tabular-nums; }
.duration-line.is-ok { background: var(--primary-light); color: var(--primary-dark); }
.duration-line.is-error { background: var(--danger-bg); color: var(--danger); }
.notice--flush { margin-top: 0; }
.field-hint { margin-top: 6px; }
.field-hint:empty { display: none; }

/* ---- Work orders --------------------------------------------------------
   The priority is carried by one coloured rule and one line of text, not by a
   filled red card. A technician sees a dozen of these a week; anything louder
   stops meaning anything by Wednesday. */
.order-list { display: flex; flex-direction: column; gap: 10px; }
.order-list--compact { gap: 8px; }
.section-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
}
.section-head .section-title { margin-bottom: 0; }

.order-card {
    background: var(--surface);
    border: 1px solid var(--border);
    border-left: 4px solid var(--border-strong);
    border-radius: var(--radius-sm);
    padding: 14px;
    display: flex;
    flex-direction: column;
    gap: 8px;
    box-shadow: var(--shadow-sm);
}
.order-card--high { border-left-color: var(--warning); }
.order-card--urgent { border-left-color: var(--danger); }

.order-card__head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 8px;
}
.order-card__flag {
    font-size: 11px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--muted);
}
.order-card--high .order-card__flag { color: var(--warning); }
.order-card--urgent .order-card__flag { color: var(--danger); }
.order-card__no {
    font-size: 12px;
    color: var(--muted);
    font-variant-numeric: tabular-nums;
    flex-shrink: 0;
}
.order-card__title { margin: 0; font-size: 15px; font-weight: 600; line-height: 1.4; }
.order-card__desc { margin: 0; line-height: 1.5; }
.order-card__meta {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 4px 8px;
}
.order-card__lift { font-weight: 600; font-size: 14px; }
.order-card__actions {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
}
.order-card__actions .btn { flex: 1 1 auto; min-height: 44px; }
.btn--sm { padding: 10px 14px; font-size: 14px; }

.tag--urgent { background: var(--danger-bg); color: var(--danger); }

/* ---- Badges ---- */
.badge--region {
    background: var(--primary-light);
    color: var(--primary);
    font-weight: 600;
}
.badge--order { background: var(--warning-bg); color: var(--warning); font-weight: 600; }

/* ---- Lift card as a link ---- */
a.lift-card { text-decoration: none; color: inherit; }
a.lift-card:hover { text-decoration: none; box-shadow: var(--shadow-sm); border-color: var(--primary); }
.lift-card { flex-direction: row; align-items: center; gap: 10px; }
.lift-card__chevron { color: var(--muted); flex-shrink: 0; display: inline-flex; }
.lift-card__no { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; }
.lift-card__status { flex-wrap: wrap; }

/* ---- Customer confirmation ---- */
.confirm-facts {
    display: flex;
    flex-direction: column;
    margin: 0 0 14px;
}
.confirm-facts > div {
    display: grid;
    grid-template-columns: minmax(0, 42%) minmax(0, 58%);
    gap: 10px;
    padding: 8px 0;
    border-bottom: 1px solid var(--border);
    font-size: 14px;
}
.confirm-facts > div:last-child { border-bottom: none; }
.confirm-facts dt { color: var(--muted); margin: 0; }
.confirm-facts dd { margin: 0; font-weight: 600; text-align: right; overflow-wrap: anywhere; }
/* The one number the signature is actually about. */
.confirm-facts__highlight {
    background: var(--primary-light);
    margin: 4px -10px 0;
    padding: 10px !important;
    border-radius: var(--radius-sm);
    border-bottom: none !important;
}
.confirm-facts__highlight dd { color: var(--primary); font-size: 15px; }

.confirm-block { margin-bottom: 12px; }
.confirm-block__title {
    font-size: 11px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--muted);
    margin: 0 0 4px;
}
.confirm-block__text {
    margin: 0;
    font-size: 14px;
    line-height: 1.5;
    overflow-wrap: anywhere;
    /* A very long description must scroll inside the sheet, not push the
       signature pad off the bottom of a small screen. */
    max-height: 30vh;
    overflow-y: auto;
}
.confirm-block__list {
    margin: 0;
    padding-left: 18px;
    font-size: 14px;
    line-height: 1.6;
}

/* ---- Wider screens ---- */
@media (min-width: 560px) {
    .time-strip { padding: 14px 18px; }
    .time-strip__value { font-size: 17px; }
    .gate-card { padding: 28px 24px; }
    .order-card__actions .btn { flex: 0 0 auto; }
}

/* ============ PIN SIGN-IN ============
   A phone-lockscreen pattern: six dots and a keypad. The keypad is the visible
   control because the login happens outdoors, one-handed, often with gloves —
   a 56px target is the point of it, not decoration. */
.pinpad__who {
    display: flex;
    align-items: baseline;
    justify-content: center;
    gap: 8px;
    margin: 0 0 14px;
    font-weight: 600;
    word-break: break-all;
}

.pin-dots {
    display: flex;
    justify-content: center;
    gap: 14px;
    margin: 4px 0 20px;
}
.pin-dot {
    width: 14px;
    height: 14px;
    border-radius: 50%;
    border: 2px solid var(--border-strong);
    background: transparent;
    transition: background 0.12s, border-color 0.12s, transform 0.12s;
}
.pin-dot.is-filled {
    background: var(--primary);
    border-color: var(--primary);
    transform: scale(1.12);
}
@media (prefers-reduced-motion: reduce) { .pin-dot { transition: none; } }

/* Visually hidden, still read by a screen reader (the PIN progress). */
.sr-only {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}

.pinpad {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 10px;
    margin-bottom: 18px;
}
.pinpad__key {
    /* No double-tap zoom and no text selection when keys are hit quickly. */
    touch-action: manipulation;
    -webkit-user-select: none;
    user-select: none;
    min-height: 56px;
    border: 1.5px solid var(--border);
    border-radius: var(--radius-sm);
    background: #fff;
    font-size: 22px;
    font-weight: 600;
    color: var(--text);
    font-variant-numeric: tabular-nums;
    transition: background 0.1s, border-color 0.1s;
}
.pinpad__key:hover { background: var(--primary-light); border-color: var(--primary); }
.pinpad__key:active { background: var(--primary-light); }
.pinpad__key:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }
.pinpad__key--ghost { font-size: 14px; font-weight: 500; color: var(--muted); }

/* =========================================================================
   FEEDBACK — one toast and one confirmation dialog for the whole app
   (static/js/ui.js). Every save, delete and status change ends in one of
   these, so nothing a user does finishes silently.
   ========================================================================= */

/* Top of the screen: the bottom edge is taken by the sticky action bars on
   the report form and the lift page, and a toast underneath a thumb is not
   read. Centred against the viewport, so it stays centred whatever the page
   does horizontally. */
.toast-host {
    position: fixed;
    left: 50%;
    top: calc(12px + env(safe-area-inset-top, 0px));
    transform: translateX(-50%);
    z-index: 400;
    display: flex;
    flex-direction: column;
    gap: 8px;
    align-items: center;
    width: max-content;
    max-width: calc(100vw - 32px);
    pointer-events: none;
}
.toast {
    display: flex;
    align-items: center;
    gap: 10px;
    background: #fff;
    color: var(--text);
    padding: 10px 16px 10px 10px;
    border-radius: 12px;
    border: 1px solid var(--border);
    font-size: 14px;
    font-weight: 500;
    line-height: 1.35;
    box-shadow: var(--shadow-lg);
    animation: toast-in 0.18s ease-out;
    pointer-events: auto;
    cursor: pointer;
    transition: opacity 0.2s, transform 0.2s;
}
.toast.is-leaving { opacity: 0; transform: translateY(-6px); }
.toast__icon {
    width: 28px;
    height: 28px;
    border-radius: 50%;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    color: #fff;
    background: var(--success);
}
.toast__text { min-width: 0; overflow-wrap: anywhere; }
.toast--ok { border-color: #A7F3D0; }
.toast--error { border-color: #FECACA; }
.toast--error .toast__icon { background: var(--danger); }
.toast--info .toast__icon { background: var(--primary); }
@keyframes toast-in { from { opacity: 0; transform: translateY(-8px); } to { opacity: 1; transform: none; } }
@media (prefers-reduced-motion: reduce) { .toast { animation: none; transition: none; } }

.ui-dialog {
    position: fixed;
    inset: 0;
    z-index: 350;
    background: rgba(15, 23, 42, 0.55);
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 16px;
    animation: fade-in 0.15s;
}
.ui-dialog__panel {
    background: #fff;
    width: min(420px, 100%);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-lg);
    padding: 22px 20px 18px;
    display: flex;
    flex-direction: column;
    gap: 10px;
    animation: pop-in 0.18s ease-out;
}
.ui-dialog__title { font-size: 18px; font-weight: 700; line-height: 1.3; margin: 0; }
.ui-dialog__message { font-size: 14px; line-height: 1.55; color: var(--muted); margin: 0; white-space: pre-line; }
.ui-dialog__label { display: flex; flex-direction: column; gap: 6px; font-size: 13px; font-weight: 500; }
.ui-dialog__input {
    width: 100%;
    padding: 10px 12px;
    font: inherit;
    font-size: 16px;
    border: 1.5px solid var(--border);
    border-radius: var(--radius-sm);
    resize: vertical;
}
.ui-dialog__input:focus { outline: none; border-color: var(--primary); }
.ui-dialog__actions { display: flex; gap: 10px; margin-top: 6px; }
.ui-dialog__actions .btn { flex: 1; min-height: 46px; }
@media (min-width: 560px) {
    .ui-dialog__actions { justify-content: flex-end; }
    .ui-dialog__actions .btn { flex: 0 0 auto; min-width: 128px; }
}
.btn--danger:hover { background: #B91C1C; }
.btn[aria-busy="true"] { cursor: progress; }

/* A section scrolled into view (an error, the time block) must not end up
   under the sticky header. */
.form-section, .form-group, .alert { scroll-margin-top: 96px; }

/* =========================================================================
   2026-09 pass: routes, service groups, session notice
   ========================================================================= */

/* The base badge lived only in admin.css, so on the technician pages the
   region and order badges had colour but no shape. */
.badge {
    display: inline-block;
    max-width: 100%;
    padding: 2px 9px;
    border-radius: 999px;
    font-size: 12px;
    font-weight: 600;
    line-height: 1.6;
    white-space: normal;
    overflow-wrap: anywhere;
}
.badge--neutral { background: #F3F4F6; color: var(--text); }
.badge--group { background: #EDE9FE; color: #5B21B6; font-weight: 600; }
.kind-tag--group { background: #EDE9FE; color: #5B21B6; }

/* ---- Today's route on the technician's home page ---- */
.route-card {
    background: var(--surface);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-md);
    border-top: 4px solid var(--accent);
    padding: 16px;
    display: flex;
    flex-direction: column;
    gap: 12px;
}
.route-card__head {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 12px;
}
.route-card__head > div { min-width: 0; }
.route-card__kicker {
    margin: 0;
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--accent);
}
.route-card__title { margin: 2px 0 2px; font-size: 19px; line-height: 1.25; overflow-wrap: anywhere; }
.route-card__progress {
    flex-shrink: 0;
    font-size: 22px;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
    color: var(--primary);
    background: var(--primary-light);
    border-radius: 12px;
    padding: 6px 12px;
    line-height: 1.2;
}
.route-stops { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 8px; }
.route-stop__link {
    display: flex;
    align-items: center;
    gap: 12px;
    min-height: 56px;
    padding: 10px 12px;
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    background: #fff;
    color: inherit;
    text-decoration: none;
}
.route-stop__link:hover { text-decoration: none; border-color: var(--primary); }
.route-stop__pos {
    flex-shrink: 0;
    width: 30px;
    height: 30px;
    border-radius: 50%;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-weight: 700;
    font-size: 14px;
    background: var(--primary-light);
    color: var(--primary);
}
.route-stop--done .route-stop__pos { background: var(--success); color: #fff; }
.route-stop--done .route-stop__link { background: #F7FBF9; }
.route-stop__main { display: flex; flex-direction: column; min-width: 0; flex: 1; }
.route-stop__no { font-weight: 700; font-size: 15px; }
.route-stop__address { font-size: 13px; color: var(--muted); overflow-wrap: anywhere; }
.route-stop .status { flex-shrink: 0; }

/* ---- Service groups (lift page, report form, home, joint report) ---- */
.group-card {
    background: var(--surface);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-sm);
    border-left: 4px solid #7C3AED;
    padding: 14px 16px;
    display: flex;
    flex-direction: column;
    gap: 10px;
}
.group-card__head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 10px;
}
.group-card__head .section-title { margin: 0; min-width: 0; overflow-wrap: anywhere; }
.group-card__head .tag { flex-shrink: 0; white-space: nowrap; }
.group-card__hint { margin: 0; line-height: 1.5; }
.group-lifts {
    list-style: none;
    margin: 0;
    padding: 0;
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(min(100%, 180px), 1fr));
    gap: 6px;
}
.group-lifts__item {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 4px 8px;
    padding: 8px 10px;
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    background: #fff;
    min-width: 0;
}
.group-lifts__item.is-current { border-color: #7C3AED; box-shadow: 0 0 0 1px #7C3AED inset; }
/* A service number is never split: it moves the status under it instead. */
.group-lifts__no { font-weight: 700; font-size: 14px; white-space: nowrap; }
.group-lifts__item .status { flex-shrink: 0; }
.group-result { text-align: left; margin-top: 12px; display: flex; flex-direction: column; gap: 10px; }
.group-entry__head { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; }
.group-entry__title { font-size: 17px; margin: 0; }
.group-entry__discard { color: var(--danger); padding: 10px 4px; }
.group-entry .data-list { margin: 8px 0 12px; }

/* Two fields that stay side by side on a tablet and stack on a phone. */
.form-row--stack { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
@media (max-width: 520px) { .form-row--stack { grid-template-columns: 1fr; } }

/* ---- Session about to end (static/js/session.js) ---- */
.session-warning {
    position: fixed;
    left: 50%;
    bottom: calc(16px + env(safe-area-inset-bottom, 0px));
    transform: translateX(-50%);
    z-index: 450;
    width: min(460px, calc(100vw - 24px));
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 10px 14px;
    padding: 14px 16px;
    background: #1F2937;
    color: #fff;
    border-radius: var(--radius);
    box-shadow: var(--shadow-lg);
}
.session-warning__text { margin: 0; flex: 1 1 220px; font-size: 14px; line-height: 1.45; }
.session-warning__btn { flex: 0 0 auto; min-height: 44px; }
@media (max-width: 420px) { .session-warning__btn { width: 100%; } }

/* =========================================================================
   Joint monthly service of a service group (templates/group_service.html)
   One scan, every lift of the group in one form. Mobile first.
   ========================================================================= */

/* The single report form after scanning a grouped lift: with the regular
   service selected there is nothing to fill in here, so everything below the
   choice of work folds away and the button leads to the joint service. */
#report-form.is-group-service > .card-body > .form-section:not(:first-child) { display: none; }

.gs-offer .btn { margin: 12px 0 4px; }

.gs-lifts {
    list-style: none;
    margin: 12px 0 8px;
    padding: 0;
    display: grid;
    gap: 6px;
}
.gs-lift__label {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 4px 10px;
    min-height: 48px;
    padding: 8px 12px;
    background: #fff;
    border: 1px solid var(--border);
    border-radius: 10px;
    cursor: pointer;
}
.gs-lift__label input { width: 22px; height: 22px; accent-color: var(--primary); flex-shrink: 0; }
.gs-lift__no { font-weight: 700; font-variant-numeric: tabular-nums; }
.gs-lift__addr { flex: 1 1 160px; min-width: 0; }
.gs-lift__tick { width: 22px; text-align: center; color: var(--success, #047857); font-weight: 700; }
.gs-lift--off .gs-lift__label { background: transparent; cursor: default; opacity: 0.8; }

.chip--small {
    margin: 0;
    padding: 2px 8px;
    font-size: 11px;
    color: var(--primary);
    background: var(--primary-light);
    border-color: transparent;
}

.gs-defects { display: grid; gap: 10px; margin: 8px 0 10px; }
.gs-defect {
    padding: 12px;
    border: 1px solid var(--border);
    border-left: 4px solid var(--warning, #D97706);
    border-radius: 10px;
    background: #fff;
}
.gs-defect__head { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.gs-defect__title { font-size: 15px; }
.gs-defect__remove { min-height: 44px; flex-shrink: 0; }

/* ---- Which lift a defect belongs to ----
   One card per lift with number and address, a radio the size of a thumb,
   and an unmistakable selected state. A small <select> made it far too easy
   to file a defect on the lift next door. */
.gs-liftpick { border: 0; margin: 10px 0 0; padding: 0; min-width: 0; }
.gs-liftpick__legend { font-size: 14px; font-weight: 700; margin-bottom: 8px; padding: 0; }
.gs-liftpick__search { width: 100%; min-height: 48px; font-size: 16px; margin-bottom: 8px; }
.gs-liftpick__list {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(min(100%, 220px), 1fr));
    gap: 8px;
    max-height: 360px;
    overflow-y: auto;
    padding: 2px;
    -webkit-overflow-scrolling: touch;
}
.gs-liftpick__opt {
    position: relative;
    display: flex;
    align-items: center;
    gap: 12px;
    min-height: 64px;
    padding: 10px 12px;
    border: 2px solid var(--border-strong);
    border-radius: 10px;
    background: #fff;
    cursor: pointer;
    transition: border-color 0.12s, background 0.12s;
}
.gs-liftpick__opt[hidden] { display: none; }
.gs-liftpick__opt input { position: absolute; opacity: 0; width: 1px; height: 1px; pointer-events: none; }
.gs-liftpick__mark {
    width: 26px;
    height: 26px;
    flex-shrink: 0;
    border: 2px solid var(--border-strong);
    border-radius: 50%;
    background: #fff;
    display: grid;
    place-items: center;
}
.gs-liftpick__text { display: grid; min-width: 0; gap: 2px; }
.gs-liftpick__no { font-size: 17px; font-variant-numeric: tabular-nums; overflow-wrap: anywhere; }
.gs-liftpick__addr { font-size: 13px; color: var(--muted); overflow-wrap: anywhere; line-height: 1.3; }
.gs-liftpick__opt:hover { border-color: var(--primary); }
.gs-liftpick__opt:has(input:focus-visible) { outline: 3px solid var(--primary-light); outline-offset: 1px; }
.gs-liftpick__opt.is-selected { border-color: var(--primary); background: var(--primary-light); }
.gs-liftpick__opt.is-selected .gs-liftpick__mark { border-color: var(--primary); background: var(--primary); }
.gs-liftpick__opt.is-selected .gs-liftpick__mark::after {
    content: "";
    width: 12px;
    height: 7px;
    border-left: 3px solid #fff;
    border-bottom: 3px solid #fff;
    transform: translateY(-2px) rotate(-45deg);
}
.gs-liftpick__picked { margin-top: 6px; font-weight: 600; color: var(--primary); }
.gs-liftpick__picked.is-empty { color: var(--warning); }
.gs-liftpick.is-invalid .gs-liftpick__list { outline: 2px solid var(--danger); outline-offset: 3px; border-radius: 10px; }
.gs-liftpick.is-invalid .gs-liftpick__picked { color: var(--danger); }
.gs-defect .form-group { margin-top: 10px; margin-bottom: 0; }
/* The label wraps its input, so a screen reader names each field. */
.gs-defect__field { display: grid; gap: 6px; font-size: 13px; font-weight: 600; }
.gs-defect__field input { font-weight: 400; }

.gs-confirm-table { width: 100%; border-collapse: collapse; font-size: 14px; }
.gs-confirm-table th,
.gs-confirm-table td { padding: 6px 8px; border-bottom: 1px solid var(--border); text-align: left; vertical-align: top; }
.gs-confirm-table th { font-size: 12px; color: var(--muted); font-weight: 600; }
.gs-confirm-table td:first-child { font-weight: 700; white-space: nowrap; }

/* =========================================================================
   Lookup pages for employees (app/routes/technician.py): lifts, reports,
   monthly services, service groups. Cards on a phone, never a wide table.
   ========================================================================= */
.tl-filters {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: 10px;
    margin-bottom: 14px;
}
.tl-filters .form-group { margin: 0; }
@media (min-width: 640px) {
    .tl-filters { grid-template-columns: minmax(0, 2fr) repeat(auto-fit, minmax(140px, 1fr)); align-items: end; }
    .tl-filters .btn { min-height: 50px; }
}
.tl-scope { margin: 0 0 10px; }
.tl-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 8px; }
.tl-item {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    min-height: 56px;
    padding: 12px 14px;
    background: #fff;
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    color: var(--text);
}
.tl-item:hover { border-color: var(--primary); text-decoration: none; }
.tl-item__main { display: grid; gap: 2px; min-width: 0; }
.tl-item__no { font-variant-numeric: tabular-nums; }
.tl-item__text { font-size: 14px; }
.tl-item .status, .tl-item .kind-tag { flex-shrink: 0; }
.tl-pager { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin: 16px 0; }
.tl-empty { padding: 24px 0; text-align: center; }
.tl-back { margin: 16px 0; }
.tl-summary { margin-bottom: 12px; }

/* ---- Home: "Završeno ovaj mjesec" under the month figures ---- */
.done-month { margin-top: 14px; border-top: 1px solid var(--border); padding-top: 10px; }
.done-month > summary { cursor: pointer; font-weight: 600; font-size: 14px; min-height: 44px; display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.done-month__list { list-style: none; margin: 6px 0 0; padding: 0; display: grid; gap: 4px; }
.done-month__item {
    display: grid;
    grid-template-columns: 44px minmax(0, 1fr) auto;
    align-items: center;
    gap: 8px;
    padding: 8px 4px;
    color: var(--text);
    border-bottom: 1px solid var(--border);
}
a.done-month__item:hover { background: var(--bg); text-decoration: none; }
.done-month__date { font-variant-numeric: tabular-nums; color: var(--muted); font-size: 13px; }
.done-month__lift { display: grid; min-width: 0; }

/* =========================================================================
   "Predati drugi radni nalog" (templates/external_order.html): photographing
   another firm's paper work order. Big targets for a thumb in a glove, the
   pages as numbered tiles, and nothing that can be tapped twice by accident.
   ========================================================================= */
.xo-intro p + p { margin-top: 4px; }
.xo-pick { display: grid; gap: 10px; }
.xo-pick__btn { cursor: pointer; }
.xo-pick__btn.is-disabled { opacity: 0.5; pointer-events: none; }
/* Visually hidden, still reachable: iOS opens the camera from the label. */
.xo-file {
    position: absolute;
    width: 1px;
    height: 1px;
    opacity: 0;
    overflow: hidden;
    pointer-events: none;
}
.xo-empty {
    display: flex;
    align-items: center;
    gap: 12px;
    margin-top: 14px;
    padding: 14px;
    border: 1.5px dashed var(--border-strong);
    border-radius: var(--radius-sm);
}
.xo-empty__icon { color: var(--muted); flex-shrink: 0; }
.xo-grid {
    list-style: none;
    margin: 14px 0 0;
    padding: 0;
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(104px, 1fr));
    gap: 10px;
}
.xo-grid:empty { display: none; }
.xo-thumb {
    position: relative;
    aspect-ratio: 3 / 4;
    border-radius: var(--radius-sm);
    overflow: hidden;
    background: #EEF1F5;
    box-shadow: var(--shadow-sm);
}
.xo-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.xo-thumb__no {
    position: absolute;
    left: 6px;
    bottom: 6px;
    min-width: 26px;
    height: 26px;
    padding: 0 7px;
    border-radius: 13px;
    background: rgba(15, 23, 42, 0.72);
    color: #fff;
    font-size: 13px;
    font-weight: 700;
    display: grid;
    place-items: center;
}
/* 40px: the remove control is the one thing on this page that must not be
   missed, nor hit instead of the photo next to it. */
.xo-thumb__remove {
    position: absolute;
    top: 4px;
    right: 4px;
    width: 40px;
    height: 40px;
    border: 2px solid #fff;
    border-radius: 50%;
    background: rgba(15, 23, 42, 0.72);
    color: #fff;
    font-size: 22px;
    line-height: 1;
    display: grid;
    place-items: center;
    cursor: pointer;
}
.xo-thumb__remove:hover, .xo-thumb__remove:focus-visible { background: var(--danger); }
.xo-thumb__remove:disabled { opacity: 0.4; cursor: not-allowed; }
.xo-thumb.is-busy { display: grid; place-items: center; }
.xo-thumb__spin {
    width: 30px;
    height: 30px;
    border-radius: 50%;
    border: 3px solid var(--border-strong);
    border-top-color: var(--primary);
    animation: xo-spin 0.8s linear infinite;
}
@keyframes xo-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { .xo-thumb__spin { animation-duration: 3s; } }
.xo-count { margin-top: 8px; min-height: 18px; }
.xo-progress { margin-top: 12px; display: grid; gap: 6px; }
.xo-progress .progress__bar { transition: width 0.2s ease; background: var(--primary); }
.xo-recent { list-style: none; margin: 8px 0 0; padding: 0; display: grid; gap: 6px; }
.xo-recent__item {
    display: grid;
    grid-template-columns: 48px minmax(0, 1fr) auto;
    align-items: center;
    gap: 10px;
    padding: 8px 0;
    border-bottom: 1px solid var(--border);
}
.xo-recent__item:last-child { border-bottom: 0; }
.xo-recent__thumb {
    width: 48px;
    height: 48px;
    border-radius: 6px;
    object-fit: cover;
    background: #EEF1F5;
    display: block;
}
.xo-recent__main { display: grid; min-width: 0; }
.xo-recent__main .small { overflow-wrap: anywhere; }

/* ---- Monthly service by year (templates/_period_years.html) ---- */
/* Sized by the box it sits in, not by the screen: the admin page puts it in
   a narrow card, the technician's page across the full width. Half a year
   per row when narrow, the whole year in one row when there is room. */
.py-list { display: grid; gap: 8px; container-type: inline-size; }
.py-year { border: 1px solid var(--border); border-radius: var(--radius-sm); background: #fff; }
.py-year.is-current { border-color: var(--primary-light); }
.py-year__head {
    display: flex;
    align-items: center;
    gap: 10px;
    min-height: 44px;
    padding: 8px 12px;
    cursor: pointer;
    list-style: none;
}
.py-year__head::-webkit-details-marker { display: none; }
.py-year__label { font-weight: 700; font-size: 15px; font-variant-numeric: tabular-nums; }
.py-year__sum { display: flex; flex-wrap: wrap; gap: 4px; flex: 1; min-width: 0; }
.py-year__caret { color: var(--muted); font-size: 18px; transition: transform 0.15s; }
.py-year[open] .py-year__caret { transform: rotate(90deg); }
.py-tag { font-size: 11.5px; font-weight: 600; padding: 1px 7px; border-radius: 999px; white-space: nowrap; }
.py-tag--done { background: var(--success-bg); color: var(--success); }
.py-tag--open { background: var(--primary-light); color: var(--primary); }
.py-tag--overdue { background: var(--danger-bg); color: var(--danger); }
.py-tag--skipped { background: #F3F4F6; color: var(--muted); }
.py-months {
    list-style: none;
    margin: 0;
    padding: 0 12px 12px;
    display: grid;
    grid-template-columns: repeat(6, minmax(0, 1fr));
    gap: 4px;
}
@container (min-width: 600px) { .py-months { grid-template-columns: repeat(12, minmax(0, 1fr)); } }
.py-month {
    display: grid;
    justify-items: center;
    gap: 1px;
    padding: 5px 2px;
    border-radius: 6px;
    background: #F3F4F6;
    color: var(--muted);
    font-size: 11.5px;
    line-height: 1.2;
}
.py-month__name { font-weight: 600; }
.py-month__state { font-size: 14px; font-weight: 700; }
.py-month--done { background: var(--success-bg); color: var(--success); }
.py-month--open { background: var(--primary-light); color: var(--primary); }
.py-month--overdue { background: var(--danger-bg); color: var(--danger); }
.py-month--skipped { background: #F3F4F6; color: var(--muted); }
.py-month--none { background: transparent; border: 1px dashed var(--border-strong); color: #9CA3AF; }
.py-month.is-now { box-shadow: 0 0 0 2px var(--primary); }

/* ---- "Moje rute" (templates/tech_routes.html) ---- */
.mr-card { display: flex; flex-direction: column; gap: 10px; }
.mr-card.is-today { border-color: var(--primary); }
.mr-card__note { margin-top: 4px; }
.mr-card__stops > summary {
    cursor: pointer;
    min-height: 44px;
    display: flex;
    align-items: center;
    font-weight: 600;
    font-size: 14px;
}
.mr-card__stops[open] > summary { margin-bottom: 6px; }

/* ---- Home: the two actions under the scan button ---- */
.home-actions { display: grid; gap: 10px; margin-bottom: 16px; }
@media (min-width: 640px) { .home-actions { grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); } }
.home-action {
    display: flex;
    align-items: center;
    gap: 12px;
    min-height: 64px;
    padding: 12px 14px;
    background: #fff;
    border: 1px solid var(--border);
    border-radius: var(--radius);
    box-shadow: var(--shadow-sm);
    color: var(--text);
}
.home-action:hover { border-color: var(--primary); text-decoration: none; }
.home-action__icon {
    width: 42px; height: 42px; flex-shrink: 0; border-radius: 10px;
    background: var(--primary-light); color: var(--primary); display: grid; place-items: center;
}
.home-action__text { display: grid; gap: 2px; min-width: 0; flex: 1; }
.home-action__text strong { overflow-wrap: anywhere; }
.home-action__arrow { color: var(--muted); flex-shrink: 0; }
