/* ==========================================================================
   Burle Systems — the tool rail. Styles for shell.js.
   --------------------------------------------------------------------------
   CANONICAL COPY: Burle Systems/shared/shell.css
   Edit it there and run shared/sync-shared.sh. Never edit a copy.

   Self-contained: every colour has a fallback, so the rail looks the same
   in a tool that defines --chrome and one that never heard of it. A skin
   overrides the --bs-* tokens and nothing else.
   ========================================================================== */

:root {
  --bs-rail-w: 44px;
  --bs-rail-bg: #0b0e14;
  --bs-rail-line: #1f2633;
  --bs-rail-ink: #8b95a7;
  --bs-rail-ink-2: #5b6577;
  --bs-rail-hover: rgba(255, 255, 255, .07);
  --bs-accent: #2563eb;
  --bs-alert: #d92d20;
  --bs-fly-w: 348px;
  --bs-fly-bg: #ffffff;
  --bs-fly-ink: #131822;
  --bs-fly-ink-2: #5a6474;
  --bs-fly-ink-3: #98a1b0;
  --bs-fly-rule: #e8ebf0;
  --bs-fly-wash: #f2f4f7;
  --bs-fly-accent-wash: #eef4ff;
  --bs-scrim: rgba(11, 14, 20, .3);
  --bs-ok: #067a53;
}

/* Layers. A tool draws its own page up to z-index 100: the site's sticky
   header is 100, and the tools' dialogs, toasts and lightboxes sit between
   40 and 90.

     58    the rail. Above the tool's page and under its dialogs, so a dialog
           dims the rail along with everything else.
     990   the rail while the pointer or the focus is on it, so its labels can
           reach out over a sticky header.
     1000  the scrim, with the flyout at 1001. Both are something the user has
           just asked for, so nothing a tool draws may cover them. At 95 the
           Kit Label Generator's sticky header (100) sat over the flyout's top.

   Outside those labels and the flyout, the rail never overlaps a tool's page,
   which is why the numbers can sit this far apart. */

.bs-rail, .bs-rail *, .bs-scrim, .bs-fly, .bs-fly * { box-sizing: border-box; }

/* Doubled class on purpose. A host tool's own reset is often
   `body.app { margin: 0 }` — the SAME specificity as a plain
   `body.bs-has-rail`, and its stylesheet loads after this one, so it would win
   and the rail would sit on top of the tool's own header. (That is exactly
   what happened to the Skills Matrix.) Doubling the class outranks any
   single-class body reset without reaching for !important, which would take
   the override away from a tool that legitimately needs it. */
body.bs-has-rail.bs-has-rail { margin-left: var(--bs-rail-w); }

/* ---------- the rail --------------------------------------------------------- */

.bs-rail {
  position: fixed;
  left: 0; top: 0; bottom: 0;
  width: var(--bs-rail-w);
  display: flex;
  flex-direction: column;
  align-items: center;
  background: var(--bs-rail-bg);
  border-right: 1px solid var(--bs-rail-line);
  z-index: 58;
  font: inherit;
  line-height: 1.3;
}
.bs-rail:hover, .bs-rail:focus-within { z-index: 990; }

.bs-rail-mark {
  position: relative;
  flex: none;
  width: 100%;
  height: 48px;
  margin: 0;
  padding: 0;
  border: 0;
  border-bottom: 1px solid var(--bs-rail-line);
  background: transparent;
  font: inherit;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: background-color .15s ease;
}
.bs-rail-mark:hover,
.bs-rail-mark[aria-expanded="true"] { background: var(--bs-rail-hover); }

/* The brand square, plain, the way the site draws it: the brand rules allow
   no effects on the mark. */
.bs-mark {
  display: inline-block;
  flex: none;
  width: 10px; height: 10px;
  background: var(--bs-accent);
}

.bs-rail-list {
  list-style: none;
  margin: 0;
  padding: 8px 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
}
.bs-rail-list > li { margin: 0; padding: 0; }
.bs-rail-sep { width: 20px; height: 1px; margin: 4px 0; background: var(--bs-rail-line); }

.bs-rail-tool {
  position: relative;
  width: 36px; height: 36px;
  margin: 0;
  padding: 0;
  border: 0;
  border-radius: 8px;
  background: transparent;
  color: var(--bs-rail-ink);
  font: inherit;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: background-color .15s ease, color .15s ease;
}
.bs-rail-tool:hover { background: var(--bs-rail-hover); color: #fff; }
.bs-rail-tool.is-current {
  color: #fff;
  background: rgba(255, 255, 255, .09);
  background: color-mix(in srgb, var(--bs-accent) 28%, transparent);
}
.bs-rail-tool.is-current::before {
  content: '';
  position: absolute;
  left: -4px; top: 9px; bottom: 9px;
  width: 3px;
  border-radius: 0 2px 2px 0;
  background: var(--bs-accent);
}
.bs-rail-tool.is-get { color: var(--bs-rail-ink-2); }
.bs-rail-tool.is-get:hover { color: var(--bs-rail-ink); }
.bs-rail-get {
  position: absolute;
  right: 5px; bottom: 5px;
  width: 6px; height: 6px;
  border-radius: 50%;
  border: 1px solid var(--bs-rail-ink-2);
}
.bs-rail-tool.has-badge::after {
  content: '';
  position: absolute;
  right: 5px; top: 5px;
  width: 7px; height: 7px;
  border-radius: 50%;
  background: var(--bs-alert);
  box-shadow: 0 0 0 2px var(--bs-rail-bg);
}
.bs-rail-mark:focus-visible { outline: 2px solid var(--bs-accent); outline-offset: -3px; }
.bs-rail-tool:focus-visible { outline: 2px solid var(--bs-accent); outline-offset: 1px; }

.bs-ico {
  width: 18px; height: 18px;
  flex: none;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.8;
  stroke-linecap: round;
  stroke-linejoin: round;
  transition: transform .12s ease;
}
.bs-rail-tool:active .bs-ico { transform: scale(.9); }

/* The name beside an icon. A drawn label rather than a title attribute: it
   also shows on keyboard focus, and its second line says where a click goes. */
.bs-tip {
  position: absolute;
  left: calc(100% + 12px);
  top: 50%;
  display: flex;
  flex-direction: column;
  gap: 1px;
  padding: 6px 10px 7px;
  border-radius: 6px;
  background: var(--bs-rail-bg);
  box-shadow: 0 0 0 1px var(--bs-rail-line), 0 8px 24px rgba(10, 14, 22, .22);
  color: #fff;
  text-align: left;
  white-space: nowrap;
  pointer-events: none;
  opacity: 0;
  visibility: hidden;
  transform: translate(-4px, -50%);
  transition: opacity .1s ease, transform .1s ease, visibility 0s linear .1s;
}
.bs-rail-mark .bs-tip { left: calc(100% + 8px); }
.bs-tip::before {
  content: '';
  position: absolute;
  left: -4px; top: 50%;
  width: 8px; height: 8px;
  margin-top: -4px;
  background: inherit;
  box-shadow: -1px 1px 0 var(--bs-rail-line);
  transform: rotate(45deg);
}
.bs-tip b { font-size: 12px; font-weight: 600; color: #fff; }
.bs-tip small { font-size: 11px; font-weight: 400; color: var(--bs-rail-ink); }
.bs-rail-mark:hover .bs-tip,
.bs-rail-tool:hover .bs-tip,
.bs-rail-mark:focus-visible .bs-tip,
.bs-rail-tool:focus-visible .bs-tip {
  opacity: 1;
  visibility: visible;
  transform: translate(0, -50%);
  transition: opacity .15s ease .1s, transform .15s ease .1s, visibility 0s linear .1s;
}
.bs-rail.is-open .bs-tip { display: none; }
/* One label at a time: a pointer on another icon outranks the focus. */
.bs-rail:hover .bs-rail-mark:focus-visible:not(:hover) .bs-tip,
.bs-rail:hover .bs-rail-tool:focus-visible:not(:hover) .bs-tip {
  opacity: 0;
  visibility: hidden;
  transition: opacity .1s ease, visibility 0s linear .1s;
}

/* ---------- the flyout ------------------------------------------------------- */

/* Dims the tool but not the rail: the flyout opens out of the rail, and the
   two read as one piece. A press on the scrim closes the flyout (shell.js). */
.bs-scrim {
  position: fixed;
  top: 0; right: 0; bottom: 0; left: var(--bs-rail-w);
  background: var(--bs-scrim);
  z-index: 1000;
  animation: bs-fade .16s ease-out;
}
.bs-scrim[hidden] { display: none; }

.bs-fly {
  position: fixed;
  left: var(--bs-rail-w); top: 0; bottom: 0;
  width: var(--bs-fly-w);
  max-width: calc(100vw - var(--bs-rail-w));
  display: flex;
  flex-direction: column;
  background: var(--bs-fly-bg);
  color: var(--bs-fly-ink);
  box-shadow: 1px 0 0 var(--bs-fly-rule), 18px 0 48px rgba(10, 14, 22, .18);
  z-index: 1001;
  font-size: 13px;
  line-height: 1.45;
  text-align: left;
  animation: bs-fly-in .2s cubic-bezier(.2, .7, .2, 1);
}
.bs-fly[hidden] { display: none; }
.bs-fly:focus { outline: none; }

@keyframes bs-fly-in { from { opacity: 0; transform: translateX(-10px); } }
@keyframes bs-fade { from { opacity: 0; } }

.bs-fly-head {
  flex: none;
  display: flex;
  align-items: center;
  gap: 10px;
  height: 48px;
  padding: 0 8px 0 18px;
  border-bottom: 1px solid var(--bs-fly-rule);
}
.bs-fly-brand {
  flex: 1;
  min-width: 0;
  font-size: 16px;
  font-weight: 300;
  letter-spacing: -.015em;
  color: var(--bs-fly-ink-2);
  white-space: nowrap;
}
.bs-fly-brand b { font-weight: 700; color: var(--bs-fly-ink); }
.bs-fly-x {
  flex: none;
  width: 32px; height: 32px;
  margin: 0;
  padding: 0;
  border: 0;
  border-radius: 8px;
  background: transparent;
  color: var(--bs-fly-ink-2);
  cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  transition: background-color .15s ease, color .15s ease;
}
.bs-fly-x:hover { background: var(--bs-fly-wash); color: var(--bs-fly-ink); }
.bs-fly-x:focus-visible { outline: 2px solid var(--bs-accent); outline-offset: -2px; }
.bs-fly-x svg { width: 16px; height: 16px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; }

.bs-fly-list {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  overscroll-behavior: contain;
  scrollbar-width: thin;
  scrollbar-color: var(--bs-fly-ink-3) transparent;
  padding: 2px 10px 12px;
}
.bs-fly-label {
  margin: 14px 10px 6px;
  font-size: 11px;
  font-weight: 600;
  line-height: 1.3;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--bs-fly-ink-2);
}
.bs-fly-group {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.bs-fly-group > li { margin: 0; padding: 0; }

.bs-fly-item {
  position: relative;
  display: grid;
  grid-template-columns: 34px minmax(0, 1fr) auto;
  grid-template-areas: "tile name act" "tile txt txt";
  align-items: center;
  column-gap: 12px;
  padding: 10px;
  border-radius: 8px;
  color: inherit;
  text-decoration: none;
  transition: background-color .15s ease;
}
a.bs-fly-item { cursor: pointer; }
a.bs-fly-item:hover { background: var(--bs-fly-wash); color: inherit; text-decoration: none; }
a.bs-fly-item:active { background: var(--bs-fly-rule); }
a.bs-fly-item:focus-visible { outline: 2px solid var(--bs-accent); outline-offset: -2px; }
.bs-fly-item.is-current { background: var(--bs-fly-accent-wash); }
.bs-fly-item.is-current::before {
  content: '';
  position: absolute;
  left: 0; top: 12px; bottom: 12px;
  width: 3px;
  border-radius: 0 2px 2px 0;
  background: var(--bs-accent);
}

.bs-fly-tile {
  grid-area: tile;
  align-self: start;
  width: 34px; height: 34px;
  border-radius: 8px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--bs-fly-wash);
  color: var(--bs-fly-ink-2);
  transition: background-color .15s ease, color .15s ease, box-shadow .15s ease;
}
a.bs-fly-item:hover .bs-fly-tile {
  background: var(--bs-fly-bg);
  color: var(--bs-fly-ink);
  box-shadow: 0 0 0 1px var(--bs-fly-rule), 0 1px 2px rgba(10, 14, 22, .06);
}
.bs-fly-item.is-current .bs-fly-tile { background: var(--bs-accent); color: #fff; }

.bs-fly-name { grid-area: name; min-width: 0; font-size: 13.5px; font-weight: 600; line-height: 1.3; color: var(--bs-fly-ink); }
.bs-fly-txt { grid-area: txt; min-width: 0; display: flex; flex-direction: column; align-items: flex-start; }
.bs-fly-tag { margin-top: 2px; font-size: 12px; line-height: 1.45; color: var(--bs-fly-ink-2); }
.bs-fly-note {
  margin-top: 5px;
  padding: 1px 6px;
  border-radius: 4px;
  box-shadow: inset 0 0 0 1px var(--bs-fly-rule);
  font-size: 11px;
  font-weight: 500;
  color: var(--bs-fly-ink-2);
}
.bs-fly-inbox {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin-top: 6px;
  padding: 3px 8px 3px 7px;
  border-radius: 999px;
  background: #fdf0ef;
  color: #a1261c;
  font-size: 11px;
  font-weight: 500;
}
.bs-fly-inbox::before {
  content: '';
  flex: none;
  width: 6px; height: 6px;
  border-radius: 50%;
  background: var(--bs-alert);
}

/* What a click on the row does, said on the row. The whole row is the link;
   this is only its label, so it fills in when the row is hovered. */
.bs-fly-act, .bs-fly-now {
  grid-area: act;
  justify-self: end;
  display: inline-flex;
  align-items: center;
  gap: 4px;
  height: 24px;
  padding: 0 10px;
  border-radius: 6px;
  font-size: 12px;
  font-weight: 500;
  white-space: nowrap;
}
.bs-fly-act {
  padding-right: 8px;
  color: var(--bs-accent);
  box-shadow: inset 0 0 0 1px rgba(37, 99, 235, .35);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--bs-accent) 35%, transparent);
  transition: background-color .15s ease, color .15s ease, box-shadow .15s ease;
}
.bs-fly-act svg {
  width: 12px; height: 12px;
  fill: none;
  stroke: currentColor;
  stroke-width: 2.2;
  stroke-linecap: round;
  stroke-linejoin: round;
  transition: transform .15s ease;
}
a.bs-fly-item:hover .bs-fly-act,
a.bs-fly-item:focus-visible .bs-fly-act {
  background: var(--bs-accent);
  color: #fff;
  box-shadow: inset 0 0 0 1px var(--bs-accent);
}
a.bs-fly-item:hover .bs-fly-act svg { transform: translateX(2px); }
a.bs-fly-item:hover .bs-fly-act.is-away svg { transform: translate(1px, -1px); }
.bs-fly-act.is-get {
  color: var(--bs-fly-ink-2);
  box-shadow: inset 0 0 0 1px rgba(90, 100, 116, .3);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--bs-fly-ink-2) 30%, transparent);
}
a.bs-fly-item:hover .bs-fly-act.is-get,
a.bs-fly-item:focus-visible .bs-fly-act.is-get {
  background: var(--bs-fly-ink);
  color: #fff;
  box-shadow: inset 0 0 0 1px var(--bs-fly-ink);
}
.bs-fly-now {
  color: var(--bs-accent);
  background: var(--bs-fly-bg);
  box-shadow: inset 0 0 0 1px rgba(37, 99, 235, .25);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--bs-accent) 25%, transparent);
}

.bs-fly-foot {
  flex: none;
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px 18px;
  border-top: 1px solid var(--bs-fly-rule);
  background: var(--bs-fly-wash);
}
.bs-fly-foot p {
  flex: 1;
  min-width: 0;
  display: flex;
  align-items: flex-start;
  gap: 8px;
  margin: 0;
  font-size: 11.5px;
  line-height: 1.45;
  color: var(--bs-fly-ink-2);
}
.bs-fly-foot p svg {
  flex: none;
  width: 14px; height: 14px;
  margin-top: 1px;
  fill: none;
  stroke: var(--bs-ok);
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.bs-fly-link {
  flex: none;
  display: inline-flex;
  align-items: center;
  gap: 4px;
  margin-right: -8px;
  padding: 6px 8px;
  border-radius: 6px;
  color: var(--bs-accent);
  font-size: 12px;
  font-weight: 600;
  text-decoration: none;
  transition: background-color .15s ease;
}
.bs-fly-link:hover { background: var(--bs-fly-accent-wash); color: var(--bs-accent); text-decoration: none; }
.bs-fly-link:focus-visible { outline: 2px solid var(--bs-accent); outline-offset: 0; }
.bs-fly-link svg {
  width: 12px; height: 12px;
  fill: none;
  stroke: currentColor;
  stroke-width: 2.2;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* Motion here only says where something came from. Asked for less, there is
   none: the flyout and the labels simply appear. */
@media (prefers-reduced-motion: reduce) {
  .bs-fly, .bs-scrim { animation: none; }
  .bs-rail *, .bs-fly * { transition-duration: 0s !important; transition-delay: 0s !important; }
}

/* A label printer must never see the rail. */
@media print {
  .bs-rail, .bs-fly, .bs-scrim { display: none !important; }
  body.bs-has-rail.bs-has-rail { margin-left: 0; }
}

/* ==========================================================================
   The passphrase dialog. Native-feeling and deliberately plain: what is typed
   here is the only thing standing between a shared drive and a customer list.
   ========================================================================== */

.pv-back {
  position: fixed; inset: 0; z-index: 80;
  background: rgba(19, 24, 34, .45);
  display: grid; place-items: center;
}
.pv {
  width: 430px; max-width: calc(100vw - 32px);
  background: var(--panel);
  border-radius: var(--r);
  box-shadow: 0 24px 64px rgba(19, 24, 34, .3);
  padding: 22px 24px 18px;
}
.pv h2 { margin: 0 0 8px; font-size: 15px; font-weight: 600; color: var(--ink); }
.pv-note { margin: 0 0 16px; font-size: 12.5px; line-height: 1.6; color: var(--ink-2); }
.pv-l { display: block; font-size: 12px; font-weight: 600; color: var(--ink-2); margin: 0 0 5px; }
.pv-in {
  width: 100%; box-sizing: border-box;
  padding: 8px 11px; margin: 0 0 14px;
  font-family: var(--mono); font-size: 13px; color: var(--ink);
  background: var(--panel); border: 1px solid var(--rule); border-radius: 4px;
}
.pv-in:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }

/* Said before the file is written, not after it cannot be opened. */
.pv-warn-perm {
  margin: 0 0 12px; padding: 9px 11px;
  background: var(--pending-wash); color: var(--pending);
  font-size: 11.5px; line-height: 1.5; border-radius: 4px;
}
.pv-err {
  margin: 0 0 12px; font-size: 12px; color: var(--late);
}
.pv-foot { display: flex; align-items: center; gap: 8px; }
.pv-sp { flex: 1 1 auto; }
.pv-plain {
  padding: 0; border: 0; background: none;
  font-family: inherit; font-size: 12px; color: var(--ink-3);
  text-decoration: underline; cursor: pointer;
}
.pv-plain:hover { color: var(--ink-2); }

/* The build number, beside the tool's name in every app. Quiet by default —
   it matters when something goes wrong, not while you work. */
.brand-ver {
  margin-left: 8px;
  font-family: var(--mono, ui-monospace, monospace);
  font-size: 10px;
  font-weight: 600;
  letter-spacing: .02em;
  color: var(--chrome-ink-2, #6b7688);
  cursor: default;
}
.brand-ver:hover { color: var(--chrome-ink, #9aa5b6); }
