/* ==========================================================================
   Font: Barlow - free to use and close in character to DIN.
   Deliberately bundled LOCALLY instead of loading from Google's servers:
   this way the app also works offline, loads faster, and no visitor data
   is sent to a third party (a real concern in the EU with embedded Google
   Fonts).
   ========================================================================== */
@font-face {
  font-family: "Barlow"; font-style: normal; font-weight: 400; font-display: swap;
  src: url("/static/fonts/barlow-latin-400-normal.woff2") format("woff2");
}
@font-face {
  font-family: "Barlow"; font-style: normal; font-weight: 500; font-display: swap;
  src: url("/static/fonts/barlow-latin-500-normal.woff2") format("woff2");
}
@font-face {
  font-family: "Barlow"; font-style: normal; font-weight: 600; font-display: swap;
  src: url("/static/fonts/barlow-latin-600-normal.woff2") format("woff2");
}
@font-face {
  font-family: "Barlow"; font-style: normal; font-weight: 700; font-display: swap;
  src: url("/static/fonts/barlow-latin-700-normal.woff2") format("woff2");
}

/* ==========================================================================
   RH Racing Tool - visual design
   Mobile-first: base rules apply to the phone, the @media rule below
   extends the layout for the counter PC.
   ========================================================================== */

:root {
  --navy:        #0f172a;
  --navy-light:   #1e293b;
  --navy-border:   #334155;
  --navy-text:   #cbd5e1;
  --navy-faint:#64748b;

  --accent:      #c81a27;      /* red only as an accent, as in the B2B portal */
  --accent-dark:#a3141f;
  --accent-light: #fdeced;
  --dark:      #17181a;      /* button colour: near-black instead of a bright colour */
  --dark-hover:#000000;

  --bg:          #f2f2f2;
  --card:       #ffffff;
  --text:        #17181a;
  --text-gray:   #64748b;
  --border:        #e3e3e3;

  --green:       #16a34a;
  --green-light:  #dcfce7;
  --yellow:        #ca8a04;
  --yellow-light:   #fef9c3;
  --red:         #dc2626;
  --red-light:    #fee2e2;
  --blue:        #2563eb;
  --blue-light:   #dbeafe;

  --r:           8px;
  --sidebar-w:   236px;
}

* { box-sizing: border-box; }

body {
  margin: 0;
  font-family: "Barlow", Roboto, Helvetica, Arial, sans-serif;
  background: var(--bg);
  color: var(--text);
  font-size: 16px;
  line-height: 1.5;
  -webkit-tap-highlight-color: transparent;
}

h1 { font-size: 1.65rem; margin: 0 0 4px; font-weight: 700; letter-spacing: -0.015em; }
h2 { font-size: 1.05rem; margin: 0 0 12px; font-weight: 700; letter-spacing: -0.01em; }
.page-hint { color: var(--text-gray); font-size: .9rem; margin: 0 0 20px; }

/* ---------- Layout ---------- */
.layout { display: flex; min-height: 100vh; }

.sidebar {
  position: fixed; top: 0; bottom: 0; left: 0; z-index: 40;
  width: var(--sidebar-w);
  background: var(--navy); color: var(--navy-text);
  display: flex; flex-direction: column;
  transform: translateX(-100%); transition: transform .2s ease;
}
.sidebar.open { transform: translateX(0); }

/* The logo sits in the middle of the sidebar, with the same air left and
   right - before this it was pushed against the right-hand edge. */
.brand { padding: 18px 16px; font-size: 1.15rem; font-weight: 800; color: #fff;
         border-bottom: 1px solid var(--navy-light);
         display: flex; justify-content: center; }
.brand a { display: block; }
.brand span { color: var(--accent); }

/* The sidebar list scrolls when the window is too short for all entries.
   The scroll bar itself should not sit there permanently: its width is
   always reserved (so nothing shifts), only the bar is invisible while
   nothing happens. It appears while scrolling and on hover, and the
   script in base.html removes the class again 1 s after the last scroll.
   Scrolling itself is never restricted - only the display is hidden. */
.nav { flex: 1; overflow-y: auto; padding: 8px 0;
       scrollbar-width: thin; scrollbar-color: transparent transparent;
       transition: scrollbar-color .25s ease; }
.nav::-webkit-scrollbar { width: 8px; }
.nav::-webkit-scrollbar-track { background: transparent; }
.nav::-webkit-scrollbar-thumb {
  background: transparent; border-radius: 4px; transition: background .25s ease;
}
.nav.scrollt, .nav:hover { scrollbar-color: rgba(255,255,255,.34) transparent; }
.nav.scrollt::-webkit-scrollbar-thumb,
.nav:hover::-webkit-scrollbar-thumb { background: rgba(255,255,255,.34); }
.nav-title { font-size: .68rem; text-transform: uppercase; letter-spacing: .08em;
             color: var(--navy-faint); padding: 16px 18px 6px; font-weight: 700; }
.nav a {
  display: flex; align-items: center; gap: 10px;
  color: var(--navy-text); text-decoration: none;
  padding: 11px 18px; font-size: .93rem;
  border-left: 3px solid transparent;
}
.nav a:hover { background: var(--navy-light); }
.nav a.active { background: var(--navy-light); color: #fff; border-left-color: var(--accent); font-weight: 600; }
.nav-icon { width: 20px; text-align: center; opacity: .85; }

.nav-foot { border-top: 1px solid var(--navy-light); padding: 14px 18px;
            display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.nav-foot .who { color: #fff; font-weight: 600; font-size: .88rem; }
.nav-foot .rolle { color: var(--navy-faint); font-size: .75rem; }
.nav-foot a { color: var(--navy-faint); text-decoration: none; font-size: .8rem; }
.nav-foot a:hover { color: #fff; }
.nav-foot-text { min-width: 0; }
/* Settings: the gear in the footer (no own row in the list above). */
.nav-foot a.nav-gear {
  flex: none; width: 36px; height: 36px; display: flex; align-items: center; justify-content: center;
  border-radius: var(--r); font-size: 1.15rem; line-height: 1; color: var(--navy-faint);
}
.nav-foot a.nav-gear:hover { background: var(--navy-light); color: #fff; }
.nav-foot a.nav-gear.active { background: var(--navy-light); color: #fff; }

/* Burger on the LEFT, logo right next to it (v16). The tap area stays at
   least as big as before: the button keeps its 1.5rem glyph and gets a
   fixed 44x44 px box, the minimum comfortable size on a phone. */
.mobile-head {
  display: flex; align-items: center; justify-content: flex-start; gap: 10px;
  background: var(--navy); color: #fff; padding: 13px 16px;
  position: sticky; top: 0; z-index: 30;
}
.mobile-head .brand-small { font-weight: 800; font-size: 1rem; }
.mobile-head .brand-small span { color: var(--accent); }
.burger {
  background: none; border: none; color: #fff; font-size: 1.5rem; cursor: pointer;
  line-height: 1; padding: 0; margin: -8px 0; flex: none;
  min-width: 44px; min-height: 44px;
  display: inline-flex; align-items: center; justify-content: center;
}

.backdrop { display: none; position: fixed; inset: 0; background: rgba(15,23,42,.55); z-index: 35; }
.backdrop.on { display: block; }

.content { flex: 1; min-width: 0; }
main { padding: 18px 16px 60px; width: 100%; }

/* ---------- Cards ---------- */
.card {
  background: var(--card); border: 1px solid var(--border);
  border-radius: var(--r); padding: 16px; margin-bottom: 14px;
}
.card-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-bottom: 12px; }
.card-head h2 { margin: 0; }
.step-no {
  display: inline-flex; align-items: center; justify-content: center;
  width: 22px; height: 22px; border-radius: 50%;
  background: var(--accent); color: #fff; font-size: .78rem; font-weight: 700;
  margin-right: 8px; flex-shrink: 0;
}

/* ---------- Forms ---------- */
label { display: block; font-weight: 600; margin: 12px 0 5px; font-size: .85rem; color: #334155; }
label:first-child { margin-top: 0; }

input[type=text], input[type=tel], input[type=search], input[type=password],
input[type=number], input[type=date], input[type=time], input[type=datetime-local],
select, textarea {
  width: 100%; padding: 11px 12px; font-size: 1rem;
  border: 1px solid var(--border); border-radius: var(--r);
  background: #fff; color: var(--text); font-family: inherit;
}
input:focus, select:focus, textarea:focus {
  outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-light);
}
textarea { min-height: 90px; resize: vertical; }

.field-row { display: flex; gap: 8px; align-items: stretch; }
.field-row > input { flex: 1; min-width: 0; }
.dial-code-field {
  width: 4.5ch; min-width: 0; flex: none !important; text-align: center;
  padding-left: 6px; padding-right: 6px;
}

.check-row { display: flex; align-items: center; gap: 9px; margin: 10px 0; }
.check-row input { width: 19px; height: 19px; flex: none; accent-color: var(--accent); }
.check-row label { margin: 0; font-weight: 500; font-size: .93rem; }

/* ---------- Buttons ---------- */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  font-size: .95rem; font-weight: 600; font-family: inherit;
  padding: 11px 18px; border-radius: var(--r); border: 1px solid transparent;
  cursor: pointer; text-decoration: none; min-height: 44px;
}
.btn-primary { background: var(--dark); color: #fff; }
.btn-primary:hover { background: var(--dark-hover); }
.btn-gray { background: #fff; color: #334155; border-color: var(--border); }
.btn-gray:hover { background: var(--bg); }
.btn-green { background: var(--green); color: #fff; }
/* WhatsApp / Benachrichtigen in der To-Do-Liste (v20): weiss mit Rahmen
   statt kräftig grün - neben jedem Eintrag stand sonst ein grüner Block.
   Das Zeichen bleibt grün, damit der Knopf trotzdem sofort erkennbar ist. */
.btn-wa {
  background: #fff; color: var(--green); border: 1px solid var(--border);
  display: inline-flex; align-items: center; gap: 7px;
}
.btn-wa svg { width: 18px; height: 18px; display: block; flex: none; }
.btn-wa:hover, .btn-wa:focus { border-color: var(--green); background: #fff; }
/* Am Handy nur das Zeichen, sonst wird die To-Do-Zeile zu voll. */
@media (max-width: 700px) { .btn-wa-text { display: none; } }
.btn-yellow  { background: var(--yellow);  color: #fff; }
.btn-blue  { background: var(--blue);  color: #fff; }
.btn-rot   { background: var(--red);   color: #fff; }
.btn-block { display: flex; width: 100%; }
.btn-small { padding: 7px 12px; font-size: .84rem; min-height: 36px; }
.btn-large { padding: 15px 20px; font-size: 1.05rem; min-height: 52px; }
.btn-row { display: flex; gap: 8px; flex-wrap: wrap; }
/* Every button/form in a button row takes up equal width by default,
   so the row fills the screen evenly instead of each button just
   sizing to its own text. */
.btn-row > .btn, .btn-row > form { flex: 1 1 0; }

/* Repair actions: three groups, told apart by a gap and a fine line only
   (no headings, no hint texts). On a phone they stack, the line goes
   above each group instead of beside it. */
/* A .btn carries display:inline-flex, which would otherwise beat the
   [hidden] attribute - a button stepping aside (e.g. "Abgeholt") would
   keep its space. */
.btn[hidden] { display: none; }
.action-bar { gap: 14px; }
.btn-group { display: flex; gap: 8px; flex: 1 1 0; min-width: 0; }
.btn-group > .btn, .btn-group > form, .btn-group > .wait-block { flex: 1 1 0; min-width: 0; }
.btn-group + .btn-group { border-left: 1px solid var(--border); padding-left: 14px; }
/* In the repair action bar the separating gap is a touch narrower, so all
   six buttons still fit side by side at the same width. */
.action-bar .btn-group + .btn-group { padding-left: 8px; }
/* Greyed out: a disabled button is dead, "faded" can still be pressed. */
.btn[disabled], .btn-off { background: #f1f5f9; color: #94a3b8; border-color: var(--border);
    box-shadow: none; cursor: default; }
.btn[disabled]:hover, .btn-off:hover { background: #f1f5f9; }
.btn-faded { opacity: .62; }
/* v20: all six action buttons are exactly the same width and height,
   whether they sit next to each other (desktop) or below each other
   (phone). A grid of equal columns guarantees that no matter how long a
   label is - minmax(0, 1fr) keeps the longest word from widening its own
   column. Each button is its own form, so the form has to stretch too. */
.action-bar .btn-group { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); }
.action-bar .btn-group > form { display: flex; min-width: 0; }
.action-bar .btn { width: 100%; height: 100%; justify-content: center; text-align: center;
  /* The longest label ("Benachrichtigen") is a single word that cannot
     wrap, so padding and type size are trimmed just enough that it fits
     into the equal share every button gets. */
  padding-left: 6px; padding-right: 6px; font-size: .85rem; min-width: 0; }
/* ---------- Language switch (3 positions) ---------- */
.language-switch { display: inline-flex; border: 1px solid var(--border); border-radius: var(--r); overflow: hidden; background: #fff; }
.language-switch label {
  margin: 0; padding: 9px 15px; cursor: pointer; font-weight: 600; font-size: .9rem;
  display: flex; align-items: center; gap: 6px; color: var(--text-gray);
  border-right: 1px solid var(--border);
}
.language-switch label:last-child { border-right: none; }
.language-switch input { position: absolute; opacity: 0; pointer-events: none; }
.language-switch input:checked + label,
.language-switch label:has(input:checked) { background: var(--accent); color: #fff; }

/* ---------- Task chips ---------- */
.chip-grid { display: flex; flex-wrap: wrap; gap: 7px; }
.chip {
  display: inline-flex; align-items: center; gap: 6px;
  background: #fff; border: 1px solid var(--border); border-radius: 999px;
  padding: 7px 13px; font-size: .87rem; cursor: pointer; font-family: inherit;
}
.chip:hover { border-color: var(--accent); color: var(--accent-dark); }
.chip.chip-active { background: var(--accent); border-color: var(--accent); color: #fff; }
.pages-group { display: inline-flex; align-items: center; gap: 0; background: #fff;
                 border: 1px solid var(--border); border-radius: 999px; overflow: hidden; }
.pages-group .page-name { padding: 7px 11px 7px 13px; font-size: .87rem; }
.pages-group button {
  border: none; border-left: 1px solid var(--border); background: #fff;
  padding: 7px 10px; font-size: .8rem; font-weight: 600; cursor: pointer;
  color: var(--text-gray); font-family: inherit;
}
.pages-group button:hover { background: var(--accent); color: #fff; }

/* ---------- Customer search results list ---------- */
/* All hits are shown, not just the first few (v16). With many of them
   the list stays this high and scrolls inside, so the page underneath
   doesn't get pushed apart. */
.hits { list-style: none; padding: 0; margin: 8px 0 0;
           border: 1px solid var(--border); border-radius: var(--r);
           max-height: 44vh; overflow-y: auto; overscroll-behavior: contain; }
.hits-more { color: var(--text-gray); font-size: .82rem; margin: 4px 2px 0; }
.hits li { padding: 11px 13px; border-bottom: 1px solid var(--border); cursor: pointer; }
.hits li:last-child { border-bottom: none; }
.hits li:hover { background: var(--accent-light); }
.hits .hit-name { font-weight: 600; }
.hits .hit-phone { color: var(--text-gray); font-size: .85rem; }

.selected-box {
  background: var(--accent-light); border: 1px solid #fed7aa;
  border-radius: var(--r); padding: 12px 14px;
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
}

/* ---------- Table / dashboard ---------- */
.table-wrap { overflow-x: auto; -webkit-overflow-scrolling: touch; }
table.list { width: 100%; border-collapse: collapse; font-size: .92rem; }
table.list th {
  text-align: left; font-size: .7rem; text-transform: uppercase; letter-spacing: .05em;
  color: var(--text-gray); padding: 10px 12px; border-bottom: 1px solid var(--border); white-space: nowrap;
}
table.list td { padding: 12px; border-bottom: 1px solid var(--border); vertical-align: middle; }
table.list tr:last-child td { border-bottom: none; }
table.list tbody tr { cursor: pointer; }
table.list tbody tr:hover { background: var(--bg); }

/* Status colour as a left-edge stripe on the repairs table. This is the
   leftmost pixel of the row, so on a narrow phone it's visible right away
   without having to scroll sideways to reach the "Status" column. */
table.list tbody tr[data-status] { border-left: 5px solid transparent; }
table.list tbody tr[data-status="Angenommen"]           { border-left-color: var(--blue); }
table.list tbody tr[data-status="In Arbeit"]             { border-left-color: var(--orange); }
table.list tbody tr[data-status="Pausiert"]              { border-left-color: var(--yellow); }
table.list tbody tr[data-status="Ersatzteil"]             { border-left-color: var(--red); }
table.list tbody tr[data-status="Anfrage"]                { border-left-color: #7c3aed; }
table.list tbody tr[data-status="Fertig"]                { border-left-color: var(--green); }
table.list tbody tr[data-status="Abgeholt"]              { border-left-color: #94a3b8; }
.no { font-weight: 700; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; color: var(--accent-dark); white-space: nowrap; }

/* ---------- Status badges ---------- */
.badge { display: inline-block; padding: 4px 11px; border-radius: 999px;
         font-size: .78rem; font-weight: 600; white-space: nowrap; }
.badge-accepted { background: var(--blue-light);  color: #1d4ed8; }
.badge-working     { background: #ffedd5;            color: #c2410c; }
.badge-paused   { background: var(--yellow-light);  color: #a16207; }
.badge-part { background: var(--red-light);   color: #b91c1c; }
.badge-done     { background: var(--green-light); color: #15803d; }
.badge-collected   { background: #e2e8f0;           color: #475569; }

/* Row at the end of a long list: as soon as it scrolls into view, the
   next rows are loaded in its place (articles, movements). */
.reload-row td { text-align: center; padding: 14px 0; }

/* ---------- KPI tiles ---------- */
.kpis { display: grid; grid-template-columns: repeat(auto-fit, minmax(145px, 1fr)); gap: 12px; margin-bottom: 16px;
              grid-auto-rows: 1fr; }
/* Every tile is a column: title on top, number at the bottom. Together
   with grid-auto-rows below this keeps all tiles of a row the same
   height and the numbers on one line, even when a title needs two. */
.kpi { background: var(--card); border: 1px solid var(--border); border-radius: var(--r); padding: 14px 16px;
      display: flex; flex-direction: column; }
.kpi .kpi-title { font-size: .68rem; text-transform: uppercase; letter-spacing: .04em; color: var(--text-gray); font-weight: 700;
                white-space: normal; overflow-wrap: anywhere; hyphens: auto; }
.kpi .kpi-value { font-size: 1.7rem; font-weight: 800; margin-top: auto; padding-top: 4px; }
.kpi-blue .kpi-value { color: var(--blue); }
.kpi-green .kpi-value { color: var(--green); }
.kpi-yellow .kpi-value { color: var(--yellow); }
.kpi-red .kpi-value { color: var(--red); }

/* ---------- Line-item list on an order ---------- */
.entry-row { display: flex; align-items: center; justify-content: space-between;
                gap: 10px; padding: 11px 0; border-bottom: 1px solid var(--border); }
.entry-row:last-of-type { border-bottom: none; }
.entry-label { font-weight: 500; }
.entry-detail { font-size: .82rem; color: var(--text-gray); }
.entry-total { font-weight: 700; white-space: nowrap; }
.total-row { display: flex; justify-content: space-between; align-items: center;
                padding: 14px 0 2px; margin-top: 6px; border-top: 2px solid var(--text);
                font-size: 1.15rem; font-weight: 800; }

/* ---------- Notices ---------- */
.notice { border-radius: var(--r); padding: 12px 15px; margin-bottom: 14px; font-size: .93rem; }
.notice-ok   { background: var(--green-light); color: #15803d; border: 1px solid #86efac; }
.notice-error { background: var(--red-light); color: #b91c1c; border: 1px solid #fca5a5; }
.notice-info { background: var(--blue-light);  color: #1d4ed8; border: 1px solid #93c5fd; }
.notice-warning { background: var(--yellow-light); color: #854d0e; border: 1px solid #fde047; }
.notice p { margin: 3px 0; }

.hint { color: var(--text-gray); font-size: .85rem; }
.empty { color: #94a3b8; font-style: italic; padding: 26px 4px; text-align: center; }

/* ---------- Article list ---------- */
.article-row {
  display: flex; justify-content: space-between; align-items: center; gap: 12px;
  background: #fff; border: 1px solid var(--border); border-radius: var(--r);
  padding: 12px 14px; margin-bottom: 7px; text-decoration: none; color: var(--text);
}
.article-row:hover { border-color: var(--accent); }
.article-row .article-name { font-weight: 600; }
.article-row .article-right { text-align: right; white-space: nowrap; }
.article-stock-low { color: var(--red); font-weight: 700; }
.ek-verborgen { display: none; }
.ek-sichtbar .ek-verborgen { display: inline; }

/* ---------- Scan overlay ---------- */
#scan-overlay { display: none; position: fixed; inset: 0; background: rgba(15,23,42,.9);
                z-index: 100; align-items: center; justify-content: center; padding: 16px; }
#scan-box { background: #fff; border-radius: 14px; padding: 16px; width: 100%; max-width: 420px; }
#scan-kamera { border-radius: var(--r); overflow: hidden; }

/* ---------- Counter PC ---------- */
@media (min-width: 1024px) {
  .mobile-head { display: none; }
  .backdrop { display: none !important; }
  .sidebar { transform: translateX(0); }
  .content { margin-left: var(--sidebar-w); }
  main { padding: 26px 32px 80px; }
  .kpis { grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); }
  h1 { font-size: 1.7rem; }
}

/* ---- Sortable tables ---- */
.sort-head { cursor: pointer; user-select: none; white-space: nowrap; }
.sort-head:hover { color: var(--accent); }
.sort-head::after { content: " ⇅"; opacity: .3; font-size: .9em; }
.sort-head.sorted-asc::after { content: " ↑"; opacity: 1; color: var(--accent); }
.sort-head.sorted-desc::after { content: " ↓"; opacity: 1; color: var(--accent); }

.table-tools {
  display: flex; gap: 10px; align-items: center; flex-wrap: wrap;
  margin-bottom: 12px;
}
.table-tools input[type=search] { flex: 1; min-width: 180px; }
/* Square icon button next to the search field (column on/off, reset filter).
   Stays square on the phone too, where normal buttons go full width. */
.icon-button {
  flex: none; width: 42px; height: 42px; padding: 0; display: inline-flex;
  align-items: center; justify-content: center; font-size: 1.1rem; line-height: 1;
}
.icon-button:focus { outline: none; box-shadow: none; }
.icon-button:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.color-row .icon-button { width: 34px; height: 34px; font-size: .95rem; }
.icon-button[disabled] { opacity: .35; cursor: default; }
.hit-count { color: var(--text-gray); font-size: .85rem; white-space: nowrap; }

/* Clickable KPI tiles used as filters */
.kpi-klick { cursor: pointer; transition: border-color .15s; }
.kpi-klick:hover { border-color: var(--accent); }
.kpi-klick.kpi-active { border-color: var(--accent); border-width: 2px; }
.kpi-gray .kpi-value { color: var(--text-gray); }

/* Keep long lists scrollable */
.table-scroll { max-height: 65vh; overflow-y: auto; overflow-x: auto; }
.table-scroll table.list thead th {
  position: sticky; top: 0; background: var(--card); z-index: 2;
}

/* ---- Country code shown before the phone number ---- */
.country-code {
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--bg); border: 1px solid var(--border); border-radius: var(--r);
  padding: 0 12px; font-weight: 700; font-size: .85rem; color: var(--text-gray);
  flex: none; min-width: 48px;
}

/* ---- Show/hide purchase prices ----
   The purchase price (EK) is visible by default. The small switch in the
   sidebar hides it, e.g. when a customer is watching at the counter.
   The browser remembers the setting. */
body.cost-hidden .cost-view { display: none !important; }

.cost-toggle {
  background: none; border: none; padding: 0;
  color: var(--navy-faint); font-size: .72rem; cursor: pointer;
  font-family: inherit; text-align: left; letter-spacing: .03em;
}
.cost-toggle:hover { color: var(--navy-text); }

/* ---- Clickable logo/wordmark ---- */
.brand a, .brand-small a { color: inherit; text-decoration: none; }

/* ---- Compact status filter bar ---- */
/* Status filter pills. On a wide screen they all sit on one line and
   share the width evenly; on a phone they wrap as before. */
.status-bar { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 14px; }
@media (min-width: 900px) {
  .status-bar { flex-wrap: nowrap; }
  .status-bar .status-pill { flex: 1 1 0; justify-content: center; min-width: 0; }
  .status-bar .status-pill .pill-count { flex: none; }
}
.status-pill {
  display: inline-flex; align-items: center; gap: 7px;
  background: #fff; border: 1px solid var(--border); border-radius: 999px;
  padding: 7px 13px; font-size: .85rem; font-weight: 600; cursor: pointer;
  font-family: inherit; color: var(--text-gray);
}
.status-pill:hover { border-color: var(--accent); }
.status-pill .pill-count {
  background: var(--bg); border-radius: 999px; padding: 1px 8px;
  font-size: .78rem; font-weight: 700;
}
.status-pill.pill-active { background: var(--navy); color: #fff; border-color: var(--navy); }
.status-pill.pill-active .pill-count { background: rgba(255,255,255,.2); color: #fff; }

/* ---- Segmented status filter (repairs, bikefitting) ----
   Up to three groups: "Alle offenen" on its own, the single states in the
   middle, the finished one set apart at the end. A pressed button can be
   pressed again to switch the filter off.
   Die REPARATURLISTE hat seit v20 nur noch die mittlere Gruppe, mit
   "Abgeholt" als ganz normalem letzten Status; die Regeln für die beiden
   anderen Gruppen gelten weiter für Bikefitting.
   Phone: the groups sit below each other, the states as a two-column
   grid with a colour dot, so everything is readable without scrolling. */
.status-filter { display: flex; flex-wrap: wrap; gap: 10px; margin-bottom: 14px; align-items: stretch; }
.filter-group {
  display: flex; flex-wrap: wrap; background: var(--card);
  border: 1px solid var(--border); border-radius: var(--r); padding: 3px; gap: 3px;
}
.filter-button {
  display: inline-flex; align-items: center; gap: 6px; white-space: nowrap;
  border: none; background: transparent; color: var(--text); cursor: pointer;
  font: inherit; font-size: .84rem; font-weight: 600;
  padding: 7px 12px; border-radius: calc(var(--r) - 2px);
}
.filter-button .filter-dot {
  width: 9px; height: 9px; border-radius: 50%; flex: none; background: var(--text-gray);
}
.filter-button .pill-count {
  font-size: .76rem; font-weight: 700; color: var(--text-gray);
  background: var(--bg); border-radius: 999px; padding: 1px 7px; margin-left: auto;
}
@media (hover: hover) { .filter-button:hover { background: var(--bg); } }
.filter-button.filter-on { background: var(--navy); color: #fff; }
.filter-button.filter-on .pill-count { background: rgba(255,255,255,.2); color: #fff; }
.filter-button.filter-on .filter-dot { background: #fff !important; }
/* "Alle offenen" and the finished state stamp out from the middle group. */
.filter-group-open .filter-button, .filter-group-done .filter-button { font-weight: 700; }

@media (max-width: 700px) {
  .status-filter { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
  .filter-group-open, .filter-group-done { padding: 0; border: none; background: none; }
  .filter-group-open .filter-button, .filter-group-done .filter-button {
    width: 100%; justify-content: space-between; border: 1px solid var(--border);
    background: var(--card); border-radius: var(--r); padding: 10px 12px;
  }
  /* Bug fix (Android): the rule above set a white background with a
     higher weight than .filter-on, so a pressed "Alle offenen" / "Abgeholt"
     turned white text on white - the button looked empty. */
  .filter-group-open .filter-button.filter-on, .filter-group-done .filter-button.filter-on {
    background: var(--navy); color: #fff; border-color: var(--navy);
  }
  /* "Alle offenen" und "Abgeholt" teilen sich die oberste Zeile; die
     einzelnen Status stehen darunter. Im Markup steht "Abgeholt" zuletzt,
     deshalb die Reihenfolge hier per order. */
  .filter-group-open { order: 1; }
  .filter-group-done { order: 2; }
  .filter-group-status {
    order: 3; grid-column: 1 / -1; display: grid; grid-template-columns: 1fr 1fr; gap: 4px;
  }
  .filter-group-status .filter-button {
    width: 100%; justify-content: flex-start; font-size: .8rem; padding: 9px 10px;
    white-space: normal; text-align: left; line-height: 1.2;
  }
}

.sp-blau  .pill-count { color: var(--blue); }
.sp-gruen .pill-count { color: var(--green); }
.sp-orange .pill-count { color: var(--orange); }
.sp-gelb  .pill-count { color: var(--yellow); }
.sp-rot   .pill-count { color: var(--red); }
.sp-grau  .pill-count { color: var(--text-gray); }

/* ---- Password field with show/hide toggle ---- */
.password-field { position: relative; }
.password-field input { padding-right: 84px; }
.password-eye {
  position: absolute; right: 8px; top: 50%; transform: translateY(-50%);
  background: none; border: none; cursor: pointer; font-family: inherit;
  font-size: .78rem; color: var(--text-gray); padding: 6px 8px;
}
.password-eye:hover { color: var(--accent); }

/* ---- Bullet-point list on the intake form ---- */
.dot-list { list-style: none; padding: 0; margin: 10px 0 0; }
.dot-list:empty { margin: 0; }
.dot-list li {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  background: #fff; border: 1px solid var(--border); border-radius: var(--r);
  padding: 9px 12px; margin-bottom: 6px; font-size: .92rem;
}
.dot-list li::before { content: "•"; color: var(--accent); font-weight: 700; margin-right: 4px; }
.dot-list .dot-text { flex: 1; }
.dot-remove {
  background: none; border: none; color: var(--text-gray);
  cursor: pointer; font-size: 1rem; padding: 0 4px; font-family: inherit;
}
.dot-remove:hover { color: var(--red); }
.dot-empty { color: #94a3b8; font-style: italic; font-size: .9rem; padding: 8px 2px; }

/* ---- Android portrait: everything more compact and not squeezed ---- */
@media (max-width: 600px) {
  body { font-size: 15px; }
  main { padding: 14px 12px 70px; }
  h1 { font-size: 1.25rem; }
  .card { padding: 13px; }
  .kpis { grid-template-columns: repeat(2, 1fr); gap: 9px; }
  .kpi { padding: 11px 12px; }
  .kpi .kpi-value { font-size: 1.35rem; }
  .kpi .kpi-title { font-size: .62rem; }
  .btn { width: 100%; }
  .btn-row { flex-direction: column; }
  .btn-group { flex-direction: column; }
  .btn-group + .btn-group { border-left: 0; padding-left: 0;
      border-top: 1px solid var(--border); padding-top: 12px; }
  /* Handy: die drei Gruppen stehen untereinander, ihre beiden Knöpfe aber
     NEBENEINANDER - also drei Zeilen zu zwei Knöpfen statt sechs Zeilen.
     Die feine Linie zwischen den Gruppen wird dafür waagrecht. */
  .action-bar .btn-group:first-child { border-left: 0; padding-left: 0; }
  .action-bar .btn-group + .btn-group { border-left: 0; padding-left: 0;
      border-top: 1px solid var(--border); padding-top: 10px; margin-top: 2px; }
  .action-bar .btn-group { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; }
  .action-bar .btn { font-size: .88rem; }
  .btn-row .btn, .btn-row form { width: 100%; }
  .btn-small { width: auto; }
  .table-tools { flex-direction: row; flex-wrap: wrap; align-items: center; }
  .table-tools .btn { width: 100%; }
  .table-tools .icon-button { width: 42px; }
  table.list { font-size: .82rem; }
  table.list th, table.list td { padding: 9px 8px; }
  .table-scroll { max-height: none; }
  .status-bar { gap: 5px; }
  .status-pill { font-size: .78rem; padding: 6px 10px; }
  .field-row { flex-wrap: wrap; }
  .field-row .btn { width: auto; flex: 1; }
  .language-switch { width: 100%; }
  .language-switch label { flex: 1; justify-content: center; padding: 10px 6px; }
  .chip-grid { gap: 6px; }
  .chip, .pages-group { font-size: .82rem; }
}

/* ---- Print view ---- */
.print-head { display: none; }
.print-table td { vertical-align: top; }

@media print {
  /* Alles ausblenden, was auf Papier nichts verloren hat */
  .sidebar, .mobile-head, .backdrop, .no-print { display: none !important; }
  .content { margin-left: 0 !important; }
  main { padding: 0 !important; }
  body { background: #fff; font-size: 10pt; }
  .print-head {
    display: flex; justify-content: space-between; align-items: baseline;
    border-bottom: 2px solid #000; padding-bottom: 6px; margin-bottom: 10px;
  }
  table.list { font-size: 9pt; }
  table.list th {
    border-bottom: 1px solid #000; color: #000; padding: 4px 6px;
  }
  table.list td { padding: 5px 6px; border-bottom: 1px solid #ccc; }
  table.list tr { page-break-inside: avoid; }
  .no { color: #000; }
  a { text-decoration: none; color: #000; }
  @page { margin: 12mm; size: landscape; }
}

/* ---- Logo ---- */
.logo-img { max-height: 34px; max-width: 100%; display: block; }
.logo-img-wide { max-height: 38px; max-width: 172px; }
.mobile-head .logo-img { max-height: 26px; }
.login-logo { text-align: center; margin-bottom: 22px; }
.login-logo img { max-height: 54px; max-width: 80%; }
.login-foot { color: var(--navy-faint); font-size: .78rem; margin-top: 18px; }
.password-eye { display: flex; align-items: center; }

/* ---- Task list, compact, stacked ---- */
.aufgaben-block { margin: 0; padding: 0; list-style: none; }
.aufgaben-block li { padding: 2px 0; display: flex; gap: 8px; }
.aufgaben-block li::before { content: "•"; color: var(--accent); font-weight: 700; }

.kpi-orange .kpi-value { color: var(--orange); }

/* ---- Phone number: country code and number clearly separated ----
   Code badge + prefix input sit side by side, narrow, and bottom-align
   with the phone number field next to them (no label of their own -
   that's what keeps them level with the actual input, not its label). */
.phone-group { display: flex; gap: 22px; margin-top: 14px; align-items: flex-end; }
.phone-dial-row { flex: none; width: auto; min-width: 0; display: flex; gap: 6px; margin: 0; }
.phone-dial-row .country-code {
  flex: none; width: 40px; min-width: 0; height: 42px; padding: 0; box-sizing: border-box;
}
.phone-dial-row .dial-code-field {
  width: 56px; min-width: 0; flex: none !important;
  padding-left: 4px; padding-right: 4px; text-align: center; margin: 0;
}
.phone-number { flex: 1; min-width: 0; }
.phone-group label { margin: 0 0 5px; }
@media (max-width: 600px) {
  .phone-group { gap: 10px; }
}

/* ---- Bullet points on the intake form as one block ---- */
.dot-list li {
  border: none; background: none; padding: 3px 0; margin: 0;
  border-radius: 0;
}
.dot-list { border: 1px solid var(--border); border-radius: var(--r); padding: 10px 12px; }
.dot-list:empty { border: none; padding: 0; }

/* ---- Line items: bullet + text always share the top line; price entry,
   if used, sits neatly on its own line underneath. ---- */
.item-block { padding: 10px 0; border-bottom: 1px solid var(--border); }
.item-block:last-of-type { border-bottom: none; }
.item-row {
  display: flex; align-items: center; gap: 9px; flex-wrap: wrap;
}
/* .item-row's own "display: flex" above would otherwise win over the
   [hidden] attribute (both are author-stylesheet rules of the same
   specificity) - this keeps a hidden row actually hidden. Needed for the
   task edit row toggled by the pencil (toggleItemEdit). */
.item-row[hidden] { display: none; }
.item-bullet { color: var(--accent); font-weight: 700; flex: none; line-height: 1.5; }
.item-text { flex: 1 1 90px; min-width: 90px; color: var(--text); font-weight: 500; }

/* The "free position" row: same shape as a task row, but the label is an
   actual input instead of static text. */
.item-text-input {
  flex: 1 1 90px !important; min-width: 90px; width: auto !important;
  border: 1px solid var(--border); border-radius: var(--r);
  padding: 6px 9px; font-size: .95rem; font-weight: 500; color: var(--text);
}
.item-price { font-weight: 700; white-space: nowrap; flex: none; }
/* Counter next to tasks that share the same text (#1, #2 ...). */
.item-no { color: var(--text-gray); font-weight: 400; font-size: .85em; }

/* Confirmed task/line item: price or checkmark shown as a small tidy
   pill instead of bare text, so the row looks intentional either way. */
.item-badge {
  display: inline-flex; align-items: center; justify-content: center;
  padding: 5px 12px; border-radius: 999px; font-weight: 700; font-size: .85rem;
  white-space: nowrap;
}
.item-badge-ok    { background: var(--green-light); color: #15803d; }
.item-badge-price { background: var(--bg); color: var(--text); }

/* Round confirm button next to an open task's price field. Empty price +
   this button = ticked off with no batch; a typed price + this button =
   confirmed with that price. Grey by default, turns green on hover/tap
   focus so it reads as "ready to confirm", matching the rest of the
   app's rounded, understated button language instead of a plain
   browser-default checkbox look. */
.item-check {
  flex: none; width: 34px; height: 34px; border-radius: 999px;
  border: 1px solid var(--border); background: #fff; color: var(--text-gray);
  cursor: pointer; font-size: 1rem; line-height: 1;
  display: inline-flex; align-items: center; justify-content: center;
}
.item-check:hover, .item-check:focus { border-color: var(--green); color: var(--green); background: var(--green-light); }

.item-row .item-input {
  width: 68px !important; flex: none; padding: 8px 8px; font-size: .9rem;
  border: 1px solid var(--border); border-radius: var(--r); text-align: right;
}
.item-row .btn-small { flex: none; width: auto; min-width: 62px; }
.item-form { display: inline; margin: 0; flex: none; }
.item-remove {
  background: none; border: none; color: var(--text-gray);
  cursor: pointer; font-size: .95rem; padding: 4px 6px; flex: none;
}
.item-remove:hover { color: var(--red); }
/* "Erledigt" looks exactly like the ✕ next to it (no frame, no
   background), only the hover colour differs: ✓ green, ✕ red. The word
   "Erledigt" lives in the title attribute now. */
.todo-done:hover { color: var(--green); }

/* A task that can't be worked on yet, because the repair hasn't been
   started - greyed out, no interactive controls shown. */
.item-locked .item-text { color: var(--text-gray); }
.item-locked .item-bullet { color: var(--border-dark, var(--border)); }

/* Task edit row, revealed by the pencil (see toggleItemEdit in
   table.js): text field + save sit together, delete is a separate small
   form right after so it can post on its own without validating the text
   field (which stays required for the rename form). */
.item-edit-form { display: flex; align-items: center; gap: 8px; flex: 1 1 160px; min-width: 0; }

.item-new, .item-scan { margin-top: 16px; }
.item-new-label { display: block; font-size: .82rem; color: var(--text-gray); margin-bottom: 5px; }
.item-new-fields { display: flex; gap: 8px; flex-wrap: wrap; }
.item-new-fields input[name=bezeichnung] { flex: 3 1 160px; min-width: 0; }
.item-new-fields input[name=einzelpreis] { flex: 1 1 90px; max-width: 120px; }
.item-new-fields input[name=ean] { flex: 2 1 140px; min-width: 0; }
.item-price-with-sign {
  position: relative; flex: 1 1 90px; max-width: 120px;
}
.item-price-with-sign input {
  width: 100%; padding-right: 28px;
}
.item-price-with-sign span {
  position: absolute; right: 12px; top: 50%; transform: translateY(-50%);
  color: var(--text-gray); font-size: .9rem; pointer-events: none;
}
.item-new-fields .btn { flex: none; }

@media (max-width: 600px) {
  .item-new-fields .btn { width: 100%; }
}

/* ---- Small fixed-width number field (order number, VAT rate) ---- */
.number-field { width: 56px !important; flex: none !important; text-align: center; }

/* ---- Narrow "Scannen" button, so the field next to it stays dominant ---- */
.btn-scan { flex: none !important; width: auto !important; padding: 8px 14px; }

/* ---- Small secondary label, e.g. above the VAT-rate field ---- */
.mini-label { display: block; font-size: .78rem; color: var(--text-gray); margin-bottom: 5px; }

/* ---- "Wartet auf Teil" button: orange, distinct from red/green/yellow ---- */
:root { --orange: #ea580c; --orange-dark: #c2410c; }
.btn-orange { background: var(--orange); color: #fff; }
.btn-orange:hover { background: var(--orange-dark); }
.btn-violet { background: #7c3aed; color: #fff; }
.btn-violet:hover { background: #6d28d9; }

/* ---- Front/rear/both buttons: highlight the currently selected one ---- */
.pages-group button.side-active { background: var(--accent); color: #fff; }

/* ---- Fine-tuning in the style of the B2B portal ---- */
.card { border-radius: 10px; }
.brand, .brand-small { letter-spacing: -0.01em; }
.nav-title { letter-spacing: .09em; }
.kpi-title { letter-spacing: .07em; }
.btn { letter-spacing: .01em; }
.login-card { border-radius: 12px; box-shadow: 0 18px 50px rgba(0,0,0,.28); }
.login-inner { padding: 38px 32px 34px; }
.login-brand { letter-spacing: -0.02em; }
.btn-large { font-weight: 700; }

/* Accent colour stays sparse: header highlight, bullet points, focus */
.nav a.active { border-left-color: var(--accent); }
.sort-head.sorted-asc::after,
.sort-head.sorted-desc::after { color: var(--accent); }

/* ---- Sidebar on phone and tablet ----
   Below 1024px the sidebar is a drawer, opened via the menu button.
   Otherwise there wouldn't be enough room left for the content. */
@media (max-width: 1023px) {
  .sidebar { width: min(82vw, 300px); box-shadow: 4px 0 24px rgba(0,0,0,.3); }
  .content { margin-left: 0 !important; width: 100%; }
  .layout { display: block; }
  body { overflow-x: hidden; }
  .nav a { padding: 13px 18px; font-size: 1rem; }
  .nav-title { padding: 14px 18px 5px; }
}

/* ---- Message-template editor in Settings ---- */
.message-input { min-height: 64px; font-size: .92rem; }
.message-preview {
  margin: 6px 0 0; padding: 8px 11px; background: var(--bg);
  border-radius: var(--r); font-size: .85rem; color: var(--text-gray);
  font-style: italic;
}

/* ---- Right-click status menu on the repairs overview ----
   A single entry "Status setzen", which reveals a submenu with the actual
   options to the right on hover - the familiar two-level pattern from
   desktop context menus, instead of a flat list of every option at once. */
.status-menu {
  display: none; position: absolute; z-index: 100;
  background: #fff; border: 1px solid var(--border); border-radius: var(--r);
  box-shadow: 0 10px 30px rgba(15,23,42,.18); padding: 6px; min-width: 170px;
}
.status-menu-item {
  position: relative; padding: 10px 14px; border-radius: 6px;
  font-size: .92rem; font-weight: 600; cursor: default;
  display: flex; align-items: center; justify-content: space-between;
}
.status-menu-main:hover { background: var(--bg); }
.status-menu-main:hover .status-submenu { display: block; }
.status-submenu {
  display: none; position: absolute; left: 100%; top: -6px;
  background: #fff; border: 1px solid var(--border); border-radius: var(--r);
  box-shadow: 0 10px 30px rgba(15,23,42,.18); padding: 6px; min-width: 190px;
}
.status-submenu button {
  display: block; width: 100%; text-align: left; background: none; border: none;
  padding: 9px 14px; border-radius: 6px; font-size: .92rem; font-family: inherit;
  cursor: pointer; color: var(--text); white-space: nowrap;
}
.status-submenu button:hover { background: var(--accent-light); color: var(--accent-dark); }

/* ---- Fast scan booking / price lookup ---- */
.han-hit-row {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  padding: 10px 4px; border-bottom: 1px solid var(--border); cursor: default;
}
.han-hit-row:last-child { border-bottom: none; }
.han-hit-row:hover { background: none; }
.han-hit-info { min-width: 0; }
.movement-card { margin-top: 14px; }
.movement-details {
  display: flex; flex-wrap: wrap; gap: 8px 18px; margin-top: 8px;
  font-size: .9rem; color: var(--text-gray);
}
.movement-details strong { color: var(--text); }

/* ---- Paging bar under long lists ---- */
.pager {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  margin-top: 14px; padding-top: 12px; border-top: 1px solid var(--border);
}
.pager .hit-count { margin: 0 4px; }

/* ---- Hide print-list link on phones (only useful at the counter PC) ---- */
@media (max-width: 1023px) {
  .desktop-only { display: none !important; }
}

/* ---- Warranty status picker on a repair ---- */
.warranty-row { display: flex; align-items: center; gap: 10px; margin-top: 12px; flex-wrap: wrap; }
.warranty-label { font-size: .82rem; color: var(--text-gray); font-weight: 600; }
.warranty-form { margin: 0; flex: 1; min-width: 170px; max-width: 260px; }
.warranty-form select { width: 100%; }

/* ---- Booking direction switch: red out, green in ---- */
.direction-switch { display: flex; gap: 0; border-radius: var(--r); overflow: hidden;
  border: 1px solid var(--border); }
.direction-switch input { position: absolute; opacity: 0; pointer-events: none; }
.direction-switch label {
  flex: 1; text-align: center; padding: 13px 10px; cursor: pointer; margin: 0;
  font-weight: 700; font-size: .95rem; color: var(--text-gray); background: #fff;
}
.direction-switch input:checked + .direction-out { background: var(--red); color: #fff; }
.direction-switch input:checked + .direction-in { background: var(--green); color: #fff; }

.qty-field { position: relative; }
.qty-field input { width: 100%; padding-right: 40px; }
.qty-field span {
  position: absolute; right: 12px; top: 50%; transform: translateY(-50%);
  color: var(--text-gray); font-size: .85rem; pointer-events: none;
}

/* Scrollable results list, so a broad search doesn't push the page down */
.hits-scroll { max-height: 320px; overflow-y: auto; }

/* "Benachrichtigt": customer has been told, bike not collected yet */
.badge-notified { background: var(--blue-light); color: #1d4ed8; }
table.list tbody tr[data-status="Benachrichtigt"] { border-left-color: var(--blue); }

/* Current warranty state shown inline next to its action buttons */
.warranty-stand {
  display: inline-flex; align-items: center; flex: none;
  padding: 8px 14px; font-size: .85rem;
}

/* Task bullets are editable in place, so a model or detail can be added
   to an already-selected task without a separate note field. */
.dot-text-edit { cursor: text; border-radius: 4px; padding: 1px 4px; margin: -1px -4px; }
.dot-text-edit:hover { background: var(--bg); }
.dot-text-edit:focus { outline: 2px solid var(--accent); background: #fff; }

/* Selected-article row on the booking page */
.selected-row {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  background: var(--bg); border-radius: var(--r); padding: 10px 12px; font-weight: 600;
}

/* Discreet pencil next to an editable task point */
.pencil {
  background: none; border: none; color: var(--text-gray);
  cursor: pointer; font-size: .95rem; padding: 2px 6px; flex: none; line-height: 1;
}
.pencil:hover { color: var(--accent); }

/* ↺ neben "Arbeitszeit" im Reparatur-Kopf: setzt die erfasste Zeit auf 0.
   Bewusst klein und grau - es soll nicht nach einem Hauptknopf aussehen. */
.time-reset {
  background: none; border: none; color: var(--text-gray); cursor: pointer;
  font: inherit; font-size: 1rem; line-height: 1; padding: 0 4px; margin-left: 2px;
  vertical-align: -1px;
}
.time-reset:hover, .time-reset:focus { color: var(--red); }

/* The status the repair is already in - shown for orientation, not clickable */
.status-submenu .status-current {
  color: var(--text-gray); cursor: default; font-weight: 700;
}
.status-submenu .status-current:hover { background: none; color: var(--text-gray); }

/* Each bike as its own visually separated block on the customer page */
.bike-block {
  border: 1px solid var(--border); border-radius: var(--r);
  padding: 12px; margin-bottom: 10px;
}
.bike-row { display: flex; align-items: flex-start; justify-content: space-between; gap: 10px; }

/* ==========================================================================
   Additions September 2026
   ========================================================================== */

/* ---- Example value next to a field label ("Marke   z.B. Specialized") ---- */
.example { color: var(--text-gray); font-weight: 400; font-size: .85rem; margin-left: 12px; }

/* ---- Sidebar: list entry with its own "+" area on the right ---- */
.nav-row { display: flex; align-items: stretch; border-left: 3px solid transparent; }
.nav-row > a { border-left: none !important; }
.nav-row > a:first-child { flex: 1; min-width: 0; }
.nav-row.active { background: var(--navy-light); border-left-color: var(--accent); }
.nav-row.active > a:first-child { color: #fff; font-weight: 600; }
.nav .nav-add {
  flex: none; width: 48px; padding: 0; justify-content: center;
  font-size: 1.05rem; color: var(--navy-faint);
  border-left: 1px solid var(--navy-light) !important;
}
.nav .nav-add:hover { background: var(--navy-border); color: #fff; }
.nav-row.active .nav-add { border-left-color: var(--navy-border) !important; }
/* Dashboard row: the right-hand area opens the To Do list instead of "+". */
.nav .nav-add.nav-add-active { background: var(--navy-border); color: #fff; }

/* ---- Buttons next to a page heading ---- */
.head-buttons { display: inline-flex; gap: 8px; flex-wrap: wrap; }
@media (max-width: 600px) { .head-buttons .btn { width: auto; } }

/* ---- Pop-up window over the current page (modal.js) ---- */
.modal-overlay {
  position: fixed; inset: 0; z-index: 90;
  display: flex; align-items: flex-start; justify-content: center;
  padding: 4vh 16px;
  background: rgba(15, 23, 42, .38);
  -webkit-backdrop-filter: blur(5px); backdrop-filter: blur(5px);
}
.modal-overlay[hidden] { display: none; }
.modal-window {
  width: 100%; max-width: 780px; max-height: 92vh;
  display: flex; flex-direction: column;
  background: var(--bg); border-radius: 12px; overflow: hidden;
  box-shadow: 0 24px 70px rgba(0, 0, 0, .35);
}
.modal-head {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  background: var(--card); border-bottom: 1px solid var(--border);
  padding: 12px 12px 12px 20px; flex: none;
}
.modal-title { font-size: 1.2rem; font-weight: 700; letter-spacing: -0.01em; }
.modal-close {
  width: 40px; height: 40px; flex: none; border-radius: 999px;
  border: 1px solid var(--border); background: #fff; color: var(--text-gray);
  font-size: 1.1rem; cursor: pointer; line-height: 1;
}
.modal-close:hover { color: var(--text); border-color: var(--text-gray); }
.modal-content { overflow-y: auto; padding: 16px 18px 22px; -webkit-overflow-scrolling: touch; }
.modal-content .card:last-child { margin-bottom: 0; }
body.modal-open { overflow: hidden; }
@media (max-width: 600px) {
  .modal-overlay { padding: 0; }
  .modal-window { max-width: none; max-height: none; height: 100%; height: 100dvh; border-radius: 0; }
  .modal-content { padding: 12px 12px 40px; }
}
@media print {
  body.modal-open { overflow: visible; }
  body.modal-open .layout { display: none !important; }
  body.modal-open .modal-overlay {
    position: static; display: block; padding: 0; background: none;
    -webkit-backdrop-filter: none; backdrop-filter: none;
  }
  body.modal-open .modal-window { max-width: none; max-height: none; box-shadow: none; border-radius: 0; background: #fff; }
  body.modal-open .modal-head { display: none; }
  body.modal-open .modal-content { overflow: visible; padding: 0; }
}

/* ---- Intake task points: checkmark shown while editing ---- */
.dot-ok {
  display: none; background: none; border: none; color: var(--green);
  cursor: pointer; font-size: 1.05rem; font-weight: 700; padding: 2px 6px; flex: none; line-height: 1;
}
.dot-list li.dot-edit .dot-ok { display: inline-block; }

/* ---- Article list toolbar: search, two filters, buttons in one row ---- */
.article-tools select { width: auto; flex: 0 1 210px; min-width: 150px; }
.article-tools .btn { flex: none; }
@media (max-width: 600px) {
  .article-tools select { flex: none; width: 100%; }
}

/* ---- Settings: tabs ---- */
.tab-bar {
  display: flex; gap: 4px; margin: 14px 0 16px; border-bottom: 1px solid var(--border);
  overflow-x: auto; -webkit-overflow-scrolling: touch;
}
.tab {
  background: none; border: none; border-bottom: 3px solid transparent;
  padding: 10px 16px; font-family: inherit; font-size: .95rem; font-weight: 600;
  color: var(--text-gray); cursor: pointer; white-space: nowrap; margin-bottom: -1px;
}
.tab:hover { color: var(--text); }
.tab.active { color: var(--text); border-bottom-color: var(--accent); }
.tab-content[hidden] { display: none !important; }

.set-grid { display: grid; grid-template-columns: 1fr; gap: 14px; align-items: start; }
.set-grid > .card { margin-bottom: 0; }
@media (min-width: 1200px) {
  .set-grid { grid-template-columns: 3fr 2fr; }
  .set-grid-single { grid-template-columns: minmax(0, 760px); }
}

.counter {
  background: var(--bg); color: var(--text-gray); border-radius: 999px;
  padding: 1px 9px; font-size: .78rem; font-weight: 700; flex: none;
}
.saved {
  color: var(--green); font-size: .85rem; font-weight: 600;
  animation: gespeichert-weg 2.5s ease forwards;
}
@keyframes gespeichert-weg { 0%, 70% { opacity: 1; } 100% { opacity: 0; } }

/* On/off switch */
.schalter-zeile {
  display: flex; align-items: center; justify-content: space-between; gap: 14px;
  margin: 0; padding: 12px 0; border-bottom: 1px solid var(--border);
  font-weight: 500; font-size: .95rem; color: var(--text); cursor: pointer;
}
.schalter-zeile:last-child { border-bottom: none; }
.schalter {
  -webkit-appearance: none; appearance: none; flex: none;
  width: 44px; height: 26px; border-radius: 999px; background: #cbd5e1;
  position: relative; cursor: pointer; transition: background .15s; margin: 0;
}
.schalter::after {
  content: ""; position: absolute; top: 3px; left: 3px; width: 20px; height: 20px;
  border-radius: 50%; background: #fff; box-shadow: 0 1px 3px rgba(0,0,0,.25);
  transition: transform .15s;
}
.schalter:checked { background: var(--green); }
.schalter:checked::after { transform: translateX(18px); }
.schalter:focus { box-shadow: 0 0 0 3px var(--accent-light); outline: none; }

/* Add row: field + "+" button */
.set-new { display: flex; gap: 8px; align-items: flex-end; margin-bottom: 12px; }
.set-field { flex: 1; min-width: 0; }
.set-field label { margin: 0 0 5px; }
.set-add { flex: none !important; width: 46px !important; padding: 0; font-size: 1.15rem; }
.set-new-small { margin: 10px 0 2px; }
.set-new-small input[type=text] { flex: 1; min-width: 0; padding: 8px 10px; }
.set-new-small .set-add { min-height: 40px; height: 40px; }

/* Rows (tasks, models without brand) */
.set-list { border-top: 1px solid var(--border); }
.set-row {
  display: flex; align-items: center; gap: 10px;
  padding: 8px 0; border-bottom: 1px solid var(--border);
}
.set-row:last-child { border-bottom: none; }
.set-name { flex: 1; min-width: 0; font-weight: 500; }

/* Up/down arrows that set the order of the quick-pick tasks. */
.sort-arrows { display: flex; flex-direction: column; flex: none; line-height: 1; }
.sort-arrows button { font-size: .72rem; padding: 1px 3px; opacity: .65; }
.sort-arrows button:hover:not([disabled]) { opacity: 1; }
.sort-arrows button[disabled] { opacity: .18; cursor: default; }

/* Front/rear pill on a task */
.side-pill, .side-choice span {
  border: 1px solid var(--border); background: #fff; color: var(--text-gray);
  border-radius: 999px; padding: 4px 10px; font-size: .78rem; font-weight: 700;
  font-family: inherit; cursor: pointer; white-space: nowrap;
}
.side-pill.on { background: var(--navy); border-color: var(--navy); color: #fff; }
.side-choice { margin: 0; flex: none; display: flex; align-items: center; height: 44px; cursor: pointer; }
.side-choice input { position: absolute; opacity: 0; pointer-events: none; }
.side-choice input:checked + span { background: var(--navy); border-color: var(--navy); color: #fff; }
.side-choice span { padding: 7px 12px; }

/* Fixed chips with a small ✕ (colours, categories, models, manufacturers) */
.chip-list { display: flex; flex-wrap: wrap; gap: 6px; }
.chip-fixed {
  display: inline-flex; align-items: center; gap: 2px;
  background: #fff; border: 1px solid var(--border); border-radius: 999px;
  padding: 4px 4px 4px 12px; font-size: .88rem;
}
.chip-fixed[hidden] { display: none; }
.chip-fixed button {
  background: none; border: none; color: var(--text-gray); cursor: pointer;
  font-size: .8rem; padding: 3px 7px; border-radius: 999px; line-height: 1;
}
.chip-fixed button:hover { color: var(--red); background: var(--red-light); }
.chip-scroll { max-height: 340px; overflow-y: auto; padding: 2px; }

/* Brand accordion */
.brands-list { border-top: 1px solid var(--border); }
.brand-block { border-bottom: 1px solid var(--border); }
.brand-head {
  display: flex; align-items: center; gap: 10px; padding: 9px 2px; cursor: pointer;
  user-select: none;
}
.brand-head:hover .set-name { color: var(--accent-dark); }
.brand-arrow { color: var(--text-gray); width: 14px; flex: none; transition: transform .15s; }
.brand-block.open .brand-arrow { transform: rotate(90deg); }
.brand-content { display: none; padding: 2px 0 12px 24px; }
.brand-block.open .brand-content { display: block; }

.no-brand { margin-top: 18px; padding-top: 4px; }
.no-brand-title {
  font-size: .72rem; text-transform: uppercase; letter-spacing: .06em;
  color: var(--text-gray); font-weight: 700; margin-bottom: 4px;
}
.brand-assign { width: auto; padding: 6px 8px; font-size: .85rem; }

/* ---- Intake: secondary save buttons under "Auftrag speichern" ---- */
.save-more { display: flex; gap: 8px; margin-top: 8px; }
.save-more .btn { flex: 1 1 0; min-height: 44px; white-space: nowrap; }
#phone-view .pencil { margin-left: 4px; }

/* ---- Repair detail: warranty block above the workflow buttons ---- */
.warranty-head { display: flex; align-items: center; gap: 6px; }
.warranty-head .item-remove { margin-left: auto; }
.warranty-info { margin: 6px 0 0; }
.warranty-info .hint { margin-right: 6px; }
.warranty-form { margin-top: 10px; }
.warranty-form label { margin: 8px 0 5px; }
/* Overview: status and warranty pill side by side in one cell */
.status-cell { white-space: nowrap; }
.status-cell .badge + .badge { margin-left: 5px; }

/* ---- Article list: spreadsheet-style column filters ---- */
.columns-arrow {
  background: none; border: none; cursor: pointer; color: var(--text-gray);
  padding: 2px 6px; margin-left: 2px; font-size: .8rem; line-height: 1;
}
.columns-arrow:hover, th.filter-on .columns-arrow { color: var(--accent); }
th.filter-on { color: var(--accent) !important; }
.columns-menu {
  position: fixed; z-index: 60; width: 240px; max-width: calc(100vw - 16px);
  background: var(--card, #fff); border: 1px solid var(--border); border-radius: var(--r);
  box-shadow: 0 8px 24px rgba(0,0,0,.14); padding: 8px;
}
.columns-menu[hidden] { display: none; }
.columns-menu-search { width: 100%; margin-bottom: 6px; }
.columns-menu-list { max-height: 280px; overflow-y: auto; }
.columns-menu-list button {
  display: block; width: 100%; text-align: left; background: none; border: none;
  padding: 8px 10px; border-radius: 6px; cursor: pointer; font: inherit; color: var(--text);
}
.columns-menu-list button:hover { background: var(--bg); }
.columns-menu-list button.active { font-weight: 700; color: var(--accent); }
.columns-menu-list button[hidden] { display: none; }
.filter-active-bar { display: flex; gap: 6px; flex-wrap: wrap; margin-top: 12px; }

/* ---- Label/value list (article details) ---- */
.data-list { display: grid; grid-template-columns: max-content 1fr; gap: 6px 18px; margin: 0; }
.data-list dt { color: var(--text-gray); font-size: .85rem; align-self: baseline; }
.data-list dd { margin: 0; overflow-wrap: anywhere; }

/* ---- Testbikes ---- */
.testbike-row { display: flex; justify-content: space-between; align-items: center; gap: 10px;
                  padding: 10px 0; border-bottom: 1px solid var(--border); flex-wrap: wrap; }
.testbike-row:first-child { padding-top: 0; }
.testbike-row:last-child { border-bottom: none; padding-bottom: 0; }
.testbike-state { display: flex; gap: 5px; flex-wrap: wrap; }
/* Status badge sits to the LEFT of the name, the name fills the rest. */
.testbike-row { justify-content: flex-start; }
.testbike-info { flex: 1; min-width: 0; }
.testbike-defect { font-size: .85rem; color: #b45309; margin-top: 3px; }
/* More breathing room between "Testbike 1" and its brand/model/SN, and
   between those details themselves, so they don't run into each other. */
.testbike-info .testbike-detail { margin-left: 10px; }
/* Handy: Name zuerst, Badges darunter - nebeneinander bleibt für den Namen
   zu wenig Platz, er bricht sonst Wort für Wort um (v20). */
@media (max-width: 700px) {
  .testbike-row { flex-direction: column; align-items: flex-start; gap: 6px; }
  /* Im Markup stehen die Badges vor dem Namen (am PC links daneben) -
     am Handy zieht order den Namen nach oben. */
  .testbike-info { width: 100%; order: -1; }
  .testbike-info .testbike-detail { margin-left: 0; display: block; }
}
.choice-list { display: flex; flex-direction: column; gap: 6px; }
.choice-row { display: flex; align-items: center; gap: 10px; margin: 0; padding: 10px 12px;
                 border: 1px solid var(--border); border-radius: var(--r); cursor: pointer; font-weight: 400; }
.choice-row:has(input:checked) { border-color: var(--accent); background: var(--accent-light); }
.choice-row input { width: auto; flex: none; margin: 0; }
.choice-text { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 8px; }
.period-fields { display: flex; gap: 12px; flex-wrap: wrap; }
.period-fields > div { flex: 1 1 200px; }
.actions-cell { white-space: nowrap; text-align: right; }
.actions-cell .btn { margin-right: 4px; }

/* Settings: testbike fields */
.testbike-fields { display: grid; grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); gap: 8px; flex: 1; min-width: 0; }
.testbike-fields label { margin: 0 0 5px; }
.testbike-new { align-items: flex-end; }

/* hidden must win over display:flex (phone fields of a stored customer) */
.phone-group[hidden] { display: none; }

/* Repair detail: warranty sits below the workflow buttons */
.btn-row + .warranty-gap { margin-top: 12px; }

/* Settings › Magazin: import mode choice */
.import-mode { display: flex; flex-wrap: wrap; gap: 6px 16px; margin-top: 10px; }
.import-mode label { display: flex; align-items: center; gap: 6px; margin: 0; font-weight: 500; }
.import-mode input { width: auto; margin: 0; }

/* Users: set a new password */
.password-row { margin: 4px 0 16px; }
/* Einstellungen -> Benutzer (v20): eine Zeile je Konto. Das Häkchen-Raster
   "Bereiche je Konto" ist raus, Bereiche gelten global - dadurch passt ein
   Konto wieder in eine Zeile: links Name und Benutzername, rechts die
   Knöpfe. Am Handy stehen die Knöpfe unter dem Namen. */
.user-list { display: flex; flex-direction: column; }
.user-row {
  display: grid; grid-template-columns: 1fr auto; align-items: center;
  gap: 2px 12px; padding: 10px 0; border-bottom: 1px solid var(--border);
}
.user-row:last-child { border-bottom: none; }
.user-name { font-weight: 600; display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.user-login { grid-column: 1; font-size: .82rem; color: var(--text-gray); }
.user-buttons {
  grid-column: 2; grid-row: 1 / span 2; display: flex; flex-wrap: wrap;
  gap: 6px; justify-content: flex-end;
}
.user-row .password-block { grid-column: 1 / -1; margin: 0; }
.user-row .password-block .password-row[hidden] { display: none; }
@media (max-width: 700px) {
  .user-row { grid-template-columns: 1fr; }
  .user-buttons { grid-column: 1; grid-row: auto; justify-content: flex-start; margin-top: 6px; }
}
.password-block { margin: 4px 0 16px; }
.password-block .password-row { margin: 0; }
.password-row .field-row .btn { flex: none; }
.password-view { font-family: ui-monospace, Menlo, Consolas, monospace; font-size: 1.05rem; letter-spacing: .03em; user-select: all; }


/* Selected bike chip */
.chip.bike-active { border-color: var(--accent); color: var(--accent-dark); }
/* Touch screens keep ":hover" after a tap, which left deselected chips
   looking selected (red). Hover colours only for real mouse pointers. */
@media (hover: none) {
  .chip:hover { border-color: var(--border); color: inherit; }
  .chip.chip-active:hover { background: var(--accent); border-color: var(--accent); color: #fff; }
  .chip.bike-active:hover { border-color: var(--accent); color: var(--accent-dark); }
  .pages-group button:hover { background: transparent; color: inherit; }
  .pages-group button.side-active:hover { background: var(--accent); color: #fff; }
}

/* --- Status "Anfrage": its own colour (violet) --------------------------- */
.badge-warranty { background: #ede9fe; color: #6d28d9; }
.pill-violet .pill-count { color: #7c3aed; }
.kpi-violet .kpi-value { color: #7c3aed; }

/* --- Dashboard tiles that are left ---------------------------------------- */
a.kpi { display: block; color: inherit; text-decoration: none; }
@media (hover: hover) { a.kpi:hover { border-color: var(--accent); } }

/* --- Warranty / service cases ---------------------------------------------- */
.case { border: 1px solid var(--border); border-radius: var(--r); padding: 12px 14px; margin-bottom: 10px; }
.case .warranty-head { margin-bottom: 6px; }
.case-title { flex: 1; min-width: 0; }
.case-missing { margin: 8px 0 0; color: #b91c1c; font-size: .88rem; font-weight: 600; }
.case-step { margin-top: 12px; }
.case-step label { margin-top: 0; }
.case-back { background: none; border: 0; padding: 6px 0 0; color: var(--text-gray); font: inherit;
  font-size: .82rem; cursor: pointer; }
@media (hover: hover) { .case-back:hover { color: var(--text); } }
.case-form label { margin-top: 10px; }
.files-chosen { margin: 6px 0 0; font-size: .85rem; color: var(--text-gray); }
.files-chosen:empty { display: none; }

/* --- Attachments ------------------------------------------------------------- */
.attachment-grid { display: flex; flex-wrap: wrap; gap: 8px; margin: 10px 0 4px; }
.attachment-tile { position: relative; width: 84px; height: 84px; border-radius: 6px; overflow: hidden;
  border: 1px solid var(--border); background: var(--bg); }
.attachment-tile a { display: flex; width: 100%; height: 100%; align-items: center; justify-content: center;
  text-decoration: none; }
.attachment-tile img { width: 100%; height: 100%; object-fit: cover; }
.attachment-pdf { font-weight: 800; color: var(--accent); letter-spacing: .05em; }
.attachment-type { position: absolute; left: 0; right: 0; bottom: 0; background: rgba(15,23,42,.72); color: #fff;
  font-size: .64rem; text-align: center; padding: 2px 0; pointer-events: none; }
.attachment-remove { position: absolute; top: 2px; right: 2px; width: 24px; height: 24px; border-radius: 50%;
  border: 0; background: rgba(255,255,255,.9); color: #475569; font-size: .8rem; cursor: pointer; line-height: 1; }
@media (hover: hover) { .attachment-remove:hover { color: var(--red); } }
.attachment-buttons { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; margin-top: 8px; }
.attachment-buttons .btn { margin: 0; cursor: pointer; }
.attachment-loading { display: none; font-size: .85rem; color: var(--text-gray); }
.attachment-upload.htmx-request .attachment-loading { display: inline; }
.attachment-upload.htmx-request label { opacity: .5; pointer-events: none; }

/* --- Intake: warranty / invoice options ---------------------------------------- */
.check-line { display: flex; align-items: center; gap: 10px; margin: 4px 0; font-weight: 600; cursor: pointer; font-size: .95rem; color: var(--text); text-transform: none; letter-spacing: 0; }
.check-line input { width: 20px; height: 20px; margin: 0; flex: none; }
.check-extra { margin: 6px 0 12px 30px; }

/* --- ToDo list ------------------------------------------------------------------ */
.todo-row { display: flex; align-items: center; gap: 10px; padding: 11px 0; border-bottom: 1px solid var(--border); }
.todo-row:last-child { border-bottom: 0; }
.todo-text { flex: 1; min-width: 0; color: inherit; text-decoration: none; }
.todo-title { font-weight: 600; }
.todo-detail { font-size: .84rem; color: var(--text-gray); margin-top: 2px; }
.todo-actions { flex: none; display: flex; gap: 6px; align-items: center; }
.todo-actions form { margin: 0; }
.todo-actions input { width: 110px; }
.todo-dot { width: 10px; height: 10px; border-radius: 50%; flex: none; background: var(--text-gray); }
.todo-notify { background: var(--green); }
.todo-update, .todo-followup { background: var(--blue); }
.todo-warranty, .todo-proof { background: var(--red); }
.todo-price, .todo-resume, .todo-submit { background: var(--orange); }
.todo-manual { background: var(--dark); }

/* One To-Do with its notes: the row, the (hidden) edit field, the notes
   below it and the field for a new note. */
.todo-block { padding: 4px 0 10px; border-bottom: 1px solid var(--border); }

/* ---- Compact To-Do list ------------------------------------------------
   Closed, a To-Do is a single line (like a note list): text on one line,
   nothing else. Tapping it adds .open and everything belonging to it
   appears - date, notes, note field, category and buttons. */
.todo-block:not(.open) { padding: 0; }
.todo-block:not(.open) .todo-row { padding: 7px 0; }
/* v20: der Text wird NICHT mehr abgeschnitten. Vorher stand hier
   nowrap + ellipsis; am Handy war von einem längeren To-Do damit die Hälfte
   nicht zu lesen, ohne es erst aufzuklappen. Jetzt bricht er einfach um. */
.todo-block:not(.open) .todo-title { white-space: pre-line; font-weight: 500; }
/* Geschlossen bleiben nur die BEARBEITEN-Teile weg (Notizfeld, Stifte).
   Die vorhandenen Notizen stehen seit v20 immer da - sie sind der halbe
   Inhalt eines To-Dos, dafür soll niemand erst tippen müssen. */
.todo-block:not(.open) .todo-detail,
.todo-block:not(.open) .todo-note-new,
.todo-block:not(.open) .pencil { display: none; }
/* Geschlossen keine Notiz-Knöpfe: die Zeile soll ruhig bleiben, geändert
   und gelöscht wird eine Notiz im aufgeklappten To-Do. */
.todo-block:not(.open) .todo-note .item-remove,
.todo-block:not(.open) .todo-note .inline-buttons { display: none; }
.todo-block.open .todo-title { white-space: pre-line; }
.todo-block .todo-text { cursor: pointer; }
/* Die Zahl "2 Notizen" ist weg (Template), seit die Notizen selbst dastehen. */

/* The note field is small while it sits there and grows when typing. */
.todo-note-new input { transition: padding .12s ease; }
.todo-note-new input:focus { padding-top: 14px; padding-bottom: 14px; }
.todo-edit textarea { min-height: 40px; transition: min-height .12s ease; }
.todo-edit textarea:focus { min-height: 110px; }
.todo-block:last-child { border-bottom: 0; }
.todo-block .todo-row { border-bottom: 0; }
.todo-edit { padding: 4px 0 6px 20px; }
.todo-note {
  display: flex; align-items: baseline; gap: 8px; padding: 3px 0 3px 20px;
  font-size: .86rem;
}
.todo-note-time { color: var(--text-gray); font-size: .78rem; white-space: nowrap; flex: none; }
.todo-note-text { flex: 1; min-width: 0; }
.todo-note-new { display: flex; gap: 6px; align-items: center; padding: 6px 0 0 20px; }
.todo-note-new input { flex: 1; min-width: 0; font-size: .88rem; padding: 7px 10px; }
.todo-note-new .btn { flex: none; }
/* Category heading gets the category's colour (set inline). */
.category-head { border-bottom: 2px solid var(--category, var(--border)); padding-bottom: 6px; }
.storage-bar { height: 8px; border-radius: 99px; background: var(--bg); overflow: hidden; }
.storage-bar span { display: block; height: 100%; background: var(--dark); }
@media (min-width: 1200px) {
  .status-bar .status-pill { flex: 1 1 auto; white-space: nowrap; }
}
@media (min-width: 900px) {
  .status-bar.marker-bar .status-pill { flex: none; }
}
.case-step .field-row { max-width: 440px; }
.kpis-fest { grid-template-columns: repeat(auto-fill, minmax(145px, 1fr)); }

/* ---- Dashboard tiles ----------------------------------------------
   The dashboard is a row of blocks, one per area. A block is only as wide
   as its own tiles (--n, set in dashboard.html), so the blocks sit next to
   each other and fill the row instead of each one stretching across the
   whole page. A block that is too wide for what is left simply moves to
   the next row; a block wider than the page wraps its own tiles.
   Phone: one block below the other, as before.
   Long titles ("Benachrichtigt") wrap instead of being cut off. */
.dash-grid { grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); }
.dash-block { min-width: 0; }

@media (min-width: 1024px) {
  .dash-flow { display: flex; flex-wrap: wrap; align-items: flex-start; gap: 0 20px; }
  /* 215 px per tile + the 12 px gap between them, and never wider than the page. */
  .dash-block { flex: 0 1 auto;
                width: calc(var(--n, 1) * 215px + (var(--n, 1) - 1) * 12px);
                max-width: 100%; }
  .dash-block .dash-grid { grid-template-columns: repeat(auto-fill, minmax(215px, 1fr)); }
  /* A section with many tiles (repair statuses) takes the whole row and
     divides it into exactly as many columns as it has tiles - so all of
     them stand side by side instead of wrapping after the fifth. The tiles
     get narrower, not fewer; padding and type shrink a little with them. */
  .dash-block-wide { width: 100%; flex: 1 1 100%; }
  .dash-block-wide .dash-grid { grid-template-columns: repeat(var(--n, 1), minmax(0, 1fr)); gap: 8px; }
  .page-dashboard .dash-block-wide .kpi { padding: 12px 12px 13px; }
  .page-dashboard .dash-block-wide .kpi .kpi-title { font-size: .66rem; }
  .page-dashboard .dash-block-wide .kpi .kpi-value { font-size: 1.75rem; }
}
@media (max-width: 600px) {
  .dash-grid { grid-template-columns: repeat(auto-fill, minmax(132px, 1fr)); gap: 8px; }
  /* Phone: flatter tiles and less air around the headings, so more areas
     fit on one screen without the numbers getting small. */
  .page-dashboard main { padding-top: 12px; }
  .page-dashboard .kpis { margin-bottom: 0; }
  .page-dashboard .kpi { padding: 7px 11px 8px; }
  .page-dashboard .kpi .kpi-value { font-size: 1.3rem; line-height: 1.15; padding-top: 1px; }
  .page-dashboard .dash-title { margin: 14px 0 6px; font-size: 1rem; }
}

.dash-title { margin: 26px 0 12px; }
.dash-title a { color: inherit; text-decoration: none; }
.dash-title a span { color: var(--text-gray); font-weight: 500; }
@media (hover: hover) { .dash-title a:hover { color: var(--accent); } .dash-title a:hover span { color: var(--accent); } }

.kpi-value-small { font-size: 1.4rem; }

/* On a PC the tiles are flatter: less padding, smaller heading, so every
   area fits on the screen with little scrolling - without making the
   numbers themselves hard to read. Must stay BELOW the normal .kpi /
   .dash-title rules, otherwise those would win again. */
@media (min-width: 1024px) {
  .page-dashboard main { padding-top: 22px; padding-bottom: 34px; }
  .page-dashboard h1 { font-size: 1.6rem; margin-bottom: 10px; }
  .page-dashboard .kpis { gap: 12px; margin-bottom: 6px; }
  .page-dashboard .kpi { padding: 16px 18px 17px; }
  .page-dashboard .kpi .kpi-title { font-size: .74rem; line-height: 1.3; }
  .page-dashboard .kpi .kpi-value { font-size: 2.1rem; line-height: 1.1; padding-top: 4px; }
  .page-dashboard .kpi-value-small { font-size: 1.6rem; }
  .page-dashboard .dash-title { margin: 22px 0 10px; font-size: 1.12rem; }
}
/* Big screen (16" / 1600 px and up): the same tiles, a little more air. */
@media (min-width: 1600px) {
  .page-dashboard .kpi { padding: 18px 20px 19px; }
  .page-dashboard .kpi .kpi-value { font-size: 2.3rem; }
}

/* ---- New movement: quantity field with ✓ / − / ＋ ---- */
.qty-row { display: flex; gap: 6px; align-items: stretch; }
.qty-row .qty-field { width: 64px; flex: none; text-align: center; font-weight: 600; }
.qty-button {
  flex: none; width: 42px; border: 1px solid var(--border); border-radius: var(--r);
  background: var(--card); color: var(--dark); font: inherit; font-size: 1.15rem; font-weight: 700;
  cursor: pointer; padding: 0; line-height: 1;
}
.qty-button[hidden] { display: none; }
/* Tapping − / ＋ must not leave a coloured ring behind (only keyboard
   navigation gets one, via :focus-visible). */
.qty-button:focus { outline: none; box-shadow: none; }
.qty-button:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.qty-button.qty-ok { background: var(--green); border-color: var(--green); color: #fff; }
@media (hover: hover) { .qty-button:not(.qty-ok):hover { border-color: var(--accent); } }

/* ---- Phone/tablet: top bar stays visible while a pop-up window is open ----
   The window starts right below the bar (height measured in modal.js), and
   the ☰ menu opens above the window. */
@media (max-width: 1023px) {
  .modal-overlay { top: var(--head-height, 52px); }
  .modal-window { max-height: 100%; }
  body.modal-open .mobile-head { z-index: 95; }
  body.modal-open .backdrop { z-index: 96; }
  body.modal-open .sidebar { z-index: 97; }
}
@media (max-width: 600px) {
  .modal-window { height: 100%; }
}

/* ---------- Settings: colour rows (status colours, To Do categories) ---------- */
.color-row { display: flex; align-items: center; gap: 10px; margin: 6px 0; text-transform: none;
              letter-spacing: 0; font-weight: 500; }
.color-row input[type=color], .color-field { width: 42px; height: 34px; padding: 2px; border: 1px solid var(--border);
              border-radius: 6px; background: #fff; flex: none; cursor: pointer; }
.set-new .color-field { height: 46px; align-self: flex-end; }

/* ---------- To Do categories ---------- */
.todo-category { display: inline-block; padding: 3px 10px; border-radius: 999px; font-size: .8rem; font-weight: 600;
            background: color-mix(in srgb, var(--category, #94a3b8) 16%, #fff);
            color: color-mix(in srgb, var(--category, #94a3b8) 75%, #000); }
/* Wird noch von "Gebraucht" benutzt (Status je Zeile), in der To-Do-Liste
   nicht mehr - dort steht seit v20 der kleine Farbpunkt darunter. */
select.todo-category-select { width: auto; max-width: 190px; min-height: 34px; padding: 4px 8px; font-size: .82rem;
            font-weight: 600; border-radius: 999px;
            background: color-mix(in srgb, var(--category, #94a3b8) 16%, #fff);
            color: color-mix(in srgb, var(--category, #64748b) 75%, #000);
            border-color: color-mix(in srgb, var(--category, #cbd5e1) 45%, #fff); }

/* Kategorie-Knopf in der To-Do-Zeile (v20): nur Farbpunkt + ▾. Vorher
   stand hier eine breite Auswahlliste mit dem Kategorienamen - der steht
   aber schon als Überschrift über der Karte, also wiederholte sich derselbe
   Text in jeder Zeile und die Liste wirkte überladen. */
.todo-cat {
  display: inline-flex; align-items: center; gap: 3px; flex: none; cursor: pointer;
  padding: 5px 7px; border-radius: 999px; font: inherit; font-size: .72rem; line-height: 1;
  background: color-mix(in srgb, var(--category, #94a3b8) 14%, #fff);
  color: color-mix(in srgb, var(--category, #64748b) 70%, #000);
  border: 1px solid color-mix(in srgb, var(--category, #cbd5e1) 40%, #fff);
}
.todo-cat:hover, .todo-cat:focus { border-color: var(--category, #94a3b8); }
.todo-cat .category-dot { width: 9px; height: 9px; }
.todo-cat-arrow { opacity: .7; }
@media (max-width: 700px) {
  /* Handy (v20): der Text steht ganz oben und ganz breit, darunter in einer
     eigenen Zeile die Knöpfe - Kategorie links, ✓/✕ und WhatsApp rechts.
     Vorher teilten sich Text und Knöpfe eine Zeile, dadurch blieb für den
     Text ein schmaler Streifen und er brach Wort für Wort um. */
  .todo-row { flex-wrap: wrap; align-items: flex-start; }
  /* Nur bei den echten To-Dos (.todo-block) bekommt der Text die ganze
     Breite - dort hängen Kategoriefeld, ✓, ✕ und WhatsApp an der Zeile.
     In der Karte "Kunde benachrichtigen" steht nur ein einziger Knopf, der
     bleibt neben dem kurzen Text stehen. */
  .todo-block .todo-text { flex: 1 0 100%; }
  .todo-block .todo-actions { width: 100%; justify-content: flex-start; margin-top: 4px; padding-left: 20px; }
  /* Der Kategorie-Knopf ist klein, die Zeichen bleiben rechts aussen. */
  .todo-actions .todo-done, .todo-actions .todo-delete { margin-left: auto; }
  .todo-actions .todo-delete { margin-left: 0; }
  /* Beim geschlossenen To-Do bleiben alle Knöpfe erreichbar - gespart wird
     nur noch der Stift, der zum Bearbeiten gehört (siehe oben). */
  .todo-block:not(.open) .contact-more { display: none; }
}

/* ---- Stock split by purchase price (batches.py) ---- */
.batches { display: flex; flex-wrap: wrap; align-items: baseline; gap: 6px 14px;
  margin: -4px 0 16px; padding: 10px 12px; border: 1px solid var(--border);
  border-radius: 10px; background: var(--bg); font-size: .88rem; }
.batches-title { font-weight: 600; width: 100%; font-size: .82rem;
  text-transform: uppercase; letter-spacing: .04em; color: var(--text-gray); }
.batch { white-space: nowrap; }
.batch-first strong { color: var(--accent-dark); }
.movement-card .batches { margin: 10px 0 0; background: #fff; }

/* ---- Category chips on the "Neues To-Do" form ---- */
.category-chips { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 4px; }
.category-chip { display: inline-flex; align-items: center; gap: 7px; cursor: pointer;
  padding: 8px 13px; border: 1px solid var(--border); border-radius: 999px;
  font-size: .9rem; font-weight: 500; background: #fff; }
.category-chip input { position: absolute; opacity: 0; width: 0; height: 0; }
.category-dot { width: 11px; height: 11px; border-radius: 50%; flex: none; background: var(--category, #94a3b8); }
.category-chip:has(input:checked) {
  border-color: var(--category, #94a3b8); font-weight: 600;
  background: color-mix(in srgb, var(--category, #94a3b8) 16%, #fff);
  color: color-mix(in srgb, var(--category, #94a3b8) 75%, #000);
}

/* ---------- Repairs overview: optional "Aufgaben" column ---------- */
.tasks-cell { font-size: .82rem; min-width: 180px; max-width: 320px; white-space: normal; }
.tasks-cell div + div { margin-top: 2px; }
/* Finished tasks stay readable but step back a little. */
.tasks-cell .task-done { color: #c2cad4; }

/* The "Aufgaben" column is off until the ☰ button above the table turns it
   on (the choice is kept in the browser, see repairs_list.html). */
/* v20 (3.3): the "Aufgaben" column is always shown - no switch any more. */

/* Intake chips: iOS paints button text blue unless a colour is set. */
.chip { color: var(--text); }

/* ---------- Repair: add a task / book out an article ---------- */
.article-confirm { margin-top: 10px; border: 1px solid var(--border); border-radius: var(--r); padding: 12px 14px; background: var(--bg); }
.article-title { font-weight: 700; }
.article-values { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; margin: 12px 0; }
.article-values > div { display: flex; flex-direction: column; gap: 2px; }
.article-values > div > span:first-child { font-size: .72rem; text-transform: uppercase; letter-spacing: .05em; color: var(--text-gray); font-weight: 700; }
.article-price { display: flex; align-items: center; gap: 6px; }
.article-price input { max-width: 120px; }
.article-buttons { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; justify-content: flex-end; }
.article-qty { display: flex; align-items: center; gap: 6px; margin: 0 auto 0 0; font-weight: 600; text-transform: none; letter-spacing: 0; }
.article-qty input { width: 60px; }
.text-rot { color: var(--red); }
@media (max-width: 480px) { .article-values { grid-template-columns: 1fr 1fr; } }

/* Serial number check below the field (static/serial.js) */
.sn-hint { font-size: 0.85rem; color: var(--muted, #64748b); margin-top: 4px; }
.sn-hint.sn-error { color: #b91c1c; font-weight: 600; }

/* ---- Customer page: data + bikes side by side on the PC ---- */
input[type=email] {
  width: 100%; padding: 11px 12px; font-size: 1rem;
  border: 1px solid var(--border); border-radius: var(--r);
  background: #fff; color: var(--text); font-family: inherit;
}
.field-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(170px, 1fr)); gap: 0 12px; }
.field-grid-address { grid-template-columns: 90px 1fr 80px 1fr; }
@media (max-width: 600px) { .field-grid-address { grid-template-columns: 90px 1fr; } }
.customer-grid { display: grid; grid-template-columns: 1fr; gap: 0 14px; align-items: start; }
@media (min-width: 1200px) { .customer-grid { grid-template-columns: minmax(0, 2fr) minmax(0, 3fr); } }
.card-hint { border-left: 4px solid var(--yellow); }
.bike-buttons { display: flex; gap: 2px; flex: none; }
.bike-traded .entry-label { color: var(--text-gray); }
.bike-history { margin-top: 8px; font-size: .88rem; }
.bike-history summary { cursor: pointer; color: var(--text-gray); font-weight: 600; padding: 4px 0; }
.history-row { display: grid; grid-template-columns: 84px 120px 1fr; gap: 8px; padding: 5px 0;
                 border-bottom: 1px solid var(--border); }
.history-row:last-child { border-bottom: none; }
.history-date { color: var(--text-gray); }
.history-kind { font-weight: 600; }
@media (max-width: 600px) {
  .history-row { grid-template-columns: 84px 1fr; }
  .history-text { grid-column: 1 / -1; }
}
a.row-link { color: inherit; text-decoration: none; }
@media (hover: hover) { a.row-link:hover { background: var(--bg); } }
.card-summary { cursor: pointer; list-style: none; }
.card-summary::-webkit-details-marker { display: none; }
.card-summary h2 { display: inline; margin: 0; }
.card-summary::after { content: " ▸"; color: var(--text-gray); }
details[open] > .card-summary::after { content: " ▾"; }
.count-pill { display: inline-block; min-width: 20px; padding: 0 6px; border-radius: 999px;
              background: var(--accent); color: #fff; font-size: .78rem; text-align: center; margin-left: 4px; }
.move-form { margin-top: 10px; padding-top: 10px; border-top: 1px dashed var(--border); }
tr.row-erledigt td { color: var(--text-gray); text-decoration: line-through; }
a.status-pill { text-decoration: none; }

/* Phone: long tables only show the columns that matter at a glance
   (the rest is one tap away on the detail page). */
@media (max-width: 600px) {
  table.list .wide-only { display: none; }
  table.list th, table.list td { padding-left: 6px; padding-right: 6px; }
  table.list .badge { white-space: normal; line-height: 1.25; padding: 3px 8px; font-size: .74rem; }
}
.data-list a { color: inherit; text-decoration-color: var(--border); }
.card-hint .btn { white-space: nowrap; }
.customer-link { color: inherit; text-decoration: none; } @media (hover: hover) { .customer-link:hover { text-decoration: underline; } }

/* Shared right-click menu (context_menu.js): tap on touch opens the
   submenu, and it can open to the left when there is no room. */
.status-menu.menu-open .status-submenu { display: block; }
.status-menu.sub-left .status-submenu { left: auto; right: 100%; }
/* Direkt-Modus (v20): der Knopf meint genau EINE Liste, deshalb fällt der
   Umweg über "Status setzen ▸" weg - die Zeile verschwindet und die Liste
   selbst steht an der Klickstelle statt daneben. */
.status-menu.menu-direct { padding: 0; border: none; box-shadow: none; min-width: 0;
  background: none; }
.status-menu.menu-direct .status-menu-main { padding: 0; display: block; }
.status-menu.menu-direct .status-menu-label { display: none; }
.status-menu.menu-direct .status-submenu { position: static; display: block; }

/* ---- Contact button: tap = WhatsApp chat, ▾ = call / SMS ---- */
.contact-button { display: inline-flex; position: relative; flex: none; }
.contact-button .contact-wa { border-top-right-radius: 0; border-bottom-right-radius: 0;
  display: inline-flex; align-items: center; justify-content: center; padding-left: 10px; padding-right: 10px; }
.contact-button .contact-wa svg { width: 18px; height: 18px; display: block; }
.contact-button .contact-more { border-top-left-radius: 0; border-bottom-left-radius: 0;
  border-left: 1px solid rgba(255,255,255,.35); padding-left: 7px; padding-right: 7px; }
.contact-list { display: none; position: absolute; right: 0; top: calc(100% + 4px); z-index: 60;
  background: #fff; border: 1px solid var(--border); border-radius: var(--r);
  box-shadow: 0 10px 30px rgba(15,23,42,.18); padding: 6px; min-width: 140px; }
.contact-button.menu-open .contact-list { display: block; }
.contact-list a { display: block; padding: 9px 12px; border-radius: 6px; color: var(--text);
  text-decoration: none; font-size: .92rem; white-space: nowrap; }
.contact-list a:hover { background: var(--accent-light); color: var(--accent-dark); }

/* ---- To-Do title line: title, customer (greyed), pencil ---- */
.todo-head-row { display: flex; align-items: baseline; gap: 8px; min-width: 0; }
.todo-head-row .todo-title { min-width: 0; flex: 0 1 auto; }
.todo-customer { color: var(--text-gray); font-size: .86rem; font-weight: 400; text-decoration: none;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; flex: 0 1 auto; min-width: 0; }
.todo-customer:hover { text-decoration: underline; }
/* "＋ Kunde" am To-Do ohne Kunden (v20): unaufdringlich, aber auffindbar.
   Nur im aufgeklappten To-Do - geschlossen soll die Zeile ruhig bleiben. */
.todo-customer-add {
  color: var(--text-gray); font-size: .78rem; text-decoration: none; flex: none;
  border: 1px dashed var(--border); border-radius: 999px; padding: 2px 9px; opacity: .8;
}
.todo-customer-add:hover { color: var(--accent); border-color: var(--accent); opacity: 1; }
.todo-block:not(.open) .todo-customer-add { display: none; }
/* Der Stift am Kundennamen gehört zum Bearbeiten und folgt derselben Regel
   wie die übrigen Stifte (geschlossen weg, siehe .todo-block:not(.open)). */
.todo-customer-edit { text-decoration: none; }
/* Created on / by, greyed, at the right end of the title line (v16). */
.todo-meta {
  margin-left: auto; flex: none; white-space: nowrap;
  font-size: .78rem; color: var(--text-gray); opacity: .85;
}
.todo-meta a { color: inherit; }
/* Narrow window: not in the CLOSED row (it would get too full) - once the
   To-Do is open it gets a line of its own. */
@media (max-width: 600px) {
  .todo-block:not(.open) .todo-meta { display: none; }
  .todo-block.open .todo-head-row { flex-wrap: wrap; }
  .todo-block.open .todo-meta { margin-left: 0; flex: 1 0 100%; }
}
/* The title pencil is always there (open or closed), a little greyed. */
.todo-block:not(.open) .todo-head-row .title-pencil { display: inline-block; }
.title-pencil, .note-pencil { opacity: .6; padding: 0 4px; font-size: .88rem; }
.title-pencil:hover, .note-pencil:hover { opacity: 1; }
.todo-block:not(.open) .todo-head-row { align-items: center; }
/* Editing in place: ✓ / ✕ instead of the pencil. */
.inline-buttons { display: none; flex: none; gap: 2px; }
.inline-active .inline-buttons { display: inline-flex; }
.inline-active .title-pencil, .inline-active .note-pencil, .inline-active .todo-customer,
.inline-active .todo-meta { display: none !important; }
.inline-ok { color: var(--green); font-weight: 700; }
.inline-edit { outline: 1px solid var(--accent); outline-offset: 3px; border-radius: 3px;
  white-space: pre-wrap !important; overflow: visible !important; text-overflow: clip !important;
  cursor: text; background: #fff;
  /* Only as wide as the text: the field grows while typing and the pencil
     (or ✓ / ✕) stays right next to it instead of jumping to the edge. */
  display: inline-block; flex: 0 1 auto !important; min-width: 2ch; max-width: 100%; }
.inline-active { flex-wrap: nowrap; }

/* New To-Do: the category select shows the category's colour at once. */
select.category-preview { border-left: 8px solid var(--category, var(--border)); }

/* ---- Repair tasks: the text pencil sits right after the text (small gap),
   the price / ✓ OK is pushed to the right edge. ---- */
.item-block .item-text { flex: 0 1 auto; min-width: 0; }
/* Der Stift steht IM Textfluss, also direkt hinter dem letzten Wort. */
.item-text > .pencil { margin-left: 2px; vertical-align: baseline; }
.item-block .item-price { margin-left: auto; }
/* Text edit row: the field stays short enough that the price badge on
   the right is never covered. */
.item-edit .item-edit-form { flex: 0 1 460px; max-width: 100%; }
.item-add { font-size: 1.1rem; font-weight: 700; }
.item-new-fields[hidden] { display: none; }
.item-scan:has(> .item-new-fields[hidden]) { margin-top: 0; }

/* ---- Repair page header: customer (name / phone + ✎) on the right,
   level with the header line - wide screens only (.desktop-only). ---- */
.repair-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 16px; }
.repair-head-customer { text-align: right; padding-top: 4px; }
.repair-head-customer .cust-view { justify-content: flex-end; }
.cust-view { display: flex; align-items: center; gap: 4px; min-height: 26px; }
.cust-view[hidden], .cust-form[hidden] { display: none; }
.cust-form { display: flex; align-items: center; gap: 6px; margin: 2px 0; }
.cust-form input { flex: 1 1 200px; min-width: 0; padding: 6px 9px; }
.repair-notes { margin: 8px 0 0; }
@media (min-width: 1024px) {
  .narrow-only { display: none !important; }
  .repair-notes { margin: 0; }
}

/* Customer number next to the name (K12). */
.customer-no { color: var(--text-gray); font-weight: 500; font-size: .7em; margin-left: 6px; }

/* Customer page: "Übersicht" card with one small heading per area. */
.overview .overview-title { display: flex; align-items: center; gap: 8px; margin: 14px 0 2px;
  font-size: .74rem; font-weight: 700; text-transform: uppercase; letter-spacing: .05em; color: var(--text-gray); }
.overview .card-head + .overview-title { margin-top: 0; }
/* ✓ / ✕ while editing - also when the To-Do is closed (where the other
   pencils are hidden). */
.inline-active .inline-buttons .pencil { display: inline-block !important; font-size: 1.05rem; padding: 2px 6px; }
/* Phone: the new line's text field gets the whole first row; price, ✓,
   Scannen and ✕ sit on the row below. */
@media (max-width: 600px) {
  .item-new-row .item-text-input { flex: 1 1 calc(100% - 30px) !important; }
  .item-new-row .item-remove { margin-left: auto; }
}

/* ---- Dashboard: section headings like the sidebar (icon + word) ---- */
.dash-title .nav-icon { display: inline-block; opacity: .55; margin-right: 2px; }

/* ---- Editing in place (inline_edit.js), used on every page ---- */
/* .inline-row is only a marker for the JS (it finds the field inside it);
   the row keeps whatever layout its own block already has. The field is
   only as wide as its text, so the pencil sits directly behind it. */
.inline-field { display: inline-block; max-width: 100%; flex: 0 1 auto; }
.inline-row .inline-field + .pencil { margin-left: -2px; }

/* ---- Point 6: while a price is being corrected, the field stays on the
   right edge - exactly where the badge was. ---- */
.item-price-edit .item-price-form,
.item-row .item-price-form { margin-left: auto; }
.item-price-edit { justify-content: flex-start; }
.item-price-form { display: flex; align-items: center; gap: 6px; }

/* ---- Point 7: the task's text field is as wide as its text and grows
   while typing (data-autowidth in inline_edit.js sets the width). ---- */
.item-edit-form .item-text-input { flex: 0 1 auto; min-width: 6ch; }
.item-edit .item-edit-form { flex: 0 1 auto; }

/* ---- Point 11: category chips all the same height and on one line ---- */
.category-chips { align-items: center; }
.category-chip { position: relative; box-sizing: border-box; min-height: 40px;
  line-height: 1.2; white-space: nowrap; margin: 0; }

/* ---- Price range "von – bis" (used-bike requests) ---- */
.price-range { display: flex; align-items: center; gap: 8px; max-width: 320px; }
.price-range input { flex: 1 1 0; min-width: 0; }
.price-range span { color: var(--text-gray); }

/* ---- Point 14: alias next to the name, set apart and greyed ---- */
.alias { color: var(--text-gray); font-weight: 400; font-size: .88em; margin-left: 10px; }

/* Repair page: name / phone field as wide as its text (data-autowidth). */
.cust-form input { flex: 0 1 auto; }


/* ---- Bike chips in the intake form ------------------------------------
   Top line bold (brand, model, size, colour), below it small and grey the
   serial number. Always two lines, never side by side - on a phone the
   chip then wraps instead of pushing the page sideways. A bike that still
   has a repair running is greyed out but stays selectable. */
.bike-chip { display: block; text-align: left; line-height: 1.3; }
.bike-chip .bike-title { display: block; font-weight: 600; }
.bike-chip .bike-sub { display: block; font-size: .82em; color: var(--text-gray); }
.bike-chip.bike-busy { opacity: .55; }
.bike-chip.bike-busy.bike-active { opacity: 1; }
.bike-busy-note { color: var(--text-gray); font-size: .85em; }
.bike-block.bike-busy > .bike-row { opacity: .55; }

/* ---- v20 (3.1): the task chips at intake stand below each other, one per
   line - side by side they were hard to scan. ---- */
.chip-grid-tasks { flex-direction: column; align-items: flex-start; }
.chip-grid-tasks > .chip, .chip-grid-tasks > .pages-group { width: auto; max-width: 100%; }

/* ---- v20 (3.5): an open task is confirmed with "OK" instead of a bare
   checkmark; Enter in the price field does the same (the form submits),
   an empty field means 0,00 €. ---- */
.item-check.item-ok { width: auto; min-width: 44px; padding: 0 12px; font-size: .85rem; font-weight: 700; }

/* ---- v20 (3.8): the line for a NEW task is set apart from the tasks that
   came in with the bike, and its field is narrower than a task row. ---- */
.item-new-block { border-top: 1px solid var(--border); padding-top: 12px; margin-top: 4px; }
.item-new-block .item-text-input { flex: 0 1 300px !important; }

/* ---- v20 (5.1/5.3): "Kunde suchen" and "Kunde neu anlegen" are two
   separate areas, and a hit shows its place clearly set apart. ---- */
.customer-new { margin-top: 18px; padding-top: 14px; border-top: 1px solid var(--border); }
.customer-area .area-label { font-weight: 700; }
.search-row { display: flex; align-items: center; gap: 6px; }
.search-row input { flex: 1 1 auto; min-width: 0; }
.search-clear { flex: none; font-size: 1.05rem; }
.search-clear[hidden] { display: none; }
.customer-new[hidden], #customer-find[hidden] { display: none; }
.name-row { display: flex; gap: 10px; }
.name-field { flex: 1 1 0; min-width: 0; }
.name-field input { width: 100%; }
.hit-place { color: var(--text); font-weight: 600; margin-right: 10px; }

/* ---- Reparaturliste: since when the order has had this status, right
   under its badge instead of in a column of its own. ---- */
.status-since { color: var(--text-gray); font-size: .78rem; margin-top: 3px; }

/* ---- Reparaturliste am Handy: eine Karte pro Auftrag statt einer Tabelle,
   die seitlich weggewischt werden muss. Es bleibt EIN DOM - die Tabelle
   wird nur anders dargestellt - damit Suche, Status-Filter und Sortierung
   unverändert weiterarbeiten. Die sonst am Handy versteckten Spalten
   (.wide-only) gehören hier wieder dazu, weil nichts mehr wegrutscht. ---- */
@media (max-width: 600px) {
  #repair-table, #repair-table tbody, #repair-table tr { display: block; width: 100%; }
  #repair-table thead { display: none; }
  .table-scroll:has(#repair-table) { overflow: visible; }
  #repair-table tr {
    border: 1px solid var(--border); border-left-width: 5px; border-radius: 10px;
    padding: 10px 12px; margin-bottom: 10px; background: var(--card);
    display: grid; grid-template-columns: 1fr auto; gap: 2px 10px;
  }
  #repair-table td {
    display: block; border: none; padding: 0; width: auto;
    min-width: 0; overflow-wrap: anywhere;
  }
  #repair-table td.wide-only { display: block; }
  #repair-table td.col-nr { grid-column: 1; font-size: 1.05rem; }
  #repair-table td.col-status { grid-column: 2; grid-row: 1; text-align: right; }
  #repair-table td:not(.col-nr):not(.col-status) { grid-column: 1 / -1; }
  #repair-table td.col-del { display: flex; justify-content: flex-end; margin-top: 2px; }
  #repair-table td[data-label]:not(.tasks-cell)::before {
    content: attr(data-label) ": "; color: var(--text-gray); font-size: .78rem;
  }
  #repair-table .status-since { display: inline; margin-left: 8px; }
  #repair-table .tasks-cell { max-width: none; min-width: 0; margin-top: 4px; }
}

/* ---- Aufgabenzeilen: Preisfeld und Knopf stehen rechts, auch wenn die
   Zeile am Handy umbricht. Vorher rutschte das "OK" in die nächste Zeile
   und stand dort ganz links. ---- */
@media (max-width: 600px) {
  .item-new-row .item-text-input { flex: 1 1 auto !important; }
  .item-new-row .item-check { margin-left: auto; }
}

/* ---- Die feste Zeile "Arbeit": nur Preisfeld und ✕, kein Stift, kein OK.
   Beides sitzt rechts, auf jeder Breite. ---- */
.item-fixed .item-remove { flex: none; }

/* ---- Telefonnummern stehen immer auf EINER Zeile: Vorwahl und Nummer
   gehören zusammen, ein Umbruch dazwischen liest sich wie zwei Nummern. --- */
.phone-cell, .col-telefon, .hit-phone, a[href^="tel:"] {
  white-space: nowrap; overflow-wrap: normal;
}

/* ---- Reparaturliste: der Zeitpunkt steht mittig unter dem Status-Badge.
   Am Handy (Karte) bleibt der Status rechtsbündig, dort sitzt der Zeitpunkt
   darunter am selben Rand. ---- */
@media (min-width: 601px) {
  table.list .status-cell { text-align: center; }
  table.list .status-cell .status-since { text-align: center; }
}

/* Feste Zeile "Arbeit": das Badge ist selbst der Weg zurück ins Preisfeld. */
.item-price-open { cursor: pointer; }

/* ---- Gewählter Kunde im Aufnahmeformular (v20): Anzeige links, ✎ und ✕
   rechts; das ✎ klappt darunter ein Formular für Vorname, Nachname,
   Nickname und Telefonnummer auf. ---- */
.cust-shown[hidden], .cust-edit[hidden] { display: none; }
.cust-edit { flex: 1 1 100%; }
.cust-edit label { display: block; margin: 8px 0 4px; }
.cust-edit input { width: 100%; }
.cust-edit-row { display: flex; align-items: center; gap: 8px; }
.cust-edit-row input { flex: 1 1 auto; min-width: 0; }
.cust-buttons { display: flex; align-items: flex-start; gap: 4px; flex: none; margin-left: auto; }
.cust-buttons .item-remove { text-decoration: none; line-height: 1; }

/* ---- Aufgabenzeilen (v20): oben der Text mit dem Stift DIREKT dahinter -
   egal wie kurz oder lang er ist. Darunter, immer gleich eingerückt,
   Preisfeld und Knöpfe. So stehen die Felder aller Zeilen in einer Flucht
   und die Reihe wirkt ruhig, statt je nach Textlänge zu springen. ---- */
.item-row:has(> .item-actions) { align-items: baseline; row-gap: 4px; }
/* Der Text nimmt die Breite neben dem Punkt und bricht in sich um - der
   Punkt bleibt also oben links neben der ersten Zeile stehen. */
.item-row:has(> .item-actions) .item-text { flex: 1 1 0; min-width: 0; }
.item-row:has(> .item-actions) > .pencil { flex: none; }
/* Auch die feste Zeile "Arbeit" (ohne .item-text) setzt ihren Block nach
   unten statt neben den Text. */
.item-fixed > .item-text { flex: 1 1 0; min-width: 0; }
.item-actions {
  display: flex; align-items: center; gap: 8px;
  /* 100% MINUS der Einrückung - sonst ist die Zeile breiter als die Karte
     und der letzte Knopf ragt rechts heraus. */
  flex: 1 0 calc(100% - 25px); margin-left: 25px;
}
.item-row .item-actions .item-input { width: 92px !important; }
.item-block .item-text { overflow-wrap: anywhere; }
/* Innerhalb von .item-actions sitzen Feld und ✓ direkt nebeneinander. */
/* Im Block beginnt alles links - die ältere Regel, die ein Preisformular
   an den rechten Rand schiebt, gilt hier nicht. */
.item-actions .item-price-form { display: inline-flex; align-items: center; gap: 8px; margin-left: 0; }

/* Am PC ist genug Platz: Preisfeld und ✓ stehen auf DERSELBEN Höhe wie der
   Text, ganz rechts am Rand - die Zeile bleibt also einzeilig. Erst wenn es
   eng wird (Handy, siehe unten), rutscht der Block unter den Text.
   Die Regeln oben gelten weiter als Grundlage; hier wird nur umgestellt. */
@media (min-width: 701px) {
  .item-actions { flex: none; margin-left: auto; }
  /* Der Text darf dafür nicht mehr die ganze Breite beanspruchen. */
  .item-row:has(> .item-actions) { align-items: center; }
  .item-row:has(> .item-actions) .item-text,
  .item-fixed > .item-text { flex: 0 1 auto; }
  /* Der Stift sitzt direkt hinter dem Text, der Rest des Platzes bleibt
     leer - dadurch landen die Felder aller Zeilen in einer Flucht rechts. */
  .item-row:has(> .item-actions) > .pencil { margin-right: 0; }
}

/* "Pausieren" ist EIN Knopf über die ganze Gruppe; aufgeklappt stehen die
   drei Gründe an derselben Stelle - am PC nebeneinander, am Handy
   untereinander, jeweils über die volle Breite der Gruppe. */
.action-bar .pause-group { grid-template-columns: 1fr; }
.pause-options { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 6px; }
.pause-options[hidden] { display: none; }
.pause-main[hidden] { display: none; }
/* Die drei Gründe passen in EINE Zeile - auch am Handy. Dafür sind sie
   kleiner als die übrigen Knöpfe, sonst bräuchte "Ersatzteil" zu viel. */
.pause-options .btn { padding: 8px 4px; font-size: .74rem; min-height: 40px; }
@media (max-width: 600px) { .pause-options .btn { font-size: .7rem; padding: 8px 2px; } }
/* Letztes Wort, Nummer und Stift bleiben zusammen - der Stift steht damit
   nie allein in einer neuen Zeile. */
.item-last { white-space: nowrap; }

/* Das ↶ sitzt im zuletzt gedrückten Knopf, direkt hinter dem Wort. */
.undo-mark { margin-left: 7px; opacity: .8; cursor: pointer; font-weight: 400; }
.undo-mark:hover { opacity: 1; }

/* ---- Aufgaben: ✓ und ＋ ohne runden Rahmen - nur das Zeichen (v20). ---- */
#line-items .item-check {
  border: none; background: none; width: auto; height: auto; min-width: 0;
  padding: 4px 6px; font-size: 1.2rem; color: var(--text-gray);
}
#line-items .item-check:hover, #line-items .item-check:focus {
  border: none; background: none; color: var(--green);
}
