/*! thingino theme v0.4.1
 *
 * GENERATED FILE, DO NOT EDIT. Built from src/tokens.css + src/components.css + src/bootstrap.css + src/alt.css + src/rtl.css.
 * Source and issues: https://github.com/thingino/theme
 */
/* thingino theme: design tokens.
 *
 * The single source of truth for every color, face and radius the thingino
 * web apps draw with. Nothing here selects anything or paints anything: it
 * only declares custom properties, so this file is safe to load first in any
 * app, framework or not.
 *
 * Naming: every token is `--th-*`. Apps that predate the prefix (buildscope
 * uses bare `--bg`, `--accent`, ...) can load `thingino-aliases.css` on top to
 * get the bare names pointed at these, without touching their own rules.
 *
 * The surfaces are GitHub's dark ramp, which is where these apps started; the
 * accent is `darkorange`, spelled as its hex here (the CSS named color
 * `darkorange` is exactly #ff8c00, so old rules using the keyword and new ones
 * using the token render identically).
 */

:root {
  /* ---------- surfaces ---------- */
  --th-bg: #0d1117;         /* page background */
  --th-surface-1: #161b22;  /* raised panel */
  --th-surface-2: #21262d;  /* control / progress track */
  --th-track: #010409;      /* recessed: log console, code wells */
  --th-line: #30363d;       /* borders */
  --th-hairline: #21262d;   /* internal rules, table separators */

  /* ---------- ink ---------- */
  --th-ink: #c9d1d9;        /* body text */
  --th-ink-bright: #e6edf3; /* emphasis */
  --th-ink-2: #8b949e;      /* muted / secondary */
  --th-ink-3: #6e7681;      /* labels, axis */
  --th-ink-4: #484f58;      /* disabled, dim log lines */

  /* ---------- accent ---------- */
  --th-accent: #ff8c00;       /* === CSS `darkorange` */
  --th-accent-hover: #ff9e2c;
  --th-on-accent: #0d1117;    /* text drawn ON the accent */

  /* Link color for the shared footer. This is Bootstrap's `--bs-secondary`,
     which its dark mode does NOT override, so it is pinned here rather than
     inherited: apps without Bootstrap must match it. */
  --th-link: #6c757d;
  --th-link-hover: #565e64;

  /* ---------- status ---------- */
  --th-good: #3fb950;
  --th-warn: #d29922;
  --th-serious: #f0883e;
  --th-crit: #f85149;

  /* ---------- categorical data palette ----------
     For charts and format/type chips. Validated for the three common color
     vision deficiencies against --th-surface-1. Use in listed order; do not
     reach for the status colors above to mean "category N", they carry a
     meaning of their own. */
  --th-data-blue: #3987e5;
  --th-data-orange: #d95926;
  --th-data-aqua: #199e70;
  --th-data-yellow: #c98500;
  --th-data-magenta: #d55181;
  --th-data-green: #008300;

  /* ---------- help balloons ----------
     Deliberately inverted: a warm paper note over the dark UI, so an opt-in
     hint never reads as part of the app's own chrome. */
  --th-balloon-bg: #fffdf0;
  --th-balloon-ink: #1a1a1a;
  --th-balloon-line: #c9bfa0;

  /* ---------- type ----------
     Montserrat is NOT bundled here. Each app ships its own subsets (via
     @fontsource or a vendored montserrat.css) so it only downloads the scripts
     it renders. Montserrat carries no Arabic or CJK glyphs, hence the named
     fallbacks before the generic. */
  --th-sans: "Montserrat", "Noto Sans Arabic", "Noto Sans CJK SC", "Noto Sans",
    system-ui, sans-serif;
  --th-mono: ui-monospace, "Cascadia Code", "JetBrains Mono", Menlo, Consolas,
    "DejaVu Sans Mono", monospace;
  /* Log consoles specifically: a fixed narrow face, so wrapped hex dumps and
     progress lines column up the same way on every machine. */
  --th-mono-console: "Courier New", monospace;

  /* ---------- geometry ---------- */
  --th-radius: 6px;
  --th-radius-lg: 12px;
  --th-radius-panel: 8px; /* buildscope's panel corner; the alt surfaces use it */
}

/* thingino theme: shared components, framework-neutral.
 *
 * Widgets that more than one thingino app draws the same way, expressed only
 * in terms of the tokens. Nothing here depends on Bootstrap, so buildscope
 * (which has no framework) can load this file too.
 *
 * Selector policy: the PRIMARY selector is the `.th-*` name, and the class or
 * id the existing apps already carry is grouped alongside it. That is what
 * makes adoption a single <link> with no markup churn. When an app's markup
 * moves to the `.th-*` name, its legacy selector can be dropped from the group
 * here.
 */

/* ---------- muted text ----------
   `!important` is inherited from the apps' own rules, where it exists to beat
   Bootstrap's `.text-*` utilities landing on the same element. */
.th-muted,
.muted {
  color: var(--th-ink-2) !important;
}

/* ---------- log console ----------
   Height is layout, not theme, so it stays a knob: verify sets 300px, webflash
   406px. Set --th-console-height on the element to pick. */
.th-console,
#log {
  height: var(--th-console-height, 300px);
  overflow-y: auto;
  font-family: var(--th-mono-console);
  font-size: var(--th-console-size, 0.78rem);
  line-height: var(--th-console-leading, 1.5);
  white-space: pre-wrap;
  word-break: break-all;
  background: var(--th-track);
  border: 1px solid var(--th-line);
  border-radius: var(--th-radius);
  padding: 0.6rem;
}

.th-console .info,
#log .info {
  color: var(--th-ink);
}
.th-console .ok,
#log .ok {
  color: var(--th-good);
}
.th-console .warn,
#log .warn {
  color: var(--th-accent);
}
.th-console .error,
#log .error {
  color: var(--th-crit);
}
.th-console .dim,
.th-console .debug,
#log .dim,
#log .debug {
  color: var(--th-ink-4);
}

/* ---------- file / device info lines ----------
   Label/value pairs: grey label, accent monospace value. webflash draws the
   connected device the same way it draws a picked file. */
.th-file-info,
.file-info,
.device-info {
  font-size: 0.85rem;
  color: var(--th-ink-2);
}

.device-info {
  font-size: 0.9rem;
}

.th-file-info .label,
.file-info .label,
.device-info .label {
  color: var(--th-ink-2);
}

.th-file-info .value,
.file-info .value,
.device-info .value {
  color: var(--th-accent);
  font-family: var(--th-mono);
}

/* The real input is always replaced by a styled label or button. */
.th-file-input,
input[type="file"] {
  display: none;
}

/* ---------- drop zone ---------- */
.th-dropzone,
#dropzone {
  border: 2px dashed var(--th-line);
  border-radius: 8px;
  cursor: pointer;
  padding: 2.2rem 1rem;
  text-align: center;
  color: var(--th-ink-2);
  transition: border-color 0.15s ease, background 0.15s ease;
}

.th-dropzone:hover,
.th-dropzone.drag,
#dropzone:hover,
#dropzone.drag {
  border-color: var(--th-accent);
  background: rgba(255, 140, 0, 0.05);
  color: var(--th-ink);
}

/* Bootstrap Icons glyph inside the zone, sized up as the zone's own mark. */
.th-dropzone .bi,
#dropzone .bi {
  font-size: 2rem;
  color: var(--th-accent);
  display: block;
  margin-bottom: 0.4rem;
}

/* Console scrollbars, buildscope's treatment scoped to the element that
   scrolls: a quiet rounded thumb on the recessed track instead of the
   browser default. */
.th-console::-webkit-scrollbar,
#log::-webkit-scrollbar {
  width: 10px;
  height: 10px;
}

.th-console::-webkit-scrollbar-thumb,
#log::-webkit-scrollbar-thumb {
  background: var(--th-line);
  border-radius: 5px;
  border: 2px solid var(--th-track);
}

.th-console::-webkit-scrollbar-track,
#log::-webkit-scrollbar-track {
  background: transparent;
}

/* ---------- the centered shell ----------
   The single card every app is: full width up to the family's 720px. The
   share viewer widens its own to 960px for 16:9 video. */
.th-shell,
.builder-card,
.verify-card,
.flasher-card {
  width: 100%;
  max-width: var(--th-shell-width, 720px);
}

/* ---------- numbers that column up ----------
   buildscope sets tabular figures on every numeric readout; this is that
   convention as a class. */
.th-num {
  font-family: var(--th-mono);
  font-variant-numeric: tabular-nums;
}

/* ---------- footer / version line ----------
   Every app closes with `<repo-name> v<version>-<short sha>`, the repo name
   being the link. No rule above it, centred, one step down in grey. */
.th-foot,
.foot,
#version-text {
  margin-top: 0.5rem;
  padding-top: 0;
  border-top: none;
  font-family: var(--th-sans);
  font-size: 0.875rem;
  text-align: center;
  color: var(--th-ink-2);
}

.th-foot a,
.foot-link,
#version-text a {
  color: var(--th-link);
  text-decoration: none;
}

.th-foot a:hover,
.th-foot a:focus,
.foot-link:hover,
.foot-link:focus,
#version-text a:hover,
#version-text a:focus {
  color: var(--th-link-hover);
  text-decoration: none;
}

/* ---------- opt-in help balloons ----------
   Off by default. The app puts `.help-on` on <body> (a `?` toggle, or a
   Settings switch) and any element carrying `data-help` becomes hoverable;
   positioning is the app's JS, this is only the look. */
body.help-on [data-help] {
  cursor: help;
}

.th-help-toggle.help-active,
#btn-help.help-active {
  color: #fff;
  background-color: var(--th-link);
  border-color: var(--th-link);
}

.th-help-balloon,
.help-balloon {
  position: fixed;
  z-index: 1100;
  max-width: 260px;
  background: var(--th-balloon-bg);
  color: var(--th-balloon-ink);
  border: 1px solid var(--th-balloon-line);
  border-radius: var(--th-radius-lg);
  padding: 0.5rem 0.7rem;
  font-size: 0.8rem;
  line-height: 1.35;
  box-shadow: 0 5px 16px rgba(0, 0, 0, 0.28);
  pointer-events: none;
  opacity: 0;
  transform: translateY(4px);
  transition: opacity 0.12s ease, transform 0.12s ease;
}

.th-help-balloon.show,
.help-balloon.show {
  opacity: 1;
  transform: translateY(0);
}

/* Tail, drawn as a rotated square sharing two of the balloon's borders. */
.th-help-balloon::before,
.help-balloon::before {
  content: "";
  position: absolute;
  top: -7px;
  left: 18px;
  width: 12px;
  height: 12px;
  background: var(--th-balloon-bg);
  border-left: 1px solid var(--th-balloon-line);
  border-top: 1px solid var(--th-balloon-line);
  transform: rotate(45deg);
}

/* Balloon flipped above its anchor: tail moves to the bottom edge, so the two
   lit borders swap to the opposite corner. */
.th-help-balloon.above::before,
.help-balloon.above::before {
  top: auto;
  bottom: -7px;
  border-left: 0;
  border-top: 0;
  border-right: 1px solid var(--th-balloon-line);
  border-bottom: 1px solid var(--th-balloon-line);
}

/* ---------- result box titles ----------
   The bold first line of a verdict or state alert. verify weighs it 600 via
   .verdict-title where the image builder reaches for <strong> (700); this is
   the shared name for the 600 treatment. */
.th-alert-title,
.verdict-title {
  font-weight: 600;
}

/* ---------- confirmation popover ----------
   The help balloon's dark twin, from the admin page: opens against the
   element that was clicked, so the action button is a few pixels away
   instead of a browser confirm() at the top of the window. Positioning is
   the app's JS; the arrow's inline offset rides a custom property. */
.th-popover,
.cpop {
  position: fixed;
  z-index: 1080;
  max-width: min(20rem, calc(100vw - 1rem));
  background: var(--th-surface-1);
  border: 1px solid var(--th-line);
  border-radius: 0.5rem;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.5);
  padding: 0.55rem 0.65rem;
  font-size: 0.8rem;
  line-height: 1.4;
  color: #dee2e6;
}

.th-popover-row,
.cpop-row {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  margin-top: 0.45rem;
}

/* Dismiss sits in the top corner, out of the way of the action button; last
   in the DOM so pointer and tab order reach the action first. inset-inline-end
   puts it top-right under LTR and top-left under RTL with no extra rules. */
.th-popover-msg,
.cpop-msg {
  padding-inline-end: 1.1rem;
}

.th-popover-x,
.cpop-x {
  position: absolute;
  top: 0.1rem;
  inset-inline-end: 0.2rem;
  border: 0;
  background: transparent;
  color: var(--th-ink-2);
  font-size: 1rem;
  line-height: 1;
  padding: 0.1rem 0.25rem;
  cursor: pointer;
}

.th-popover-x:hover,
.cpop-x:hover {
  color: #dee2e6;
}

.th-popover::after,
.cpop::after {
  content: "";
  position: absolute;
  width: 9px;
  height: 9px;
  background: var(--th-surface-1);
  border-left: 1px solid var(--th-line);
  border-top: 1px solid var(--th-line);
  transform: rotate(45deg);
  top: -5px;
  left: var(--th-popover-arrow, var(--cpop-arrow, 1rem));
}

.th-popover.above::after,
.cpop.above::after {
  top: auto;
  bottom: -5px;
  border-left: 0;
  border-top: 0;
  border-right: 1px solid var(--th-line);
  border-bottom: 1px solid var(--th-line);
}

/* thingino theme: Bootstrap 5.3 bridge.
 *
 * Skins a stock Bootstrap 5.3 dark build (`data-bs-theme="dark"`) into the
 * thingino look. Only for apps that ship Bootstrap: the image builder, verify
 * and webflash. buildscope has no framework and loads tokens + components
 * alone.
 *
 * LOAD ORDER: after bootstrap.min.css. The two rules that must survive being
 * loaded BEFORE it (some builds inline their page CSS ahead of the bundle) are
 * written at a specificity that wins either way, and say so where they sit.
 *
 * DO NOT set --bs-body-bg here. These apps override the PAGE background only,
 * which leaves cards, modals and dropdowns on Bootstrap's own #212529 grey.
 * Retinting --bs-body-bg would flatten the card off the page and is the one
 * change that silently restyles all three apps at once.
 */

/* `html:root` is 0,1,1 and beats Bootstrap's own `:root { --bs-font-sans-serif }`
   at 0,1,0, so the face holds whichever order the two files land in. */
html:root {
  --bs-font-sans-serif: var(--th-sans);
}

/* The app shell every thingino page uses: full height, single centred column.
   `html body` is 0,0,2 and beats Bootstrap reboot's `body { background-color }`
   at 0,0,1 regardless of order. */
html body {
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  align-items: center;
  background: var(--th-bg);
}

/* ---------- accents on stock Bootstrap parts ---------- */

.card-title {
  color: var(--th-accent) !important;
}

code {
  color: var(--th-accent);
}

/* Bootstrap's dark theme puts white text on bg-warning, which is unreadable on
   the yellow. These apps use the badge for busy states (Reading/Writing). */
.badge.bg-warning {
  color: var(--th-on-accent) !important;
}

/* ---------- the thingino button ----------
   Solid accent, dark text: the ARMED state of the primary action (the image
   builder's Build, verify's Verify). The apps keep it disabled until there is
   something to act on, so at rest their pages read as all-outline; the solid
   accent appearing is itself the signal. webflash goes further and uses
   outline buttons for everything. */
.btn-thingino {
  background: var(--th-accent);
  border-color: var(--th-accent);
  color: var(--th-on-accent);
  font-weight: 600;
}

.btn-thingino:hover,
.btn-thingino:focus {
  background: var(--th-accent-hover);
  border-color: var(--th-accent-hover);
  color: var(--th-on-accent);
}

/* PREFER THIS ONE. Accent outline that fills on hover, Bootstrap's own
   btn-outline-* behavior. The family's buttons are outline by default
   (webtorrent-viewer's Connect wears this); reach for the solid button above
   only when an armed primary action should shout. Weight stays the Bootstrap
   400 every other outline button has; only the armed solid is 600. */
.btn-outline-thingino {
  background: transparent;
  border-color: var(--th-accent);
  color: var(--th-accent);
}

.btn-outline-thingino:hover,
.btn-outline-thingino:active,
.btn-outline-thingino.active {
  background: var(--th-accent);
  border-color: var(--th-accent);
  color: var(--th-on-accent);
}

/* Keyboard focus gets a ring, NOT the fill: a just-clicked button keeps
   :focus until something else takes it, and filling on plain :focus left
   Connect sitting stuck-solid after a click. Bootstrap's own outline
   buttons behave exactly this way (fill on hover/press only). */
.btn-outline-thingino:focus-visible {
  border-color: var(--th-accent);
  box-shadow: 0 0 0 2px rgba(255, 140, 0, 0.5);
  outline: 0;
}

/* Disabled reads as clearly OFF: flat muted grey, not a dimmed accent. Bootstrap
   would only fade the fill, which on a bright accent still reads as clickable.
   `opacity:1` undoes that fade so the flat colors are what shows.
   `.th-off` is the same treatment for buttons that are not .btn-thingino (a
   solid btn-warning, say), which otherwise dim to a slightly darker yellow. */
.btn-thingino:disabled,
.btn-thingino.disabled,
.btn-outline-thingino:disabled,
.btn-outline-thingino.disabled,
.th-off:disabled,
.th-off.disabled {
  background: transparent !important;
  background-color: transparent !important;
  border-color: var(--th-line) !important;
  color: var(--th-ink-4) !important;
  opacity: 1 !important;
  box-shadow: none !important;
  cursor: not-allowed;
}

/* ---------- extra alert level ----------
   Bootstrap ships no purple, so the "important" notice level brings its own.
   It goes through Bootstrap's own alert variables, so the box is identical in
   shape to the stock variants sitting next to it. */
.alert-purple {
  --bs-alert-color: #c8a2ff;
  --bs-alert-bg: #241a35;
  --bs-alert-border-color: #4b357a;
}

/* ---------- narrow screens ----------
   Tighten the card's own padding so the content, not the chrome, gets the
   width. App-specific reflow (stacking button rows, shrinking a log) stays in
   the app. */
@media (max-width: 576px) {
  body {
    padding: 0.5rem !important;
  }
  .card-header {
    padding: 0.6rem 0.75rem;
  }
  .card-body,
  .card-footer {
    padding: 0.75rem;
  }
}

/* ---------- attention glow ----------
   The "click me" state webflash puts on Connect when a manual re-pick is
   needed (first authorization of the DFU gadget). The app adds and removes
   the class; this is only the look. */
@keyframes th-attention-glow {
  0%   { box-shadow: 0 0 0 0 rgba(255, 140, 0, 0.65); }
  70%  { box-shadow: 0 0 0 9px rgba(255, 140, 0, 0); }
  100% { box-shadow: 0 0 0 0 rgba(255, 140, 0, 0); }
}

.th-attention,
.btn-attention {
  animation: th-attention-glow 1.3s infinite;
  border-color: var(--th-accent) !important;
  color: var(--th-accent) !important;
  background-color: rgba(255, 140, 0, 0.08) !important;
}

/* webflash shipped the glow without this guard; the accent border and tint
   still mark the button when motion is off. */
@media (prefers-reduced-motion: reduce) {
  .th-attention,
  .btn-attention {
    animation: none;
  }
}

/* ---------- progress ----------
   webflash's treatment, as the family's: accent fill on the control-surface
   track, and high-contrast DARK diagonal stripes, because Bootstrap's faint
   white ones are invisible on the bright bar. */
.progress {
  height: 14px;
  background-color: var(--th-surface-2);
  border-radius: var(--th-radius);
}

.th-progress-fill,
#progress-fill {
  background-color: var(--th-accent) !important;
}

.th-progress-fill.progress-bar-striped,
#progress-fill.progress-bar-striped {
  background-image: linear-gradient(45deg,
    rgba(13, 17, 23, 0.5) 25%, transparent 25%,
    transparent 50%, rgba(13, 17, 23, 0.5) 50%,
    rgba(13, 17, 23, 0.5) 75%, transparent 75%, transparent);
  background-size: 1rem 1rem;
}

/* Drift the stripes rightward; Bootstrap's keyframe moves them left. */
.th-progress-fill.progress-bar-animated,
#progress-fill.progress-bar-animated {
  animation-direction: reverse;
}

.th-progress-label,
#progress-label {
  color: var(--th-ink);
  font-size: 0.8rem;
}

/* ---------- purple, the badge ----------
   The admin page's counterpart to .alert-purple, for the same "important"
   notice level. */
.th-badge-purple,
.bg-purple {
  background: #a371f7;
  color: var(--th-on-accent);
}

/* ---------- tables on cards ----------
   Bootstrap dark gives table cells their own background, which reads as a
   slab floating on the card; the admin page flattens them onto whatever
   surface they sit on. Headers muted, cells vertically centred, nothing
   wraps mid-value. */
.table > :not(caption) > * > * {
  background: transparent;
}

.table th {
  color: var(--th-ink-2);
  font-weight: 600;
  white-space: nowrap;
}

.table td {
  white-space: nowrap;
  vertical-align: middle;
}

/* thingino theme: alt surfaces, the buildscope ramp. OPT-IN.
 *
 * buildscope draws its panels one step darker than the Bootstrap apps do:
 * surfaces on --th-surface-1 (#161b22) with hard --th-line borders and an 8px
 * corner, where stock Bootstrap dark keeps cards on #212529 with translucent
 * borders. Same tokens, different surface mapping. This layer makes that look
 * available to the Bootstrap apps as a variant.
 *
 * Opt in by putting `data-th-alt` on <html> (or any ancestor of what should
 * change). Without the attribute this file is inert, so it ships inside
 * thingino-theme.css without affecting anyone.
 *
 * Ground rules:
 *  - Everything routes through Bootstrap's own component variables, so shape,
 *    spacing and behavior stay stock; only the surfaces move.
 *  - --bs-body-bg stays untouched HERE TOO. Each surface is retinted through
 *    its own component variable, never the global that everything derives
 *    from (see bootstrap.css for why that one is radioactive).
 *  - Only surfaces. buildscope's 13px density and its typography are part of
 *    being a data-heavy viewer, not part of the ramp, so they are deliberately
 *    not in this layer. Its .btn is already .btn-thingino, so buttons need
 *    nothing.
 *
 * Bootstrap-only: these rules write --bs-* variables, which mean nothing
 * without Bootstrap loaded. buildscope itself never loads this; it IS this.
 */

[data-th-alt] {
  /* Hard borders everywhere Bootstrap would use its softer translucent grey:
     hr, table edges, input-group seams, accordion, pagination. */
  --bs-border-color: var(--th-line);
  --bs-border-color-translucent: var(--th-line);
}

/* ---------- cards, the visible difference ---------- */
[data-th-alt] .card {
  --bs-card-bg: var(--th-surface-1);
  --bs-card-border-color: var(--th-line);
  --bs-card-border-radius: var(--th-radius-panel);
  --bs-card-inner-border-radius: calc(var(--th-radius-panel) - 1px);
  /* buildscope's panel head is the panel surface itself, no tinted strip. */
  --bs-card-cap-bg: transparent;
}

/* ---------- the other raised surfaces follow the cards ---------- */
[data-th-alt] .modal {
  --bs-modal-bg: var(--th-surface-1);
  --bs-modal-border-color: var(--th-line);
}

[data-th-alt] .dropdown-menu {
  --bs-dropdown-bg: var(--th-surface-1);
  --bs-dropdown-border-color: var(--th-line);
  --bs-dropdown-link-hover-bg: var(--th-surface-2);
  --bs-dropdown-link-active-bg: var(--th-surface-2);
}

[data-th-alt] .list-group {
  --bs-list-group-bg: var(--th-surface-1);
  --bs-list-group-border-color: var(--th-line);
}

[data-th-alt] .toast {
  --bs-toast-bg: var(--th-surface-1);
  --bs-toast-border-color: var(--th-line);
  --bs-toast-header-bg: transparent;
  --bs-toast-header-border-color: var(--th-hairline);
}

/* ---------- inputs ----------
   buildscope sets its search and filter controls on the PAGE color (--th-bg),
   not the recessed track: inside a panel they read as cut-outs to the page.
   Focus is its exact treatment: accent border plus a soft accent halo. */
[data-th-alt] .form-control,
[data-th-alt] .form-select {
  background-color: var(--th-bg);
  border-color: var(--th-line);
  color: var(--th-ink);
}

[data-th-alt] .form-control:focus,
[data-th-alt] .form-select:focus {
  background-color: var(--th-bg);
  border-color: var(--th-accent);
  box-shadow: 0 0 0 2px rgba(255, 140, 0, 0.5);
  color: var(--th-ink);
}

[data-th-alt] .form-control::placeholder {
  color: var(--th-ink-3);
}

/* ---------- odds and ends on the ramp ---------- */
[data-th-alt] .table {
  /* buildscope separates rows with the hairline, one step quieter than the
     panel border. */
  --bs-table-border-color: var(--th-hairline);
}

[data-th-alt] .progress {
  background-color: var(--th-surface-2);
}

/* thingino theme: shared right-to-left support.
 *
 * The apps vendor the LTR build of Bootstrap, so its directional utilities
 * (ms-* and me-*) compile to physical left/right and do NOT flip under
 * dir="rtl". Each app's i18n sets <html dir="rtl"> for RTL languages; these
 * rules mirror the utilities the family actually uses. Before this file,
 * image-builder and webflash each carried their own copy of exactly these
 * flips.
 *
 * Everything here is inert until something sets dir="rtl", so this ships
 * inside thingino-theme.css without affecting LTR pages at all. It is also
 * built standalone as thingino-rtl.css for apps on the base bundle.
 *
 * App-specific RTL stays in the app: image-builder's notice-sweep mirroring
 * and #commit-badge, webflash's #log and .device-info isolation. The pair
 * "ms-*" "/" must never appear inside a comment here: it closes the comment
 * early and the parser's error recovery then eats the rule below it (it did
 * exactly that to image-builder's .me-1 for weeks).
 */

[dir="rtl"] .me-1 { margin-right: 0 !important; margin-left: 0.25rem !important; }
[dir="rtl"] .me-2 { margin-right: 0 !important; margin-left: 0.5rem !important; }
[dir="rtl"] .ms-1 { margin-left: 0 !important; margin-right: 0.25rem !important; }
[dir="rtl"] .ms-2 { margin-left: 0 !important; margin-right: 0.5rem !important; }
[dir="rtl"] .ms-4 { margin-left: 0 !important; margin-right: 1.5rem !important; }
[dir="rtl"] .ms-auto { margin-left: 0 !important; margin-right: auto !important; }

/* Checkboxes and radios (settings panels, admin forms) move to the right edge. */
[dir="rtl"] .form-check { padding-left: 0; padding-right: 1.5em; }
[dir="rtl"] .form-check .form-check-input { float: right; margin-left: 0; margin-right: -1.5em; }

/* Bootstrap toggle switch (help-hints and debug toggles). */
[dir="rtl"] .form-switch { padding-left: 0; padding-right: 2.5em; }
[dir="rtl"] .form-switch .form-check-input { float: right; margin-left: 0; margin-right: -2.5em; }

/* Input groups reverse visually via flex, which Bootstrap already handles;
   fix the corner rounding of the attached control. */
[dir="rtl"] .input-group > :not(:first-child) { border-radius: 0.375rem 0 0 0.375rem; }
[dir="rtl"] .input-group > :first-child { border-radius: 0 0.375rem 0.375rem 0; }

/* Technical Latin tokens stay LTR so they read correctly embedded in RTL
   sentences: inline code, the footer version, console output. */
[dir="rtl"] code,
[dir="rtl"] #version-num {
  direction: ltr;
  unicode-bidi: isolate;
}

[dir="rtl"] .th-console,
[dir="rtl"] #log {
  direction: ltr;
  text-align: left;
}
