:root{
  --bg: #eef0f1;
  --panel: #ffffff;
  --panel-2: #f6f7f8;
  --border: #dcdfe1;
  --text: #24282b;
  /* muted/good/warn darkened in the 2026-09-05 release audit - the
     originals failed WCAG AA's 4.5:1 text-contrast minimum at the small
     sizes they're actually used at (labels, hints, status-pill text):
     muted 4.17:1/3.89:1/3.65:1 and warn 3.86:1/3.60:1/3.38:1 against
     white/panel-2/bg, good 3.96:1/3.69:1/3.46:1 the same way - these
     replacements clear 5.2:1 or better everywhere they're used as text,
     including each status-pill's own background. danger/accent-dim
     already passed (6.2+/7.9:1) and are untouched. */
  --muted: #5c6369;
  --accent: #616A71;
  --accent-dim: #4a525a;
  --stoba: #616A71;
  --good: #2f6e48;
  --warn: #8f5620;
  --danger: #a1442c;
  --sans: "Helvetica Neue", Arial, sans-serif;
  --mono: "JetBrains Mono", "Consolas", "SFMono-Regular", monospace;
}
* { box-sizing: border-box; }
body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: var(--sans);
  padding: 32px 16px 60px;
}
.wrap { max-width: 900px; margin: 0 auto; }
a { color: var(--accent-dim); }

/* ---- letterhead / nav, shared with parameter_editor.html look ---- */
.letterhead {
  background: #ffffff;
  border: 1px solid var(--border);
  border-radius: 4px;
  padding: 20px 22px 18px;
  margin-bottom: 16px;
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  row-gap: 12px;
  gap: 20px;
}
/* logo + name = one link to the start page */
.lh-brand { display: flex; align-items: center; gap: 20px; color: inherit; text-decoration: none; border-radius: 4px; }
.lh-brand:hover { opacity: 0.8; }
.lh-brand:focus-visible { outline: 2px solid var(--stoba); outline-offset: 4px; }
.letterhead img { height: 32px; width: auto; display: block; }
.letterhead .divider { width: 1px; align-self: stretch; background: #d5d8da; }
.letterhead .lh-title { margin: 0; color: var(--text); font-size: 0.95rem; font-weight: 700; letter-spacing: 0.01em; line-height: 1.3; }
.letterhead .lh-sub { color: var(--muted); font-size: 0.72rem; margin-top: 3px; text-transform: uppercase; letter-spacing: 0.06em; }
.letterhead nav,
.lh-nav-primary,
.lh-nav-secondary {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  align-items: center;
}
.lh-nav-group {
  margin-left: auto;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 8px;
}
/* Two deliberate rows (primary navigation, then account/actions)
   instead of one long strip that wraps wherever it happens to run out
   of room - with this many items, an unplanned wrap point tends to
   strand a single button awkwardly on its own line. */
.lh-nav-primary, .lh-nav-secondary { justify-content: flex-end; }
/* Plain nav links get real button framing (background + border) so
   they read as clickable controls at rest, not just colored text -
   the previous version only changed color on hover, which meant
   there was no visual cue at all until the pointer was already on
   top of it. The one true .btn (+ New motor) keeps its own look;
   this only targets the rest. */
.letterhead nav a:not(.btn) {
  font-size: 0.78rem;
  color: var(--accent-dim);
  text-decoration: none;
  font-weight: 600;
  padding: 8px 13px;
  border-radius: 4px;
  background: var(--panel-2);
  border: 1px solid var(--border);
  white-space: nowrap;
  transition: background 0.15s, border-color 0.15s, color 0.15s;
}
.letterhead nav a:not(.btn):hover { color: #ffffff; background: var(--stoba); border-color: var(--stoba); }
.letterhead nav a:not(.btn):active { background: var(--accent-dim); border-color: var(--accent-dim); }
.letterhead nav a.active { color: #ffffff; background: var(--stoba); border-color: var(--stoba); }
/* the logged-in user's name + the divider before it read as identity,
   not as another clickable nav item - kept visually separate so the
   row doesn't look like one undifferentiated strip of buttons */
.letterhead nav .nav-sep { width: 1px; align-self: stretch; background: var(--border); margin: 0 2px; }
.nav-user { color: var(--muted); font-size: 0.78rem; padding: 0 2px; white-space: nowrap; display: flex; align-items: center; }

/* the "ruler" tick motif from parameter_editor.html, reused as a recurring
   divider — precision/measurement is the whole point of this data, so the
   tick-strip is the one visual signature this tool borrows deliberately. */
.ruler {
  height: 12px;
  border-left: 1px solid var(--border);
  border-right: 1px solid var(--border);
  background-image: repeating-linear-gradient(
    to right, var(--border) 0, var(--border) 1px, transparent 1px, transparent 20px
  );
  margin: 22px 0;
}

.card {
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 4px;
  padding: 18px 20px;
  margin-bottom: 16px;
}
.card h2 { margin: 0 0 14px; font-size: 0.95rem; }
.card h3 { margin: 0 0 10px; font-size: 0.8rem; text-transform: uppercase; letter-spacing: 0.06em; color: var(--muted); }

label {
  display: block;
  font-size: 0.7rem;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--muted);
  margin-bottom: 6px;
  font-weight: 600;
}
/* password/email were missing here until 2026-09-23 (second manual check):
   login, password change, user admin and the SMTP settings all showed bare
   unstyled browser boxes next to the app's own fields */
input[type=text], input[type=number], input[type=date], input[type=password], input[type=email],
input[type=search], input[type=datetime-local],
select, textarea {
  width: 100%;
  /* caps the inline style="width:320px" some add-forms use, so on a phone
     the field shrinks to the card instead of pushing its button offscreen */
  max-width: 100%;
  background: var(--panel-2);
  border: 1px solid var(--border);
  color: var(--text);
  border-radius: 3px;
  padding: 8px 10px;
  font-family: var(--mono);
  font-size: 0.85rem;
  /* the default "normal" line height clipped the underscore of the
     monospace fallback font - "test_report_{sn}" read as "test report
     {sn}" (found 2026-10-01 on the file-name settings) */
  line-height: 1.45;
}
textarea { min-height: 90px; resize: vertical; line-height: 1.5; font-size: 0.72rem; }
input:focus, select:focus, textarea:focus { outline: 2px solid var(--stoba); outline-offset: 1px; border-color: var(--stoba); }
input:read-only { opacity: 0.4; cursor: not-allowed; }
input:read-only:focus { outline: none; border-color: var(--border); }

.field { margin-bottom: 14px; }
.field-row { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }
.field-hint { font-size: 0.72rem; color: var(--muted); margin-top: 5px; font-family: var(--sans); }

button, .btn {
  display: inline-block;
  background: var(--stoba);
  color: #ffffff;
  border: 1px solid var(--stoba);
  border-radius: 3px;
  padding: 9px 18px;
  font-size: 0.8rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  cursor: pointer;
  font-weight: 600;
  font-family: var(--sans);
  text-decoration: none;
}
button:hover, .btn:hover { background: var(--accent-dim); border-color: var(--accent-dim); }
.btn.secondary { background: transparent; border-color: var(--border); color: var(--muted); }
.btn.secondary:hover { border-color: var(--stoba); color: var(--stoba); background: transparent; }
/* One shared destructive-action style (2026-09-05 release audit: ~14
   delete buttons across admin/settings pages each re-implemented this
   inline, in two slightly different variants, and NONE of them could
   have a :hover state - CSS pseudo-classes can't be expressed via the
   style="" attribute - making them the one set of buttons in the app
   with no hover feedback at all). */
.btn.danger { background: var(--danger); border-color: var(--danger); color: #fff; }
.btn.danger:hover { background: #832c1a; border-color: #832c1a; }
.btn.danger.outline { background: transparent; color: var(--danger); }
.btn.danger.outline:hover { background: var(--danger); color: #fff; }
.btn-row { display: flex; gap: 10px; align-items: center; margin-top: 16px; flex-wrap: wrap; }

.status { font-size: 0.8rem; padding: 10px 12px; border-radius: 3px; margin-bottom: 10px; line-height: 1.5; border-left: 3px solid transparent; }
.status.ok { background: #f0f6f2; border-left-color: var(--good); color: #2c6b47; }
.status.err { background: #fbf1eb; border-left-color: var(--danger); color: var(--danger); }
.status.warn { background: #fdf6ec; border-left-color: var(--warn); color: #8a5417; }
.draft-banner {
  font-size: 0.8rem;
  padding: 10px 12px;
  border-radius: 3px;
  margin-top: 8px;
  line-height: 1.5;
  border-left: 3px solid var(--danger);
  background: #fbf1eb;
  color: var(--danger);
  font-weight: 600;
}
.draft-notice-list { margin-bottom: 14px; }
.draft-notice-list a {
  display: block;
  padding: 10px 12px;
  border-radius: 3px;
  margin-bottom: 6px;
  border-left: 3px solid var(--danger);
  background: #fbf1eb;
  color: var(--danger);
  font-weight: 600;
  text-decoration: none;
}
.draft-notice-list a:hover { text-decoration: underline; }
.draft-notice-row { display: flex; align-items: stretch; gap: 8px; margin-bottom: 6px; }
.draft-notice-row a { flex: 1; margin-bottom: 0 !important; }
.draft-delete-x {
  flex-shrink: 0; width: 34px; border: none; border-radius: 50%;
  background: var(--danger); color: #fff; font-size: 1.2rem; font-weight: 700;
  cursor: pointer; line-height: 1;
}
.draft-delete-x:hover { opacity: 0.85; }

/* ---- motor list ---- */
.searchbar { display: flex; gap: 10px; margin-bottom: 16px; }
.searchbar input { flex: 1; }
table.motorlist { width: 100%; border-collapse: collapse; background: var(--panel); border: 1px solid var(--border); border-radius: 4px; overflow: hidden; }
table.motorlist th {
  text-align: left; font-size: 0.68rem; text-transform: uppercase; letter-spacing: 0.06em;
  color: var(--muted); padding: 10px 14px; background: var(--panel-2); border-bottom: 1px solid var(--border);
}
table.motorlist td { padding: 12px 14px; border-bottom: 1px solid var(--border); font-size: 0.85rem; vertical-align: top; }
table.motorlist tr:last-child td { border-bottom: none; }
table.motorlist tr:hover td { background: var(--panel-2); }
table.motorlist tr[data-href] { cursor: pointer; }
table.motorlist a.sn-link { font-family: var(--mono); font-weight: 700; color: var(--text); text-decoration: none; }
table.motorlist a.sn-link:hover { color: var(--stoba); }
.muted { color: var(--muted); }
.mono { font-family: var(--mono); }
.empty-msg { color: var(--muted); font-size: 0.85rem; padding: 20px; text-align: center; }

/* ---- spec sheet (motor detail) ---- */
.identity {
  display: flex; align-items: baseline; gap: 18px; flex-wrap: wrap; margin-bottom: 4px;
}
.identity .sn { font-family: var(--mono); font-size: 1.5rem; font-weight: 700; }
.identity .typ { font-family: var(--mono); font-size: 0.9rem; color: var(--muted); }
.identity-meta { font-size: 0.75rem; color: var(--muted); margin-bottom: 10px; }

.paramlist { display: flex; flex-direction: column; gap: 1px; background: var(--border); border: 1px solid var(--border); border-radius: 3px; overflow: hidden; }
.param {
  display: grid; grid-template-columns: 1fr 140px; gap: 4px 10px; align-items: center;
  background: var(--panel); padding: 10px 14px;
}
.param .name { font-size: 0.82rem; font-weight: 600; }
.param .idn { font-size: 0.68rem; color: var(--muted); font-family: var(--mono); }
.param .val { font-family: var(--mono); font-size: 0.9rem; text-align: right; font-weight: 700; }
.param .val.bad { color: var(--danger); }
.checksum-flag { font-size: 0.62rem; color: var(--danger); font-family: var(--sans); font-weight: 700; text-transform: uppercase; }
.info-flag { font-size: 0.62rem; color: var(--muted); font-family: var(--sans); font-weight: 700; text-transform: uppercase; }

.field-heading { font-size: 0.72rem; color: var(--muted); text-transform: uppercase; letter-spacing: 0.06em; margin: 18px 0 8px; }
.field-heading:first-child { margin-top: 0; }

/* ---- repair timeline ---- */
.timeline { position: relative; padding-left: 26px; }
.timeline::before {
  content: ""; position: absolute; left: 6px; top: 4px; bottom: 4px; width: 1px;
  background-image: repeating-linear-gradient(to bottom, var(--border) 0, var(--border) 1px, transparent 1px, transparent 8px);
}
.timeline-item { position: relative; margin-bottom: 18px; }
.timeline-item::before {
  content: ""; position: absolute; left: -26px; top: 3px; width: 9px; height: 9px;
  border-radius: 50%; background: var(--stoba); border: 2px solid var(--panel);
}
.timeline-item .trow { background: var(--panel); border: 1px solid var(--border); border-radius: 4px; padding: 14px 16px; }
.repair-row-click:hover { background: var(--panel-2); border-radius: 3px; }
.timeline-date { font-family: var(--mono); font-weight: 700; font-size: 0.85rem; }
.timeline-item dl { margin: 10px 0 0; display: grid; grid-template-columns: 130px 1fr; gap: 4px 10px; font-size: 0.82rem; }
.timeline-item dt { color: var(--muted); font-size: 0.7rem; text-transform: uppercase; letter-spacing: 0.05em; padding-top: 2px; }
.timeline-item dd { margin: 0; }
.timeline-item .note { font-style: italic; color: var(--accent-dim); }

.commutation-badge {
  display: inline-flex; align-items: baseline; gap: 6px; background: var(--panel-2);
  border: 1px solid var(--border); border-radius: 3px; padding: 6px 12px; font-size: 0.78rem;
}
.commutation-badge .v { font-family: var(--mono); font-weight: 700; font-size: 1rem; }

.section-title { display: flex; align-items: center; justify-content: space-between; margin-bottom: 10px; }

/* ---- tags ---- */
.tag-row-wrap { display: flex; align-items: center; gap: 12px; margin-left: auto; flex-wrap: wrap; }
.tag-row {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  overflow: hidden;
  max-height: 25px;
  max-width: 260px;
  align-content: flex-start;
}
.tag-chip {
  display: inline-flex;
  align-items: center;
  padding: 3px 10px;
  border-radius: 12px;
  font-size: 0.66rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  text-decoration: none;
  white-space: nowrap;
  border: 1px solid transparent;
  line-height: 1.4;
}
.tag-chip.tag-error { background: #fbf1eb; color: var(--danger); border-color: var(--danger); }
.tag-chip.tag-warn { background: #fdf6ec; color: #8a5417; border-color: var(--warn); }
.tag-chip.tag-neutral { background: var(--panel-2); color: var(--muted); border-color: var(--border); }
.tag-chip:hover { filter: brightness(0.95); }
.tag-more {
  display: inline-flex;
  align-items: center;
  padding: 3px 10px;
  border-radius: 12px;
  font-size: 0.66rem;
  font-weight: 700;
  background: var(--panel-2);
  color: var(--muted);
  border: 1px solid var(--border);
  position: relative;
  cursor: default;
}
.tag-more-popup {
  display: none;
  position: absolute;
  top: 100%;
  right: 0;
  margin-top: 6px;
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 8px;
  box-shadow: 0 4px 14px rgba(0,0,0,0.15);
  z-index: 50;
  flex-direction: column;
  gap: 6px;
  min-width: 150px;
}
.tag-more:hover .tag-more-popup { display: flex; }

/* ---- Jira-style tag picker ---- */
.tag-picker { position: relative; display: flex; align-items: center; gap: 8px; }
.tag-picker-trigger {
  flex-shrink: 0;
  width: 22px; height: 22px;
  border-radius: 50%;
  border: 1px dashed var(--border);
  background: var(--panel-2);
  color: var(--muted);
  font-size: 0.9rem;
  line-height: 1;
  cursor: pointer;
  display: flex; align-items: center; justify-content: center;
}
.tag-picker-trigger:hover { border-color: var(--stoba); color: var(--stoba); }
.tag-picker-menu {
  display: none;
  position: absolute;
  top: 100%;
  left: 0;
  margin-top: 6px;
  width: 260px;
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 6px;
  box-shadow: 0 6px 20px rgba(0,0,0,0.15);
  z-index: 100;
  padding: 8px;
}
.tag-picker-menu.open { display: block; }
.tag-picker-search {
  width: 100%;
  padding: 6px 8px;
  margin-bottom: 6px;
  border: 1px solid var(--border);
  border-radius: 4px;
  font-size: 0.82rem;
  background: var(--panel-2);
}
.tag-picker-list { max-height: 220px; overflow-y: auto; display: flex; flex-direction: column; gap: 2px; }
.tag-picker-item {
  display: flex; align-items: center; gap: 8px;
  padding: 6px 6px;
  border-radius: 4px;
  cursor: pointer;
}
.tag-picker-item:hover { background: var(--panel-2); }
.tag-picker-check { font-family: var(--mono); color: var(--muted); width: 14px; flex-shrink: 0; }
.tag-picker-manage {
  display: block;
  margin-top: 8px;
  padding-top: 8px;
  border-top: 1px solid var(--border);
  font-size: 0.72rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--muted);
  text-decoration: none;
}
.tag-picker-manage:hover { color: var(--stoba); }
.tag-picker-error {
  margin-top: 8px;
  padding: 6px 8px;
  border-radius: 3px;
  background: #fbf1eb;
  color: var(--danger);
  font-size: 0.74rem;
}

/* ---- Test Report sections ---- */
.test-report-section summary {
  cursor: pointer;
  font-weight: 700;
  font-size: 0.85rem;
  color: var(--accent-dim);
  padding: 2px 0;
}
.test-report-section summary:hover { color: var(--stoba); }
.tr-body { margin-top: 16px; display: flex; flex-direction: column; gap: 14px; }
.tr-row { display: grid; grid-template-columns: 220px 1fr; gap: 10px 16px; align-items: start; }
.tr-row-block { grid-template-columns: 1fr; }
.tr-row > label { font-size: 0.78rem; font-weight: 600; color: var(--text); text-transform: none; padding-top: 6px; }
.tr-row textarea { min-height: 44px; font-family: var(--sans); font-size: 0.85rem; }
.tr-row input[type="date"] { width: 170px; }
/* one measurement = caption + input + unit, wrapped as a single unit so
   a row breaks BETWEEN measurements, never through the middle of one */
.meas { display: inline-flex; align-items: center; gap: 5px; white-space: nowrap; }
.meas-label, .meas-unit { color: var(--text); }
.tr-hint { font-weight: 400; color: var(--muted); font-size: 0.72rem; }
.inline-check {
  display: inline-flex; align-items: center; gap: 4px;
  font-size: 0.82rem; font-weight: 400; text-transform: none;
  margin-right: 14px; cursor: pointer; white-space: nowrap;
}
.inline-check input { width: auto; }
.inline-input {
  display: inline-block; width: 90px; padding: 4px 6px; font-size: 0.82rem;
  background: var(--panel-2); border: 1px solid var(--border); border-radius: 3px;
  font-family: var(--mono); vertical-align: middle;
}
.parts-table { width: 100%; border-collapse: collapse; font-size: 0.82rem; }
.parts-table th { text-align: left; font-size: 0.68rem; text-transform: uppercase; color: var(--muted); padding: 4px 6px; }
.parts-table td { padding: 3px 6px; }
.parts-table input { width: 100%; padding: 4px 6px; background: var(--panel-2); border: 1px solid var(--border); border-radius: 3px; font-size: 0.82rem; }
.parts-mobile-label { display: none; }
.row-remove { padding: 2px 8px; line-height: 1; font-size: 0.9rem; }

/* ---- locked (motor-type) nominal values in the repair form ---- */
.locked-value {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 3px 8px;
  background: var(--panel-2);
  border: 1px dashed var(--border);
  border-radius: 3px;
  font-family: var(--mono);
  font-size: 0.82rem;
  color: var(--accent-dim);
}
.locked-value em { color: var(--muted); font-style: normal; }
.locked-value-edit {
  font-family: var(--sans);
  font-size: 0.68rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--muted);
  text-decoration: none;
}
.locked-value-edit:hover { color: var(--stoba); }

/* ---- settings hub ---- */
.settings-grid { display: flex; flex-wrap: wrap; gap: 14px; }
.settings-tile {
  display: block;
  flex: 1 1 300px;
  padding: 16px 18px;
  border: 1px solid var(--border);
  border-radius: 6px;
  text-decoration: none;
  color: inherit;
  background: var(--panel-2);
  transition: border-color 0.15s;
}
.settings-tile:hover { border-color: var(--stoba); }
.settings-tile-title { font-weight: 700; font-size: 0.9rem; color: var(--accent-dim); margin-bottom: 5px; }
.settings-tile-desc { font-size: 0.78rem; color: var(--muted); line-height: 1.4; }
.settings-two-col { display: flex; gap: 28px; flex-wrap: wrap; }
.settings-two-col > div { flex: 1 1 280px; min-width: 0; }
.settings-value-list { list-style: none; padding: 0; margin: 0; }
.settings-value-list li {
  display: flex; align-items: center; justify-content: space-between;
  padding: 6px 0; border-bottom: 1px solid var(--border); font-size: 0.85rem;
}
.settings-value-list li:last-child { border-bottom: none; }

/* ---- QR tags (2026-10-09) ---- */
/* the tag's QR: big on screen (scannable off the monitor), its real size
   in mm when printed - the SVG carries width/height in mm */
.qr-tag-print { background: #fff; display: inline-block; padding: 8px; border: 1px solid var(--border); border-radius: 6px; }
@media screen { .qr-tag-img { width: 240px; height: auto; display: block; } }
@media print { .qr-tag-print { border: none; padding: 0; } }
.qr-tag-facts { display: flex; flex-wrap: wrap; gap: 6px 24px; margin: 10px 0 0; }
.qr-tag-facts dt { font-size: 0.72rem; color: var(--muted); text-transform: uppercase; letter-spacing: 0.04em; }
.qr-tag-facts dd { margin: 2px 0 0; overflow-wrap: anywhere; }
.qr-tag-code { font-size: 1.05rem; overflow-wrap: anywhere; }
.qr-tag-belongs { margin: 14px 0 10px; }
/* the check after sticking: the S/N big enough to compare with the nameplate at arm's length */
.qr-tag-big { font-family: var(--mono); font-weight: 700; font-size: 2.4rem; line-height: 1.15; overflow-wrap: anywhere; }
.qr-tag-sub { font-family: var(--mono); color: var(--muted); margin-top: 4px; overflow-wrap: anywhere; }
.qr-tag-step { border: 1px solid var(--border); border-radius: 6px; padding: 12px; }
.qr-tag-row { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
.qr-tag-row input { flex: 1 1 300px; min-width: 0; max-width: 380px; }
.scan-result.scan-result-ok { background: #f0f6f2; color: var(--good); }
.scan-result-link { font-weight: 600; }
.qr-counts { display: flex; flex-wrap: wrap; gap: 8px; margin: 10px 0; }
.qr-batch-form { display: flex; flex-wrap: wrap; gap: 4px 16px; align-items: flex-end; }
.qr-batch-form .field { margin-bottom: 0; }
.qr-tag-table td.mono, .qr-tag-table td.qr-date, .qr-batch-table td.qr-date, .qr-batch-table td:last-child { white-space: nowrap; }
.table-scroll { overflow-x: auto; }
/* the QR tag tables on a phone (2026-10-09, Ladislav: "stránka administrace
   QR štítky není přizpůsobena na telefon, nevidím celý řádek"): each row
   becomes a small card, every value with its column name beside it - no
   sideways scrolling to find the state or the download button. `html`
   in front so these out-rank both the general phone rule (.report-table
   display:block + overflow) and the tablet paddings further down
   (.ui-tablet .report-table td), whatever the order in this file. */
@media (max-width: 700px) {
  html .report-table.qr-stack, html .report-table.qr-stack tbody, html .report-table.qr-stack tr,
  html .report-table.qr-stack td { display: block; width: 100%; overflow: visible; }
  html .report-table.qr-stack tr.qr-head { display: none; }
  html .report-table.qr-stack tr { border: 1px solid var(--border); border-radius: 6px; padding: 8px 12px; margin-bottom: 10px; }
  /* the column name in a fixed left strip, the value beside it */
  html .report-table.qr-stack td { position: relative; border: none; padding: 3px 0 3px 36%; min-height: 1.5em; white-space: normal; }
  html .report-table.qr-stack td[data-label]::before {
    content: attr(data-label); position: absolute; left: 0; top: 5px; width: 34%; font-size: 0.68rem; color: var(--muted);
    text-transform: uppercase; letter-spacing: 0.04em; font-family: var(--sans); overflow-wrap: anywhere;
  }
  /* the tag code is the card's title - no label; the series number reads "Série 1" */
  html .report-table.qr-stack td.qr-stack-title { padding-left: 0; font-weight: 600; }
  html .report-table.qr-stack td.qr-stack-title::before { display: none; }
  html .report-table.qr-stack td.qr-stack-inline { padding-left: 0; font-weight: 600; }
  html .report-table.qr-stack td.qr-stack-inline::before {
    position: static; display: inline; width: auto; margin-right: 0.35em; font-size: inherit; color: inherit;
    text-transform: none; letter-spacing: 0; font-family: inherit;
  }
  html .report-table.qr-stack td.qr-stack-empty { display: none; }
  html .report-table.qr-stack td.mono { overflow-wrap: anywhere; }
  html .report-table.qr-stack td.qr-stack-action { padding: 8px 0 0; }
  html .report-table.qr-stack td.qr-stack-action .btn { display: block; text-align: center; }
}
.qr-plate-layout { display: flex; flex-wrap: wrap; gap: 24px; align-items: flex-start; }
.qr-plate-form { flex: 1 1 320px; min-width: 0; }
.qr-fields { display: grid; grid-template-columns: repeat(auto-fill, minmax(190px, 1fr)); gap: 0 16px; }
.qr-plate-preview { flex: 0 1 300px; min-width: 0; }
.qr-plate-img { width: 100%; max-width: 280px; height: auto; background: #fff; border: 1px solid var(--border); border-radius: 6px; padding: 10px; }

/* ---- dashboard ---- */
.dash-stats { display: flex; flex-wrap: wrap; gap: 12px; margin-bottom: 20px; }
.dash-stat {
  flex: 1 1 140px;
  padding: 16px;
  border: 1px solid var(--border);
  border-radius: 6px;
  background: var(--panel);
  text-decoration: none;
  color: inherit;
  text-align: center;
}
a.dash-stat:hover { border-color: var(--stoba); }
.dash-stat-num { font-size: 1.8rem; font-weight: 700; font-family: var(--mono); color: var(--accent-dim); }
.dash-stat-label { font-size: 0.72rem; text-transform: uppercase; letter-spacing: 0.04em; color: var(--muted); margin-top: 4px; }
.dash-stat-error .dash-stat-num, .dash-stat-warn .dash-stat-num { color: var(--danger); }
.dash-stat-warn .dash-stat-num { color: var(--warn); }

/* ---- HTML report (mirrors the Word Test Report) ---- */
.report-header-top {
  display: flex; align-items: center; justify-content: space-between;
  background: var(--stoba); color: #fff; padding: 12px 16px; margin: -20px -20px 14px;
  border-radius: 5px 5px 0 0;
}
.report-header-top .rh-brand { font-weight: 700; font-size: 1.05rem; }
.report-header-top .rh-title { font-size: 0.78rem; opacity: 0.9; }
.report-header-grid {
  /* 3 columns since the production date left the header (2026-09-29) */
  display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 10px 18px; font-size: 0.82rem;
}
.report-header-grid strong { display: block; font-size: 0.68rem; text-transform: uppercase; letter-spacing: 0.04em; color: var(--muted); font-weight: 700; margin-bottom: 2px; }
.report-table { width: 100%; border-collapse: collapse; font-size: 0.82rem; margin-bottom: 2px; }
.report-table tr { border-bottom: 1px solid var(--border); }
.report-table tr:last-child { border-bottom: none; }
.report-table th {
  text-align: left; font-weight: 700; padding: 9px 10px 9px 0; width: 24%;
  vertical-align: top; font-size: 0.8rem;
}
.report-table td { padding: 9px 14px 9px 0; vertical-align: top; color: var(--accent-dim); }
.report-table td:last-child { padding-right: 0; }
.report-check { font-family: var(--mono); margin-right: 3px; }
.report-summary-dl {
  display: grid; grid-template-columns: max-content 1fr; gap: 6px 16px; font-size: 0.85rem;
}
.report-summary-dl dt { color: var(--muted); font-weight: 600; }
.report-summary-dl dd { margin: 0; }
.signature-block { display: flex; justify-content: space-between; align-items: flex-end; gap: 30px; }
.signature-block .sig-line { flex: 1; border-bottom: 1px solid var(--accent-dim); padding-bottom: 4px; font-size: 0.82rem; }
.retention-note { text-align: center; color: var(--muted); font-size: 0.72rem; margin-top: 14px; }

@media print {
  .no-print, .letterhead, .letterhead nav { display: none !important; }
  body { background: #fff; }
  .card { border: none; box-shadow: none; padding: 0; margin-bottom: 14px; }
  .wrap { max-width: 100%; }
  .report-header-top { margin: 0 0 14px; border-radius: 0; }
  .report-table { page-break-inside: auto; }
  .report-table tr { page-break-inside: avoid; }
}

/* logged-in user name next to the logout link - see .nav-sep/.nav-user near the top for the full nav treatment */
.login-card { max-width: 320px; margin: 60px auto; }

/* defect category picker - multi-select chips, same click-to-toggle
   idea as the motor tag picker, but plain checkboxes underneath so the
   form still submits correctly without JavaScript */
.defect-picker { display: flex; flex-wrap: wrap; gap: 6px; margin: 4px 0; }
.defect-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  /* the global label rule uppercases and letter-spaces; a category
     name is a readable phrase, not a field caption, so undo both */
  text-transform: none;
  letter-spacing: normal;
  font-weight: 600;
  font-size: 0.78rem;
  padding: 6px 11px;
  border: 1px solid var(--border);
  border-radius: 12px;
  background: var(--panel-2);
  color: var(--muted);
  cursor: pointer;
  user-select: none;
}
.defect-chip:hover { border-color: var(--stoba); color: var(--stoba); }
.defect-chip.on { background: var(--stoba); border-color: var(--stoba); color: #ffffff; }
.tr-row-block { display: block; }
.tr-row-block > label { display: block; margin-bottom: 6px; }

/* PWA install hint banner (_pwa_install_hint.html) */
.pwa-install-banner {
  display: flex;
  align-items: center;
  gap: 12px;
  background: var(--panel);
  border: 1px solid var(--border);
  border-left: 3px solid var(--stoba);
  border-radius: 4px;
  padding: 10px 14px;
  margin-bottom: 16px;
  font-size: 0.82rem;
  color: var(--text);
}
.pwa-install-banner #pwa-install-text { flex: 1; }
.pwa-install-dismiss {
  background: none;
  border: none;
  color: var(--muted);
  font-size: 1.1rem;
  line-height: 1;
  cursor: pointer;
  padding: 2px 4px;
}
.pwa-install-dismiss:hover { color: var(--text); }

/* measurement tolerance warning - input on the form, or a read-only
   cell on the Test Report view - same red as .status.err, but as an
   outline/background rather than the left-border treatment used for
   flash messages, so the two don't look interchangeable at a glance */
input.oot { border-color: var(--danger); background: #fbf1eb; }
td.oot-cell { background: #fbf1eb; }

/* signature capture (repair_edit.html) and read-only display
   (repair_report.html) */
.sig-pad-wrap { margin-bottom: 22px; }
.sig-pad-wrap:last-child { margin-bottom: 0; }
.sig-canvas {
  display: block;
  border: 1px solid var(--border);
  border-radius: 4px;
  background: #fff;
  touch-action: none;
  cursor: crosshair;
  max-width: 100%;
}
.sig-status { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.sig-status.sig-correction-status { margin-top: 8px; }
.sig-date { margin-left: auto; }
.sig-image { height: 50px; border: 1px solid var(--border); border-radius: 3px; background: #fff; }

/* Sequential section locking (2026-09-19): each Test Report section's
   gated fields are wrapped in a <fieldset disabled> rather than a
   <div>, so the browser itself keeps a locked section's inputs both
   visually inert and out of the submitted form - see
   _repair_form_fields.html and app.py's _section_unlocked. Reset to
   look exactly like the plain .tr-body it replaces (same flex column,
   same gap) rather than a bordered/padded native fieldset box. */
fieldset.tr-fieldset {
  border: 0;
  margin: 0;
  padding: 0;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 14px;
}
fieldset.tr-fieldset:disabled { opacity: 0.65; }

/* the big drawing area on /account/signature (Ladislav, 2026-09-19:
   "podpisová sekce byla na půl stránky z důvodu kvality podpisu",
   later: "aby byl podpis velký přes celý displej") - a wide backing
   resolution (set via the width/height attributes in
   account_signature.html) held at a matching aspect ratio here so the
   canvas scales up cleanly instead of stretching/distorting strokes.
   Spans (almost) the full available width rather than a fixed cap, so
   a landscape phone actually uses its whole screen. */
.sig-canvas-big { width: 100%; max-width: 1400px; aspect-ratio: 1600 / 700; max-height: 60vh; }

/* On a phone held in portrait, that same width leaves barely any
   height to draw in - a legible signature needs a genuinely wide
   surface, not a cramped one. Rather than trying to lock screen
   orientation via JS (screen.orientation.lock() needs Fullscreen API
   and iOS Safari doesn't support it at all, even then), hide the pad
   entirely below tablet width while the device is actually held in
   portrait, and show a prompt to rotate instead - it only reacts to a
   REAL rotation, so there is nothing to fake or work around. */
.sig-rotate-hint { display: none; }
@media (max-width: 900px) and (orientation: portrait) {
  .sig-rotate-hint { display: block; text-align: center; padding: 32px 16px; font-weight: 600; }
  .sig-pad-area { display: none; }
}

/* photo documentation gallery (repair_edit.html + repair_report.html) */
.photo-gallery { display: flex; flex-wrap: wrap; gap: 12px; margin-bottom: 10px; }
.photo-thumb {
  width: 140px;
  border: 1px solid var(--border);
  border-radius: 4px;
  padding: 6px;
  background: var(--panel);
  text-align: center;
  font-size: 0.72rem;
  color: var(--muted);
}
.photo-thumb img { width: 100%; height: 100px; object-fit: cover; border-radius: 3px; display: block; }
.photo-caption { margin-top: 4px; word-break: break-word; }
.photo-delete-btn { margin-top: 6px; font-size: 0.7rem; padding: 4px 8px; }


/* ================================================================
   UI MODE SWITCH + TABLET LAYER
   The whole tablet "version" is this one block of overrides scoped to
   html.ui-tablet - there is no second stylesheet and no duplicated
   template anywhere, so a change to a page is automatically correct in
   both modes and can't drift between them. Active state of the switch
   is pure CSS off the same class, so it needs no server-side flag.
   ================================================================ */
.ui-switch {
  display: flex;
  justify-content: flex-end;
  gap: 0;
  margin-bottom: 10px;
}
.ui-switch-opt {
  font-size: 0.68rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  font-weight: 600;
  text-decoration: none;
  color: var(--muted);
  background: var(--panel);
  border: 1px solid var(--border);
  padding: 5px 12px;
}
.ui-switch-opt:first-child { border-radius: 3px 0 0 3px; border-right: none; }
.ui-switch-opt:last-child { border-radius: 0 3px 3px 0; }
.ui-switch-opt:hover { color: var(--stoba); }
.ui-desktop .ui-switch-desktop,
.ui-tablet .ui-switch-tablet {
  background: var(--stoba);
  border-color: var(--stoba);
  color: #fff;
}

/* ---------------- tablet overrides ---------------- */

/* 1rem base on inputs is deliberate: iOS/Android zoom the whole page in
   when a focused field is under 16px, which on a form this long is far
   more disruptive than slightly larger controls. */
.ui-tablet body { padding: 14px 12px 60px; }
.ui-tablet .wrap { max-width: 100%; }

.ui-tablet button,
.ui-tablet .btn {
  padding: 13px 22px;
  font-size: 0.86rem;
  min-height: 46px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.ui-tablet .btn-row { gap: 12px; }

.ui-tablet input[type=text],
.ui-tablet input[type=number],
.ui-tablet input[type=date],
.ui-tablet input[type=password],
.ui-tablet input[type=email],
.ui-tablet input[type=search],
.ui-tablet input[type=datetime-local],
.ui-tablet select,
.ui-tablet textarea {
  padding: 12px 12px;
  font-size: 1rem;
  min-height: 46px;
}
.ui-tablet textarea { min-height: 96px; font-size: 0.95rem; }
.ui-tablet label { font-size: 0.74rem; margin-bottom: 8px; }
.ui-tablet .field { margin-bottom: 18px; }
.ui-tablet .field-hint { font-size: 0.8rem; }

/* two-up form rows and the Test Report's label|value grid both get too
   tight on a ~768px portrait tablet - stack them instead of squeezing */
.ui-tablet .field-row { grid-template-columns: 1fr; }
/* Label beside its field on tablet too, not stacked above it. The
   label column is narrower than on desktop, but keeping the SAME
   two-column shape is the point: a form that puts some labels beside
   the field and others above reads as broken. */
.ui-tablet .tr-row { grid-template-columns: 150px minmax(0, 1fr); gap: 8px 12px; align-items: start; }
/* the second column is one flex line that wraps as a unit, so a row
   that runs out of width breaks under its own field, never under the
   label */
.ui-tablet .tr-row > div { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 8px; }
.ui-tablet .tr-row-block { grid-template-columns: 1fr; }
.ui-tablet .tr-row > label { padding-top: 0; font-size: 0.82rem; }
.ui-tablet .tr-body { gap: 20px; }

/* checkboxes are the smallest tap target in the app by far */
.ui-tablet input[type=checkbox] {
  width: 22px;
  height: 22px;
  min-height: 0;
}
.ui-tablet .inline-check {
  font-size: 0.9rem;
  gap: 7px;
  margin-right: 18px;
  margin-bottom: 10px;
  min-height: 34px;
}

/* these carry an inline width= from the Jinja macros, so overriding it
   needs !important - cheaper than threading a mode flag through every
   macro call site */
.ui-tablet .inline-input {
  width: 130px !important;
  min-height: 44px;
  font-size: 0.95rem;
  padding: 8px 10px;
}
.ui-tablet .parts-table input { width: 100% !important; min-height: 44px; font-size: 0.95rem; }
.ui-tablet .parts-table td { padding: 6px 5px; }
.ui-tablet .parts-table th { font-size: 0.74rem; }

.ui-tablet .letterhead { padding: 16px 16px 14px; gap: 14px; flex-wrap: wrap; }
.ui-tablet .lh-nav-group { width: 100%; margin-left: 0; margin-top: 10px; align-items: flex-start; }
.ui-tablet .letterhead nav { gap: 4px; flex-wrap: wrap; width: 100%; margin-left: 0; justify-content: flex-start; }
.ui-tablet .letterhead nav a {
  font-size: 0.82rem;
  padding: 10px 12px;
  border: 1px solid var(--border);
  border-radius: 3px;
}
.ui-tablet .letterhead nav a.btn { border-color: var(--stoba); margin-left: 0; }

/* wide data tables scroll sideways rather than crushing their columns;
   done on the table itself so no template needs a wrapper div */
.ui-tablet table.motorlist,
.ui-tablet .report-table,
.ui-tablet .parts-table {
  display: block;
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  /* without this the block-level table grows to its content width and
     takes the whole PAGE sideways with it, instead of scrolling inside
     its own box - which is the entire point of the rule */
  max-width: 100%;
}
/* Found in the 2026-09-05 release audit: every rule above is scoped to
   .ui-tablet, which is only applied via matchMedia('pointer: coarse')
   detection (base.html's inline script) or the manual Desktop/Tablet
   switch - so a non-touch device under ~600px (a small laptop, or any
   phone/tablet someone has switched to "Desktop") gets NO responsive
   CSS at all: a wide table, or the two-row nav, drags the entire page
   sideways with nothing to stop it (confirmed with a real headless
   Chromium render at 375px in desktop mode - the search box and the
   letterhead nav both overflowed). This is deliberately just the
   overflow-safety subset, unconditional and layered underneath the
   opt-in rules above - it does not touch the deeper touch-target/
   single-column-stacking .ui-tablet enhancements, which stay exactly
   as they were. */
@media (max-width: 599px) {
  table.motorlist,
  .report-table,
  .parts-table {
    display: block;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    max-width: 100%;
  }
  .card { overflow-x: auto; }
  .letterhead { flex-wrap: wrap; }
  .lh-nav-group { width: 100%; margin-left: 0; }
  .letterhead nav { flex-wrap: wrap; }
  .searchbar { flex-wrap: wrap; }
  .searchbar input[type="text"] { flex: 1 1 100%; min-width: 0; }
}

.ui-tablet table.motorlist td,
.ui-tablet table.motorlist th { padding: 14px; font-size: 0.9rem; white-space: nowrap; }
/* Motor type is the one column long enough to run past the screen
   edge on a phone with nothing but a sideways scroll (technically
   scrollable, see .motorlist's own overflow-x:auto above, but with no
   visual hint that more is there) to reveal the rest - wrap it instead,
   the same way .report-table's own type columns already do (plain
   white-space:normal is enough - the browser breaks at the hyphens in
   a typ_motoru string like "MSK030C-0900-NN-M1-UG1-NNNN" on its own;
   adding word-break:break-word on top of that made it worse, breaking
   at literally every character once the column got narrow). */
.ui-tablet table.motorlist td.wrap-cell,
.ui-tablet table.motorlist th.wrap-cell { white-space: normal; }
.ui-tablet .report-table th,
.ui-tablet .report-table td { padding: 12px 14px 12px 0; font-size: 0.88rem; }

.ui-tablet .identity .sn { font-size: 1.7rem; }
.ui-tablet .identity .typ { font-size: 1rem; }
.ui-tablet .tag-row-wrap { width: 100%; margin-left: 0; margin-top: 12px; }
.ui-tablet .tag-row { max-width: none; max-height: none; }
.ui-tablet .tag-chip { font-size: 0.74rem; padding: 6px 12px; }

/* the tag picker is a dropdown of small rows - the single most
   fiddly thing to hit accurately with a finger */
.ui-tablet .tag-picker-trigger { width: 34px; height: 34px; font-size: 1.1rem; }
.ui-tablet .tag-picker-menu { width: 300px; padding: 10px; }
.ui-tablet .tag-picker-item { padding: 12px 8px; }
.ui-tablet .tag-picker-search { padding: 11px 10px; font-size: 1rem; }
.ui-tablet .tag-picker-list { max-height: 300px; }

.ui-tablet .timeline-date { font-size: 1rem; }
.ui-tablet .param { padding: 12px 14px; }
.ui-tablet .param .name { font-size: 0.9rem; }
.ui-tablet .param .idn { font-size: 0.76rem; }
.ui-tablet .param .val { font-size: 1rem; }
.ui-tablet .field-heading { font-size: 0.8rem; }
.ui-tablet .commutation-badge { padding: 10px 14px; font-size: 0.88rem; }
.ui-tablet .commutation-badge .v { font-size: 1.15rem; }
.ui-tablet .settings-tile { padding: 20px; }
.ui-tablet .dash-stat { padding: 20px; }
.ui-tablet .dash-stat-num { font-size: 2.1rem; }
.ui-tablet .locked-value { font-size: 0.9rem; padding: 8px 10px; }
.ui-tablet .searchbar { gap: 12px; }
.ui-tablet details summary { padding: 10px 0; font-size: 0.92rem; }

/* the switch itself is a navigation control, never part of a printout */
@media print {
  .ui-switch { display: none !important; }
}

/* ================================================================
   TOUCH + SMALL SCREEN RULES
   Numbers here are not invented: WCAG 2.2 AA (2.5.8) sets a 24x24 CSS
   pixel floor for any pointer target, Apple's HIG asks for 44pt and
   Material for 48dp, and Safari on iOS zooms the page in whenever a
   focused field's text is under 16px. The app is used on a phone in a
   workshop, so it follows the platform numbers rather than the floor.
   ================================================================ */

/* a fixed pixel width is a suggestion, never a reason to push the row
   off the side of a phone. `input.inline-input` (not just `.inline-input`)
   is deliberate - this needs to actually beat `input[type=number]`'s own
   `width: 100%` above (same specificity, source order decides), or the
   per-field --field-width is silently ignored and every measurement
   input balloons out to whatever inline-flex ends up computing for
   width:100% on an auto-sized flex container (measured ~195px instead
   of the intended 90/110px) - the exact same class of bug already found
   and fixed for the parts table in §28 (a `.parts-table input` rule
   there, `input[type=number]` here), just never caught in this specific
   spot until it started stacking up multiple fields per Test Report row
   (2026-09-24, Ladislav: "formátování polí zase je to rozhozené"). */
input.inline-input, select.inline-input {
  width: var(--field-width, 90px);
  max-width: 100%;
}

/* 16px exactly - below this, iOS zooms in on focus and the technician
   then has to pinch back out after every field */
html.ui-tablet input,
html.ui-tablet select,
html.ui-tablet textarea,
html.ui-tablet button,
html.ui-tablet .btn,
html.ui-tablet .tr-row textarea,
html.ui-tablet .parts-table input { font-size: 16px; }

/* checkbox and its text are one 44px-tall target, per Apple's HIG:
   a 22px box on an oily glove is a miss waiting to happen */
.ui-tablet .inline-check,
.ui-tablet .defect-chip {
  min-height: 44px;
  display: inline-flex;
  align-items: center;
  gap: 10px;
  padding: 4px 10px;
}
.ui-tablet .inline-check input[type="checkbox"],
.ui-tablet .inline-check input[type="radio"],
.ui-tablet .defect-chip input[type="checkbox"] {
  width: 24px;
  height: 24px;
  flex-shrink: 0;
}
.ui-tablet input[type="date"],
.ui-tablet .inline-input { min-height: 44px; }
.ui-tablet button,
.ui-tablet .btn { min-height: 44px; }

/* Below this width a two-column row cannot hold a label AND a field
   without one of them being unusably narrow, so the label goes above -
   the single-column stack every mobile form guide converges on. Above
   it, the label stays beside the field as asked. */
@media (max-width: 599px) {
  .ui-tablet .tr-row { grid-template-columns: minmax(0, 1fr); gap: 4px; }
  .ui-tablet .tr-row > label { padding-top: 0; }
  .ui-tablet .tr-row > div { gap: 8px 10px; }
  .ui-tablet .meas {
    flex: 1 1 100%;
    white-space: normal;
    justify-content: flex-start;
  }
  .ui-tablet .meas .inline-input { flex: 1 1 auto; min-width: 0; }
  .ui-tablet .meas-label { flex: 0 0 auto; }
  /* nothing may be wider than the screen, whatever inline width it asks for */
  .ui-tablet .tr-row input,
  .ui-tablet .tr-row textarea,
  .ui-tablet .tr-row select { max-width: 100%; }
  .ui-tablet .locked-value { flex: 1 1 100%; }
  .ui-tablet .parts-table,
  .ui-tablet .parts-table tbody,
  .ui-tablet .parts-table tr { display: block; }
  .ui-tablet .parts-table thead { display: none; }
  .ui-tablet .parts-table tr {
    border-bottom: 1px solid var(--border);
    padding-bottom: 8px;
    margin-bottom: 8px;
  }
  .ui-tablet .parts-table tr:last-child { border-bottom: none; margin-bottom: 0; }
  .ui-tablet .parts-table td { display: block; width: 100%; padding: 3px 6px; }
  .ui-tablet .parts-table td:last-child { padding-top: 6px; }
  .ui-tablet .parts-table input { width: 100%; }
  .ui-tablet .parts-mobile-label {
    display: block;
    font-size: 0.68rem;
    text-transform: uppercase;
    color: var(--muted);
    margin-bottom: 2px;
  }
}

/* The save button is the whole point of the screen, and on a form this
   long it would otherwise sit several swipes below the fold. */
.ui-tablet .form-actions {
  position: sticky;
  bottom: 0;
  background: var(--bg);
  padding: 10px 0;
  border-top: 1px solid var(--border);
  z-index: 5;
  margin-top: 16px;
}
.ui-tablet .form-actions button { flex: 1 1 auto; }

/* long Czech field names must wrap rather than widen the row */
.ui-tablet .tr-row > label,
.ui-tablet .meas-label { overflow-wrap: anywhere; hyphens: auto; }

/* On a phone the header's two button rows are wider than the screen and
   drag the whole page sideways. They become one full-width wrapping
   block, and the buttons shrink to fit instead of insisting on their
   natural width. */
@media (max-width: 599px) {
  .ui-tablet .letterhead { padding: 12px; gap: 10px; }
  .ui-tablet .lh-nav-group { width: 100%; margin-left: 0; align-items: stretch; gap: 6px; }
  .ui-tablet .lh-nav-primary,
  .ui-tablet .lh-nav-secondary { width: 100%; justify-content: flex-start; gap: 6px; }
  .ui-tablet .letterhead nav a,
  .ui-tablet .letterhead nav a.btn {
    flex: 1 1 auto;
    min-width: 0;
    text-align: center;
    white-space: normal;
    padding: 10px 8px;
  }
  .ui-tablet .letterhead .nav-sep { display: none; }
  .ui-tablet .nav-user { width: 100%; }
  .ui-tablet .ui-switch { display: none; }   /* the mode is already right */
}

/* checkbox captions wrap on a phone rather than widening their row */
@media (max-width: 599px) {
  .ui-tablet .inline-check { white-space: normal; }
  .ui-tablet .tr-row > div { min-width: 0; }
}

@media (max-width: 599px) {
  /* A wide data table scrolls inside its own card instead of taking the
     page with it. Belt and braces with the rule on the table itself:
     that one relies on the table being the widest thing in the card,
     which stops being true as soon as a card holds a table AND a
     toolbar. */
  .ui-tablet .card { overflow-x: auto; }
  .ui-tablet .btn-row { flex-wrap: wrap; }
  .ui-tablet .btn-row > .btn,
  .ui-tablet .btn-row > button { flex: 1 1 auto; }
}

@media (max-width: 599px) {
  /* The search bar is a single flex line with two export buttons pushed
     to the right by margin-left:auto - on a phone that line is wider
     than the screen, so it wraps and the buttons share a row. */
  .ui-tablet .searchbar { flex-wrap: wrap; gap: 8px; }
  .ui-tablet .searchbar input[type="text"] { flex: 1 1 100%; min-width: 0; }
  .ui-tablet .searchbar .btn,
  .ui-tablet .searchbar button { flex: 1 1 auto; margin-left: 0 !important; }
  /* the motor list itself scrolls inside its own box */
  .ui-tablet table.motorlist { display: block; max-width: 100%; overflow-x: auto; }
}

/* how long a trashed item has left before the automatic purge */
.days-left { font-size: 0.72rem; color: var(--muted); white-space: nowrap; }
.days-left.soon { color: var(--danger); font-weight: 700; }

/* Forces a computed-status pill onto its own line directly under the
   measurement row it belongs to (2026-09-24, Ladislav: "chci aby to
   bylo vždy pod názvem meření"), instead of sitting inline after the
   last input where it only wraps there by accident once a row runs out
   of horizontal room. */
.tr-status-row { display: block; margin-top: 5px; }

/* computed-status pill (Isolation OK / PTC status) - read-only summary
   of a measured value against its tolerance, never a clickable input */
.computed-status {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 4px 10px; border-radius: 12px; font-size: 0.82rem;
  background: var(--panel-2); color: var(--muted); border: 1px solid var(--border);
  cursor: default; user-select: none;
}
.computed-status-dot {
  width: 8px; height: 8px; border-radius: 50%; flex-shrink: 0;
  background: var(--muted);
}
.computed-status[data-state="ok"] { color: #1a7a3c; border-color: #bfe3cc; background: #eef9f1; }
.computed-status[data-state="ok"] .computed-status-dot { background: #1a7a3c; }
.computed-status[data-state="bad"] { color: var(--danger); border-color: #f0c4c4; background: #fdf1f1; }
.computed-status[data-state="bad"] .computed-status-dot { background: var(--danger); }

/* mutually-exclusive checkbox options: the one that lost the click
   greys out and cannot be reached, rather than merely staying
   unchecked - a contradictory pair can never both be ticked */
.inline-check.mutex-disabled { opacity: 0.4; }
.inline-check.mutex-disabled input { cursor: not-allowed; }

/* ---- popup action menu (repair row actions, account menu) --------- */
.action-menu { position: relative; display: inline-flex; flex-shrink: 0; }
.action-menu-trigger {
  width: 34px; height: 34px; border-radius: 50%;
  border: 1px solid var(--border); background: var(--panel-2);
  color: var(--muted); font-size: 1.05rem; line-height: 1;
  display: inline-flex; align-items: center; justify-content: center;
  cursor: pointer; padding: 0;
}
.action-menu-trigger:hover { color: var(--stoba); border-color: var(--stoba); }
.action-menu.open .action-menu-trigger { color: #fff; background: var(--stoba); border-color: var(--stoba); }
.action-menu.open .account-trigger .nav-user { color: #fff; }   /* grey on the dark open button was unreadable */
/* the account trigger sits inline in the nav row next to the other
   links, so it keeps their shape - unlike the round icon-only button
   used for a repair row's actions */
.action-menu-trigger.account-trigger {
  width: auto; height: auto; border-radius: 6px; font-size: inherit;
  padding: 7px 12px; gap: 6px;
}
.action-menu-panel {
  display: none;
  position: absolute; top: calc(100% + 6px); right: 0; z-index: 30;
  min-width: 168px; background: #fff; border: 1px solid var(--border);
  border-radius: 8px; box-shadow: 0 6px 20px rgba(0,0,0,0.14);
  padding: 6px; flex-direction: column; gap: 2px;
}
.action-menu.open .action-menu-panel { display: flex; }
.action-menu-panel a, .action-menu-panel button {
  display: block; width: 100%; text-align: left;
  padding: 9px 12px; border-radius: 6px; border: none; background: none;
  font-size: 0.85rem; font-family: var(--sans); color: var(--text);
  text-decoration: none; cursor: pointer;
}
.action-menu-panel a:hover, .action-menu-panel button:hover { background: var(--panel-2); }
/* ONE look for every menu item (2026-10-02, Ladislav: the menus looked
   different from each other) - links and form buttons alike. Before, a
   <button> item inherited the global uppercase/bold button style and an
   account-menu link the bordered nav-link style, so "Změna hesla" sat in
   a box while "ODHLÁSIT" shouted. The selectors are as specific as the
   nav / tablet link rules they have to beat. */
.action-menu-panel a:not(.btn), .action-menu-panel button:not(.btn),
.letterhead nav .action-menu-panel a:not(.btn),
.ui-tablet .letterhead nav .action-menu-panel a:not(.btn) {
  display: block; flex: none; width: 100%; margin: 0; padding: 9px 12px;
  border: none; border-radius: 6px; background: none; box-shadow: none;
  font-family: var(--sans); font-size: 0.85rem; font-weight: 500;
  letter-spacing: normal; text-transform: none; text-align: left; white-space: nowrap;
  color: var(--text); text-decoration: none; cursor: pointer;
}
.action-menu-panel a:not(.btn):hover, .action-menu-panel button:not(.btn):hover,
.letterhead nav .action-menu-panel a:not(.btn):hover {
  background: var(--panel-2); color: var(--text); border: none;
}
.action-menu-panel a:not(.btn):focus-visible, .action-menu-panel button:not(.btn):focus-visible {
  outline: 2px solid var(--stoba); outline-offset: -2px;
}
.action-menu-panel button.danger:not(.btn), .action-menu-panel a.danger:not(.btn),
.action-menu-panel button.danger:not(.btn):hover, .action-menu-panel a.danger:not(.btn):hover,
.letterhead nav .action-menu-panel a.danger:not(.btn), .letterhead nav .action-menu-panel a.danger:not(.btn):hover { color: var(--danger); }
.action-menu-panel form { margin: 0; }
.action-menu-user-label {
  padding: 8px 12px 4px; font-size: 0.72rem; color: var(--muted);
  border-bottom: 1px solid var(--border); margin-bottom: 4px; font-weight: 600;
}

/* ---- Machines / stations / axes ---- */
.accordion-section summary {
  cursor: pointer;
  font-weight: 700;
  font-size: 0.85rem;
  color: var(--accent-dim);
  padding: 2px 0;
}
.accordion-section summary:hover { color: var(--stoba); }
.accordion-section + .accordion-section { margin-top: 10px; }
.axis-row {
  display: flex; align-items: center; justify-content: space-between;
  gap: 12px; padding: 10px 0; border-bottom: 1px solid var(--border); flex-wrap: wrap;
}
.axis-row:last-child { border-bottom: none; }
.axis-name { font-weight: 600; font-size: 0.85rem; }
.motor-pill {
  display: inline-flex; align-items: center; gap: 6px;
  font-size: 0.78rem; padding: 5px 10px; border-radius: 3px;
  background: var(--panel-2); border: 1px solid var(--border); color: var(--text);
}
.motor-pill.empty { color: var(--muted); font-style: italic; background: transparent; }
.status-pill { font-size: 0.7rem; padding: 3px 8px; border-radius: 999px; font-weight: 600; letter-spacing: 0.02em; }
.status-pill.mounted { background: #f0f6f2; color: var(--good); }
.status-pill.awaiting_repair { background: #fdf6ec; color: var(--warn); }
.status-pill.queued { background: #fdf6ec; color: var(--warn); }
.status-pill.in_repair { background: #fbf1eb; color: var(--danger); }
.status-pill.available { background: var(--panel-2); color: var(--accent-dim); }
.inline-form { display: flex; gap: 8px; align-items: flex-end; flex-wrap: wrap; margin: 0; }
.inline-form .field { margin: 0; }

/* ---- QR exchange wizard ---- */
.scan-step { border: 1px solid var(--border); border-radius: 6px; padding: 16px; margin-bottom: 14px; }
.scan-step.done { border-color: var(--good); background: #f0f6f2; }
.scan-step h3 { margin-top: 0; }
.qr-video { width: 100%; max-width: 420px; border-radius: 6px; background: #000; display: block; margin: 10px 0; }
/* the scanner hides the camera picture and "Stop camera" until the camera
   runs - `button`/.qr-video set a display of their own, which beat the
   plain [hidden] attribute (both used to show all the time, found 2026-10-09) */
.scan-step [hidden] { display: none !important; }
.scan-result { font-size: 0.85rem; padding: 10px; border-radius: 4px; background: var(--panel-2); margin: 10px 0; }

/* ---- Filter query autocomplete (export_filtered.html) ---- */
.filter-suggestions {
  position: absolute; z-index: 20; left: 0; right: 0; top: 100%;
  margin: 2px 0 0; padding: 4px; list-style: none;
  background: var(--panel); border: 1px solid var(--border); border-radius: 6px;
  box-shadow: 0 4px 12px rgba(0,0,0,0.12); max-height: 260px; overflow-y: auto;
}
.filter-suggestions li {
  padding: 7px 10px; border-radius: 4px; cursor: pointer;
  font-family: var(--mono); font-size: 0.85rem;
  display: flex; align-items: baseline; gap: 8px; justify-content: space-between;
}
.filter-suggestions li:hover, .filter-suggestions li.active { background: var(--panel-2); }
.filter-suggestion-hint {
  font-family: inherit; font-size: 0.72rem; color: var(--muted); font-weight: 400;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 55%;
}
.help-question-btn {
  display: inline-flex; align-items: center; justify-content: center;
  width: 26px; height: 26px; border-radius: 50%; margin-left: 8px;
  background: var(--panel-2); border: 1px solid var(--border); color: var(--accent-dim);
  font-weight: 700; font-size: 0.85rem; text-decoration: none; vertical-align: middle;
}
.help-question-btn:hover { background: var(--stoba); border-color: var(--stoba); color: #fff; }

/* ---- inspection rules (Administration editor + repair-form note) ---- */
/* .card h3 (0,1,1) would otherwise override a bare .rule-step margin */
.card h3.rule-step { margin: 22px 0 10px; }
/* Clickable condition tree (rule_editor.js). Nested groups indent with a
   coloured left rule so AND/OR nesting stays readable at a glance. */
.rule-tree [hidden], .rule-text-wrap[hidden], .rule-suggest[hidden], .rule-errors[hidden] { display: none !important; }
.rule-group {
  border: 1px solid var(--border); border-left: 4px solid var(--stoba);
  border-radius: 8px; padding: 8px 10px; margin: 6px 0; background: var(--panel);
}
.rule-group .rule-group { background: var(--panel-2); }
.rule-group-not { border-left-color: var(--danger); }
.rule-group-head { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; margin-bottom: 6px; }
/* input.inline-input/select.inline-input size themselves from
   --field-width (see above) - set that, not width, or it loses */
.rule-group-op, .rule-op, .rule-value-type, select.rule-value-input { --field-width: auto; margin: 0; }
.rule-group-notbox { margin: 0; font-size: 0.85rem; }
.rule-group-items { display: flex; flex-direction: column; gap: 2px; }
.rule-joiner, .rule-joiner-inline {
  font-size: 0.72rem; font-weight: 700; text-transform: uppercase; color: var(--muted); letter-spacing: 0.04em;
}
.rule-joiner { padding: 2px 0 2px 12px; }
.rule-cond { display: flex; flex-wrap: wrap; gap: 8px; align-items: flex-start; padding: 4px 0; }
.rule-var, .rule-value { position: relative; display: flex; flex-wrap: wrap; gap: 6px; align-items: flex-start; }
.rule-var { flex-direction: column; min-width: 0; flex: 1 1 280px; }
.rule-value .rule-var { flex: 1 1 280px; }
.rule-value { flex: 0 1 auto; }
.rule-value:has(.rule-var) { flex: 1 1 320px; }
.rule-var-input { --field-width: 100%; margin: 0; }
/* the mono font's underscore sits below the default line box - without
   this, repair.holding_brake_opens reads as "holding brake opens" */
.rule-tree input.inline-input { line-height: 1.6; }
.rule-var-label { font-size: 0.75rem; color: var(--muted); }
.rule-var-unknown { color: var(--danger); }
.rule-value-input { --field-width: 150px; margin: 0; }
.rule-list-input { --field-width: 240px; }
.rule-chip {
  display: inline-block; padding: 4px 10px; border-radius: 6px; font-family: monospace; font-size: 0.85rem;
  background: var(--panel-2); border: 1px solid var(--border);
}
.rule-small-btn { padding: 4px 10px; font-size: 0.8rem; margin: 0; }
.rule-remove { color: var(--danger); }
.rule-suggest {
  position: absolute; z-index: 30; top: 100%; left: 0; min-width: 100%; max-width: 560px;
  max-height: 280px; overflow-y: auto; margin: 2px 0 0; padding: 4px 0; list-style: none;
  background: var(--panel); border: 1px solid var(--border); border-radius: 6px;
  box-shadow: 0 6px 18px rgba(0, 0, 0, 0.15);
}
.rule-suggest-item { display: flex; justify-content: space-between; gap: 12px; padding: 5px 10px; cursor: pointer; }
.rule-suggest-item.active, .rule-suggest-item:hover { background: var(--panel-2); }
.rule-suggest-item.disabled { opacity: 0.45; cursor: not-allowed; }
.rule-suggest-label { font-size: 0.85rem; }
.rule-suggest-detail { font-size: 0.75rem; color: var(--muted); font-family: monospace; white-space: nowrap; }
.rule-mode-switch { display: flex; gap: 6px; margin-bottom: 8px; }
.rule-mode-switch .btn { margin: 0; }
.rule-mode-switch .btn.rule-mode-active, .rule-mode-switch .btn.rule-mode-active:hover { background: var(--stoba); border-color: var(--stoba); color: #fff; }
.rule-text-wrap { position: relative; }
.rule-text-wrap textarea { width: 100%; font-family: monospace; font-size: 0.9rem; }
.rule-errors {
  margin: 8px 0; padding: 8px 12px; border-radius: 8px; font-size: 0.85rem;
  background: #fbf1eb; color: var(--danger); border: 1px solid var(--danger);
}
.rule-errors > div { margin: 2px 0; }
.rule-tag-picker { display: flex; flex-wrap: wrap; gap: 10px; }
.rule-problems { margin-top: 4px; }
.rule-try-bar { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
.rule-try-bar input.inline-input { --field-width: 220px; }
.rule-try-bar .btn { margin: 0; }
.rule-try-result { margin-top: 10px; font-size: 0.85rem; }
.rule-try-summary { font-weight: 700; margin: 6px 0; }
.rule-try-table td { vertical-align: top; }
.rule-try-fires td:first-child { color: var(--danger); font-weight: 700; }
.rule-try-unknown td:first-child { color: #8a5417; }
.rule-try-no td:first-child { color: var(--muted); }
.rule-try-message { margin-top: 4px; font-weight: 700; }
.rule-why { margin-top: 4px; font-size: 0.8rem; }
.rule-why summary { cursor: pointer; color: var(--muted); }
.rule-why ul { margin: 4px 0 0; }
.rule-findings-report { margin-top: 12px; }
.rule-summary {
  margin: 16px 0 4px; padding: 10px 12px; border-radius: 8px;
  background: var(--panel-2); border: 1px solid var(--border); font-size: 0.9rem;
}
.rule-summary-incomplete { color: var(--muted); font-style: italic; }
/* overflow-wrap: a message placeholder like {repair.holding_brake_resistor_actual}
   is one unbreakable word that pushed the gear menu offscreen on a phone */
.rule-summary-cell { font-size: 0.85rem; width: 65%; overflow-wrap: anywhere; }
.rule-inactive { opacity: 0.55; }
.rule-findings {
  margin-bottom: 14px; padding: 10px 14px; border-radius: 8px;
  background: #fff7e6; border: 1px solid #f0d49a; border-left: 4px solid #d99a1e;
}
.rule-findings-title { font-weight: 700; font-size: 0.85rem; margin-bottom: 4px; }
.rule-findings ul { margin: 0; padding-left: 18px; }
.rule-findings li { margin: 3px 0; }

/* Restore / Delete forever (trash) and Download / Restore / Delete
   (backups) side by side made the row wider than a phone, pushing the
   buttons past the card edge behind a sideways scroll (2026-09-23,
   second manual check) - wrapping stacks them instead. */
.row-actions { display: flex; gap: 8px; flex-wrap: wrap; }
/* ...and on a phone even stacked buttons didn't fit next to a long S/N +
   type or backup filename, so those two tables become one card per row:
   every cell on its own line, header row hidden (the values read on
   their own), the buttons last. */
@media (max-width: 599px) {
  table.stack-sm, table.stack-sm tbody, table.stack-sm tr, table.stack-sm td {
    display: block; width: 100%; overflow-x: visible;
  }
  table.stack-sm tr:has(> th) { display: none; }
  table.stack-sm tr { padding: 10px 0; }
  table.stack-sm td { padding: 3px 0; }
  table.stack-sm td.row-actions { padding-top: 8px; }
}

/* Motor parameter editor (Tools menu, 2026-09-25) - carried over from
   Ladislav's standalone parameter_editor.html, on top of the app's own
   .paramlist/.param rows the motor detail page already uses */
.pe-sub { font-family: var(--mono); font-size: 0.7rem; color: var(--muted); font-weight: 400; margin-left: 6px; }
.pe-intro { max-width: 72ch; margin: -6px 0 14px; }
.param input[type=number] { text-align: right; }
.param .pe-range { font-size: 0.68rem; font-weight: 400; color: var(--muted); margin-top: 2px; font-family: var(--mono); }
details.pe-spec { background: var(--panel-2); border: 1px solid var(--border); border-radius: 3px; margin-bottom: 14px; }
details.pe-spec summary {
  cursor: pointer; padding: 10px 14px; font-size: 0.78rem; font-weight: 600;
  text-transform: uppercase; letter-spacing: 0.06em; color: var(--muted); user-select: none;
}
details.pe-spec summary:hover { color: var(--stoba); }
.pe-spec-body { padding: 4px 14px 12px; display: flex; flex-direction: column; gap: 8px; }
.pe-spec-row { display: grid; grid-template-columns: 1fr minmax(0, 340px); gap: 4px 10px; align-items: center; }
.pe-spec-row .name { font-size: 0.82rem; font-weight: 600; }
.pe-spec-row .idn { font-size: 0.68rem; color: var(--muted); font-family: var(--mono); font-weight: 400; }
.pe-copybar { display: flex; justify-content: space-between; align-items: center; gap: 10px; margin-bottom: 10px; }
.pe-copybar label { margin-bottom: 0; }
#pe-input, #pe-output { font-size: 0.8rem; }
@media (max-width: 560px) {
  .pe-spec-row { grid-template-columns: 1fr; }
  .param:has(input[type=number]) { grid-template-columns: 1fr 120px; }
}
#pe-parse-status, #pe-gen-status { margin-top: 12px; margin-bottom: 0; }
.rule-try-na td:first-child { color: var(--muted); font-style: italic; }

/* E-mail sending page (2026-09-30) - Gmail app password steps */
.app-password-steps { margin-bottom: 14px; }
.app-password-steps summary { cursor: pointer; font-weight: 600; font-size: 0.85rem; }
.app-password-steps ol { margin: 10px 0 0; padding-left: 20px; font-size: 0.85rem; line-height: 1.5; }
.app-password-steps li { margin-bottom: 6px; }
.email-test-form { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; margin-top: 12px; }
.email-test-form input[type=email] { width: 280px; max-width: 100%; }
.email-method-form { display: flex; gap: 14px; flex-wrap: wrap; align-items: center; margin-bottom: 12px; }
.email-method-label { font-size: 0.78rem; font-weight: 600; text-transform: uppercase; letter-spacing: 0.06em; color: var(--muted); }

/* ---- Administration -> Database (db_editor.js, 2026-09-30) ---- */
.dbe-head { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 10px; }
.dbe-head h2 { margin-bottom: 0; }
.dbe-switch { margin: 0; min-width: 220px; }
.dbe-autosubmit { cursor: pointer; }
.dbe-search { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin: 14px 0 10px; }
.dbe-search input[type=search] { flex: 1 1 220px; min-width: 0; }
.dbe-inline { display: inline-flex; align-items: center; gap: 6px; font-size: 0.8rem; color: var(--muted); }
.dbe-inline select { max-width: 260px; }
.dbe-columns { margin-bottom: 10px; font-size: 0.82rem; }
.dbe-columns summary { cursor: pointer; color: var(--accent-dim); font-weight: 600; }
.dbe-column-list { display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); gap: 4px 14px; margin: 10px 0; }
.dbe-colname { color: var(--muted); font-size: 0.72rem; }
.dbe-scroll { overflow-x: auto; max-width: 100%; border: 1px solid var(--border); border-radius: 3px; }
.dbe-grid { border-collapse: collapse; font-size: 0.8rem; min-width: 100%; }
.dbe-grid th, .dbe-grid td { border-bottom: 1px solid var(--border); padding: 6px 10px; text-align: left; vertical-align: top; }
.dbe-grid th { background: var(--panel-2); position: sticky; top: 0; white-space: nowrap; font-weight: 600; }
.dbe-grid th a { color: var(--accent-dim); text-decoration: none; }
.dbe-grid td { max-width: 320px; min-width: 60px; }
.dbe-val { display: block; white-space: pre-wrap; overflow-wrap: break-word; max-height: 6.5em; overflow: hidden; }
.dbe-cell { cursor: pointer; }
.dbe-cell:hover, .dbe-cell:focus { background: #f1f5f8; outline: none; box-shadow: inset 0 0 0 1px var(--stoba); }
.dbe-ro { color: var(--muted); background: var(--panel-2); cursor: help; }
.dbe-open { white-space: nowrap; width: 1%; }
.dbe-open a { text-decoration: none; font-weight: 700; }
.dbe-locked td.dbe-cell { background: #fdf9f2; }
tr[data-deleted="1"] td { text-decoration: line-through; text-decoration-color: rgba(0,0,0,0.25); }
td.dbe-editing { background: var(--panel) !important; box-shadow: inset 0 0 0 2px var(--stoba); cursor: default; min-width: 280px; }
.dbe-editor { display: flex; flex-direction: column; gap: 6px; }
.dbe-editor-label { font-weight: 600; color: var(--accent-dim); }
.dbe-editor input, .dbe-editor select, .dbe-editor textarea { width: 100%; min-width: 220px; }
.dbe-editor .status { margin: 0; }
.dbe-editor-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.dbe-multi { display: flex; flex-direction: column; gap: 4px; }
.dbe-multi input { width: auto; min-width: 0; }
.dbe-saved { animation: dbe-flash-ok 1.6s ease-out; }
.dbe-conflict { animation: dbe-flash-warn 1.6s ease-out; }
@keyframes dbe-flash-ok { from { background: #dcefe3; } to { background: transparent; } }
@keyframes dbe-flash-warn { from { background: #f9e3c9; } to { background: transparent; } }
.dbe-pager { align-items: center; }

/* ---- Database: tree view (2026-10-02, db_editor_tree.py) ---- */
.dbe-tabs { display: flex; flex-wrap: wrap; gap: 4px; border-bottom: 1px solid var(--border); margin: 6px 0 14px; }
.dbe-tabs a { padding: 8px 14px; font-size: 0.85rem; font-weight: 600; color: var(--accent-dim); text-decoration: none;
  border: 1px solid transparent; border-bottom: none; border-radius: 3px 3px 0 0; margin-bottom: -1px; }
.dbe-tabs a:hover { color: var(--stoba); }
.dbe-tabs a.active { background: var(--panel); border-color: var(--border); color: var(--text); }
.dbe-count { display: inline-block; min-width: 1.7em; text-align: center; font-size: 0.7rem; font-weight: 700;
  background: var(--accent-dim); color: #fff; border-radius: 999px; padding: 1px 6px; margin-left: 4px; }
.dbe-count.none { background: var(--border); color: var(--muted); }
.dbe-focus { margin: 0 0 10px; }
.dbe-group-title { margin: 18px 0 6px; font-size: 0.85rem; color: var(--accent-dim); }
.dbe-tree { display: flex; flex-direction: column; gap: 6px; }
.dbe-node { border: 1px solid var(--border); border-radius: 4px; background: var(--panel); }
.dbe-node > summary { cursor: pointer; padding: 8px 12px; font-size: 0.85rem; display: list-item; list-style-position: inside; }
.dbe-node > summary:hover { background: #f1f5f8; }
.dbe-node-body { padding: 2px 12px 12px 16px; display: flex; flex-direction: column; gap: 6px; }
.dbe-node-motor > summary, .dbe-node-machine > summary, .dbe-node-station > summary { font-weight: 700; }
.dbe-node-section { background: var(--panel-2); }
.dbe-node-section > summary { font-weight: 600; color: var(--accent-dim); padding: 6px 12px; }
.dbe-node-title { margin-right: 10px; }
.dbe-node-sub { margin-right: 10px; color: var(--muted); font-weight: 400; }
.dbe-node .status-pill { margin-right: 6px; vertical-align: middle; }
.status-pill.trash { background: #f1e6e6; color: var(--danger); }
.status-pill.count { background: var(--panel-2); color: var(--accent-dim); border: 1px solid var(--border); }
.dbe-uuid { font-size: 0.68rem; color: var(--muted); font-weight: 400; margin-left: 6px; }
.dbe-open-app { text-decoration: none; font-weight: 700; margin-right: 6px; }
.dbe-hits { display: block; margin: 6px 0 0 18px; }
.dbe-hit { display: inline-block; margin: 2px 8px 2px 0; padding: 2px 8px; font: inherit; font-size: 0.75rem; font-weight: 600; text-transform: none; letter-spacing: 0;
  color: var(--accent-dim); background: #fff; border: 1px solid var(--stoba); border-radius: 3px; cursor: pointer; text-align: left; }
.dbe-hit:hover { background: var(--stoba); color: #fff; }
.dbe-hit[hidden], .dbe-hits-hidden { display: none; }
.dbe-hit-more { font-size: 0.75rem; color: var(--muted); }
.dbe-hit-target > summary { box-shadow: inset 0 0 0 2px var(--stoba); background: #f1f5f8; }
.dbe-loading { color: var(--muted); font-size: 0.8rem; padding: 6px 0; }
.dbe-text { font-size: 0.82rem; color: var(--text); }
.dbe-empty { color: var(--muted); font-style: italic; }
.dbe-slot-free { color: var(--muted); font-size: 0.82rem; padding: 6px 12px; border: 1px dashed var(--border); border-radius: 4px; }
.dbe-rec { border: 1px solid var(--border); border-radius: 3px; background: #fff; padding: 4px 10px; }
.dbe-rec-title { font-weight: 700; font-size: 0.82rem; padding: 4px 0; }
.dbe-locked { background: #fdf9f2; }
.dbe-fields { margin: 0; display: flex; flex-direction: column; }
.dbe-field { display: grid; grid-template-columns: minmax(150px, 280px) 1fr; gap: 4px 12px; padding: 5px 0;
  border-bottom: 1px dashed var(--border); font-size: 0.82rem; }
.dbe-field:last-child { border-bottom: none; }
.dbe-field dt { color: var(--muted); font-weight: 600; }
.dbe-field dd { margin: 0; min-width: 0; padding: 1px 6px; border-radius: 3px; }
.dbe-field dd.dbe-cell { cursor: pointer; }
.dbe-field dd.dbe-cell:hover, .dbe-field dd.dbe-cell:focus { background: #f1f5f8; outline: none; box-shadow: inset 0 0 0 1px var(--stoba); }
.dbe-field dd.dbe-ro { color: var(--muted); cursor: help; }
.dbe-facts dd.dbe-ro { cursor: default; }
.dbe-field dd.dbe-editing { background: var(--panel); box-shadow: inset 0 0 0 2px var(--stoba); cursor: default; padding: 6px; }
.dbe-field .dbe-val { max-height: 12em; overflow: auto; }
.dbe-ref { margin-left: 10px; font-size: 0.75rem; font-weight: 600; }
.dbe-mini { font-size: 0.78rem; }
@media (max-width: 700px) {
  .dbe-field { grid-template-columns: 1fr; gap: 0; }
  .dbe-node-body { padding-left: 8px; padding-right: 8px; }
}
.sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0,0,0,0); white-space: nowrap; border: 0; }

/* ---- "← parent page" link under the letterhead (base.html, 2026-10-01) ---- */
.back-bar { margin: -6px 0 12px; }
.back-link { display: inline-flex; align-items: center; gap: 8px; padding: 7px 14px 7px 10px; border: 1px solid var(--border);
  border-radius: 3px; background: var(--panel); color: var(--accent-dim); font-size: 0.82rem; font-weight: 600;
  text-decoration: none; max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.back-link:hover, .back-link:focus { border-color: var(--stoba); color: var(--text); }
.back-arrow { font-size: 1.1rem; line-height: 1; }
.ui-tablet .back-link { padding: 12px 18px 12px 14px; font-size: 1rem; min-height: 46px; }
.back-bottom { margin-top: 18px; }

/* ---- "?" placeholder help (templates/_placeholder_help.html, 2026-10-01) ---- */
.label-help { display: flex; align-items: center; gap: 4px; position: relative; flex-wrap: wrap; margin-bottom: 6px; }
.label-help label { margin-bottom: 0; }
.ph-help { display: inline-block; }
.ph-help > summary { list-style: none; cursor: pointer; margin-left: 4px; width: 22px; height: 22px; font-size: 0.8rem; }
.ph-help > summary::-webkit-details-marker { display: none; }
.ph-help[open] > summary { background: var(--stoba); border-color: var(--stoba); color: #fff; }
.ph-help-panel { position: absolute; left: 0; top: calc(100% + 6px); z-index: 30; width: min(640px, 100%);
  background: var(--panel); border: 1px solid var(--border); border-left: 3px solid var(--stoba); border-radius: 3px;
  box-shadow: 0 6px 24px rgba(0,0,0,0.12); padding: 12px 14px; text-transform: none; letter-spacing: 0;
  font-weight: 400; font-size: 0.8rem; color: var(--text); }
.ph-help-title { font-weight: 700; margin-bottom: 8px; color: var(--accent-dim); }
.ph-help-table { width: 100%; border-collapse: collapse; margin-bottom: 10px; }
.ph-help-table th, .ph-help-table td { text-align: left; padding: 4px 8px 4px 0; border-bottom: 1px solid var(--border); vertical-align: top; }
.ph-help-table th { font-size: 0.72rem; color: var(--muted); font-weight: 600; }
.ph-help-example { background: var(--panel-2); border-radius: 3px; padding: 8px 10px; margin-bottom: 8px; display: grid; gap: 2px; }
.ph-help-code { white-space: pre-wrap; overflow-wrap: anywhere; }
.form-section-title { font-size: 0.78rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.04em; color: var(--accent-dim); margin: 4px 0 12px; }
.toggle-line { display: flex; align-items: center; gap: 10px; text-transform: none; letter-spacing: 0; font-weight: 400;
  font-size: 0.9rem; cursor: pointer; margin-bottom: 12px; color: var(--text); }
.toggle-line input { width: auto; }
.ph-help-table td, .ph-help-table td .mono { overflow-wrap: anywhere; }
@media (max-width: 560px) {
  .ph-help-panel { padding: 10px; font-size: 0.76rem; }
  .ph-help-table th:nth-child(3), .ph-help-table td:nth-child(3) { width: 38%; }
}

/* ---- Help center (Nápověda, help_center.py + templates/help_*.html, 2026-10-01) ---- */
.back-bar { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.page-help-link { margin-left: auto; display: inline-flex; align-items: center; gap: 8px; padding: 6px 12px 6px 7px;
  border: 1px solid var(--border); border-radius: 999px; background: var(--panel); color: var(--accent-dim);
  font-size: 0.8rem; font-weight: 600; text-decoration: none; white-space: nowrap; }
.page-help-link:hover, .page-help-link:focus { border-color: var(--stoba); color: var(--text); }
.page-help-q, .nav-help-q { display: inline-flex; align-items: center; justify-content: center; width: 20px; height: 20px;
  border-radius: 50%; background: var(--stoba); color: #fff; font-size: 0.75rem; font-weight: 700; line-height: 1; }
.letterhead nav a.nav-help { display: inline-flex; align-items: center; gap: 6px; }
.letterhead nav a.nav-help.active .nav-help-q, .letterhead nav a.nav-help:hover .nav-help-q { background: #fff; color: var(--stoba); }
.ui-tablet .page-help-link { padding: 11px 16px 11px 11px; font-size: 1rem; min-height: 46px; }
.help-lead { color: var(--muted); margin: 0 0 12px; line-height: 1.5; }
.help-search { display: flex; gap: 8px; flex-wrap: wrap; }
.help-search input[type=search] { flex: 1 1 260px; min-width: 0; }
.help-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(320px, 1fr)); gap: 0 16px; align-items: start; }
.help-list { list-style: none; margin: 0; padding: 0; }
.help-list li { padding: 8px 0; border-bottom: 1px solid var(--border); }
.help-list li:last-child { border-bottom: none; }
.help-list a { font-weight: 600; }
.help-list-summary { font-size: 0.78rem; color: var(--muted); margin-top: 2px; line-height: 1.45; }
.help-results { list-style: none; margin: 0; padding: 0; }
.help-results li { padding: 10px 0; border-bottom: 1px solid var(--border); }
.help-result-title { font-weight: 600; }
.help-result-cat { font-size: 0.72rem; color: var(--muted); margin-left: 8px; }
.help-result-snippet { font-size: 0.8rem; color: var(--text); margin-top: 3px; line-height: 1.5; }
.help-result-snippet mark { background: #fbe9b7; color: inherit; padding: 0 1px; }
.help-article { max-width: 920px; }
.help-crumb { font-size: 0.72rem; text-transform: uppercase; letter-spacing: 0.06em; color: var(--muted); margin-bottom: 4px; }
.card h2.help-title { font-size: 1.3rem; margin: 0 0 6px; }
.help-toc { background: var(--panel-2); border: 1px solid var(--border); border-radius: 4px; padding: 10px 14px; margin: 12px 0 18px; }
.help-toc-title { font-weight: 700; font-size: 0.78rem; color: var(--accent-dim); margin-bottom: 4px; }
.help-toc ol { margin: 0; padding-left: 20px; columns: 2 220px; font-size: 0.85rem; line-height: 1.7; }
.help-body { font-size: 0.92rem; line-height: 1.6; }
.help-body h2 { font-size: 1.05rem; margin: 26px 0 8px; padding-top: 12px; border-top: 1px solid var(--border); text-transform: none; letter-spacing: 0; color: var(--text); }
.help-body h3 { font-size: 0.95rem; margin: 18px 0 6px; text-transform: none; letter-spacing: 0; color: var(--text); }
.help-body p { margin: 0 0 10px; }
.help-body ul, .help-body ol { margin: 0 0 12px; padding-left: 24px; }
.help-body li { margin-bottom: 4px; }
.help-body li > ul, .help-body li > ol { margin: 4px 0 4px; }
.help-body code { font-family: var(--mono); font-size: 0.85em; background: var(--panel-2); border: 1px solid var(--border); border-radius: 3px; padding: 0 4px; overflow-wrap: anywhere; }
.help-ui { display: inline-block; font-size: 0.85em; font-weight: 600; padding: 0 7px; border: 1px solid #b9bfc4; border-radius: 3px;
  background: var(--panel-2); color: var(--accent-dim); white-space: nowrap; line-height: 1.5; }
.help-figure { margin: 12px 0 18px; }
.help-figure img { display: block; max-width: 100%; height: auto; border: 1px solid var(--border); border-radius: 4px; box-shadow: 0 1px 3px rgba(0,0,0,0.08); }
.help-figure-narrow img, .help-figure-phone img { max-width: 360px; width: 100%; }
.help-figure-small img { max-width: 560px; width: 100%; }
.help-figure figcaption { font-size: 0.78rem; color: var(--muted); margin-top: 6px; line-height: 1.45; }
.help-callout { border-left: 4px solid var(--stoba); background: var(--panel-2); border-radius: 3px; padding: 10px 14px; margin: 12px 0 14px; }
.help-callout > :last-child { margin-bottom: 0; }
.help-callout-tip { border-left-color: var(--good); background: #f0f6f2; }
.help-callout-warning { border-left-color: var(--danger); background: #fbf1eb; }
.help-callout-important { border-left-color: var(--warn); background: #fdf6ec; }
.help-callout-tip::before, .help-callout-note::before, .help-callout-warning::before, .help-callout-important::before {
  display: block; font-weight: 700; font-size: 0.78rem; text-transform: uppercase; letter-spacing: 0.05em; margin-bottom: 4px; }
.help-callout-tip::before { content: "Tip"; color: var(--good); }
.help-callout-note::before { content: "Poznámka"; color: var(--accent-dim); }
.help-callout-warning::before { content: "Pozor"; color: var(--danger); }
.help-callout-important::before { content: "Důležité"; color: var(--warn); }
.help-table-wrap { overflow-x: auto; margin: 0 0 14px; }
.help-table { border-collapse: collapse; width: 100%; font-size: 0.86rem; }
.help-table th, .help-table td { text-align: left; vertical-align: top; padding: 6px 10px; border: 1px solid var(--border); }
.help-table th { background: var(--panel-2); font-weight: 600; }
@media (max-width: 600px) {
  .page-help-link { margin-left: 0; }
  .help-ui { white-space: normal; }
  .help-grid { grid-template-columns: 1fr; }
  .help-body { font-size: 0.88rem; }
}
@media print {
  .help-figure img { max-width: 100%; box-shadow: none; }
  .help-callout { break-inside: avoid; }
}

/* free station slot on the machine page - one compact line in step with the
   station rows (was the centred, padded .empty-msg box, 2026-10-01) */
.slot-free { color: var(--muted); font-size: 0.85rem; padding: 7px 0 7px 16px; border-top: 1px dashed var(--border); }
.accordion-section + .slot-free, .slot-free:first-of-type { margin-top: 10px; }

/* the placeholder names themselves never break mid-name ("{protocols_" /
   "note}" was unreadable in a narrow panel) - the meaning column wraps instead */
.ph-help-table td:first-child, .ph-help-table td:first-child .mono { white-space: nowrap; overflow-wrap: normal; }

/* numbered badges: the same red circle tools/help_screenshots.py draws into
   the picture, in the legend under it and in the steps that refer to it */
.help-num { display: inline-flex; align-items: center; justify-content: center; min-width: 20px; height: 20px;
  padding: 0 5px; border-radius: 10px; background: #d9381e; color: #fff; font: 700 0.72rem/1 Arial, sans-serif;
  vertical-align: 1px; }
.help-figure-title { display: block; font-weight: 600; color: var(--text); }
.help-legend { list-style: none; margin: 6px 0 0; padding: 0; display: grid; gap: 4px; font-size: 0.82rem; color: var(--text); }
.help-legend li { display: flex; align-items: flex-start; gap: 8px; line-height: 1.45; }
.help-legend .help-num { flex: none; margin-top: 1px; }
