/*
 * Temporary compatibility layer for the Bootstrap 3 -> 5 migration
 * (see the migration plan, Phase 1). Loaded right after bootstrap.min.css
 * on every page that shares templates/head.html (+ variants).
 *
 * Purpose: pages/components not yet rewritten to BS5 markup still use BS3
 * class names (e.g. .form-horizontal - see the "reduz dependência do shim"
 * commit history for classes already migrated away, like .label-*,
 * .checkbox-inline/.radio-inline and .btn-default). None of these exist in
 * Bootstrap 5, so without this
 * file that markup would render unstyled the moment bootstrap.min.css is
 * swapped to 5.3.8, even though the underlying HTML hasn't been touched
 * yet. This file re-creates just enough of their old appearance on top of
 * BS5 primitives so migration can proceed screen-by-screen instead of in
 * one atomic rewrite.
 *
 * NOT covered here (out of scope for a CSS-only shim):
 *  - Glyphicons: BS5 ships no icon font at all, there is no CSS trick that
 *    recreates specific glyphs. Pages using <span class="glyphicon ...">
 *    will show missing icons until their markup is converted to Font
 *    Awesome (already vendored/used app-wide) in Phases 2-4.
 *  - JS behavior (data-toggle="modal"/"tab"/"tooltip"/"popover", the
 *    jQuery .modal()/.tab()/.tooltip()/.popover() plugin API): these are
 *    renamed/rewritten directly in the same Phase 1 commit that swaps this
 *    CSS in, not shimmed.
 *
 * DELETE this file in Phase 6 once no template/generated markup references
 * any class below.
 */

/* ---- root font-size ----
 * The old assets/plugins/bootstrap/css/bootstrap.min.css (BS 3.3.6) carried
 * a hardcoded "html { font-size: 10px; }" reset. Nothing in this app's own
 * CSS (main.css/main-responsive.css) actually reads from it via rem - it
 * was inert there. But BS5 sizes many of its own components in rem
 * (.btn/.form-control font-size: 1rem, every spacing utility, etc.), which
 * resolve against the ROOT element's font-size regardless of what body's
 * own font-size is set to (this theme sets body to 14px, matching BS3's
 * hardcoded 14px buttons/inputs). Dropping the old bootstrap.min.css during
 * the BS5 swap silently left html at the browser default of 16px, so every
 * BS5 rem-sized element (buttons first and foremost) now renders ~14%
 * bigger than this theme was built for - e.g. it's what made the
 * FullCalendar toolbar's button group wide enough to wrap/overlap the page
 * title at viewport widths that fit it on one line before the migration.
 * Pin the root back to the theme's actual intended base size (14px, not
 * the old incidental 10px) so BS5's rem math lines up with body's own
 * font-size again. */
:root {
  font-size: 14px;
}

/* ---- default link underline ----
 * BS3's scaffolding.less shipped "a { text-decoration: none; }" as a base
 * reset, only underlining on ":hover"/":focus". BS5's Reboot deliberately
 * inverts this default for accessibility: its own "a" rule is
 * "text-decoration: underline" out of the box (see bootstrap.min.css).
 * This theme's main.css never carried its own blanket override - it just
 * relied on whichever Bootstrap version happened to be loaded - so every
 * plain "<a>" without a more specific per-component "text-decoration: none"
 * elsewhere in main.css (most are scoped, e.g. ".navbar-tools a") picked up
 * BS5's underline the moment the core CSS swapped: header toolbar links,
 * Dynamic Page workflow step labels, etc. Restore BS3's default verbatim. */
a {
  text-decoration: none;
}
a:hover,
a:focus {
  text-decoration: underline;
}
/* `a:hover`/`a:focus` above (element + pseudo-class) outranks BS5's own
 * `.btn { text-decoration: none }` (a single class, no :hover variant -
 * BS5 never needed one, since its Reboot doesn't underline on hover to
 * begin with). Any real <a class="btn ...">, like the header's Salvar/
 * Salvo button, was picking up an underline on hover/focus as a result.
 * BS3 shipped this exact counter-rule for the same reason; restore it. */
.btn:hover,
.btn:focus {
  text-decoration: none;
}
/* Same outranking problem as .btn above, for real BS5 `.nav-link` markup
 * (e.g. the header's notification/user/plan dropdown toggles and the
 * Dynamic Page tab nav, migrated to `.nav-link` in the "reduz dependência
 * do shim" lote 8, 2026-09-03): BS5's own `.nav-link { text-decoration:
 * none }` has lower specificity than `a:hover`/`a:focus` above, so it lost
 * that property back to an underline on hover/focus without this. */
.nav-link:hover,
.nav-link:focus {
  text-decoration: none;
}

/* ---- forms ---- */
/* BS5 only styles `.form-control:disabled` (grey background via
 * --bs-secondary-bg); it has no equivalent rule for `[readonly]`, so a
 * readonly field currently renders identically to a normal editable one
 * (white background from main.css's own `input[type="text"], ...` rule).
 * Give read-only fields the same grey look as disabled ones so the two are
 * visually indistinguishable, as requested. Scoped to input/textarea (not
 * a bare `.form-control:read-only`): CSS's `:read-only` isn't specific to
 * form fields - it matches ANY element that isn't an editable form control
 * or itself contenteditable. Tagify's `<tags class="tagify ... form-control">`
 * wrapper (the actual editable part is a nested `contenteditable` <span>,
 * not the <tags> element itself) matched a bare `.form-control:read-only`
 * and rendered grey/"disabled"-looking even though it's fully enabled. */
input.form-control:read-only,
textarea.form-control:read-only {
  background-color: var(--bs-secondary-bg);
  opacity: 1;
}
/* BS3 bolded and spaced out EVERY <label> by default (a bare element-level
 * rule, no class needed): `label { margin-bottom: 5px; font-weight: bold }`.
 * BS5 dropped that base rule entirely - it only styles the opt-in
 * `.form-label` class. Markup that never adopted `.form-label` (e.g. the
 * bootstrap-table add/edit row modal forms built by dynamic_page.js's
 * dialogForm builder, which emit plain `<label for="...">`) lost bold +
 * spacing entirely, and reads noticeably thinner/tighter than the rest of
 * the app. Restore BS3's base look for any bare label. Needs !important:
 * main.css's own `label { font-weight: normal }` (a leftover from this
 * theme's pre-Bootstrap-5 design) has the same bare selector specificity
 * and loads after this shim, so it would otherwise win by cascade order.
 * `.form-check-label` below is bumped back to normal weight so it still
 * wins against this where a different weight is intended. */
label {
  margin-bottom: 6px !important;
  font-weight: 700 !important;
}
/* The per-option text label next to a checkbox/radio (`.form-check-label`,
 * from the "reduz dependência do shim" checkbox-inline/radio-inline
 * rewrite) is meant to read at normal weight, same as its BS3
 * `.checkbox-inline`/`.radio-inline` predecessor did - only the FIELD's own
 * label (`.form-label`, e.g. "Sexo"/"Receber cópia dos e-mails...") should
 * be bold. Without this override it inherits the bare `label` rule above
 * and renders bold like a field label, which it isn't. */
.form-check-label {
  font-weight: 400 !important;
}
/* BS3's own .form-group had `margin-bottom: 15px` as a plain, unscoped base
 * rule - every `<div class="form-group">` got it, regardless of what kind of
 * form it sat in. BS5 dropped `.form-group` entirely (no styling at all,
 * confirmed absent from bootstrap.min.css), so any un-migrated form that
 * still wraps each field in a bare `<div class="form-group">` - which is
 * most of them, ~100 templates app-wide, not just forms using this app's own
 * "horizontal-form"/BS3's "form-horizontal" class - lost all spacing between
 * one field's input and the next field's label. E.g. the public customer
 * self-edition form (customer/public_customer_edition_form.html, on a
 * `<form class="horizontal-form">` - this app's own class, unrelated to
 * Bootstrap's "form-horizontal" - so the more specific rule below never
 * applied here either): every label rendered flush against the input right
 * above it. Restore the base rule so it applies everywhere by default;
 * bumped a bit past BS3's original 15px for more visual breathing room,
 * matching the more specific ".form-horizontal .form-group" rule below.
 *
 * `.form-horizontal` itself was removed from the Dynamic Page / Report /
 * modal framework's own generated `<form>` tags (DynamicPage.java,
 * ScreenComponentModalForm.java, ReportController.java,
 * ResourceController.java) in a 2026-08-31 follow-up - confirmed via live
 * before/after screenshots (DevTomcatLauncher + Puppeteer) that it was pure
 * dead weight there: none of those forms' own field markup uses a bare
 * `.form-group` with `col-sm-*` siblings the way this rule expects, so
 * removing the class changed nothing visually.
 *
 * The `.form-horizontal .form-group { display: flex; ... }` rule that used
 * to sit here was removed in the "reduz dependência do shim" lote 10
 * (2026-09-03): the ~14 hand-authored templates that DID use the classic
 * BS3 shape (`<label class="col-sm-3">` + `<div class="col-sm-7">` as
 * siblings inside one `.form-group`, e.g. the SmartWizard forms - bulk
 * email/SMS/WhatsApp marketing, create_company.html, company_change_plan/
 * company_hire_plan.html, change_user_company.html) had `row` added
 * directly to each of the ~128 `.form-group` divs that actually contain a
 * `col-*` direct child (`class="form-group row"`), so they now get their
 * flex/grid behavior from BS5's own native `.row` class instead of this
 * shim rule keying off the `.form-horizontal` ancestor. The other ~98
 * `.form-group` occurrences in those same 14 files are plain single-column
 * fields with no `col-*` child (or already wrap their own self-contained
 * inner `.row`) and were deliberately left untouched - adding `row` to a
 * form-group with no columns to lay out side-by-side would only add an
 * unnecessary negative-margin outdent. `.form-horizontal` itself was left
 * on these forms' `<form>` tags as an inert marker (no CSS keys off it
 * anymore) rather than stripped, to keep the diff to just the actual
 * layout fix. */
.form-group {
  margin-bottom: 20px;
}
/* intl-tel-input replaces the plain <input> with a <div class="iti"> wrapper
 * at runtime. BS5's .input-group only grants flex-item sizing to
 * .form-control/.form-select/.form-floating children, so .iti falls back to
 * its own vendor CSS `width: 100%`, which claims the whole flex row and
 * pushes the addon spans onto separate lines. intlTelInput.css itself pins
 * `.iti { width: 100% !important; }` (see its "FIX DEFINITIVO" block), so
 * this override must also be !important and more specific to win. */
.input-group > .iti {
  flex: 1 1 auto !important;
  width: 1% !important;
  min-width: 0 !important;
}
/* select2 replaces the <select> with a sibling <span class="select2
 * select2-container select2-container--bootstrap"> that holds the visible
 * widget (the original <select> stays in the DOM but hidden/off-screen via
 * .select2-hidden-accessible). select2-bootstrap.css ships
 * `.input-group > .select2-container--bootstrap { display: table;
 * width: 100% }`, written for BS3's table-based .input-group — it fights
 * BS5's flex .input-group and forces this span, plus the addon spans, onto
 * separate lines. It also overrides select2's own inline `style="width:
 * ...px"`. Force BS5's .form-control flex-item sizing instead. */
.input-group > .select2-container {
  display: block !important;
  flex: 1 1 auto !important;
  width: 1% !important;
  min-width: 0 !important;
}
/* CKEditor 5 replaces the plain <textarea class="ckeditor"> with a sibling
 * <div class="ck ck-editor ..."> holding the toolbar + editable area (the
 * original <textarea> stays in the DOM, hidden via display:none). Same
 * story as .iti/.select2-container above: BS5's .input-group only grants
 * flex-item sizing to .form-control/.form-select/.form-floating children,
 * so this div falls back to its default flex-item sizing, sized by its
 * (wide) toolbar content instead of shrinking to share the row - pushing
 * the help-icon addon onto its own line. */
.input-group > .ck.ck-editor {
  flex: 1 1 auto;
  width: 1%;
  min-width: 0;
}
/* jQuery Validate's shared defaults (initValidator in dynamic_page.js) were
 * migrated to BS5-native `.is-invalid`/`.invalid-feedback` - but only there.
 * The other ~15 form validators in the app (login.js, form-wizard.js,
 * event/*_validator.js, customer_validator.js, etc.) still configure
 * `errorClass: 'help-block'`, `errorElement: 'em'`,
 * `errorPlacement: error.insertAfter(element)` themselves, inserting the
 * validation message as a plain <em class="help-block"> right after the
 * <input>/<select>, as just another flex child of .input-group, and marking
 * the group with BS3's .has-error/.has-success validation-state classes.
 * BS5 dropped both the classes and any styling for them, so the message
 * just sits on the same flex row as the input instead of wrapping onto its
 * own line below it, and never turns red. `flex: 0 0 100%` forces it to
 * claim the full row width on its own, which - combined with
 * .input-group's flex-wrap: wrap - pushes it onto a new line. For a
 * select2 field, insertAfter(element) inserts the <em> right after the
 * original (now hidden) <select>, which puts it BEFORE the visible
 * select2 container span in DOM order - flex lays out children in DOM
 * order, so without `order` the message would render between the help-icon
 * addon and the select2 widget instead of below everything. `order` pushes
 * it to the end of the row regardless of where it landed in the DOM.
 * Keep this block until all ~15 remaining validators are migrated too. */
.input-group > .help-block {
  order: 10;
  flex: 0 0 100%;
  margin-top: 5px;
  margin-bottom: 0;
}
.input-group.has-error > .help-block {
  color: var(--app-danger-text);
}
/* dynamic_page.js's migrated initValidator() inserts `.invalid-feedback`
 * as a sibling of the `.iti` (intl-tel-input) wrapper div, not of the real
 * <input> inside it (which is what actually gets `.is-invalid`) - same
 * placement problem the checkbox case has (error inserted after the
 * <label> that wraps the input, not after the input itself). BS5's own
 * `.is-invalid ~ .invalid-feedback` CSS requires the two to be direct
 * siblings, which they aren't in either case, so relying on it would leave
 * the message hidden. Force it visible unconditionally instead - same
 * approach as `.input-group > .help-block` above - rather than chase every
 * markup shape that can appear inside .input-group. */
.input-group > .invalid-feedback {
  order: 10;
  flex: 0 0 100%;
  display: block;
  margin-top: 5px;
  margin-bottom: 0;
}
/* main.css's own `span.input-icon` (a monetary/decorated-input wrapper
 * around <input> + a trailing fa-* icon, e.g. the $ sign on currency
 * fields) is, like .iti/.select2-container/.ck-editor above, just a plain
 * flex child of .input-group - not a .form-control/.form-select/
 * .form-floating - so BS5 never grants it flex-item sizing. It falls back
 * to default flex sizing next to the help-icon addon and wraps onto its
 * own line instead of sharing the row. */
.input-group > .input-icon {
  flex: 1 1 auto;
  width: 1%;
  min-width: 0;
}
/* select2-bootstrap.css hardcodes `.select2-selection--single { height: 34px;
 * line-height: 1.42857143; padding: 6px 24px 6px 12px }`, tuned to match a
 * stock Bootstrap .form-control's height. But this app's own main.css has an
 * older, higher-specificity rule - `input[type="text"], input[type="tel"],
 * ... { padding: 5px 4px; line-height: 1.2; border: 1px solid #D5D5D5 }`
 * (an `input[type=...]` attribute selector outranks .form-control's class
 * selector) - that makes every real text input render at ~29px tall, not
 * 34px. Select2's fixed 34px box never adapted to that, so a select2 field
 * sits visibly taller than every plain input/select next to it in the same
 * row. Match select2's box to the same padding/line-height math instead of
 * the stale fixed height. select2-bootstrap.css loads AFTER this shim (see
 * head.html) and both rules share the same selector specificity, so this
 * needs !important to actually win the cascade. */
.select2-container--bootstrap .select2-selection--single {
  height: auto !important;
  padding: 5px 24px 5px 12px !important;
  line-height: 1.2 !important;
}
/* The bootstrap-table add/edit row modal form builder (dynamic_page.js,
 * inputType == 'select' branch) unconditionally hardcodes
 * `style="width:100%"` on every generated <select>, whether or not that
 * column actually turns it into a select2 widget. For a plain select (no
 * .select2 class - select2 was never initialized on it), that inline style
 * beats BS5's own un-!important `.input-group > .form-control { width: 1% }`
 * rule, so the select claims the whole row's width and the help-icon addon
 * gets pushed onto its own line. Selects that DO become select2 are exempt
 * ((:not(.select2)) - their original <select> is hidden via
 * .select2-hidden-accessible regardless, so this never applied to them in
 * the first place.
 * Also: main.css's `input[type="text"], input[type="tel"], ...{ padding:
 * 5px 4px; line-height: 1.2 }` (which shrinks every plain <input> to ~29px
 * tall, see the .select2-selection--single fix above) is an input[type=...]
 * attribute selector, so it never matches a bare <select> at all - a plain
 * select falls back fully to BS5's own .form-control sizing (~34px) and
 * ends up visibly taller than the input fields right next to it. Give it
 * the same padding/line-height so it matches. */
.input-group > select.form-control:not(.select2) {
  width: 1% !important;
  flex: 1 1 auto !important;
  min-width: 0 !important;
  padding: 5px 4px !important;
  line-height: 1.2 !important;
}
/* Tagify replaces the plain <input> with a <tags class="tagify form-control">
 * wrapper. tagify.css (loaded after this shim, see head.html) gives it
 * `padding: 0` and sizes it purely from its inner .tagify__input span,
 * which carries its own `margin: 5px` + line-height: 1.1 - a taller,
 * margin-based box model than this app's real inputs (main.css's
 * `input[type="text"]... { padding: 5px 4px; line-height: 1.2 }`, ~29px
 * tall). Match that same padding/line-height on the tagify box itself and
 * zero out the inner span's own margin so the two stay the same height. */
.input-group tags.tagify.form-control {
  padding: 5px 4px !important;
  line-height: 1.2 !important;
}
.input-group tags.tagify.form-control .tagify__input {
  margin: 0 !important;
  padding: 0 !important;
  line-height: inherit !important;
}
/* The fix above only matches height while the field is EMPTY (only the
 * .tagify__input placeholder is on screen). The moment a real tag exists,
 * tagify.css's `.tagify__tag { margin: 5px 0 5px 5px }` +
 * `.tagify__tag > div { padding: .3em .5em }` kick in - a much taller,
 * margin/em-padding-heavy box model than the compact `5px 4px` line above -
 * so the field visibly jumps taller the instant the FIRST tag is added
 * (confirmed live: 28.8px -> 47.2px for one short tag, no wrapping
 * involved), not just once tags wrap onto a second line. Shrink the tag
 * pill's own margin/padding to bring a one-line-of-tags row back in line
 * with a one-line-of-placeholder row (28.8px -> 34.8px instead - the
 * remaining few px is the pill's own background/shadow, expected and
 * harmless). Multi-line growth once tags actually wrap is left alone -
 * that's tagify doing its job, not a bug. */
.input-group tags.tagify.form-control .tagify__tag {
  margin: 2px 4px 2px 0 !important;
}
.input-group tags.tagify.form-control .tagify__tag > div {
  padding: 1px 6px !important;
}
/* ---- buttons ----
 * .btn-default removed here in the "reduz dependência do shim" lote 6
 * (2026-08-31). Live usage turned out to span three different roles across
 * both static views and generated Java/JS markup - not the isolated case
 * it first looked like:
 *  - static password-visibility-toggle icon buttons (company/create_account/
 *    create_account.html + create_account_trial.html);
 *  - assets/js/global/global.js's showConfirm() Cancel/Confirm pair (used
 *    app-wide, called from 21 feature scripts across ~71 pages) and
 *    assets/js/settings/food_menu_report.js's sibling modal;
 *  - assets/js/dynamicpage/dynamic_page.js's x-editable inline-edit Cancel
 *    button template (paired with .btn-primary's checkmark submit button);
 *  - Java-generated row-action icons on EVERY Report grid (edit/delete/
 *    show-details/custom ReportButton, all in services/impl/
 *    ReportServiceImpl.java), the Cancel button on EVERY Dynamic Page modal
 *    form (domain/dynamicpage/screen/component/ScreenComponentModalForm.java),
 *    a resource-removal button in controller/event/EventController.java,
 *    and the GenAI-suggestion button on text inputs (ScreenComponentInputText
 *    /ScreenComponentInputTextArea.java - though that one's `.btn-ai-inline`
 *    class already fully overrides color/background/border in main.css, so
 *    its own base class was cosmetically irrelevant either way).
 * All were renamed uniformly to BS5's `.btn-secondary` (solid gray, the
 * idiomatic BS5 pairing for `.btn-primary` in modal/dialog footers) for a
 * single consistent neutral-button convention, rather than splitting by
 * context (e.g. `.btn-outline-secondary` for the input-group password
 * button, which would arguably fit that one spot slightly better but adds a
 * second neutral-button style to the app).
 * As with lote 5's `.label-*` cleanup, a large share of the raw `grep -r
 * btn-default` hit count (85 of 87 files) was NOT real usage - it was the
 * same dead "Panel Configuration" modal Close button described in the
 * `.label` comment below, confirmed unreachable app-wide (its trigger only
 * exists in home*.html's own dead prototype body, itself shadowed by
 * `th:include="templates/homecontent :: pageContent"`, and the real
 * homecontent*.html fragments never reference it). Left untouched for the
 * same reason as that dead content generally: renaming classes inside
 * unreachable markup has no visual effect. */
/* BS5 renamed .close -> .btn-close (different markup: no inner <span>×</span>,
 * styled via a background-image X icon). Most of this app's own modal/alert
 * dismiss buttons were converted to real `.btn-close` markup in the "reduz
 * dependência do shim" lote 4 (2026-08-31) - grep the codebase before
 * assuming any given screen still needs this rule. What's left relying on
 * the BS3 shape (`<button class="close">×</button>` or
 * `<button class="close">…<span>&times;</span></button>`):
 *  - ecommerce/ecommerce_company_home.html's search-popup close icon - a
 *    `<div class="close">` wrapping a custom Font Awesome-style span, not a
 *    Bootstrap dismiss button at all (coincidental class name collision);
 *  - assets/js/ecommerce/main.js's contact-form success/error message -
 *    generates `<a class="close"><i class="icon icon-close2"></i></a>`, same
 *    coincidental collision with the ecommerce theme's own icon classes, not
 *    a Bootstrap dismiss button (and has no click handler wired to it at all
 *    in this app - the icon shows but clicking it does nothing beyond the
 *    bare `href="#"` jump, a pre-existing vendored-theme leftover, not
 *    something introduced by this migration).
 * (assets/js/ui-modals.js - the unreferenced vendored-theme demo leftover
 * that used to be listed here too - was deleted outright, 2026-09-06:
 * `grep -rl "ui-modals" src/main/webapp` found no `<script src>` or any
 * other reference to it anywhere, confirming it was never wired into any
 * real page.)
 * (assets/js/settings/food_menu_report.js, assets/js/global/global.js, and
 * assets/js/dynamicpage/dynamic_page.js used to belong on this list too -
 * their JS-generated modal/alert dismiss buttons paired `class='close'` with
 * the OLD `data-dismiss` attribute, missing BS5's required `bs-` prefix, so
 * the buttons were both unstyled AND non-functional. Fixed directly - both
 * the class and the attribute - in the same follow-up session that found it,
 * not shimmed.)
 * Restore the BS3 look for all of the above, and additionally fix
 * modal-header's flex ordering via `order` + auto margin for the ones that
 * sit inside one (BS5's own .btn-close uses the same trick).
 * Scoped to :not(.btn-close): newer Bootbox (6.x) emits BOTH classes on the
 * same button (`class="close btn-close"`) for its own back-compat. Since
 * .close and .btn-close have equal specificity and this shim loads after
 * bootstrap.min.css, our `background: transparent` here would otherwise
 * win the cascade and blank out .btn-close's real background-image X icon,
 * leaving an empty, invisible button - exactly the "close button
 * disappeared" case. Buttons that already carry BS5's own .btn-close are
 * left alone to use its native styling untouched. */
.close:not(.btn-close) {
  float: right;
  padding: 0;
  background: transparent;
  border: 0;
  -webkit-appearance: none;
  font-size: 21px;
  font-weight: 700;
  line-height: 1;
  color: #000;
  text-shadow: 0 1px 0 #fff;
  opacity: 0.5;
  cursor: pointer;
}
.close:not(.btn-close):hover,
.close:not(.btn-close):focus {
  color: #000;
  text-decoration: none;
  opacity: 0.75;
}
.modal-header .close:not(.btn-close) {
  order: 2;
  margin-left: auto;
  float: none;
}

/* ---- .label base shape (BS3's small colored tag, -> .badge in BS5) ----
 * The 5 semantic color modifiers (.label-primary/success/info/warning/danger
 * + .label-default) were removed here in the "reduz dependência do shim"
 * lote 5 (2026-08-31): their only genuinely live usage app-wide (2
 * occurrences, both .label-primary, in templates/head.html's notification
 * bell/cart icon badges) was converted to native BS5 `badge text-bg-primary`
 * markup, and main.css's own `.navbar-tools .dropdown-menu.notifications
 * li > a > .badge` selector was updated to match. `.label-default`'s
 * removal is a pure no-op: main.css already carries its own
 * `.label-default, .badge-default { background-color: #3A87AD !important }`
 * (next to its .label-green/.label-orange/etc siblings below), which was
 * already winning the cascade over this shim's non-!important version.
 * This base `.label` rule itself MUST stay - main.css's own custom calendar
 * category colors (.label-green/.label-orange/.label-purple/.label-yellow/
 * .label-teal/.label-beige, used live by home.html's FullCalendar event
 * coloring in assets/js/index.js) are color-only (`background-color` +
 * `border-color`, both !important) and depend entirely on this rule for
 * their actual shape/padding/sizing.
 * Everything that still shows up in a `grep -r label-danger` / `label-
 * success` / etc across src/main/webapp/WEB-INF/views is dead: ~85 view
 * files carry a leftover static "todo dropdown" demo widget (hardcoded
 * "Meeting"/"Hire developers"/etc list items, part of the vendored
 * Clip-One admin theme's prototype markup) inside a
 * `<... th:include="templates/head :: headerTools">` host tag - Thymeleaf's
 * th:include discards that static content at render time and injects the
 * real headerTools fragment instead, so none of it ever reaches a browser.
 * Left untouched: migrating class names inside genuinely unreachable markup
 * has no visual effect and isn't worth the diff noise; deleting that dead
 * prototype content outright would be a separate, unrelated cleanup. */
.label {
  display: inline-block;
  padding: 0.25em 0.6em;
  font-size: 75%;
  font-weight: 700;
  line-height: 1;
  color: #fff;
  text-align: center;
  white-space: nowrap;
  vertical-align: baseline;
  border-radius: 0.25rem;
}

/* ---- dropdown divider: `<li class="divider">` -> `<li><hr
 * class="dropdown-divider"></li>` removed here in the "reduz dependência do
 * shim" lote 7 (2026-09-03). The only genuinely live occurrence app-wide was
 * templates/head.html's user-profile dropdown fragment (now migrated); the
 * other ~9 grep hits (home*.html, generic_application_message*.html,
 * kpi_page.html, generic_controller_error.html,
 * product_specification_edit.html, new_event_select_event_category.html)
 * all sit inside a `<div class="navbar-tools" th:include="templates/head ::
 * headerTools">` container - Thymeleaf discards that static content and
 * injects the real fragment instead, so those copies never reach a browser
 * (same dead-markup pattern as the lote 5 .label-* investigation). ---- */

/* ---- navbar > .container no longer fills the navbar's width ----
 * BS3's .navbar was a plain block box, so the theme's own
 * ".container { width: auto !important }" (main.css) filled 100% of it as
 * intended (a deliberate full-width header for this admin theme, not an
 * accidental override). BS5 made .navbar "display: flex" AND added its own
 * rule making ".navbar > .container" also "display: flex" - which turns
 * that .container into a flex ITEM of .navbar. As a flex item, "width:
 * auto" no longer means "fill available width", it means "shrink to fit
 * content", so .container collapses to just wide enough for
 * .navbar-logo + .navbar-tools and then gets centered in the leftover
 * space by its own (otherwise-inert) "margin: 0 auto" - which is exactly
 * why the logo/menu/user-icons end up bunched in the middle of the screen
 * instead of pinned to the left/right edges. Force it back to filling the
 * flex line so .container's own "justify-content: space-between" (also
 * from BS5) can push .navbar-logo left and .navbar-tools right again. */
.navbar > .container {
  flex: 1 1 auto;
}

/* ---- .navbar-brand needs float:left restored ----
 * BS5's own ".navbar-brand" rule sets no "display" at all - it relies on the
 * brand being a DIRECT child of the flex-container ".navbar" itself, where
 * flex auto-blockifies any inline child. Here it's nested two levels down
 * (inside the sidebar-toggle header partial, itself "display: block", not a
 * flex context), so it never gets blockified and stays at the browser
 * default for an "<a>": "display: inline". An inline box wrapping this
 * app's "display: block" logo <img> (plus its own vertical padding) lays
 * out incorrectly - Chrome measured it at ~103px tall with a -5px top
 * offset for a 45px-tall image, which is what stretched the whole header
 * to ~98px instead of ~47px. BS3 never hit this because "float: left" on
 * ".navbar-brand" blockifies it directly (floats always compute to
 * "display: block"), independent of any flex context. */
.navbar-brand {
  float: left;
}

/* ---- .navbar-collapse / .navbar-header / .navbar-toggle: renamed, not shimmed ----
 * These three borrowed-from-Bootstrap class names drove the persistent left
 * sidebar (built on ".navbar-collapse") and its mobile toggle button
 * (".navbar-header" / ".navbar-toggle") - a genuinely different UI pattern
 * (fixed top header + a separate, always-present left nav) than Bootstrap's
 * own navbar-with-nested-collapse component, which is why BS5's native
 * ".navbar-expand-*" support could never apply to them: it requires the
 * collapse target to be a DOM descendant of the navbar, and this app's
 * sidebar lives in a sibling ".main-container > .navbar-content" tree
 * entirely outside the fixed header. Making the native pattern work would
 * require moving the sidebar to be a descendant of the navbar - a
 * page-layout restructure across every page, not a class rename, and not
 * worth it for a layout that already works and has no real relationship to
 * Bootstrap's mobile-hamburger navbar to begin with.
 *
 * Renamed to ".sidebar-collapse" / ".navbar-logo" / ".navbar-menu-toggle"
 * (2026-09-05) and their styling moved to main.css, since it was never
 * migration debt in the first place - just this app's own layout classes
 * that happened to borrow Bootstrap's naming. See main.css for the rules. */

/* ---- .nav-tabs / .nav with bare <li>/<a> (BS3 shape) ----
 * Removed here in the "reduz dependência do shim" lote 8 (2026-09-03).
 * BS3's own nav.less gave "display: block; padding: 10px 15px" to EVERY
 * `.nav > li > a` as base styling; BS5 moved that base styling onto an
 * explicit `.nav-link` class instead of styling bare `<a>` tags. Two
 * consumers were still emitting the un-migrated bare `<li><a>` shape:
 *  - the Dynamic Page ScreenComponentTab tab nav, plus ~18 hand-authored
 *    tab-nav templates sharing the same `.tab-blue`/`.tab-teal`/`.tab-bricky`/
 *    `.tab-green`/`.tab-purple` skin classes in main.css - all migrated to
 *    `.nav-item`/`.nav-link` in this lote, with `active` moved onto the
 *    `<a>` (also still added to the first tab's `<li>` at initial render,
 *    for markup clarity - not load-bearing for CSS anymore). BS5's native
 *    Tab.js only ever toggles `.active` on the `[data-bs-toggle="tab"]`
 *    element itself, never on the parent `<li>` - `util/
 *    bootstrap5-jquery-modal-shim.js` already has a `shown.bs.tab` handler
 *    from an earlier migration pass that manually keeps `<li class="active">`
 *    in sync for exactly that reason (see its own comment). main.css's
 *    color-skin selectors no longer need that JS-side sync at all now:
 *    ~110 `li.active > a` / `li:not(.active) > a` selectors (base
 *    `.nav-tabs` plus all 5 skin colors, including the
 *    `tabs-left`/`tabs-right`/`tabs-below`/`.tab-padding` orientation
 *    variants and `.panel-tabs .nav-tabs`) were mechanically rewritten to
 *    `li > a.active` / `li > a:not(.active)` to key off the `<a>` that
 *    Tab.js actually maintains. The JS shim itself was left in place
 *    (still harmless/idempotent, and deleting it wasn't part of this
 *    lote's scope - it also covers `$(...).tab('show')` call sites
 *    unrelated to this CSS). The dropdown-in-tab
 *    sub-rules (`li.dropdown.open.active`, `li.open .dropdown-toggle`, the
 *    bare descendant `.tab-X .active > a`) were left untouched - dead
 *    weight for a sub-feature no tab nav in this app actually uses;
 *    functionally unreachable either way, so unrelated to the migration.
 *  - templates/head.html's `<ul class="nav navbar-right">` (notification
 *    bell / user menu / plan-info dropdown toggles, plus the JS-generated
 *    "Salvar" button in dynamic_page.js's setSaveButtonState()) - given
 *    `.nav-link` alongside their existing `.dropdown-toggle` class. BS5's
 *    `.nav-link` doesn't supply `position: relative` (unlike this shim
 *    rule did), which the notification/plan badges need for their
 *    `position: absolute` counter - added directly to
 *    `.navbar-tools > ul > li > a` in main.css instead. */

/* ---- .breadcrumb <li> separators: no shim entry needed anymore ----
 * ControllerInterceptor.generateBreadCrumbHtml() (Java) now emits
 * `.breadcrumb-item` on every `<li>` it builds, so BS5's own native
 * `.breadcrumb-item + .breadcrumb-item::before` separator rule (in
 * bootstrap.min.css) applies with no shim help. Used to restore BS3's
 * separator CSS verbatim, scoped to bare `<li>` without that class, for
 * when the Java side still emitted plain `<li>`. */
/* BS3's own `.breadcrumb` had `background-color: #f5f5f5` as part of its
 * base component style. BS5's `.breadcrumb` sets `background-color:
 * var(--bs-breadcrumb-bg)`, and that variable's default value is blank
 * (transparent) - a deliberate BS5 design change, not something this app's
 * own main.css ever overrode itself (its `.breadcrumb` rule only touches
 * margin/padding/border/height). Losing that background made the whole bar
 * go from light grey to white. Restore BS3's default. */
.breadcrumb {
  background-color: var(--app-surface-bg);
}
/* BS3's own `.navbar` shipped `border: 1px solid transparent` as a base
 * component rule. This theme's main.css explicitly zeroes out the
 * top/left/right sides (`.navbar { border-right: none; border-left: none;
 * border-top: none; }`) but leaves border-BOTTOM alone, relying on that
 * BS3 base to still supply its width/style - only the *color* is themed
 * separately (`.navbar-inverse { border-color: #C8C7CC }` in
 * theme_light.css, and equivalents in the other theme_*.css files). BS5's
 * `.navbar` has no border property at all (see bootstrap.min.css), so
 * with no base width/style left to color, the bottom border - the line
 * dividing the header from the breadcrumb bar below it - disappeared
 * entirely. Restore just the missing width/style; the theme's own
 * border-color rules still apply on top of this since they load after. */
.navbar {
  border-bottom: 1px solid;
}

/* ---- FullCalendar (bootstrap theme) month-grid vertical borders ----
 * FullCalendar's own bootstrap theme connector (fullcalendar-4.3.1's
 * packages/bootstrap/main.js, active because dynamic_page.js initializes
 * the calendar with themeSystem: 'bootstrap') deliberately assigns bare
 * "table-bordered" - never "table table-bordered" - to the month grid's
 * table/row/cell elements, banking on that class being self-contained. It
 * was: BS3's own ".table-bordered { border: 1px solid #ddd }" needed
 * nothing else. BS5's ".table-bordered" only sets border-WIDTH
 * (".table-bordered > :not(caption) > *", "> * > *" in bootstrap.min.css);
 * the border-COLOR comes from a separate ".table > :not(caption) > * > *"
 * rule scoped to the ".table" class itself, which FullCalendar never adds.
 * Cells were left with a border width but no color, i.e. invisible - only
 * the day rows' own ".fc-row" divider (a plain "border-style: solid" on a
 * wrapper div, unrelated to any table class) kept the horizontal week
 * separators visible, which is why only the VERTICAL lines between days
 * disappeared. Restore the color FullCalendar's own unthemed fallback uses
 * (".fc-unthemed td { border-color: #ddd }", core/main.css), scoped to
 * ".fc-bootstrap" (the widget class FC itself adds) so it never leaks into
 * real ".table.table-bordered" usage elsewhere in the app. */
.fc-bootstrap .table-bordered > :not(caption) > *,
.fc-bootstrap .table-bordered > :not(caption) > * > * {
  border-color: #ddd;
}

/* ---- .fade.in -> .fade.show: no shim entry needed anymore ----
 * Removed here in the "reduz dependência do shim" lote 11 (2026-09-03).
 * BS3's own transitions.less: ".fade { opacity: 0 }" plus ".fade.in {
 * opacity: 1 }" - two independent rules. BS5 rewrote it as a single
 * selector, ".fade:not(.show) { opacity: 0 }", dropping ".in" in favor of
 * ".show". The only two consumers hardcoding the "already visible" state
 * directly in server-rendered HTML (troubleticket/documentation_home.html
 * and videos_home.html's "<div class='alert ... fade in'>" help cards,
 * meant to render visible by default with no JS involved) were renamed
 * from ".in" to ".show" directly - BS5's own selector now matches them
 * with no shim help. */

/* ---- Systematic audit pass (2026-08-30) ----
 * Everything below was found by diffing every class BS3's bootstrap.min.css
 * defines against what BS5's bootstrap.min.css and this shim already cover,
 * then keeping only the ones actually referenced somewhere in this app's own
 * views/Java/JS (not vendor/plugin code). Each entry below is a confirmed,
 * currently-broken usage - not a preemptive/speculative restoration. Classes
 * that came up in that diff but turned out NOT to need a shim entry, so
 * don't re-add them without new evidence:
 *  - .caret: every "<span class='caret'>" in this app sits directly next to
 *    a ".dropdown-toggle" (e.g. home.html's per-widget gear-icon dropdowns).
 *    BS5 already draws its own caret via ".dropdown-toggle::after" - see the
 *    header Salvar/Salvo button fix earlier in this file's history. Styling
 *    the old BS3 ".caret" shape here would draw a second, redundant arrow
 *    next to BS5's own.
 *  - .open: this app's own main.css (ul.main-navigation-menu li.open,
 *    .tab-*  > li.open, #style_selector > .open) and main.js (manual
 *    addClass/removeClass('open')) already own this class end-to-end for
 *    every place it's used - none of it depends on Bootstrap's own
 *    dropdown component (which BS5 renamed to ".show").
 *  - .page-header, .checkbox, .radio (block-level, not *-inline): main.css
 *    already carries its own rules for these independent of Bootstrap.
 *  - .sr-only: still fully defined by font-awesome.min.css (loaded on every
 *    page), which ships the identical clip-based hidden-but-accessible rule
 *    Bootstrap used to provide.
 *  - .navbar-right at desktop width: empirically confirmed still visually
 *    correct (right-aligned) via live screenshots - ".navbar > .container"
 *    being "justify-content: space-between" (see below in this file) already
 *    pins the whole ".navbar-tools" block right, making the child list's own
 *    missing float redundant. Not restored to avoid a shim entry with no
 *    observed effect; revisit if a narrower ".navbar-tools" layout surfaces
 *    where this stops being true. */


/* ---- .icon-bar / .navbar-default (BS3 navbar internals, dropped in BS5) ----
 * Removed here in the "reduz dependência do shim" lote 9 (2026-09-03).
 * Was used only on company/create_account/create_account.html and
 * create_account_trial.html's standalone top nav (not the main app shell,
 * which uses BS5's native ".fixed-top" directly). Unlike the main shell's
 * toggler (renamed to ".navbar-menu-toggle" and moved to main.css - ~90
 * files, bigger blast radius, see above), this standalone nav's toggler
 * had no other markup depending on the old BS3 shape, so it was switched
 * to BS5's native `.navbar-toggler` +
 * `.navbar-toggler-icon` (SVG background-image, no custom CSS needed) and
 * `.navbar-default` was replaced with the native utility classes
 * `bg-body-tertiary border-bottom` (#f8f9fa/#dee2e6 - close enough to the
 * old #f8f8f8/#e7e7e7 for a one-off signup-page navbar that nothing else
 * needs to color-match). */

/* ---- .panel-group / .panel-collapse: no shim entry needed ----
 * troubleticket/faq_home.html's FAQ accordion keeps ".panel-group" in its
 * markup on purpose (not a leftover) - main.css's own
 * ".accordion-custom.panel-group .card-header .accordion-toggle >
 * .icon-arrow" rule requires it alongside ".accordion-custom" for the
 * expand-state arrow icon's size/opacity. The rest of that same block
 * already uses real BS5 markup - .card/.card-header/.card-body (both exist
 * natively in BS5). BS3's own ".panel-group{margin-bottom:20px}" (the only
 * thing this shim used to restore here) had no other purpose, so it was
 * dropped without replacing the class in markup - a 20px gap below the
 * accordion is not worth carrying shim weight for.
 * ".panel-collapse" needs no shim entry either - it carried zero CSS in
 * BS3 too, purely a JS/semantic hook - but the FAQ markup's initially-open
 * panel used BS3's "collapse in" state class, which BS5 doesn't recognize
 * (".collapse:not(.show){display:none}" - only ".show" means expanded),
 * so the first FAQ answer rendered collapsed on load; fixed directly in
 * faq_home.html to "collapse show". ---- */
