/* VTM Custom Styles — supplements Bootstrap 5 */

/* ============================================================
   VTM Brand Color Variables
   Source: PHP custom.css + vtm-theme.css
   ============================================================ */
:root {
  --vtm-dark-blue: #024C8B;
  --vtm-link-blue: #005D9E;
  --vtm-hover-blue: #0f85e6;
  --vtm-light-bg: #f5f5f5;
  --vtm-required-red: #d00;
  --vtm-green: #8DA844;

  /* VTM3 tone (2026-07-08 owner request): retire Bootstrap 5's neon
     defaults in favor of VTM3's palette. Remapping the RGB vars retones
     every derived utility (.text-primary/.bg-primary/.border-primary,
     .text-info, subtle backgrounds) app-wide without touching markup.
     --bs-info matches BS3's text-info (#31708f — the slate VTM3 used),
     NOT BS5's cyan (#0dcaf0), which is unreadable on white. */
  --bs-primary: var(--vtm-dark-blue);
  --bs-primary-rgb: 2, 76, 139;
  /* Info BACKGROUNDS (badges etc.) use BS3's label-info blue — a light,
     friendly blue (#5bc0de) instead of BS5 neon cyan or a heavy slate.
     Info TEXT stays BS3's slate via the explicit .text-info rule below
     (pale text would be unreadable). */
  --bs-info: #5bc0de;
  --bs-info-rgb: 91, 192, 222;
}

/* Belt-and-braces for the two utilities above: BS5 compiles them with
   !important, so restate at equal strength in case a component reads the
   compiled literal instead of the var. */
.text-primary { color: var(--vtm-dark-blue) !important; }
.text-info { color: #31708f !important; }

/* .btn-info — BS5 compiles the button's own --bs-btn-* locals from the SCSS
   $info literal (neon cyan #0dcaf0); the :root --bs-info remap above never
   reaches it. Restate BS3's btn-info palette (VTM3's Preview buttons). */
.btn-info {
  --bs-btn-color: #fff;
  --bs-btn-bg: #5bc0de;
  --bs-btn-border-color: #46b8da;
  --bs-btn-hover-color: #fff;
  --bs-btn-hover-bg: #31b0d5;
  --bs-btn-hover-border-color: #269abc;
  --bs-btn-focus-shadow-rgb: 91, 192, 222;
  --bs-btn-active-color: #fff;
  --bs-btn-active-bg: #31b0d5;
  --bs-btn-active-border-color: #269abc;
  --bs-btn-disabled-color: #fff;
  --bs-btn-disabled-bg: #5bc0de;
  --bs-btn-disabled-border-color: #46b8da;
}

/* Humanized-schedule "Months Skipped" block (utils/schedule.py). VTM3
   emitted class="bg-info", which in BOOTSTRAP 3 was the PALE #d9edf7
   info panel with slate text — not a solid fill. Restore that exact
   pairing; !important beats BS5's .bg-info background utility. */
.schedule-skip-note {
  background-color: #d9edf7 !important;
  color: #31708f;
}

/* Checked radios/checkboxes — BS5 hardcodes #0d6efd in the compiled CSS
   (not var-driven), so restate in brand navy (VTM3's fuelux radio-custom
   rendered in the theme blue, never bright #0d6efd). */
.form-check-input:checked {
  background-color: var(--vtm-dark-blue);
  border-color: var(--vtm-dark-blue);
}
.form-check-input:focus {
  border-color: var(--vtm-hover-blue);
  box-shadow: 0 0 0 0.25rem rgba(2, 76, 139, 0.15);
}

/* ============================================================
   Main content container — base.html uses ``.container-fluid`` so
   content fills the viewport on typical laptops/desktops. On
   ultrawide monitors (≥1800px) cap the content width and centre
   it so lines of text don't stretch into unreadable territory.
   ============================================================ */
@media (min-width: 1400px) {
  body > .container-fluid {
    max-width: 1200px;
    margin-left: auto;
    margin-right: auto;
  }
}

/* ============================================================
   Sticky footer — short pages (login, "no results" lists) used
   to leave the footer floating mid-viewport. Make ``body`` a
   flex column that fills the screen, the main content region
   ``flex: 1`` so it grows to absorb remaining space, and pin
   the footer at the bottom. Fixed/absolute elements (loading
   bar, back-to-top, modals) sit outside flex flow and aren't
   affected.
   ============================================================ */
body {
  min-height: 100vh;
  display: flex;
  flex-direction: column;
}
body > .container-fluid,
body > .container {
  flex: 1 0 auto;
}
body > .footer {
  flex-shrink: 0;
}

/* ============================================================
   Link Colors — match PHP custom.css lines 23-31
   ============================================================ */
a { color: var(--vtm-link-blue); }
a:hover { color: #000; text-decoration: none; }

/* ============================================================
   Header Styling — match PHP custom.css lines 278-281
   ============================================================ */
.header-wrapper {
  height: 60px;
  background-color: #fff;
}

/* Blue accent bar between header and navbar
   Source: PHP custom.css lines 360-363 (.menu-top) */
.menu-accent-bar {
  height: 3px;
  background-color: var(--vtm-dark-blue);
}

/* ============================================================
   Main navigation bar — direct PHP port of ``.navbar-inverse``
   (vtm-theme.css :371-385 + custom.css :462-485).

   Gray (#ABABAB) bar with white UPPERCASE links sized at 16px;
   hover flips to dark-blue text on a light-gray pill. Active link
   uses the same hover style so the user always knows where they
   are. Replaces Bootstrap's ``bg-dark navbar-dark`` shipped pair.
   ============================================================ */
.navbar-vtm {
  background-color: #ababab;
  min-height: 45px;
  padding-top: 0;
  padding-bottom: 0;
}
.navbar-vtm .navbar-nav .nav-link {
  color: #fff;
  text-transform: uppercase;
  font-size: 16px;
  padding: 0.75rem 1rem;
  text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
  transition: background-color 0.15s ease, color 0.15s ease;
}
.navbar-vtm .navbar-nav .nav-link:hover,
.navbar-vtm .navbar-nav .nav-link:focus,
.navbar-vtm .navbar-nav .nav-link.active,
.navbar-vtm .navbar-nav .show > .nav-link {
  color: var(--vtm-dark-blue);
  background-color: var(--vtm-light-bg);
  text-shadow: none;
}
.navbar-vtm .navbar-toggler {
  border-color: rgba(255, 255, 255, 0.4);
  color: #fff;
}
.navbar-vtm .navbar-toggler-icon {
  background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%28255,255,255,0.85%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e");
}

/* ============================================================
   Tab Colors — match PHP custom.css lines 164-188 (.tab-v1)
   Used by Site view, Contact view, Company view, Task pages
   ============================================================ */
.tab-v1 .nav-tabs {
  border-bottom: solid 2px var(--vtm-dark-blue);
}

.tab-v1 .nav-link.active,
.tab-v1 .nav-link.active:hover,
.tab-v1 .nav-link.active:focus {
  color: #fff;
  background-color: var(--vtm-dark-blue);
  border-color: var(--vtm-dark-blue);
}

/* ============================================================
   Tab content panel — direct PHP-parity equivalent of
   ``.form-horizontal`` / ``.tab-edit`` (PHP custom.css :190-193).
   The Bootstrap tab strip's bottom edge meets this card's top
   edge, giving the active tab a "filled folder" feel. Applies
   to every page that uses ``<div class="tab-content">`` (task
   view + task edit + tasktype edit + …) so the look is uniform.
   ============================================================ */
.tab-content {
  background: #fff;
  border: 10px solid #f5f5f5;
  border-top: 0;          /* tab strip carries the top edge */
  border-bottom-left-radius: 0.4rem;
  border-bottom-right-radius: 0.4rem;
  padding: 1.25rem;
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.04);
  margin-bottom: 1.5rem;
}

/* ============================================================
   Nav-tabs strip — sit flush on top of the .tab-content panel
   with the same gray bar behind the tab buttons so the strip +
   panel read as one continuous chrome (matches VTM3 PHP look).
   ``mb-0`` overrides Bootstrap's mb-3 utility on the templates
   that currently apply it; ``border-bottom: 0`` lets the panel
   carry the dividing edge.
   ============================================================ */
.nav-tabs {
  background-color: #f5f5f5;
  padding: 0.4rem 0.5rem 0;
  border-top-left-radius: 0.4rem;
  border-top-right-radius: 0.4rem;
  /* VTM3 tab-v1 (PHP custom.css :164-188): the tab strip carries a 2px
     brand-navy underline. */
  border-bottom: solid 2px var(--vtm-dark-blue);
  margin-bottom: 0 !important;
}
/* Inactive tab buttons sit transparent against the gray bar so
   the active tab is the only thing that "lifts" off the strip. */
.nav-tabs .nav-link {
  background-color: transparent;
  border-color: transparent;
  /* VTM3 tone: tab labels are quiet dark-gray text, not Bootstrap's
     bright link blue (VTM3 tab-v1 tabs read as plain dark text on the
     gray strip). */
  color: #495057;
}
.nav-tabs .nav-link:hover {
  border-color: transparent;
  background-color: rgba(255, 255, 255, 0.4);
  color: var(--vtm-dark-blue);
}
/* Active tab — VTM3 tab-v1: white text on the brand navy (PHP
   custom.css :164-188). */
.nav-tabs .nav-link.active,
.nav-tabs .nav-link.active:hover,
.nav-tabs .nav-link.active:focus {
  color: #fff;
  background-color: var(--vtm-dark-blue);
  border-color: var(--vtm-dark-blue);
  font-weight: 600;
}

/* ============================================================
   Schedule chooser panel — VTM3 task edit's ``#sched_select``
   (edit.php:82: ``panel panel-primary`` holding the schedule-change
   notice + default/custom radios + repeat widget). A quiet white body
   with the brand-navy border; the ONLY blue accent in the form body.
   ============================================================ */
.sched-select-panel {
  border: 1px solid var(--vtm-dark-blue);
  border-radius: 0.375rem;
  padding: 0.75rem 1rem;
  background: #fff;
}

/* VTM3 horizontal-form labels are bold (<strong> in every control-label /
   <dt>). ``vtm-hform`` is the shared opt-in class for VTM3-parity
   horizontal forms (tasktype create/edit, …); task edit predates it and
   keeps its own class. */
.task-edit-form .col-form-label,
.vtm-hform .col-form-label {
  font-weight: 600;
}

/* ============================================================
   Required Field Indicator — match PHP custom.css lines 48-63
   Applied to labels with class "required" or inside .required
   ============================================================ */
.required .form-label::after,
label.required::after,
.form-group.required .form-label::after {
  content: " *";
  color: var(--vtm-required-red);
  font-weight: bold;
}

/* ============================================================
   Flash message auto-dismiss animation
   ============================================================ */
.flash-auto-dismiss {
  transition: opacity 0.5s ease-out;
}

/* ============================================================
   Back-to-top button
   ============================================================ */
.back-to-top {
  position: fixed;
  bottom: 20px;
  right: 20px;
  z-index: 1000;
  display: none;
  opacity: 0.7;
  transition: opacity 0.3s;
}
.back-to-top:hover {
  opacity: 1;
}

/* ============================================================
   HTMX Loading Indicators
   ============================================================ */
.htmx-indicator {
  display: none;
}
.htmx-request .htmx-indicator,
.htmx-request.htmx-indicator {
  display: inline-block;
}

/* Loading overlay (full-page) */
.loading-overlay {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background: rgba(255, 255, 255, 0.7);
  z-index: 9999;
  display: none;
  justify-content: center;
  align-items: center;
}
.htmx-request .loading-overlay {
  display: flex;
}

/* ============================================================
   Tab Content Areas — match PHP custom.css lines 165-193
   Used by multi-tab CRUD pages (Site, Contact, Task views)
   ============================================================ */
.tab-body {
  padding: 20px;
  background: #f7f7f7;
}

.tab-edit {
  padding: 20px;
  background: #fff;
}

/* ============================================================
   Tooltip Width Override — match PHP custom.css lines 204-206
   PHP overrides BS3 default 200px to 350px for longer help text
   ============================================================ */
.tooltip-inner {
  max-width: 350px;
}

/* ============================================================
   Footer Link Hover — match PHP custom.css lines 220-229
   Footer links hover to bright blue (not black like body links)
   ============================================================ */
footer a:hover {
  color: #0098fd;
  text-decoration: none;
}

/* ============================================================
   Unable-to-Complete Background — match PHP custom.css lines 893-896
   Applied to due date rows marked "unable to complete"
   ============================================================ */
.unable {
  background-color: #dddcdb !important;
}

/* ============================================================
   Card Header (Panel Migration) — match PHP custom.css lines 712-721
   BS3 .panel-primary = BS5 .card-vtm
   Used for info panels on CRUD detail pages
   ============================================================ */
.card-vtm .card-header {
  color: #fff;
  background-color: var(--vtm-dark-blue);
  border-color: var(--vtm-dark-blue);
}

.card-vtm {
  border-color: var(--vtm-dark-blue);
}

/* ============================================================
   Primary Button Brand Override — match PHP custom.css lines 595-620
   Override BS5 default blue (#0d6efd) with VTM dark blue (#024C8B)
   ============================================================ */
.btn-primary {
  --bs-btn-bg: var(--vtm-dark-blue);
  --bs-btn-border-color: var(--vtm-dark-blue);
  --bs-btn-hover-bg: var(--vtm-hover-blue);
  --bs-btn-hover-border-color: var(--vtm-hover-blue);
  --bs-btn-active-bg: #023a6b;
  --bs-btn-active-border-color: #023a6b;
}

/* VTM3 tone: outline-primary in brand navy too (BS5 compiles per-button
   literals, so the :root --bs-primary remap doesn't reach these). Used by
   the schedule widget's skip-month / weekday toggle chips, search buttons,
   etc. */
.btn-outline-primary {
  --bs-btn-color: var(--vtm-dark-blue);
  --bs-btn-border-color: var(--vtm-dark-blue);
  --bs-btn-hover-bg: var(--vtm-dark-blue);
  --bs-btn-hover-border-color: var(--vtm-dark-blue);
  --bs-btn-active-bg: var(--vtm-dark-blue);
  --bs-btn-active-border-color: var(--vtm-dark-blue);
  --bs-btn-focus-shadow-rgb: 2, 76, 139;
}

/* ============================================================
   Pagination Brand Colors — match PHP custom.css lines 816-891
   Minimal overrides for VTM link colors on pagination
   ============================================================ */
.pagination .page-link {
  color: var(--vtm-link-blue);
}

.pagination .page-link:hover {
  color: var(--vtm-link-blue);
}

.pagination .page-item.active .page-link {
  color: #999;
  background-color: var(--vtm-light-bg);
  border-color: #ddd;
}

/* ============================================================
   Alpine.js x-cloak — keeps elements hidden until Alpine has
   finished initialising. Without this, every element marked
   x-cloak is visible during the brief pre-init window AND if
   Alpine ever fails to load the page is "stuck" with all
   x-show branches visible at once. Ref: alpinejs.dev/directives/cloak
   ============================================================ */
[x-cloak] {
  display: none !important;
}

/* ============================================================
   Global Loading Indicator
   3px bar pinned to the top of the viewport. Pure-CSS animated
   "indeterminate" stripe — no spinner image, no JS animation loop.
   Show by removing .d-none; the keyframe runs on its own.
   ============================================================ */
#vtm-loading-bar {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  height: 3px;
  z-index: 1090; /* above modals (1055) and toasts (1080) */
  background: rgba(2, 76, 139, 0.15);
  overflow: hidden;
  pointer-events: none;
}

#vtm-loading-bar::before {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  height: 100%;
  width: 30%;
  background: var(--vtm-dark-blue);
  animation: vtm-loading-slide 1.1s ease-in-out infinite;
}

@keyframes vtm-loading-slide {
  0%   { left: -30%; width: 30%; }
  50%  { left: 30%;  width: 50%; }
  100% { left: 100%; width: 30%; }
}

/* ============================================================
   Task list table — direct port of PHP/Bootstrap-3 .table style
   for visual parity with VTM3.

   Used by:
     - templates/task/partials/_index_body.html (main /task/ page)
     - templates/task/partials/_task_table.html (company-area selector)

   Source: php_build/VTM3/public/assets/css/summernote-bs3.css
           lines 1427-1490 (verbatim Bootstrap-3 .table rules)

   No table-layout:fixed — the browser auto-distributes column widths
   based on content, exactly like VTM3. The .col-* classes in
   _task_thead.html are kept as semantic hooks but not given widths,
   so adjusting one column in the future is a one-line edit here.
   ============================================================ */
.task-table {
  width: 100%;
  margin-bottom: 1.25rem;
}

/* Cell base — 8px padding, 1px top divider, top-aligned (BS3 default). */
.task-table > thead > tr > th,
.task-table > thead > tr > td,
.task-table > tbody > tr > th,
.task-table > tbody > tr > td {
  padding: 8px;
  line-height: 1.428571429;
  vertical-align: top;
  border-top: 1px solid #ddd;
  border-bottom: 0;
  background-color: transparent;
  box-shadow: none;        /* clear BS5 .table-striped/-hover overlay */
}

/* Header — bold, bottom-aligned, 2px divider, no top border. */
.task-table > thead > tr > th {
  vertical-align: bottom;
  border-top: 0;
  border-bottom: 2px solid #ddd;
  font-weight: bold;
}

/* Sort link inherits the bold header weight + dark color (Bootstrap's
   <a> defaults to regular weight + brand blue otherwise). */
.task-table > thead > tr > th a {
  font-weight: inherit;
  color: inherit;
}
.task-table > thead > tr > th a > i {
  margin-left: .25rem;
}

/* Striping — BS3 #f9f9f9 (lighter than BS5's default rgba(0,0,0,0.05)). */
.task-table.table-striped > tbody > tr:nth-child(odd) > td,
.task-table.table-striped > tbody > tr:nth-child(odd) > th {
  background-color: #f9f9f9;
}

/* Hover — BS3 #f5f5f5; overrides striped tint when hovered. */
.task-table.table-hover > tbody > tr:hover > td,
.task-table.table-hover > tbody > tr:hover > th {
  background-color: #f5f5f5;
}

/* Column width hints — match PHP's BS3 grid classes at the col-lg
   breakpoint (php_build/VTM3/fuel/app/views/task/index.php:76-80).
   With table-layout:auto these are *starting points*; the browser
   still lets columns grow if content demands. The Task Type cap is
   the important one — it stops the description text from sprawling
   past PHP's 33% allocation. */
.task-table .col-bulk         { width: 30px; }
.task-table .col-site         { width: 16.66%; }
.task-table .col-tasktype     { width: 33.33%; }
.task-table .col-responsible  { width: 16.66%; }
.task-table .col-assigned     { width: 16.66%; }
.task-table .col-duedate      { width: 16.66%; }

/* ============================================================
   Task view info card — single-column key-value layout matching
   PHP/VTM3 task/view.php:51-112. The wrapping ``.tab-content``
   already supplies the gray border + padding (see "Tab content
   panel" rule above), so the inner card is purely a no-op
   wrapper today — kept so the partial's class hook still
   exists in case future styling needs to target only the info
   tab pane (vs other tab panes inside the same .tab-content).
   ============================================================ */
.task-info-card {
  background: #fff;
}

.task-info-table {
  margin-bottom: 0;
  width: 100%;
}

.task-info-table > tbody > tr > th,
.task-info-table > tbody > tr > td {
  padding: 10px 12px;
  vertical-align: top;
  border-top: 1px solid #ddd;
  border-bottom: 0;
  background-color: transparent;
  box-shadow: none;
}

/* Striping — alternating row tint matches the PHP screenshot. The
   first row gets no top border so the table reads as one continuous
   block under the tab strip. */
.task-info-table > tbody > tr:nth-child(odd) > th,
.task-info-table > tbody > tr:nth-child(odd) > td {
  background-color: #f9f9f9;
}
.task-info-table > tbody > tr:first-child > th,
.task-info-table > tbody > tr:first-child > td {
  border-top: 0;
}

/* Label column — right-aligned, bold, fixed width so values line
   up across rows (matches PHP <th class="col-..."> sizing). */
.task-info-table .task-info-label {
  width: 220px;
  font-weight: bold;
  color: #333;
  text-align: right;
  white-space: nowrap;
}

/* Compact modifier — used by Site view where the info table sits
   side-by-side with a fixed-height map. The default 10px row padding
   makes the table noticeably taller than the 253px map iframe; trim to
   4px so the two columns top + bottom out together. Apply with
   ``<table class="task-info-table task-info-compact ...">``. Task view
   keeps the looser default (no compact class) so dense, longer Task
   tables stay readable. */
.task-info-table.task-info-compact > tbody > tr > th,
.task-info-table.task-info-compact > tbody > tr > td {
  padding: 4px 12px;
}

@media (max-width: 768px) {
  /* On narrow viewports the fixed label column wastes space; let
     value cells take full width and stack labels above values. */
  .task-info-table .task-info-label {
    width: auto;
    text-align: left;
    white-space: normal;
  }
  /* Tighter tab-content padding on phones — saves ~16px of margin. */
  .tab-content {
    padding: 0.75rem;
  }
}

/* ============================================================
   Quill WYSIWYG editor — PHP parity with Summernote's
   ``.note-editor.panel.panel-default`` look. PHP wraps the editor
   in a Bootstrap 3 panel so the toolbar reads as a gradient-gray
   ``.panel-heading`` sitting on top of a white ``.panel-body``
   editable area, with a subtle outer shadow on the whole thing.

   Quill's default Snow theme is much flatter (a thin gray border
   around the toolbar, plain white below). We restyle ``.ql-toolbar``
   + ``.ql-container`` so they read as one panel matching PHP.

   Source:
     - PHP vtm-theme.css :535-538 (.panel shadow)
     - PHP vtm-theme.css :539-545 (.panel-default > .panel-heading
       linear-gradient #f5f5f5 → #e8e8e8)
     - PHP summernote-bs3.css (.note-editor structure)
   ============================================================ */
/* Specificity boost: every selector below repeats ``.ql-snow`` so it
   counts as an extra class and wins over Quill's CDN default rules
   (which load AFTER vtm.css via the per-page ``{% block head %}``).
   See full rationale in the buttons block further down. */
.ql-toolbar.ql-snow {
  border: 1px solid #ddd !important;
  border-bottom: 0 !important;
  border-top-left-radius: 0.25rem !important;
  border-top-right-radius: 0.25rem !important;
  background-image: linear-gradient(to bottom, #f5f5f5 0%, #e8e8e8 100%) !important;
  background-color: #f5f5f5 !important; /* fallback */
  /* Tight padding + ``flex-wrap: nowrap`` keep all toolbar groups on a
     single row (PHP/Summernote default). Quill's default ``display:
     block`` + floated buttons makes vertical alignment between buttons
     and pickers inconsistent — flex with ``align-items: center``
     baselines them all. */
  padding: 5px 6px !important;
  display: flex !important;
  flex-wrap: nowrap !important;
  align-items: center !important;
  /* MUST stay ``visible``: the size / align / Placeholders pickers render
     their dropdowns as ``position: absolute`` children that extend BELOW
     the toolbar. ``overflow-x: auto`` (the previous value) forces
     ``overflow-y`` to compute as ``auto`` too, which CLIPS those dropdowns
     so the editor text shows through and the options can't be clicked.
     Keep the single-row layout via ``flex-wrap: nowrap`` + the widened
     modal instead of toolbar scrolling. */
  overflow: visible !important;
  white-space: nowrap !important;
  box-shadow: 0 -1px 0 rgba(0, 0, 0, 0.02);
}
.ql-container.ql-snow.ql-snow {
  border: 1px solid #ddd;
  border-bottom-left-radius: 0.25rem;
  border-bottom-right-radius: 0.25rem;
  background: #fff;
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
}
/* Editable area — comfortable padding + readable line-height
   like PHP's note-editable default. */
.ql-snow .ql-editor.ql-editor {
  min-height: 200px;
  padding: 12px 15px;
  font-size: 14px;
  line-height: 1.5;
}
/* Toolbar groups — narrow gap between groups (PHP keeps them snug). */
.ql-toolbar.ql-snow.ql-snow .ql-formats {
  margin-right: 6px;
  display: inline-flex;
  align-items: center;
}
.ql-toolbar.ql-snow.ql-snow .ql-formats:last-child {
  margin-right: 0;
}
/* Buttons + picker labels — bordered "btn-default" look matching
   PHP's ``.note-editor .btn-default`` (summernote-bs3.css :2003-2016):
   white bg + 1px #ccc border + 4px corners, gray on hover, active
   state slightly darker.

   Specificity note: the CDN ``quill.snow.css`` is included AFTER
   ``vtm.css`` (loaded via the per-page ``{% block head %}``), so a
   selector tied with Quill's ``.ql-toolbar.ql-snow button`` (0,2,1)
   loses the cascade — Quill's ``border:none`` wins. We bump
   specificity to (0,3,1) by repeating ``.ql-snow`` in the selector,
   which is a no-op for matching but counts as a third class. This
   sidesteps ``!important`` while still overriding Quill defaults.
*/
/* ``!important`` is used here because Quill's CDN ``quill.snow.css``
   loads AFTER ``vtm.css`` (via the per-page ``{% block head %}``)
   and ships ``border: none; background: none; float: left`` on
   buttons. Without ``!important``, even a higher-specificity
   override loses when Quill's selectors happen to match at the
   same specificity. This is the canonical pattern for overriding
   third-party widget CSS that we don't control the load order of. */
.ql-toolbar.ql-snow button,
.ql-toolbar.ql-snow .ql-picker-label {
  height: 28px !important;
  background-color: #fff !important;
  border: 1px solid #ccc !important;
  border-radius: 4px !important;
  padding: 2px 6px !important;
  margin: 0 2px 0 0 !important;
  color: #333 !important;
  /* Replace Quill's ``float: left`` with flex centering so icons +
     dropdown labels share a baseline regardless of intrinsic height. */
  float: none !important;
  display: inline-flex !important;
  align-items: center !important;
  justify-content: center !important;
  box-sizing: border-box !important;
}
.ql-toolbar.ql-snow button {
  width: 30px !important;
}
.ql-toolbar.ql-snow button:hover,
.ql-toolbar.ql-snow button:focus,
.ql-toolbar.ql-snow .ql-picker-label:hover {
  background-color: #ebebeb !important;
  border-color: #adadad !important;
  color: #333 !important;
}
/* Active / "engaged" formats (Quill adds ``.ql-active`` and the
   picker's open state). Slightly darker tint, inset shadow like
   PHP's ``.btn:active``. */
.ql-toolbar.ql-snow button.ql-active,
.ql-toolbar.ql-snow .ql-picker.ql-expanded .ql-picker-label {
  background-color: #d9d9d9 !important;
  border-color: #adadad !important;
  box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.125) !important;
  color: #333 !important;
}
/* Pickers (size, align, header, custom Placeholders) — cap their
   label width so a long current-value (e.g. "Normal") doesn't push
   neighbours off-screen. */
.ql-toolbar.ql-snow.ql-snow .ql-picker {
  height: 26px;
  font-size: 13px;
}
.ql-toolbar.ql-snow.ql-snow .ql-size {
  width: 75px;
}
.ql-toolbar.ql-snow.ql-snow .ql-align {
  width: 32px;
}
/* Placeholders dropdown is widest — PHP shows it last on the row.
   Keep its label readable but stop it from stretching. */
.ql-toolbar.ql-snow.ql-snow .ql-placeholder {
  width: auto;
}
.ql-toolbar.ql-snow.ql-snow .ql-placeholder .ql-picker-label {
  white-space: nowrap;
}

/* ============================================================
   Email-template modal — wider than the default ``modal-lg``
   (800px) so the Quill toolbar has room for every button group on
   a single row. The PHP screenshot lands at ~960px usable width;
   match that. Targeted by id so it doesn't bleed into other modals.
   ============================================================ */
#et-modal .modal-dialog {
  max-width: 1000px;
  /* Smooth transform/opacity transition so the slide-up below
     animates instead of jumping (BS5 already animates the dialog's
     translate(0, -50px) / opacity for show/hide; we add transform
     here so our explicit translateY animates too). */
  transition: transform 0.3s ease, opacity 0.3s ease;
}

/* When ``#preview-modal`` opens on top of the Add Template modal,
   ``emailtemplate.js`` adds ``.et-behind-preview`` to ``#et-modal``.
   PHP parity: the Add Template form should disappear so the preview
   reads as the focal element, then return when the preview closes.

   We just ``display: none`` the modal element here. ``!important``
   defeats Bootstrap's ``.modal.show { display: block }`` rule. We
   also hide the immediately-following ``.modal-backdrop`` element
   (Bootstrap appends a backdrop sibling per shown modal — the
   et-modal's backdrop would otherwise stack with the preview's,
   creating a double-dim layer). When the preview closes,
   ``emailtemplate.js`` removes the class and Bootstrap's regular
   ``.modal.show`` restores ``display: block``.
   ============================================================ */
#et-modal.et-behind-preview {
  display: none !important;
}

/* Belt-and-braces fallback using CSS ``:has()``. If JS toggling
   fails for any reason (cache, Alpine init order, etc.), this rule
   still hides ``#et-modal`` whenever the document has a visible
   ``#preview-modal.show``. Both selectors must satisfy at the same
   time — so when preview closes (``.show`` removed by Bootstrap),
   et-modal returns to its normal display.
   ``:has()`` is supported in all evergreen browsers (Chromium 105+,
   Firefox 121+, Safari 15.4+). */
body:has(#preview-modal.show) #et-modal {
  display: none !important;
}

/* ============================================================
   Form sections — PHP-parity gray-bordered field group. Wraps a
   set of related ``mb-3 row`` form fields so the form reads as
   a stack of distinct cards rather than one long undifferentiated
   list. Source: PHP ``.panel.panel-default`` (BS3 :535-545).

   Optional ``.form-section-title`` puts a small light-gray header
   bar at the top of the section. Pair like:

       <div class="form-section">
         <div class="form-section-title">Schedule</div>
         <div class="form-section-body">
           …form fields…
         </div>
       </div>
   ============================================================ */
.form-section {
  border: 1px solid #ddd;
  border-radius: 0.4rem;
  background: #fff;
  margin-bottom: 1.25rem;
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.04);
}
.form-section-title {
  background-color: #f5f5f5;
  border-bottom: 1px solid #ddd;
  border-top-left-radius: 0.4rem;
  border-top-right-radius: 0.4rem;
  padding: 0.55rem 1rem;
  font-weight: 600;
  font-size: 0.95rem;
  color: var(--vtm-dark-blue);
}
.form-section-body {
  padding: 1rem 1.25rem 0.25rem;
}

/* ============================================================
   Form labels — PHP-style horizontal-form treatment. Standalone
   ``.form-label`` (BS5 stacked forms) and checkbox labels stay
   light-weight at 14px, matching PHP custom.css :453-456.

   Horizontal-row labels (``.col-form-label``, e.g. the
   ``<label class="col-sm-3 col-form-label">`` in task edit) are
   bold + right-aligned so the text sits flush against the input
   column — same look as PHP's ``.control-label`` in BS3
   ``.form-horizontal``. Closes the visual gap between a short
   label (e.g. "Site") and its select/input.
   ============================================================ */
.form-label,
.form-check-label {
  font-weight: normal;
  font-size: 14px;
}
.col-form-label {
  font-weight: 600;
  font-size: 14px;
  text-align: right;
}

/* On narrow viewports the label stacks on top of the input
   (Bootstrap collapses col-sm-3/col-sm-9 below the sm
   breakpoint), so right-aligning would look odd — kick it
   back to left-align below sm. */
@media (max-width: 575.98px) {
  .col-form-label {
    text-align: left;
  }
}

/* ============================================================
   Date / time inputs — Bootstrap's ``.form-control`` stretches
   any input to 100% of its parent column. For date pickers that
   only need ~9 chars (mm/dd/yyyy) plus the spinner, that reads
   as wasted space. Cap them at 12rem so they sit at a natural
   size and let the column gutter handle alignment. Applies to
   every ``type=date`` / ``type=time`` form control across the
   app — opt out per-input with an inline ``style="max-width:none"``.
   ============================================================ */
input[type="date"].form-control,
input[type="time"].form-control {
  max-width: 12rem;
}

/* ============================================================
   Multi-select picker (macros/_pickers.html) — the selected
   "pill" tray. A large selection (e.g. dozens of report sites)
   would otherwise grow unbounded and push the rest of the form
   off-screen. Cap the tray height and let it scroll instead.
   ``padding-right`` keeps the scrollbar off the pills.
   ============================================================ */
.picker-pills {
  max-height: 8.5rem;
  overflow-y: auto;
  padding-right: 0.25rem;
}

/* ============================================================
   Breadcrumbs — VTM4-specific polish (intentionally diverges
   from PHP's flat sharp-cornered list). Wraps the trail in a
   light-gray pill with rounded corners and a subtle border so
   it reads as a piece of page chrome, not loose body text.
   Custom chevron separator + hover underline keeps it crisp.
   The standard Bootstrap markup in _breadcrumbs.html is
   unchanged; this is purely a CSS reskin.
   ============================================================ */
.breadcrumb {
  background-color: var(--vtm-light-bg);
  border: 1px solid #e3e3e3;
  border-radius: 0.5rem;
  padding: 0.5rem 0.9rem;
  margin-bottom: 1rem;
  font-size: 0.9rem;
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.04);
}

/* Custom separator — Font Awesome-style chevron, sized down so
   it sits midline with the text. Bootstrap's default is "/". */
.breadcrumb-item + .breadcrumb-item::before {
  content: "›";
  color: #999;
  font-weight: bold;
  padding: 0 0.35rem;
}

.breadcrumb-item a {
  color: var(--vtm-link-blue);
  text-decoration: none;
  transition: color 0.12s ease;
}
.breadcrumb-item a:hover {
  color: var(--vtm-dark-blue);
  text-decoration: underline;
}

.breadcrumb-item.active {
  color: #495057;
  font-weight: 500;
}

/* ============================================================
   Footer — match PHP ``.footer`` (custom.css :406-414): light
   gray bg, subtle top border, comfortable padding. Sticky-footer
   flex layout above pins it to the viewport bottom on short pages.
   ============================================================ */
footer.footer {
  background-color: var(--vtm-light-bg);
  border-top: 1px solid #e0e0e0;
  color: #666;
}
footer.footer a {
  color: var(--vtm-link-blue);
}

/* ============================================================
   Page heading — page titles use ``<h2 class="text-muted">``.
   Bootstrap's default h2 (2rem / 32px) sits too proud above
   subdued page chrome; PHP's ``h2.heading-md`` lands at 20px /
   24px line-height. We don't drop quite that low (would clash
   with badges + action buttons living in the same row), but
   we trim the weight so the title doesn't dominate.
   ============================================================ */
#content-area > .d-flex > div > h2,
#content-area > h2 {
  font-size: 1.5rem;
  font-weight: 400;
  line-height: 1.3;
}

/* ============================================================
   Subtle elevation utility — PHP's ``.shadow-box``. The main
   ``.tab-content`` panel already gets its own shadow above; this
   utility class is here for ad-hoc cards / panels elsewhere.
   ============================================================ */
.shadow-box {
  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.06);
}

/* ============================================================
   Site View "At-a-Glance" card body — used by the Tasks card and
   every element card (permits, tank systems, inspections, etc.)
   on the Site view page. PHP parity: ``.fixed-panel`` from
   custom.css. The cards live in a 3-up grid; without a fixed
   height the row collapses to the tallest card and an empty
   "Constructions" card sits next to a tall "Permits" card with
   ten rows — visually awkward. Fix the body to ~10rem and let
   long lists scroll inside the card.
   ============================================================ */
.glance-card-body {
  height: 10rem;
  overflow-y: auto;
}

/* ============================================================
   Multi-step wizard — direct port of PHP fuelux ``.wizard``
   (fuelux.css :2702-2941). One outer banner with rounded corners
   contains: (1) a horizontal step strip on the left where each
   step is a colored pill with a triangular chevron pointing to
   the next, (2) a Prev/Next action panel pinned to the top-right
   corner. The form content sits below the banner inside
   ``.step-content``, separated by a top border.

   States per step:
     • inactive (default): gray fill #eee, gray text
     • active            : light-blue fill #eef7fb, blue text
     • complete          : light-gray fill #f5f5f5, green text
   ============================================================ */
.vtm-wizard {
  position: relative;
  border: 1px solid #d4d4d4;
  border-radius: 4px;
  background-color: #fafafa;
  min-height: 48px;
  margin-bottom: 1.25rem;
}
.vtm-wizard .steps-container {
  border-radius: 4px 4px 0 0;
  overflow: hidden;
}
.vtm-wizard .steps {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  flex-wrap: nowrap;
  /* Reserve room for the absolutely-positioned actions panel. */
  padding-right: 170px;
}
.vtm-wizard .steps li {
  position: relative;
  flex: 1 1 0;
  height: 46px;
  line-height: 46px;
  padding: 0 20px 0 30px;
  background: #eeeeee;
  color: #888;
  font-size: 14px;
  font-weight: 600;
  cursor: default;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.vtm-wizard .steps li:first-child {
  border-radius: 4px 0 0 0;
  padding-left: 20px;
}
.vtm-wizard .steps li .badge {
  /* Flex-center the digit — Bootstrap's own .badge adds vertical padding
     (.35em .65em) that pushed the number to the bottom of the fixed-size
     circle under line-height centering. */
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  width: 22px;
  height: 22px;
  line-height: 1;
  border-radius: 50%;
  margin-right: 8px;
  background: #c8c8c8;
  color: #fff;
  font-size: 12px;
  font-weight: 700;
  text-align: center;
  vertical-align: middle;
}
/* CSS-triangle chevron — two stacked borders so the inner color
   floats on top of an outer border line, exactly like fuelux. */
.vtm-wizard .steps li .chevron {
  position: absolute;
  right: -14px;
  top: 0;
  display: block;
  border: 23px solid transparent;
  border-left: 14px solid #d4d4d4;
  border-right: 0;
  z-index: 2;
}
.vtm-wizard .steps li .chevron::before {
  content: "";
  position: absolute;
  right: 1px;
  top: -23px;
  border: 23px solid transparent;
  border-left: 14px solid #eeeeee;
  border-right: 0;
}
.vtm-wizard .steps li:last-child .chevron {
  display: none;
}
/* Active step — blue fill + chevron tip + badge */
.vtm-wizard .steps li.active {
  background: #eef7fb;
  color: var(--vtm-link-blue);
}
.vtm-wizard .steps li.active .chevron::before {
  border-left-color: #eef7fb;
}
.vtm-wizard .steps li.active .badge {
  background: var(--vtm-link-blue);
}
/* Complete step — light-gray fill + green text + green badge */
.vtm-wizard .steps li.complete {
  background: #f5f5f5;
  color: #468847;
}
.vtm-wizard .steps li.complete .chevron::before {
  border-left-color: #f5f5f5;
}
.vtm-wizard .steps li.complete .badge {
  background: #468847;
}

/* Top-right Prev/Next action panel — pinned absolutely so it
   slots into the banner's right shoulder, matching fuelux. */
.vtm-wizard .actions {
  position: absolute;
  top: 0;
  right: 0;
  height: 46px;
  line-height: 46px;
  padding: 0 12px;
  background-color: #e6e6e6;
  border-left: 1px solid #d4d4d4;
  border-radius: 0 4px 0 0;
  z-index: 3;
  display: flex;
  align-items: center;
  gap: 6px;
}
.vtm-wizard .actions .btn {
  font-size: 12px;
}

/* The pane that hosts the step's form body. */
.vtm-wizard .step-content {
  border-top: 1px solid #d4d4d4;
  padding: 1.25rem 1.5rem 0.75rem;
  background: #fff;
  border-radius: 0 0 4px 4px;
}
.vtm-wizard .step-content h4 {
  font-size: 1.05rem;
  font-weight: 600;
  color: var(--vtm-dark-blue);
  margin-bottom: 1rem;
}
/* Bottom Prev/Next strip — sits inside the step-content footer.
   Cancel + Submit live here too (Submit appears only on the last
   step). PHP includes ``common/wizardbuttons.php`` to render the
   bottom bar; we keep both top + bottom to match. */
.vtm-wizard-actions {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-top: 1.25rem;
  padding-top: 1rem;
  border-top: 1px solid #eee;
}

/* On narrow viewports collapse the absolute action panel into the
   row below the steps so the steps don't get squashed. */
@media (max-width: 767.98px) {
  .vtm-wizard .steps {
    padding-right: 0;
    flex-wrap: wrap;
  }
  .vtm-wizard .actions {
    position: static;
    width: 100%;
    height: auto;
    line-height: 1.4;
    padding: 0.5rem 0.75rem;
    border-left: 0;
    border-top: 1px solid #d4d4d4;
    border-radius: 0;
    justify-content: flex-end;
  }
}

/* ============================================================
   PHP-style horizontal form rows — label on the left, input
   group on the right with an icon prefix ("input-group-addon"
   in BS3 became "input-group-text" in BS5). Used by the task
   create/edit wizard, anywhere we want to mimic PHP's
   ``.form-horizontal`` look without rewriting markup tooling.
   The ``.required`` modifier on a label gets a leading red dot.
   ============================================================ */
.form-horizontal-row {
  display: flex;
  flex-wrap: wrap;
  margin-bottom: 1.1rem;
  align-items: flex-start;
}
.form-horizontal-row > .fh-label {
  flex: 0 0 16.6667%;
  max-width: 16.6667%;
  padding: 0.4rem 0.75rem 0 0;
  text-align: right;
  font-weight: 600;
  font-size: 14px;
  line-height: 1.4;
}
.form-horizontal-row > .fh-input {
  flex: 0 0 66.6667%;
  max-width: 66.6667%;
}
.form-horizontal-row > .fh-input-narrow {
  flex: 0 0 25%;
  max-width: 25%;
}
.form-horizontal-row > .fh-input-mid {
  flex: 0 0 41.6667%;
  max-width: 41.6667%;
}
.form-horizontal-row > .fh-help {
  flex: 0 0 16.6667%;
  max-width: 16.6667%;
  padding: 0.5rem 0 0 0.5rem;
  color: #5bc0de;
  font-size: 1.1rem;
}
.form-horizontal-row .help-block {
  display: block;
  font-size: 12px;
  color: #888;
  margin-top: 0.35rem;
  line-height: 1.35;
}
.form-horizontal-row .fh-label.required::before {
  content: "*";
  color: var(--vtm-required-red);
  font-weight: 700;
  margin-right: 0.25rem;
}

/* Stack the label above the input on anything narrower than ``lg``
   (Bootstrap's 992px breakpoint). Below that the standard 16.67% +
   66.67% horizontal split squeezes any sub-grid (e.g. the schedule
   widget's ``col-sm-2 + col-sm-10`` rows) so the form behaves
   better as a single full-width column on tablets and split-screen
   desktop windows. */
@media (max-width: 991.98px) {
  .form-horizontal-row > .fh-label,
  .form-horizontal-row > .fh-input,
  .form-horizontal-row > .fh-input-narrow,
  .form-horizontal-row > .fh-input-mid,
  .form-horizontal-row > .fh-help {
    flex: 0 0 100%;
    max-width: 100%;
    text-align: left;
    padding-right: 0;
  }
}

/* Input-group icon prefix — reskinned to match PHP's gray
   ``.input-group-addon``. BS5 ships ``.input-group-text`` flat;
   we tighten the padding and use the standard light-gray fill. */
.input-group .input-group-text.fh-addon {
  background-color: #eaeaea;
  border-color: #ccc;
  color: #555;
  min-width: 2.4rem;
  justify-content: center;
}

/* Schedule selector panel — wraps the radio + repeat widget so it
   visually clusters under the Task Type field. Mirrors PHP's
   ``.panel.panel-primary`` blue-bordered box. */
.sched-panel {
  border: 1px solid var(--vtm-dark-blue);
  border-radius: 0.4rem;
  background: #fff;
  margin-top: 0.25rem;
}
.sched-panel-header {
  background: var(--vtm-dark-blue);
  color: #fff;
  padding: 0.4rem 0.85rem;
  font-weight: 600;
  font-size: 13px;
  border-top-left-radius: 0.35rem;
  border-top-right-radius: 0.35rem;
}
.sched-panel-body {
  padding: 0.75rem 1rem;
}


/* ================================================================
   Print styles — VTM3 parity (Bootstrap 3 shipped `hidden-print`;
   BS5 dropped it). Chrome (page furniture) is hidden when printing so
   only the page content lands on paper: header/logo bar, blue accent
   bar, main navbar, breadcrumb bar, footer, back-to-top FAB, loading
   bar, modals, and action buttons. Links keep their on-screen look
   (no BS3-era href expansion).
   ================================================================ */
@media print {
  header,
  .header-wrapper,
  .menu-accent-bar,
  .navbar,
  nav[aria-label="breadcrumb"],
  .breadcrumb,
  footer.footer,
  .back-to-top,
  #vtm-loading-bar,
  .modal,
  .modal-backdrop,
  .dropdown-menu,
  .btn {
    display: none !important;
  }

  /* Let the content use the full sheet width. */
  .container-fluid {
    padding-left: 0 !important;
    padding-right: 0 !important;
    margin-top: 0 !important;
  }

  body {
    background: #fff !important;
  }

  /* Don't split table rows across pages when avoidable. */
  tr {
    page-break-inside: avoid;
  }
}

/* Company metrics panel collapse toggle (company/_metrics_panel.html). */
#metric-dash .metrics-collapse-toggle i {
  transition: transform 0.2s ease;
}
#metric-dash .metrics-collapse-toggle.collapsed i {
  transform: rotate(180deg);
}
