/* Lyxter AI — brand stylesheet (drop-in, no build step). Matches lyxter.com. */

/* Fonts are self-hosted (variable woff2, latin + latin-ext) so no visitor
   request ever goes to Google - a GDPR requirement, not an optimization. */
@font-face {
  font-family: "Inter";
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url("fonts/inter-var-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Inter";
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url("fonts/inter-var-latin-ext.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: "JetBrains Mono";
  font-style: normal;
  font-weight: 400 500;
  font-display: swap;
  src: url("fonts/jetbrains-mono-var-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "JetBrains Mono";
  font-style: normal;
  font-weight: 400 500;
  font-display: swap;
  src: url("fonts/jetbrains-mono-var-latin-ext.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

:root {
  /* colors */
  --lx-ink: #101828;
  --lx-ink-2: #1d2939;
  /* Amber ramp (Tailwind amber 500/600/700-800). The first two are FILL
     ONLY - buttons, dots, borders, tints. Neither is legible as text:
     #f59e0b is 2.15:1 on white and #d97706 only 3.19:1, under the 4.5:1
     body-text bar. Amber TEXT therefore always takes --lx-signal-text,
     which measures 7.09:1 on white and 6.31:1 on an amber tint. The one
     owner-approved exception is index.html's .welcome-title span; the
     comment above that rule states its scope. */
  --lx-signal: #f59e0b;
  --lx-signal-hover: #d97706;
  --lx-signal-text: #92400e;
  --lx-bg: #ffffff;
  --lx-bg-muted: #f7f8fa;
  --lx-hairline: #e4e7ec;
  --lx-text-muted: #475467;

  /* fonts */
  --lx-font-sans: "Inter", ui-sans-serif, system-ui, -apple-system, sans-serif;
  --lx-font-mono: "JetBrains Mono", ui-monospace, "SFMono-Regular", monospace;

  /* radii */
  --lx-radius-sm: 6px;
  --lx-radius-md: 12px;
  --lx-radius-lg: 16px;
  --lx-radius-full: 9999px;

  /* shadow */
  --lx-shadow-card: 0 10px 30px -12px rgba(16, 24, 40, 0.18);

  /* Content-column caps for the app pages (owner decision 2026-08-22). Two
     roles, named by what the column HOLDS, never by the page:
       records - a list or a card grid (Fleet, Service, Documents, Customers,
                 Manuals). 1280px: wide enough that a 1440px laptop fills its
                 content area and a 1920px monitor no longer spends a third of
                 its width on margins, narrow enough that a list row is still a
                 row and Fleet's 400px cards land on exactly three columns.
       form    - forms and prose (Settings). 820px, because a text input as
                 wide as a records column is worse, not better, and prose
                 past ~75ch stops being readable.
     The chat's message column (index.html, 1000px) and the sidebar rail are
     owner-calibrated and deliberately NOT on this scale. Prose inside a
     records page still caps itself in ch (.page-head .sub, .note). */
  --lx-content-width-records: 1280px;
  --lx-content-width-form: 820px;

  /* iOS standalone: top safe-area inset (status bar / notch). Pages pad their
     top chrome with this instead of raw env() so a fixed top banner can absorb
     the inset (html.lx-viewas, html.lx-has-topbar) without every page
     double-paying it. */
  --lx-inset-top: env(safe-area-inset-top, 0px);
}
html.lx-viewas, html.lx-has-topbar { --lx-inset-top: 0px; }

/* base typography (opt-in; remove this block if it clashes with the tool's CSS) */
body {
  font-family: var(--lx-font-sans);
  color: var(--lx-ink);
  background: var(--lx-bg);
  font-feature-settings: "cv11", "ss01";
  -webkit-font-smoothing: antialiased;
  font-size: 16px;
  line-height: 1.6;
}

/* Headings follow the ACTIVE theme, not the raw ink constant: in light
   --lx-text resolves to --lx-ink (identical result), but in steel the ink
   value equals the page background, which rendered every page title
   invisible (Fleet/Manuals/Team/Billing/Support and every legal heading). */
h1, h2, h3, h4 {
  font-family: var(--lx-font-sans);
  font-weight: 600;
  color: var(--lx-text);
  line-height: 1.15;
}
h1, h2 {
  letter-spacing: -0.02em;
}
a {
  color: var(--lx-ink);
}

/* buttons */
.lx-btn {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  border: 0;
  cursor: pointer;
  font-family: var(--lx-font-sans);
  font-weight: 600;
  font-size: 1rem;
  line-height: 1;
  padding: 0.75rem 1.5rem;
  min-height: 44px; /* workshop phones: the platform minimum tap target */
  border-radius: var(--lx-radius-full);
  text-decoration: none;
  transition: background-color 0.2s ease, color 0.2s ease;
}
.lx-btn--primary {
  background: var(--lx-signal);
  color: var(--lx-ink); /* white on amber fails WCAG (2.2:1); ink passes */
}
.lx-btn--primary:hover {
  background: var(--lx-signal-hover);
}
.lx-btn--ink {
  background: var(--lx-ink);
  color: #ffffff;
}
.lx-btn--ink:hover {
  background: var(--lx-ink-2);
}
.lx-btn:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}
.lx-btn--primary:active:not(:disabled) {
  transform: translateY(1px);
}

/* Header lockup suffix: every page reads `Lyxter / <Surface>`, so the
   mechanic always knows which surface they are on. It was an inline style
   repeated on four pages and simply absent on two - Service baked "AI" into
   the wordmark instead, and Settings said nothing at all. Surface names stay
   ENGLISH in every language (the i18n law), so the text is a literal in the
   markup, never a catalog key. */
.logo-sub {
  color: var(--lx-muted);
  font-weight: 400;
  font-size: 13px;
}

/* fault-code chip — e.g. P0420, SPN 3226 FMI 15 */
.lx-chip {
  font-family: var(--lx-font-mono);
  font-size: 0.8em;
  background: rgba(245, 158, 11, 0.12);
  color: var(--lx-signal-text);
  border: 1px solid rgba(245, 158, 11, 0.35);
  border-radius: var(--lx-radius-sm);
  padding: 0.05em 0.45em;
  white-space: nowrap;
}
.lx-chip--dark {
  background: rgba(245, 158, 11, 0.16);
  color: #fbbf24;
  border-color: rgba(245, 158, 11, 0.4);
}

/* card */
.lx-card {
  background: var(--lx-bg);
  border: 1px solid var(--lx-hairline);
  border-radius: var(--lx-radius-lg);
  padding: 1.75rem;
  box-shadow: var(--lx-shadow-card);
}

/* amber accent rule (above a heading) */
.lx-rule {
  display: block;
  height: 4px;
  width: 40px;
  border-radius: var(--lx-radius-full);
  background: var(--lx-signal);
}

/* inputs */
.lx-input {
  font-family: var(--lx-font-sans);
  font-size: 1rem;
  width: 100%;
  padding: 0.75rem 1rem;
  background: var(--lx-bg);
  color: var(--lx-ink);
  border: 1px solid var(--lx-hairline);
  border-radius: var(--lx-radius-md);
  outline: none;
  transition: border-color 0.2s ease;
}
.lx-input:focus {
  border-color: var(--lx-signal);
}

/* helpers */
.lx-muted { color: var(--lx-text-muted); }
.lx-hairline { border-top: 1px solid var(--lx-hairline); }
.lx-surface-muted { background: var(--lx-bg-muted); }
.lx-surface-ink { background: var(--lx-ink); color: #ffffff; }

/* ============================================================
   Lyxter theming layer — light (default) + steel blue
   Switch with <html data-theme="light|steel">; persisted in JS.
   Steel reuses the brand ink palette (#101828 / #1d2939) so the
   dark mode stays on-brand and amber remains accent-only.
   Pages consume the semantic --lx-page/-panel/-text/... tokens.
   ============================================================ */
:root,
html[data-theme="light"] {
  --lx-page:        var(--lx-bg);        /* #ffffff */
  --lx-panel:       #ffffff;             /* cards, bubbles, inputs */
  --lx-sidebar:     var(--lx-bg-muted);  /* #f7f8fa */
  --lx-sunken:      var(--lx-bg-muted);
  --lx-text:        var(--lx-ink);
  --lx-muted:       var(--lx-text-muted);
  --lx-border:      var(--lx-hairline);
  --lx-hover:       rgba(16, 24, 40, 0.05);
  --lx-accent-soft: rgba(245, 158, 11, 0.12);
  --lx-shadow:      0 10px 30px -12px rgba(16, 24, 40, 0.18);
  color-scheme: light;
}
html[data-theme="steel"] {
  --lx-page:        #101828;  /* ink navy */
  --lx-panel:       #1d2939;  /* ink-2 */
  --lx-sidebar:     #0c121e;
  --lx-sunken:      #161f2e;
  --lx-text:        #f7f8fa;
  --lx-muted:       #98a2b3;
  --lx-border:      #2a3647;
  --lx-hover:       rgba(255, 255, 255, 0.06);
  --lx-accent-soft: rgba(245, 158, 11, 0.16);
  --lx-shadow:      0 10px 30px -12px rgba(0, 0, 0, 0.55);
  color-scheme: dark;
}

/* make the verbatim brand components follow the active theme */
body { background: var(--lx-page); color: var(--lx-text); }

/* iOS standalone: opaque strip behind the translucent status bar so scrolling
   content never shows under the clock/notch. Height is 0 everywhere else.
   Raw env() on purpose: the strip must exist even when the view-as banner
   collapses --lx-inset-top. z-index sits above sticky tab bars (5) and below
   the app sidebar/drawer/overlays (10+) and the view-as banner (99999). */
body::before {
  content: "";
  position: fixed;
  top: 0; left: 0; right: 0;
  height: env(safe-area-inset-top, 0px);
  background: var(--lx-page);
  z-index: 9;
  pointer-events: none;
}
.lx-card { background: var(--lx-panel); border-color: var(--lx-border); box-shadow: var(--lx-shadow); }
.lx-muted { color: var(--lx-muted); }

/* keyboard focus: visible amber ring; pointer clicks stay clean */
:focus-visible {
  outline: 2px solid var(--lx-signal);
  outline-offset: 2px;
}
input:focus-visible, textarea:focus-visible, select:focus-visible {
  outline: none; /* fields signal focus via border-color instead */
}

/* ============================================================
   Shared modal system — used on a native <dialog> opened with
   showModal(). The class carries margin:auto because every app
   page has a *{margin:0} reset that kills the UA centering.
   Desktop: centered card. Phones (<=640px): bottom sheet.
   ============================================================ */
:root,
html[data-theme="light"] {
  --lx-danger: #d92d20;
  --lx-danger-hover: #b42318;
}
html[data-theme="steel"] {
  --lx-danger: #e5484d;
  --lx-danger-hover: #d33a3f;
}

/* Status TEXT colours, the deep end of each hue. Any text carrying a status -
   at any size - uses these; the vivid #3a9a40 / #e05555 / --lx-signal stay
   FILL values for dots, borders and chip backgrounds, where a graphic only
   owes 3:1. Measured on white / on their own 15% tint: green 5.9 / 5.7,
   red 6.6 / 5.5, amber 7.1 / 6.3. Steel gets lighter tones, all >= 4.5:1 on
   both the panel and the tint. --lx-danger stays a FILL token: the danger
   button carries white on it, so it must not be darkened. */
:root,
html[data-theme="light"] {
  --lx-danger-text: #b42318;
  --lx-ok-text: #27682c;
}
html[data-theme="steel"] {
  --lx-danger-text: #f27779;
  --lx-ok-text: #57c26a;
  --lx-signal-text: #fbbf24;
}

.lx-btn--ghost {
  background: transparent;
  border: 1px solid var(--lx-border);
  color: var(--lx-text);
}
.lx-btn--ghost:hover {
  border-color: var(--lx-signal);
  color: var(--lx-text);
}
.lx-btn--danger {
  background: var(--lx-danger);
  color: #ffffff; /* red fill carries white; the ink-text rule is amber-only */
}
.lx-btn--danger:hover {
  background: var(--lx-danger-hover);
}

.lx-modal {
  margin: auto; /* the centering fix: restores what *{margin:0} removed */
  border: 0;
  padding: 0; /* stays 0 so click-on-backdrop light dismiss (e.target===dialog) holds */
  background: transparent;
  width: min(440px, calc(100vw - 2rem));
  max-height: calc(100dvh - 2rem);
}
.lx-modal::backdrop {
  background: rgba(16, 24, 40, 0.5);
  backdrop-filter: blur(2px);
  -webkit-backdrop-filter: blur(2px);
}
.lx-modal-card {
  background: var(--lx-panel);
  border: 1px solid var(--lx-border);
  border-radius: var(--lx-radius-lg);
  box-shadow: var(--lx-shadow);
  padding: 1.5rem;
  color: var(--lx-text);
  max-height: calc(100dvh - 2rem);
  overflow-y: auto;
}
.lx-modal-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 1.1rem;
}
.lx-modal-title {
  font-size: 17px;
  font-weight: 600;
  letter-spacing: -0.01em;
}
.lx-modal-x {
  background: none;
  border: none;
  color: var(--lx-muted);
  cursor: pointer;
  width: 32px;
  height: 32px;
  border-radius: var(--lx-radius-full);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 18px;
  line-height: 1;
  flex-shrink: 0;
}
.lx-modal-x:hover {
  background: var(--lx-hover);
  color: var(--lx-text);
}
.lx-modal-foot {
  display: flex;
  justify-content: flex-end;
  gap: 10px;
  margin-top: 1.1rem;
}
/* app-scale buttons inside modal feet (pages size .lx-btn for marketing) */
.lx-modal-foot .lx-btn {
  font-size: 13px;
  padding: 0 16px;
  min-height: 40px;
  width: auto;
}

/* confirm dialog: small centered card at every width */
.lx-confirm {
  width: min(380px, calc(100vw - 2rem));
}
.lx-confirm-msg {
  font-size: 14px;
  line-height: 1.55;
  color: var(--lx-muted);
  overflow-wrap: break-word;
}

/* typed confirmation (lxConfirm requireText): the operator has to type the
   exact name of what is about to be destroyed. Own tokens rather than
   .lx-input, whose --lx-ink text on --lx-bg belongs to a page surface, not to
   the panel a modal card is painted in. */
.lx-confirm-type {
  display: block;
  margin-top: 0.9rem;
}
.lx-confirm-type-lbl {
  display: block;
  font-size: 12.5px;
  font-weight: 600;
  color: var(--lx-muted);
  margin-bottom: 0.35rem;
}
.lx-confirm-type-input {
  font-family: var(--lx-font-sans);
  font-size: 14px;
  width: 100%;
  min-height: 40px;
  padding: 0.5rem 0.7rem;
  background: var(--lx-sunken);
  color: var(--lx-text);
  border: 1px solid var(--lx-border);
  border-radius: var(--lx-radius-md);
  outline: none;
}
.lx-confirm-type-input:focus {
  border-color: var(--lx-signal);
}

/* phones: form modals become a bottom sheet that rides the keyboard */
@media (max-width: 640px) {
  .lx-modal:not(.lx-confirm) {
    margin: auto 0 0;
    width: 100%;
    max-width: 100%;
    max-height: calc(100dvh - 3rem);
  }
  .lx-modal:not(.lx-confirm) .lx-modal-card {
    border-radius: var(--lx-radius-lg) var(--lx-radius-lg) 0 0;
    border-bottom: 0;
    max-height: calc(100dvh - 3rem);
    padding-bottom: calc(1.25rem + env(safe-area-inset-bottom, 0px));
  }
  /* drag-handle bar: the sheet cue (visual only) */
  .lx-modal:not(.lx-confirm) .lx-modal-card::before {
    content: "";
    display: block;
    width: 36px;
    height: 4px;
    border-radius: var(--lx-radius-full);
    background: var(--lx-border);
    margin: -6px auto 12px;
  }
  .lx-modal-foot .lx-btn {
    min-height: 44px;
  }
}

@media (prefers-reduced-motion: no-preference) {
  .lx-modal[open] {
    animation: lx-modal-pop 0.2s ease-out;
  }
  .lx-modal[open]::backdrop {
    animation: lx-modal-fade 0.2s ease-out;
  }
  @media (max-width: 640px) {
    .lx-modal[open]:not(.lx-confirm) {
      animation: lx-modal-rise 0.25s ease-out;
    }
  }
}
@keyframes lx-modal-pop {
  from { opacity: 0; transform: translateY(8px) scale(0.98); }
}
@keyframes lx-modal-fade {
  from { opacity: 0; }
}
@keyframes lx-modal-rise {
  from { transform: translateY(24px); opacity: 0.6; }
}

/* shared theme-toggle control (sun in steel mode, moon in light) */
.lx-theme-toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 34px;
  height: 34px;
  border-radius: var(--lx-radius-full);
  background: transparent;
  border: 1px solid var(--lx-border);
  color: var(--lx-muted);
  cursor: pointer;
  flex-shrink: 0;
  transition: color 0.15s, border-color 0.15s, background 0.15s;
}
.lx-theme-toggle:hover { color: var(--lx-signal-text); border-color: var(--lx-signal); }
.lx-theme-toggle .sun { display: none; }
.lx-theme-toggle .moon { display: block; }
html[data-theme="steel"] .lx-theme-toggle .sun { display: block; }
html[data-theme="steel"] .lx-theme-toggle .moon { display: none; }
/* The visual box stays 34px on purpose - it is a quiet control beside a form
   heading - so the coarse-pointer tap floor is bought with a pseudo-element
   band rather than by growing the ring, the idiom index.html already uses for
   the citation pill. The gate is (pointer:coarse) and NOT html.lx-thumb:
   every page that renders this control (login, signup, reset-password,
   delete-account and the two staff consoles) is outside the app shell and
   loads no branding/thumb.js, so a thumb-class rule here would be dead CSS.
   A fine-pointer desktop stays pixel-identical either way.
   position:relative is unconditional: a ::after that positions against some
   ancestor instead is the failure mode this guards. */
.lx-theme-toggle { position: relative; }
@media (pointer: coarse) {
  .lx-theme-toggle::after {
    content: "";
    position: absolute;
    top: 50%; left: 50%;
    width: 44px; height: 44px;
    transform: translate(-50%, -50%);
  }
}

/* ============================================================
   Shared failure state — the honest-status law, rendered.

   A region that could not be READ says so IN PLACE of its
   content, never in a line beside it: an outage must never be
   paintable as "you have nothing". manuals.html proved the
   shape; this is that shape promoted so Fleet, Manuals, Service
   and the case list all fail the same way and the count they
   cannot vouch for renders unknown rather than zero.

   branding/sidebar.js lxSidebar.failCard() is the ONE owner of
   the markup, and lxSidebar.UNKNOWN_COUNT the ONE spelling of a
   count nobody could check. Colour is never the encoding: the
   card carries a glyph, a title and a reason, and its way out is
   the SECONDARY button tier - amber is the app's signal colour
   and a failure is not the thing to spend it on.
   ============================================================ */
.lx-fail {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  text-align: center;
  padding: 2.25rem 1rem;
  background: color-mix(in srgb, var(--lx-danger) 4%, var(--lx-panel));
  border: 1px solid color-mix(in srgb, var(--lx-danger) 40%, var(--lx-border));
  border-radius: var(--lx-radius-lg);
  color: var(--lx-text);
}
.lx-fail-mark {
  color: var(--lx-danger-text);
  margin-bottom: 2px;
}
.lx-fail-title {
  font-size: 15px;
  font-weight: 650;
  color: var(--lx-danger-text);
}
.lx-fail-reason {
  font-size: 13px;
  line-height: 1.55;
  max-width: 420px;
  color: var(--lx-muted);
}
.lx-fail .lx-btn,
.lx-fail button {
  margin-top: 10px;
}
/* A PAGE-level failure banner, for the case where the page around it is
   still usable and only one thing did not load. It belongs directly under
   the page head, where the reader is looking - settings.html printed it as
   the LAST element on the page, under ~1500px of form, and ops.html printed
   one at the foot while two regions above it still said "Loading..."
   forever, which is two contradictory signals with the reassuring one on
   top. Same vocabulary as .lx-fail: a glyph as well as the colour, because
   colour is never the encoding. The glyph is a ::before mask so it survives
   the textContent writes the pages set their message with. */
.lx-banner {
  display: flex;
  align-items: flex-start;
  gap: 9px;
  padding: 10px 12px;
  border-radius: var(--lx-radius-md);
  font-size: 13px;
  line-height: 1.5;
  color: var(--lx-danger-text);
  background: color-mix(in srgb, var(--lx-danger) 6%, var(--lx-panel));
  border: 1px solid color-mix(in srgb, var(--lx-danger) 35%, var(--lx-border));
}
/* .lx-banner declares a display of its own, which beats the browser's own
   [hidden]{display:none}. Declared here so no page has to remember. */
.lx-banner[hidden] { display: none; }
.lx-banner::before {
  content: "";
  flex: none;
  width: 16px;
  height: 16px;
  margin-top: 2px;
  background: currentColor;
  -webkit-mask: var(--lx-warn-glyph) center / contain no-repeat;
          mask: var(--lx-warn-glyph) center / contain no-repeat;
}
:root {
  --lx-warn-glyph: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M8 1.5L15 13.5H1L8 1.5z' fill='none' stroke='%23000' stroke-width='1.4' stroke-linejoin='round'/%3E%3Cpath d='M8 6v3.2M8 11.4v.2' stroke='%23000' stroke-width='1.6' stroke-linecap='round'/%3E%3C/svg%3E");
}

/* the sidebar case list is ~230px wide: same card, less air */
.lx-fail--compact {
  padding: 1rem 0.75rem;
  gap: 4px;
}
.lx-fail--compact .lx-fail-mark { width: 20px; height: 20px; }
.lx-fail--compact .lx-fail-title { font-size: 13px; }
.lx-fail--compact .lx-fail-reason { font-size: 12px; }
.lx-fail--compact .lx-btn { font-size: 13px; padding: 0 14px; min-height: 40px; }

/* A horizontally scrolling strip whose scrollbar is hidden by design, with
   a visible edge cue so it does not read as clipped. The classes are toggled
   off the real scroll position by lxSidebar.watchScrollX(), which is the ONE
   owner - a fixed right-hand gradient would fade the last chip of a row that
   is already scrolled to its end. */
.lx-scroll-x.lx-fade-r {
  -webkit-mask-image: linear-gradient(to right, #000 calc(100% - 32px), transparent);
          mask-image: linear-gradient(to right, #000 calc(100% - 32px), transparent);
}
.lx-scroll-x.lx-fade-l {
  -webkit-mask-image: linear-gradient(to right, transparent, #000 32px);
          mask-image: linear-gradient(to right, transparent, #000 32px);
}
.lx-scroll-x.lx-fade-l.lx-fade-r {
  -webkit-mask-image: linear-gradient(to right, transparent, #000 32px, #000 calc(100% - 32px), transparent);
          mask-image: linear-gradient(to right, transparent, #000 32px, #000 calc(100% - 32px), transparent);
}

/* An unknown count. Never a 0, never a blank: a blank reads as
   "nothing to say" and a zero is a claim nobody checked. */
.lx-unknown {
  color: var(--lx-danger-text);
  font-variant-numeric: normal;
  cursor: help;
}
