/* BAKORA v4 web - the Streamlit app's look, measured from the running v4 Streamlit page (2026-10-11):
   ground #F4F4F4, ink #333, border #D9D9D9, Inter for text and numbers, Space Grotesk for display type, square
   corners everywhere, widget labels 12.25px, page title 26px/700 with a 72x3 rule, block 1400px wide. */
:root {
  --ink: #333333; --ink-soft: #525252; --tint: #EDEDED; --gray: #222222; --gray-mid: #555555; --gray-light: #737373;
  --bg: #F4F4F4; --white: #FFFFFF; --border: #D9D9D9; --faint: rgba(34, 34, 34, 0.2); --muted: rgba(34, 34, 34, 0.6);
  --font: 'Inter', 'Space Grotesk', 'Segoe UI', Arial, sans-serif;
  --display: 'Space Grotesk', 'Inter', 'Segoe UI', Arial, sans-serif;
}
*, *::before, *::after { box-sizing: border-box; border-radius: 0 !important; }
html, body { margin: 0; background: var(--bg); color: var(--gray); font: 14px/1.6 var(--font); }
a { color: var(--ink); }

/* ---- top bar (ui/theme.top_nav) ---- */
.topnav { position: fixed; top: 0; left: 0; right: 0; z-index: 1000; background: var(--bg);
  border-bottom: 1px solid var(--border); padding: 0.35rem 2.5rem 0; }
.topnav .inner { max-width: 1400px; margin: 0 auto; display: grid; align-items: end;
  grid-template-columns: 244fr 145fr 196fr 209fr 158fr 183fr 75fr; }   /* the Streamlit bar's measured widths */
.nav-mark { font: 700 20px var(--display); color: var(--ink); letter-spacing: -0.3px; white-space: nowrap;
  display: flex; align-items: center; height: 2.7rem; padding-bottom: 3px; text-decoration: none; overflow: hidden; }
.nav-item { position: relative; text-align: center; }
.nav-item > a, .nav-item > button { display: flex; align-items: center; justify-content: center; gap: 4px; width: 100%;
  height: 38px; padding: 0 2.8px; border: 0; border-bottom: 2.4px solid transparent; background: transparent;
  font: 700 14px var(--display); color: var(--ink); text-decoration: none; cursor: pointer; white-space: nowrap; }
.nav-item.active > a, .nav-item.active > button { border-bottom-color: var(--ink); }
.nav-item > a:hover, .nav-item > button:hover { color: var(--ink-soft); }
.chev { width: 14px; height: 14px; display: inline-block; }
.nav-menu { display: none; position: absolute; top: 40px; left: 50%; transform: translateX(-50%); min-width: 170px;
  background: var(--white); border: 1px solid var(--border); box-shadow: 0 6px 18px rgba(0,0,0,.08); z-index: 1001; padding: 6px 0; }
.nav-item.right .nav-menu { left: auto; right: 0; transform: none; }
.nav-item.open .nav-menu { display: block; }
.nav-menu a { display: block; padding: 7px 16px; text-align: left; font: 500 14px var(--display); color: var(--ink);
  text-decoration: none; white-space: nowrap; }
.nav-menu a:hover { background: var(--tint); }
.nav-menu a.current { border-left: 2.4px solid var(--ink); padding-left: 13.6px; }
.kz-mark { height: 15px; width: auto; vertical-align: -2px; }
.burger { width: 22px; height: 22px; }

/* ---- page ---- */
.block { max-width: 1400px; margin: 0 auto; padding: 100.8px 70px 28px; }   /* the Streamlit title sits 101px down */
.page-title { font: 700 26px var(--display); color: var(--ink); margin: 0 0 4px; line-height: 1.6; }
.page-rule { height: 3px; width: 72px; background: var(--ink); margin: 0 0 1.1rem; }
.cols { display: grid; grid-template-columns: 1fr 1fr; gap: 0 1rem; }
.cols3 { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 0 1rem; align-items: end; }
.cols5 { display: grid; grid-template-columns: repeat(5, 1fr); gap: 0 1rem; align-items: end; }
/* st.columns: <div class="stcols"> with one child per column; a child's weight is style="--w: 2" (default 1).
   Columns share the row with Streamlit's 1rem gap and stack, in order, at Streamlit's 640 px breakpoint (each column's
   items stay together, so a column holding Years + Days of month stacks before the next column). .bottom / .center =
   vertical_alignment="bottom" / "center". The children's own 1rem foot margin (.field) is the stacked gap. */
.stcols { display: flex; flex-wrap: nowrap; gap: 0 1rem; align-items: flex-start; }
.stcols.bottom { align-items: flex-end; }
.stcols.center { align-items: center; }
.stcols > * { flex: var(--w, 1) 1 0%; min-width: 0; }
.stcols.bk-f > * { flex: 1 1 calc(var(--f) * 100% - 1rem); }   /* Streamlit's column basis (app.js stcolsFit sets --f = w / W) */
.field { margin: 0 0 1rem; min-width: 0; }
.wlabel { display: block; font-size: 12.25px; color: var(--gray); line-height: 1.6; min-height: 21px; margin: 0 0 3.5px; }   /* stWidgetLabel: 21 px + 0.25rem */
/* ui/theme's .widget-label drawn by st.markdown ("Library (N)", a loaded file's head): 14px / 21px, its <b> at 600 */
.wlabel.mdl { font-size: 14px; line-height: 21px; }
.wlabel.mdl b { font-weight: 600; }
/* Streamlit's help "?" (macros.help / app.js initHelp, measured on 8641): a bare 14 px button, the lucide circle-help
   icon stroked rgba(34,34,34,.6) at 2.25 px; in a label row (.lhelp) it sits at the row's right end */
.bkhelp { display: inline-flex; align-items: center; justify-content: center; flex: none; width: 14px; height: 14px; padding: 0;
  margin: 0 0 0 5.25px; border: 0; background: none; color: inherit; line-height: 0; cursor: pointer; vertical-align: middle; }
.bkhelp svg { width: 14px; height: 14px; stroke: rgba(34, 34, 34, 0.6); stroke-width: 2.25px; display: block; }
.bkhelp:focus { outline: none; }
.bkhelp:focus-visible { box-shadow: 0 0 0 0.2rem rgba(51, 51, 51, 0.5); }
.wlabel.lhelp { display: flex; justify-content: space-between; align-items: center; }
/* Streamlit's tooltip (app.js showTip): white, 0 1px 4px rgba(0,0,0,.16), 12.25px / 19.6px, 5.25 / 10.5 px padding,
   680 px at most (the window less 3rem on phones), fading in over 0.1 s */
.bk-tip { position: absolute; left: 0; top: 0; z-index: 1000060; box-sizing: border-box; max-width: 680px; padding: 5.25px 10.5px;
  background: var(--white); color: var(--gray); font: 400 12.25px/19.6px var(--font); box-shadow: 0 1px 4px rgba(0, 0, 0, 0.16);
  white-space: normal; overflow-wrap: break-word; pointer-events: auto; opacity: 0; visibility: hidden; transition: opacity 0.1s; }
.bk-tip.on { opacity: 1; visibility: visible; }
.bk-tip.thru { pointer-events: none; }
@media (max-width: 640px) { .bk-tip { max-width: calc(100% - 42px); } }
hr.rule { border: 0; border-bottom: 0.8px solid var(--border); margin: 42px 0 28.2px; }   /* st.markdown("---") after an expander: 14 + 28 above, 1 + 28 + 14 below the rule */
.caption { font-size: 12.25px; color: var(--muted); margin: 0 0 1rem; line-height: 1.6; }
.strong { font-weight: 600; margin: 0.6rem 0 0.5rem; }
/* st.info / st.warning / st.error / st.success, measured on the Streamlit pages */
.info, .warn, .warning, .error, .success { padding: 14px; margin: 0 0 1rem; font-size: 14px; line-height: 1.5; }   /* 49 px for one line, as st.alert */
.info { background: rgba(28, 131, 255, 0.1); color: rgb(0, 84, 163); }
.warn, .warning { background: rgba(255, 255, 18, 0.1); color: rgb(146, 108, 5); }   /* yellow65 #FFFF12 at 10 % (Streamlit's theme) */
.error { background: rgba(255, 43, 43, 0.1); color: rgb(189, 64, 67); }   /* re-measured 2026-10-12 (st.error on 8641) */
.success { background: rgba(33, 195, 84, 0.1); color: rgb(21, 130, 55); }   /* re-measured 2026-10-12 (st.success on 8641) */

/* ---- expander (st.expander) ---- */
/* st.expander: a #D9D9D9 box (stExpander's 0.8 px border) around a faint one (the details' 0.8 px border), 36.2 px
   closed. Both are real borders, as Streamlit's, so they round the same way at every pixel ratio (at 2x each draws 1 px:
   37 px closed on both): the outer one is the details' own, the faint one is drawn by the summary (closed: all round;
   open: its foot is stExpanderDetails' top rule) and the body (sides and foot). */
details.exp { border: 0.8px solid var(--border); background: var(--white); margin: 0 0 1rem; }
details.exp > summary { list-style: none; cursor: pointer; background: transparent; padding: 3.5px 10.5px; min-height: 26px;
  box-sizing: content-box; border: 0.8px solid var(--faint); display: flex; align-items: center; gap: 7px; font: 400 14px/22.4px var(--display); color: var(--gray); }   /* a long title wraps in
  22.4 px lines (52 px closed with two), the text 35 px in: the 17.5 px chevron box + 7 px, as st.expander (measured at 375 px) */
details.exp > summary::-webkit-details-marker { display: none; }
/* st.expander header (measured on 8641): white at rest, rgba(173,173,173,.15) and #333 text under the pointer */
details.exp > summary:hover { background: rgba(173, 173, 173, 0.15); color: var(--ink); }
details.exp > summary::before { content: ""; width: 7px; height: 7px; border-right: 1.5px solid var(--gray);
  border-bottom: 1.5px solid var(--gray); transform: rotate(-45deg); margin: 0 5.25px; flex: none; transition: transform .15s; }
details.exp[open] > summary::before { transform: rotate(45deg); }
details.exp > .exp-body { padding: 14px 14px 0; border: 0.8px solid var(--faint); border-top: 0; }   /* the summary's foot = stExpanderDetails' top rule */

/* ---- inputs (st.text_input, st.selectbox, st.number_input, textarea) ---- */
input[type=text], input[type=number], input[type=date], select.plain, textarea {
  width: 100%; font: 14px var(--font); color: var(--gray); background: var(--white); border: 0.8px solid var(--border);
  height: 35px; padding: 7px 7px 7px 10.5px; outline: none; }
textarea { box-sizing: content-box; height: 39px; width: -webkit-fill-available; width: stretch; padding: 10.5px; resize: vertical; display: block; }   /* st.text_area: a 60 px box (39 + 2 x 10.5) inside its 0.8 px frame - the frame added, as Streamlit's (62 px at 2x); block (no line-box gap under it) */
/* focus (ui/theme.py A2 on 8641): the 0.8 px rule turns #333 and a 1 px #333 ring sits round it (1.8 px of ink) */
input:focus, select.plain:focus, textarea:focus { border-color: var(--ink); box-shadow: 0 0 0 1px var(--ink); }
input::placeholder, textarea::placeholder { color: var(--muted); }   /* fadedText60, as Streamlit's */
/* the number box (st.number_input's stepper): .numbox, so it never meets a table's td.num (Admin's Data Status).
   div.num = the old name, kept only until ISO Operation's template (isoop/_items.html) moves to .numbox */
.numbox, div.num { display: flex; height: 35px; border: 0.8px solid var(--bg); background: var(--white); }
.numbox input, div.num input { border: 0; height: 33px; flex: 1; min-width: 0; -moz-appearance: textfield; appearance: textfield; }
.numbox input:focus, div.num input:focus { box-shadow: none; }
/* Streamlit hides the browser's own spinner (NumberInput: ::-webkit-inner/outer-spin-button appearance none) */
.numbox input::-webkit-inner-spin-button, .numbox input::-webkit-outer-spin-button,
div.num input::-webkit-inner-spin-button, div.num input::-webkit-outer-spin-button { -webkit-appearance: none; margin: 0; }
/* focused (measured at 3x on 8641): the whole box, steppers too, framed by 1 px of #333 over its 0.8 px rule */
.numbox:focus-within, div.num:focus-within { outline: 1px solid var(--ink); outline-offset: -1px; }
.numbox button, div.num button { width: 28px; height: 33px; border: 0; background: var(--bg); color: var(--gray); font-size: 16px; cursor: pointer;
  display: flex; align-items: center; justify-content: center; padding: 0; transition: color 300ms, background-color 300ms; }
.numbox button:hover:enabled, div.num button:hover:enabled { background: var(--ink); color: var(--white); transition: none; }   /* primary, white icon */
.numbox button:disabled, div.num button:disabled { cursor: not-allowed; color: rgba(34, 34, 34, 0.4); }   /* fadedText40 */
/* st.number_input / st.text_input / st.text_area "Press Enter to apply" (app.js hintShow): InputInstructions */
.bk-hashint { position: relative; }
.bk-instr { position: absolute; font: 400 10.5px/16.8px var(--font); color: var(--muted); text-align: right; white-space: nowrap; pointer-events: none; z-index: 1; }
.bk-instr .dot::before { content: "•"; margin: 0 1.75px; color: var(--muted); }

/* ---- st.date_input with a (from, to) value (macros.date_range, app.js): one box (35.2 px in a 0.8 px frame, the text
   11.25 px in) and BaseWeb's range calendar (measured on the Streamlit page) ---- */
.drange { display: block; }
.drange-frame { border: 0.8px solid var(--border); background: var(--white); padding-right: 3.5px; }   /* BaseWeb's input: the frame
   (0.8 px, 3.5 px inside on the right) around a 33.6 px box - so the box is 5.1 px narrower than the frame, as Streamlit's */
.drange-frame:focus-within { border-color: var(--ink); }
input.drange-box, input.drange-box:focus { border: 0; height: 33.6px; padding: 7px 7px 7px 11.25px; cursor: text; }
.dpick { position: absolute; z-index: 1000; width: 308px; background: var(--white); color: var(--gray);
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.16); font: 14px/22.4px var(--font); user-select: none; }
.dpick-top { display: flex; align-items: flex-start; justify-content: space-between; padding: 16px 16px 8px; }   /* 48.39 px: BaseWeb pads 16 / 16 / 8 round its 24.39 px buttons */
.dpick-nav { width: 24px; height: 24px; padding: 0; border: 0; background: none; color: var(--gray); cursor: pointer; display: flex; }
/* the month and year buttons (BaseWeb, measured on 8641): 14px / 22.4px, padding 1 / 6 px, the 16 px chevron 12 px after */
.dpick-mb { display: flex; align-items: center; border: 0; background: none; font: 400 14px/22.4px var(--font); color: var(--gray);
  cursor: pointer; padding: 1px 6px; height: 24.39px; white-space: nowrap; }
.dpick-mb:focus { outline: none; }
.dpick-mb:focus-visible { box-shadow: 0 0 0 3px rgba(51, 51, 51, 0.5); }
.dpick-chev { display: flex; margin-left: 12px; }
.dpick-chev svg { width: 16px; height: 16px; display: block; }
/* BaseWeb's menu in the calendar (app.js openList): month / year / quick range lists */
.dpick-list { position: absolute; z-index: 2; margin: 0; padding: 8px 0; list-style: none; background: var(--white); max-height: 257px;
  overflow: auto; box-shadow: 0 4px 16px rgba(0, 0, 0, 0.16); box-sizing: border-box; outline: none; scrollbar-width: thin; }
.dpick-list li { padding: 8px 16px; font: 400 14px/22.4px var(--font); color: var(--gray); cursor: pointer; white-space: nowrap; }
.dpick-list li.hi { background: var(--tint); color: #525252; }
/* "Choose a date range" (a BaseWeb select): a 35 px #F4F4F4 box, "None" at 60 % 13 px in, the 20 px triangle 13 px from the right */
.dpick-qbox { display: flex; align-items: center; justify-content: space-between; height: 35px; box-sizing: border-box; background: var(--bg);
  border: 1px solid var(--bg); padding: 0 12px; font: 400 14px/22.4px var(--font); color: var(--muted); cursor: text; outline: none; }
.dpick-qbox:focus, .dpick-qbox.open { border-color: var(--ink); }
.dpick-tri { color: var(--gray); flex: none; }
/* a day reached with the keys: the same 2 px frame as the hover */
.dpick-d.kbd:not(.on)::after { content: ""; position: absolute; inset: -1px 0; border: 1.6px solid rgb(51, 51, 51); }
.dpick-d:focus { outline: none; }
.dpick-wk, .dpick-grid { display: grid; grid-template-columns: repeat(7, 42px); padding: 0 7px; }
.dpick-grid { padding-top: 7px; padding-bottom: 9px; row-gap: 2px; }   /* BaseWeb (8641): weeks 40 px, 2 px apart, 7 px in from the grid top (224 px for 5 weeks) */
.dpick-wk div { height: 40px; padding: 8px 6px; font: 14px/24px var(--font); color: rgb(107, 107, 107); text-align: center; }
.dpick-d { position: relative; height: 40px; padding: 8px; font: 12.25px/19.6px var(--font); text-align: center; cursor: pointer; }
.dpick-d > div { position: relative; z-index: 1; line-height: 24px; }
.dpick-d:not(.dpick-pad):not(.off):hover::after { content: ""; position: absolute; inset: -1px 0; border: 1.6px solid rgb(51, 51, 51); }
.dpick-d.mid::before { content: ""; position: absolute; inset: 0; background: rgba(173, 173, 173, 0.15); }
.dpick-d.start::before { content: ""; position: absolute; top: 0; bottom: 0; left: 21px; width: 21px; background: rgba(173, 173, 173, 0.15); }
.dpick-d.end::before { content: ""; position: absolute; top: 0; bottom: 0; left: 0; width: 21px; background: rgba(173, 173, 173, 0.15); }
.dpick-d.on { color: var(--white); }
.dpick-d.on::after { content: ""; position: absolute; inset: -1px 0; background: rgb(51, 51, 51); border: 1.6px solid rgb(51, 51, 51); }
.dpick-d.off { color: rgba(34, 34, 34, 0.3); cursor: not-allowed; }
.dpick-pad { cursor: default; }
.dpick-quick { padding: 8px 16px 16px; }
.dpick-ql { font-size: 14px; line-height: 22.4px; margin-bottom: 8px; }

/* ---- Tom Select = st.multiselect ---- */
/* Streamlit 1.56's Multiselect (its bundle; measured on 8648, mscap 2026-10-15): the box (BaseWeb's ControlContainer) is
   capped at calc(4.5 * (24.5px tag + 4.25px gap) + 4.25px + 2 * 1px border) = 135.625 px, about 4.5 rows of tags, and
   its value area (ValueContainer: overflow-y auto, padding 4.25 0 0 4.25, ending 49 px short of the right edge where
   the clear icon and chevron sit) scrolls inside it, so the page below never moves; it stays scrolled to the top after
   a pick. Here the wrapper is that bordered box (a column flex box, so its max-height caps the control) and .ts-control
   the scrolling value area; the chevron (the wrapper's ::after) and "Clear all" (app.js capBox moves it into the
   wrapper) keep to the right column, and the list opens 1 px lower, clear of the wrapper's border. */
.ts-wrapper.multi { display: flex; flex-direction: column; max-height: 135.625px; box-sizing: border-box; background: var(--white);
  border: 0.8px solid var(--border); box-shadow: none; }
.ts-wrapper.multi .ts-control, .ts-wrapper.multi.has-items .ts-control { flex: 0 1 auto; width: calc(100% - 49px); min-height: 33px; box-sizing: border-box;
  overflow: hidden auto; border: 0 !important; background: transparent; box-shadow: none !important; padding: 4.25px 0 0 4.25px !important; font-size: 14px;
  scrollbar-width: thin; scrollbar-color: transparent transparent; }   /* the tags' rows end 49 px in: the clear + chevron column (measured); Streamlit's thin scrollbar, its thumb on hover */
.ts-wrapper.multi .ts-control:hover { scrollbar-color: rgba(34, 34, 34, 0.4) transparent; }
.ts-wrapper.multi .ts-dropdown { margin-top: 4.5px; }
.ts-wrapper.multi .ts-dropdown.bk-up { margin-bottom: 5.5px; }
/* focused or open (measured at 3x on 8641, both widgets): the rule turns #333 and a 1 px #333 ring sits round it */
.ts-wrapper.multi.focus, .ts-wrapper.multi.dropdown-active { border-color: var(--ink); box-shadow: 0 0 0 1px var(--ink); }
.ts-wrapper.single.focus .ts-control, .ts-wrapper.single.dropdown-active .ts-control, .ts-wrapper.single.input-active.focus .ts-control { border-color: var(--ink) !important; box-shadow: 0 0 0 1px var(--ink) !important; }
.ts-wrapper.disabled .ts-control, .ts-wrapper.disabled .ts-control * { cursor: default !important; }   /* Streamlit: default, not not-allowed */
/* st.selectbox while a filter is typed: the picked value is hidden, only the typed text shows */
.ts-wrapper.single.bk-typing .ts-control > .item { display: none; }
/* BaseWeb's tag, measured on 8641: 24.5 px tall (border-box), padding 2/8/2/7, 3.5 px apart, rows 4.25 px apart; the
   delete icon is its 8.75 px svg 8 px after the text (app.js gives remove_button that svg) */
.ts-wrapper.multi .ts-control > .item { background: var(--ink); color: var(--white); border: 0; padding: 2px 8px 2px 7px !important; box-sizing: border-box;
  height: 24.5px; margin: 0 3.5px 4.25px 0; font-size: 14px; line-height: 22.4px; max-width: calc(100% - 14px); display: inline-flex; align-items: center; min-width: 0; }
.ts-wrapper.multi .ts-control > .item .tl { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; max-width: 128px; }   /* BaseWeb's tag text: 128 px at most, then … */
.ts-wrapper.multi .ts-control > .item.active { background: var(--ink-soft); color: var(--white); }
.ts-wrapper.plugin-remove_button .item .remove, .ts-wrapper.plugin-remove_button:not(.rtl) .item .remove { border-left: 0 !important; padding: 0; margin-left: 8px !important;
  width: 8.75px; height: 8.75px; flex: none; display: flex; color: var(--white); background: transparent !important; }
.ts-wrapper.plugin-remove_button .item .remove svg { width: 8.75px; height: 8.75px; display: block; fill: currentColor; }
.ts-wrapper.plugin-remove_button .item .remove:hover { background: transparent; color: #ddd; }
/* "Clear all" (BaseWeb's icon, measured on 8641): a 21 px svg, 1.75 px padding, rgba(49,51,63,.6), its right edge 29 px in */
.ts-wrapper .clear-button { right: 29px !important; width: 21px; opacity: 1 !important; background: transparent !important; display: flex; align-items: center; padding: 0; }
.ts-wrapper .clear-button svg { width: 21px; height: 21px; padding: 1.75px; box-sizing: border-box; display: block; fill: rgba(49, 51, 63, 0.6); cursor: pointer; }
.ts-wrapper .clear-button svg:hover { fill: var(--gray); }
.ts-wrapper.multi::after { content: ""; position: absolute; right: 12px; top: 50%; width: 7px; height: 7px; margin-top: -6px;
  border-right: 1.6px solid var(--gray); border-bottom: 1.6px solid var(--gray); transform: rotate(45deg); }
.ts-dropdown { font-size: 14px; }
.ts-control input { font-size: 14px !important; }
/* with tags picked, BaseWeb's search input is a 16 px box after the last tag: it moves to a line of its own only when
   less than that is left on the row (Tom Select's 7rem minimum wrapped it under a full row, 18 px taller: RFP Regions) */
.ts-wrapper.multi.has-items .ts-control > input { min-width: 16px !important; }

/* ---- Tom Select (single) = st.selectbox (measured): a 35 px white box, 1 px #D9D9D9 rule, 14px text 12.3 px in, the
   21 px expand_more chevron 8 px from the right; open, the same menu as st.multiselect, and typing searches ---- */
.ts-wrapper.single { min-height: 35px; }
.ts-wrapper.single .ts-control, .ts-wrapper.single.input-active .ts-control { height: 35px; min-height: 35px; background: var(--white);
  border: 1px solid var(--border); box-shadow: none; padding: 7px 33px 7px 11.3px !important; font: 14px/19px var(--font);
  color: var(--gray); flex-wrap: nowrap; cursor: pointer; }
.ts-wrapper.single.input-active .ts-control { cursor: text; }
.ts-wrapper.single.focus .ts-control { border-color: var(--ink); }
.ts-wrapper.single .ts-control > .item { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-width: 0; }
.ts-wrapper.single .ts-control::after, .ts-wrapper.single.dropdown-active .ts-control::after { content: ""; position: absolute;
  right: 8px; top: 6px; width: 21px; height: 21px; margin: 0; border: 0; transform: none;
  background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='%23222222' d='M16.59 8.59L12 13.17 7.41 8.59 6 10l6 6 6-6z'/%3E%3C/svg%3E") center / 21px 21px no-repeat; }
/* the open menu (st.selectbox and st.multiselect share baseweb's, measured on 8641 for both): 3.5 px below the box (or,
   with no room below, 4.5 px above it: app.js fitList), white 1 px edge, 0 4px 16px shadow at 16 %, 35 px options #222
   with the text 11.25 px in, 7.5 options tall */
.ts-dropdown { margin-top: 3.5px; border: 1px solid var(--white); box-shadow: 0 4px 16px rgba(0, 0, 0, 0.16); }
.ts-dropdown.bk-up { top: auto; bottom: 100%; margin-top: 0; margin-bottom: 4.5px; }
.ts-dropdown .ts-dropdown-content { max-height: 260.5px;   /* + the 1 px edges = 262.5 */
  scrollbar-width: thin; scrollbar-color: transparent transparent; }   /* Streamlit's: a 10 px gutter, the thumb shows on hover */
.ts-dropdown .ts-dropdown-content:hover { scrollbar-color: rgba(34, 34, 34, 0.4) transparent; }
.ts-dropdown .option { height: 35px; padding: 6.3px 7px 0 11.25px; line-height: 22.4px; white-space: nowrap; overflow: hidden;
  text-overflow: ellipsis; color: var(--gray); position: relative; z-index: 0; }
/* the highlighted (hovered / keyboard; on opening a selectbox, the picked) row: the row tint #EDEDED / #525252 and BaseWeb's
   inner box, 24.5 px tall, 5.25 px down, 4.25 px in from each side (on the right minus the scrollbar gutter, app.js fitList), square corners
   (radii.md2 = 0 in this theme), rgba(173,173,173,.15); the text sits 7 px inside it. A picked option that is not
   highlighted is a plain row, as Streamlit's */
.ts-dropdown .option.active { background: var(--tint); color: #525252; }
.ts-dropdown .option.active::before { content: ""; position: absolute; z-index: -1; left: 4.25px; top: 5.25px;
  right: max(0px, calc(4.25px - var(--sbg, 0px)));
  height: 24.5px; background: rgba(173, 173, 173, 0.15); border-radius: 0; pointer-events: none; }
/* st.multiselect's "Select all" / "Select N matches" (app.js selectAll): the first row, an option like the others with a
   1 px rgba(34,34,34,.2) rule along its foot, 4.25 px in from each side (Streamlit 1.56's $isSelectAll ::after) */
.ts-dropdown .option.ts-selall { overflow: visible; }
.ts-dropdown .option.ts-selall::after { content: ""; position: absolute; left: 4.25px; right: max(0px, calc(4.25px - var(--sbg, 0px)));
  bottom: 0; height: 1px;
  background: rgba(34, 34, 34, 0.2); transform: translateY(50%); pointer-events: none; }
/* "No results" (a multiselect with nothing left to pick, or a filter matching none in either widget): BaseWeb's empty
   list, 78.75 px tall, the words centred, 14px / 22.4px at rgba(34,34,34,.6) */
.ts-dropdown .no-results { height: 78.75px; box-sizing: border-box; padding: 0; display: flex; align-items: center;
  justify-content: center; line-height: 22.4px; color: rgba(34, 34, 34, 0.6); }

/* ---- noUiSlider = st.slider / st.select_slider (range) ---- */
.slider-field { padding: 0; height: 59.5px; box-sizing: content-box; margin-bottom: 14px; position: relative; }
/* the min / max shown on hover (Streamlit 1.56 TickBar: top = the 35 px track box's foot - 10.5 px; app.js sliderTicks) */
.slider-ticks { position: absolute; left: 0; right: 0; top: 49px; display: flex; justify-content: space-between; pointer-events: none;
  font: 400 12.25px/19.6px var(--font); color: var(--muted); opacity: 0; transition: opacity 300ms 200ms; white-space: nowrap; }
.slider-field:hover > .slider-ticks, .slider-field:focus-within > .slider-ticks { opacity: 1; transition: none; }   /* st.slider 59.5 px + the 14 px block gap (73.5 px a slider) */
.slider-field .sl { margin-left: 5.25px; margin-right: 5.25px; }   /* only the track is inset (the thumbs' radius); label and values start at the column edge, as st.slider */   /* st.slider: label 21 + 4 + 35 */
.slider-vals { position: relative; height: 19px; margin-top: -8.9px; font-size: 12.25px; color: var(--ink); line-height: 19px; }
.slider-vals span { position: absolute; transform: translateX(-50%); white-space: nowrap; }
.noUi-target { background: var(--faint); border: 0; box-shadow: none; height: 4px; margin: 3.85px 0 0; }   /* st.slider (measured): values 17.2 px, thumbs 36.8 px below the widget top */
.noUi-connect { background: var(--ink); }
.noUi-horizontal .noUi-handle { width: 10.5px; height: 10.5px; right: -5.25px; top: -3.25px; background: var(--ink); border: 0;
  box-shadow: none; cursor: grab; }
.noUi-handle::before, .noUi-handle::after { display: none; }
.noUi-handle:focus { outline: 2px solid rgba(51,51,51,.25); }

/* ---- st.radio (horizontal) and st.checkbox: square boxes ---- */
.radios { display: flex; flex-wrap: wrap; align-items: center; gap: 0; margin: 0; min-height: 35px; }   /* st.radio: 14 px between options; wrapped rows 22.4 px, no gap (measured) */
.radios > .box { padding-right: 1.75px; margin-right: 14px; min-height: 22.4px; }   /* each label carries its own 14 px, the last one too, so rows wrap where Streamlit's do */   /* each option: 14 px dot, 8 px, the text, 1.75 px (measured) */
.box { display: inline-flex; align-items: center; gap: 8px; font-size: 14px; color: var(--gray); cursor: pointer; line-height: 1.5; }
.box input { appearance: none; -webkit-appearance: none; width: 14px; height: 14px; margin: 0; flex: none; cursor: pointer;
  background: var(--white); border: 0.8px solid var(--faint); display: grid; place-content: center; }
.box input[type=radio]:checked { background: var(--ink); border-color: var(--ink); }
.box input[type=radio]:checked::after { content: ""; width: 5px; height: 5px; background: #F0F2F6; }   /* st.radio, measured */
.box input[type=checkbox]:checked { background: var(--ink); border-color: var(--ink); }
.field.cbcell { padding-top: 7px; height: 28px; }   /* st.checkbox beside another widget in st.columns: its 28 px element, the box 7 px down (both widths) */
.box input[type=checkbox]:checked::after { content: ""; width: 4px; height: 8px; border: solid var(--white);
  border-width: 0 1.6px 1.6px 0; transform: rotate(45deg) translate(-1px, -1px); }

/* ---- buttons (st.button / download_button) ---- */
.btn { display: inline-flex; align-items: center; justify-content: center; gap: 6px; width: 100%; height: auto;
  min-height: 2.5rem; padding: 3.5px 10.5px; border: 0.8px solid var(--ink); background: var(--white); color: var(--ink);
  font: 400 14px/22.4px var(--font); text-align: center; cursor: pointer; text-decoration: none; }   /* 35 px; a label too long
  for the button wraps in 22.4 px lines (53.4 px with two), as st.button / st.download_button */
.btn:hover { background: rgba(0, 0, 0, 0.06); color: var(--ink-soft); }   /* st.button secondary hover (8641) */
.btn.dark { background: var(--ink); color: var(--white); letter-spacing: 0.3px; }   /* the label is 400 (the button weight does not reach its text; measured) */
.btn.dark:hover { background: var(--ink-soft); border-color: var(--ink-soft); color: var(--white); }   /* primary hover: #525252 fill and frame */
.btn[disabled] { cursor: not-allowed; }   /* Streamlit draws these disabled buttons unchanged */
.btn[disabled]:hover { background: var(--white); color: var(--ink); }
.btn.dark[disabled]:hover { background: var(--ink); border-color: var(--ink); color: var(--white); }

/* ---- chart and tables ---- */
.chart { width: 100%; height: 537px; background: var(--white); margin: 0 0 1rem; min-width: 0; contain: inline-size; }   /* the box sets the
   figure's width, never the figure the box's (so a narrowing page narrows the chart); the height is the figure's at every width */
/* st.plotly_chart in fullscreen (app.js chartFull; Streamlit's withFullScreenWrapper, measured on 8641) */
.chart.bk-chart-full { position: fixed !important; inset: 0; z-index: 1000050; width: auto !important; height: auto !important; margin: 0;
  background: var(--white); padding: 40.25px 12px 10.5px; box-sizing: border-box; display: flex; justify-content: center;
  align-items: flex-start; overflow: auto; contain: none; }
.tablewrap { position: relative; margin: 0 0 1rem; }
/* st.dataframe's toolbar (stElementToolbar, measured on 8641; app.js rebuilds every page's .tbar to it): right-aligned,
   its white box 29.1 px above the table, shown while the pointer is over the table (always in fullscreen) */
.tbar { position: absolute; right: 0; top: -36.1px; display: none; padding: 7px 0 7px 7px; z-index: 5; }
.tbar-in { display: flex; background: var(--white); padding: 3.5px; box-shadow: 1px 2px 8px rgba(0, 0, 0, 0.08); }
.tablewrap:hover .tbar, .tbar.on, .tablewrap.fullscreen .tbar, .tablewrap:has(.dfsearch) .tbar { display: block; }
.tablewrap.fullscreen .tbar { top: 4.16px; right: 11.5px; }
.tbar button { display: flex; align-items: center; justify-content: center; width: 19.59px; height: 19.59px; padding: 3.5px; border: 0;
  background: transparent; cursor: pointer; color: var(--muted); line-height: 0; box-sizing: border-box; }
.tbar button:hover { background: rgba(173, 173, 173, 0.15); }
.tbar svg { width: 12.59px; height: 12.59px; display: block; }
.tsearch { display: none; }
/* st.dataframe = Streamlit 1.56's glide grid (app.js BK.table): a 1 px frame (the element) around a 1 px box (the grid),
   header 31 px + its rule, rows 31 px with the rule, cells 12.25px Inter, padding 7 px, every grid line #D9D9D9 */
.dfframe { position: relative; border: 1px solid var(--border); background: transparent; }
.dfframe:not(.auto) { border-bottom: 0; }          /* with height=: the box's own rule closes the foot, 1 px lower */
.dfbox.tabulator { border: 1px solid var(--border); background: var(--white); font: 400 12.25px var(--font); color: var(--gray); margin: 0; }
.dfbox .tabulator-tableholder { background: var(--white); scrollbar-width: thin; }   /* glide's scroller: thin */
.dfbox .tabulator-header { background: var(--white); border-bottom: 1px solid var(--border); color: rgba(34, 34, 34, 0.6); font-weight: 400; }
.dfbox .tabulator-header .tabulator-col { background: var(--white); border-right: 1px solid var(--border); height: 31px; min-height: 31px; }
.dfbox .tabulator-header .tabulator-col .tabulator-col-content { padding: 0 7px; height: 31px; display: flex; align-items: center; }
.dfbox .tabulator-header .tabulator-col .tabulator-col-title-holder { width: 100%; }
/* glide draws the header text with fillText, clipped only at the column's edge (no ellipsis): the title may run into the
   right padding, so a title that is a hair wider than its measured width still shows whole, as in Streamlit */
.dfbox .tabulator-header .tabulator-col .tabulator-col-content .tabulator-col-title { padding-right: 0 !important; white-space: nowrap; overflow: visible; text-overflow: clip; }
/* web table alignment (Karl, 2026-10-16): the leftmost column's header and values right-aligned, every other column's
   centred (app.js table(): bk-c0 / bk-cn on the column, hozAlign on the cells); the first column's menu dots move to
   its left edge so they never sit on a right-aligned title */
.dfbox .tabulator-header .tabulator-col.bk-c0 .tabulator-col-content { justify-content: flex-end; }
.dfbox .tabulator-header .tabulator-col.bk-c0 .tabulator-col-content .tabulator-col-title { text-align: right; }
.dfbox .tabulator-header .tabulator-col.bk-cn .tabulator-col-content { justify-content: center; }
.dfbox .tabulator-header .tabulator-col.bk-cn .tabulator-col-content .tabulator-col-title { text-align: center; }
.dfbox .tabulator-header .tabulator-col.bk-c0 .dfmenu { right: auto; left: 6px; }
.dfbox .tabulator-row .tabulator-cell.bk-c0 { text-align: right; }
.dfbox .tabulator-row .tabulator-cell.bk-cn { text-align: center; }
.dfbox .tabulator-header .tabulator-col .tabulator-col-sorter { display: none; }
.dfbox .tabulator-header .tabulator-col[aria-sort="ascending"] .tabulator-col-title::before { content: "\2191  "; white-space: pre; }   /* glide: the arrow before the title */
.dfbox .tabulator-header .tabulator-col[aria-sort="descending"] .tabulator-col-title::before { content: "\2193  "; white-space: pre; }
.dfbox .tabulator-header .tabulator-col:last-child { border-right: 0; }
.dfbox .tabulator-row { height: 31px; min-height: 31px; border-bottom: 1px solid var(--border); background: var(--white); color: var(--gray); }
.dfbox .tabulator-row.tabulator-row-even { background: var(--white); }
.dfbox .tabulator-row .tabulator-cell { height: 30px; padding: 0 7px; line-height: 30px; border-right: 1px solid var(--border);
  white-space: nowrap; overflow: hidden; text-overflow: clip; }
.dfbox .tabulator-row .tabulator-cell:last-of-type { border-right: 0; }
.dfbox .tabulator-row .tabulator-cell.tabulator-frozen, .dfbox .tabulator-header .tabulator-col.tabulator-frozen { border-right: 1px solid var(--border); }
.dfbox .tabulator-row .tabulator-cell.idx { color: rgba(34, 34, 34, 0.6); }          /* index columns: glide's "faded" (60 %) */
.dfbox .tabulator-cell .na { color: rgba(34, 34, 34, 0.4); }                          /* the missing-value sign, textLight */
.dfbox .tabulator-cell.idx .na { opacity: 0.6; }
.dfbox .tabulator-cell .dfchk { vertical-align: middle; opacity: 0.4; display: inline-block; margin-top: -2px; }
.dfbox .tabulator-row:hover, .dfbox .tabulator-row:hover .tabulator-cell.tabulator-frozen:not(.bk-sel):not(.bk-hit) { background: #FCFCFC !important; }   /* glide hovered row, Streamlit 1.56 (lead, 2026-10-13) */
.dfbox .tabulator-cell a { color: rgb(0, 84, 163); }                                   /* glide linkColor */
.dfbox .tabulator-placeholder { display: none; }
/* st.dataframe in fullscreen (withFullScreenWrapper, measured on 8641): fixed, white, padding 40.25 / 10.5 / 10.5 px */
.tablewrap.fullscreen { position: fixed !important; inset: 0; z-index: 1000050; background: var(--white); padding: 40.25px 10.5px 10.5px; margin: 0 !important; overflow: auto; }
.fullscreen:not(.tablewrap) { position: fixed !important; inset: 20px; z-index: 2000; background: var(--white); padding: 40px 10px 10px; overflow: auto; }
/* glide's header: hover / the clicked cell's column #F7F7F7; the menu dots 15 px in from the right, shown on hover */
.dfbox.tabulator .tabulator-header .tabulator-col:hover, .dfbox.tabulator .tabulator-header .tabulator-col.tabulator-sortable:hover,
.dfbox.tabulator .tabulator-header .tabulator-col.bk-colsel { background: #F7F7F7 !important; }
.dfbox .tabulator-header .tabulator-col { position: relative; }
.dfmenu { position: absolute; right: 11px; top: 50%; margin-top: -6.5px; width: 6px; height: 13px; padding: 0; border: 0; background: none;
  color: rgba(34, 34, 34, 0.6); cursor: pointer; display: none; line-height: 0; z-index: 2; }
.dfmenu svg { display: block; fill: currentColor; }
.dfbox .tabulator-header .tabulator-col:hover .dfmenu { display: block; }
/* a clicked cell / the current search hit: #EAEAEA in a 1 px #333 frame; other search hits #EAEAEA */
.dfbox .tabulator-row .tabulator-cell.bk-hit { background: #EAEAEA; }
.dfbox .tabulator-row .tabulator-cell.bk-sel { background: #EAEAEA; outline: 1px solid var(--ink); outline-offset: -1px; position: relative; z-index: 1; }
/* Streamlit's code font: Source Code Pro, the variable files Streamlit 1.56 ships (static/media/SourceCodeVF-*), and
   ui/theme's rule that puts every code / pre / kbd / samp in it */
@font-face { font-family: "Source Code Pro"; font-style: normal; font-weight: 100 900; src: url("fonts/SourceCodeVF-Upright.woff2") format("woff2"); }
@font-face { font-family: "Source Code Pro"; font-style: italic; font-weight: 100 900; src: url("fonts/SourceCodeVF-Italic.woff2") format("woff2"); }
code, pre, kbd, samp { font-family: "Source Code Pro", ui-monospace, Consolas, monospace; }
/* a Plotly chart's text (titles, subtitles, axes, legend, hover labels) draws in Inter whatever the figure asks for: ui/theme's
   `.stApp *` rule is !important, so it beats the font Plotly writes on each SVG text (Plotly still measures its layout in the
   figure's own font, in its tester outside the chart, as under Streamlit) */
.js-plotly-plot text, .js-plotly-plot tspan { font-family: var(--font) !important; }
/* Streamlit's icon font (Material Symbols Rounded, the same file Streamlit 1.56 ships) for the table menus */
@font-face { font-family: "Material Symbols Rounded"; font-style: normal; font-weight: 100 700; font-display: block;
  src: url("fonts/MaterialSymbols-Rounded.woff2") format("woff2"); }
.msym { font-family: "Material Symbols Rounded"; font-weight: 400; font-style: normal; font-size: 14px; line-height: 1; letter-spacing: normal;
  text-transform: none; white-space: nowrap; word-wrap: normal; direction: ltr; -webkit-font-feature-settings: "liga"; font-feature-settings: "liga";
  -webkit-font-smoothing: antialiased; display: inline-block; width: 14px; height: 14px; overflow: hidden; user-select: none; flex: none; }
/* the column menu, its Format list and Show/hide columns (glide / Streamlit, measured on 8641) */
.dfpop { position: absolute; z-index: 1000070; background: var(--white); border: 1px solid var(--white); box-shadow: 0 4px 16px rgba(0, 0, 0, 0.16);
  font: 400 12.25px/19.6px var(--font); color: var(--gray); box-sizing: border-box; }
.dfcolmenu, .dfsub { padding: 1.75px 5.25px; }
.dfm-head { display: flex; gap: 3.5px; padding: 3.5px 0; cursor: default; }
.dfm-type { display: flex; align-items: center; justify-content: center; width: 23px; height: 23px; padding: 3.5px; box-sizing: border-box; border: 1px solid var(--faint); flex: none; }
.dfm-name { display: flex; align-items: center; justify-content: space-between; flex: 1; min-width: 0; height: 23px; padding: 1.75px; box-sizing: border-box;
  background: var(--bg); border: 1px solid var(--faint); }
.dfm-name > span { font-size: 10.5px; line-height: 16.8px; margin: 0 5.25px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dfm-copy { display: flex; align-items: center; justify-content: center; width: 17.5px; height: 17.5px; padding: 3.5px; border: 0; background: transparent; cursor: pointer; flex: none; box-sizing: border-box; }
.dfm-copy:hover { background: rgba(34, 34, 34, 0.1); }
.dfm-copy .msym { font-size: 10.5px; width: 10.5px; height: 10.5px; }
.dfm-i { display: flex; align-items: center; gap: 7px; height: 23.09px; padding: 1.75px 7px; margin: 3.5px 0; box-sizing: border-box; cursor: pointer; white-space: nowrap; }
.dfm-i:hover, .dfm-i.open { background: rgba(173, 173, 173, 0.15); }
.dfm-fmt { justify-content: space-between; }
.dfm-fmt > div { display: flex; align-items: center; gap: 7px; }
.dfm-rule { height: 1px; margin: 5.25px; background: var(--faint); }
.dfcols .dfc-in { padding: 7px 0; max-height: min(262.5px, 70vh); overflow: auto; }
.dfc-row { display: flex; align-items: flex-start; padding: 3.5px 10.5px; cursor: pointer; white-space: nowrap; line-height: 18.375px; }
.dfc-row input { position: absolute; opacity: 0; width: 0; height: 0; margin: 0; }
.dfc-box { display: flex; align-items: center; justify-content: center; width: 14px; height: 14px; margin: 3.5px 2px 0 0; box-sizing: border-box; flex: none;
  border: 1px solid var(--ink); background: var(--white); }
.dfc-row.on .dfc-box { background: var(--ink); }
.dfc-row:not(.on) .dfc-box svg { display: none; }
.dfc-row > div { padding-left: 7px; }
/* glide's search bar (app.js): 9 px in from the grid's top right */
.dfsearch { position: absolute; top: 8px; right: 8px; z-index: 6; width: 266px; padding: 7px; box-sizing: border-box; background: var(--white);
  border: 1px solid var(--white); box-shadow: 0 4px 16px rgba(0, 0, 0, 0.16); font: 400 12.25px/19.6px var(--font); color: var(--gray); }
.dfs-row { display: flex; align-items: center; height: 21.59px; }
.dfsearch input[type=text] { flex: none; width: 199.84px; height: 21.59px; padding: 1px 2px; border: 0; box-shadow: 0 0 0 1px var(--ink); font: 400 12.25px/19.6px var(--font); background: var(--white); }
.dfsearch button { display: flex; align-items: center; justify-content: center; width: 16.72px; height: 21px; padding: 0; border: 0; background: transparent;
  color: rgba(34, 34, 34, 0.8); cursor: pointer; flex: none; }
.dfsearch button:disabled { opacity: 0.4; cursor: default; }
.dfs-count { padding: 3.5px 0 0; font-size: 10.5px; line-height: 16.8px; }
.dfs-count label { line-height: 13px; display: inline-block; margin-top: 1px; }

.htmx-indicator { display: none; }
.htmx-request .htmx-indicator, .htmx-request.htmx-indicator { display: block; }
/* no "Running..." chip: BAKORA's Streamlit theme hides the status widget (ui/theme.py, stStatusWidget display none);
   a rerun shows only as stale elements fading (below). #busy stays in the page (its class still tracks a request). */
.busy, #busy, #busy.htmx-request, #busy.io-running { display: none !important; }
/* a stale element (Streamlit 1.56, measured on 8641): opacity 1 -> .33, transition opacity 1s ease-in .5s; back at once */
.bk-stale > *:not(.loadfail), .bk-stale-el { opacity: 0.33; transition: opacity 1s ease-in 0.5s; }

@media (max-width: 1040px) { .nav-mark { font-size: 17px; letter-spacing: -0.4px; } }
@media (max-width: 940px) { .topnav { padding-left: 1rem; padding-right: 1rem; } .nav-mark { font-size: 15px; } .block { padding: 100.8px 1rem 28px; } }
@media (max-width: 720px) {
  .topnav .inner { grid-template-columns: auto 1fr; }
  .topnav .nav-item:not(.right) { display: none; }
  .topnav .nav-item.right { justify-self: end; width: 48px; }
}
@media (max-width: 640px) {   /* st.columns stack at Streamlit's breakpoint */
  .cols, .cols3, .cols5 { grid-template-columns: 1fr; }
  .stcols { flex-direction: column; align-items: stretch; }
  .stcols > *, .stcols.bk-f > * { flex: none; width: 100%; }
  /* .stcols > .empty = a column the page left empty: Streamlit still stacks it with its 1rem gap (flex-wrap, gap 1rem,
     a 0 px column). A filled column's gap is its last .field's foot margin, so only the empty one needs the 1rem itself */
  .stcols > .empty { height: 1rem; }
}

/* ---- saved views, input files ---- */
.popover { position: absolute; right: 0; top: calc(100% - 0.6rem); width: 320px; background: var(--white); border: 1px solid var(--border);
  box-shadow: 0 6px 18px rgba(0,0,0,.1); padding: 14px 14px 4px; z-index: 50; }
.code { background: var(--white); border: 1px solid var(--border); padding: 10px 12px; margin: 0 0 0.6rem; font: 13px "Source Code Pro", Consolas, monospace; white-space: pre-wrap; word-break: break-all; }
/* st.file_uploader's drop zone (Streamlit 1.56, measured at 1440 and 375 px and read from its bundle): a 59.5 px white
   box in a 0.8 px dashed #D9D9D9 frame, 10.5 px padding, the Upload button (94.5 x 35: 0.8 px #333 frame, 5.25/10.5 px
   padding, the 17.5 px icon, 7 px, "Upload" in 14px/400) at the top left, 14 px, then the limit line (12.25px, 60 %,
   one line, cut with "…") centred. Narrower than 23rem (322 px at the app's 14 px root: Energy's or Fuel's half column
   at 375 px) it stacks - the button over the limit line, 10.5 px apart (87.7 px) - Streamlit 1.56's compact drop zone
   (FileUploader: width < convertRemToPx("23rem")); Load's 347 px phone column and 497 px desktop box keep the row. */
.uploader { display: flex; align-items: flex-start; gap: 14px; background: var(--white); border: 0.8px dashed var(--border);
  padding: 10.5px; height: 59.5px; min-width: 0; }
.uploader .btn.up { flex: none; width: auto; min-height: 35px; height: 35px; padding: 5.25px 10.5px; gap: 7px; font-weight: 400; }
.uploader .btn.up svg { width: 17.5px; height: 17.5px; flex: none; }
.uploader .hint { align-self: center; flex: 1; min-width: 0; line-height: 19.6px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.field:has(> .uploader) { container-type: inline-size; }
@container (max-width: 321.98px) {
  .uploader { flex-direction: column; align-items: stretch; gap: 10.5px; height: auto; }
  .uploader .btn.up { align-self: flex-start; }
  .uploader .hint { align-self: stretch; flex: none; }
}
.hint { font-size: 12.25px; color: var(--muted); }
/* st.file_uploader's states (app.js, Streamlit 1.56 FileUploader + file chips, measured on 8641) */
.uploader, .lup { position: relative; cursor: pointer; }
.uploader.has-chips > .btn.up, .uploader.has-chips > .hint { display: none; }
.lup.has-chips > .btn.lup-b, .lup.has-chips > .hint { display: none; }
.uploader.bk-drag, .lup.bk-drag { box-shadow: inset 0 0 0 2px var(--ink); }
.up-drag { position: absolute; inset: 1.75px; z-index: 3; display: flex; align-items: center; justify-content: center; background: var(--bg); pointer-events: none; }
.up-drag span { color: var(--ink); font: 800 12.25px/19.6px var(--font); }
.up-chips { display: flex; flex-wrap: wrap; gap: 7px; align-items: center; line-height: 1.25; min-width: 0; max-height: 125.5px; overflow-y: auto; }
.up-chip { display: inline-flex; align-items: center; width: fit-content; min-width: 126px; max-width: 100%; padding: 3.5px; gap: 7px;
  background: var(--white); cursor: default; font-size: 14px; line-height: 17.5px; color: var(--gray); }
.up-chip.err { background: rgba(255, 43, 43, 0.1); }
.up-ic { display: flex; align-items: center; justify-content: center; width: 28px; height: 28px; flex: none; background: var(--gray); color: var(--white); }
.up-chip.err .up-ic { background: rgba(255, 43, 43, 0.1); color: rgb(189, 64, 67); }
.up-meta { display: flex; flex-direction: column; flex: 1; min-width: 68.25px; }
.up-n { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 12.25px; line-height: 15.3125px; color: var(--gray); }
.up-s { font-size: 10.5px; line-height: 13.125px; color: var(--muted); }
.up-x { display: flex; align-self: flex-start; line-height: 0; flex: none; }
.up-x button { display: flex; padding: 0; border: 0; background: transparent; color: var(--muted); cursor: pointer; line-height: 0; }
.up-x button:hover { color: var(--gray); }
.up-chip.err .up-x button { color: rgb(189, 64, 67); }
.up-chip.err .up-x button:hover { color: rgb(255, 43, 43); }
.up-sr { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0; }
.up-add { display: flex; align-items: center; justify-content: center; width: 21px; height: 21px; padding: 1.75px; border: 0; background: transparent;
  color: var(--muted); cursor: pointer; }
.up-add:hover { color: var(--gray); }
.filerow { display: grid; gap: 0 1rem; align-items: start; margin: 0 0 0.4rem; }
.fline { font-size: 14px; color: var(--gray); line-height: 2.5rem; }
.mobile-only { display: none !important; }
@media (max-width: 720px) { .mobile-only { display: block !important; } }
@media (max-width: 640px) { .filerow { grid-template-columns: 1fr !important; } }   /* st.columns breakpoint */

/* ---- st.tabs (measured on the v4 Streamlit page): 35 px tabs, 10px 20px padding, 12.25px Inter 400, #555 / #333 picked
   with a 3 px underline and baseweb's 1.75 px highlight under it, then the list's 2 px #D9D9D9 rule (bar 38.75 px);
   the panel starts 14 px lower ---- */
.tabs { display: flex; gap: 0; padding-bottom: 1.75px; border-bottom: 2px solid var(--border); margin: 0 0 14px; }
.tab { display: flex; align-items: center; height: 35px; padding: 0 20px; margin: 0; background: transparent; border: 0;
  border-bottom: 3px solid transparent; font: 400 12.25px/19.6px var(--font); color: var(--gray-mid); cursor: pointer; white-space: nowrap; }
.tab:hover { color: var(--ink); }
.tab.on { color: var(--ink); border-bottom-color: var(--ink); box-shadow: 0 1.75px 0 var(--ink); }
/* a strip wider than its column scrolls sideways with no scrollbar (BaseWeb's TabList: overflow-x scroll, y hidden), and
   app.js's tabScroll lays Streamlit's scroll buttons over its ends: 17.5 x 35, a 17.5 px chevron at 60 % ink (#222 on
   hover) on a fade to white (stTabsScrollLeft / stTabsScrollRight, measured at 375 px) */
.tabs { flex-wrap: nowrap; overflow-x: auto; overflow-y: hidden; scrollbar-width: none; }
.tabs::-webkit-scrollbar { display: none; }
.tabs .tab { flex: none; }
.bk-tabwrap { position: relative; }
.bk-tscroll { position: absolute; top: 0; z-index: 1; display: flex; align-items: center; justify-content: center;
  width: 17.5px; height: 35px; padding: 0; border: 0; cursor: pointer; color: rgba(34, 34, 34, 0.6); background: transparent; }
.bk-tscroll[hidden] { display: none; }
.bk-tscroll:hover { color: var(--gray); }
.bk-tscroll:focus { outline: none; }
.bk-tscroll:focus-visible { box-shadow: 0 0 0 0.2rem rgba(51, 51, 51, 0.5); }
.bk-tscroll svg { width: 17.5px; height: 17.5px; flex: none; }
.bk-tscroll.r { right: 0; background-image: linear-gradient(to right, rgba(255, 255, 255, 0), rgb(255, 255, 255) 40%); }
.bk-tscroll.l { left: 0; background-image: linear-gradient(to left, rgba(255, 255, 255, 0), rgb(255, 255, 255) 40%); }

/* the footer caption ends the page flush, as Streamlit's last element; Streamlit's thin scrollbar */
main > p.caption:last-child { margin-bottom: 0; }
html { scrollbar-width: thin; }   /* no reserved gutter: Streamlit's short pages sit 5 px right (x 90) with no scrollbar, as here (re-audit 2026-10-12) */

/* Tom Select's typing box is not a text field: the shared input rule must not size it */
.ts-control input, .ts-control input[type=text] { height: auto !important; min-height: 0 !important; border: 0 !important; padding: 0 !important; width: auto; background: transparent !important; }
