/* OptioFlo global responsive layer
   Purpose: improve tablet and phone layouts without changing routes, links, fields,
   models, forms, or desktop page logic. Loaded after Bootstrap and base styles. */

:root {
  --ofo-mobile-gap: .75rem;
  --ofo-touch-min: 2.35rem;
}

*, *::before, *::after { box-sizing: border-box; }
img, svg, video, canvas { max-width: 100%; height: auto; }

/* Prevent one wide element from forcing the whole app wider than the screen. */
.perpetua-shell,
.perpetua-page,
.perpetua-page-body,
#content,
main,
section,
.card,
.container,
.container-fluid,
.row,
[class*="col-"] {
  min-width: 0;
  max-width: 100%;
}

/* Desktop stays essentially unchanged. These rules only make shared desktop rows safer. */
.perpetua-page .btn,
.perpetua-page button,
.perpetua-page input,
.perpetua-page select,
.perpetua-page textarea {
  max-width: 100%;
}

.perpetua-page .btn,
.perpetua-page button.btn,
.perpetua-page a.btn {
  white-space: normal;
  overflow-wrap: anywhere;
  min-height: var(--ofo-touch-min);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: .25rem;
}

/* Common action/filter/search rows. Allows buttons to wrap instead of overlap. */
.perpetua-page .btn-group,
.perpetua-page .btn-toolbar,
.perpetua-page .button-row,
.perpetua-page .actions,
.perpetua-page .action-row,
.perpetua-page .page-actions,
.perpetua-page .toolbar,
.perpetua-page .filter-row,
.perpetua-page .filters,
.perpetua-page .search-row,
.perpetua-page .controls,
.perpetua-page .perpetua-page-controls,
.perpetua-page form.d-flex,
.perpetua-page .d-flex.flex-nowrap {
  flex-wrap: wrap !important;
  gap: .5rem;
  min-width: 0;
}

.perpetua-page .input-group,
.perpetua-page .form-floating,
.perpetua-page .form-control,
.perpetua-page .form-select {
  min-width: 0;
  max-width: 100%;
}

/* Tables: keep desktop table look, but allow a safe horizontal pan where columns are too many. */
.perpetua-page .table-responsive,
.perpetua-page .table-wrapper,
.perpetua-page .list-table-wrapper,
.perpetua-page .table-scroll,
.perpetua-page [class*="table"]:has(> table) {
  max-width: 100%;
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
}

.perpetua-page table {
  max-width: 100%;
}

.perpetua-page td,
.perpetua-page th {
  min-width: 0;
  vertical-align: middle;
}

/* Managed app data tables: keep rows scannable and consistent. Normal text
   cells get a two-line visual allowance; checkbox columns are centered so the
   row boxes line up with the header select box. Form/control-heavy cells opt
   out so entry grids remain usable. */
:root {
  --ofo-table-row-height: 3.65rem;
  --ofo-table-cell-line-height: 1.18;
}

.perpetua-page .perpetua-managed-table:not(.order-items-table) > tbody > tr,
.finance-content-body table.table > tbody > tr,
.tc-content table:not(.pr-table) > tbody > tr {
  height: var(--ofo-table-row-height);
}

.perpetua-page .perpetua-managed-table:not(.order-items-table) > tbody > tr > td,
.finance-content-body table.table > tbody > tr > td,
.tc-content table:not(.pr-table) > tbody > tr > td {
  max-height: var(--ofo-table-row-height);
  line-height: var(--ofo-table-cell-line-height);
  vertical-align: middle !important;
  overflow: hidden;
}

.perpetua-page .perpetua-managed-table:not(.order-items-table) .perpetua-cell-text,
.finance-content-body table.table .perpetua-cell-text,
.tc-content table:not(.pr-table) .perpetua-cell-text {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  max-height: calc(2em * var(--ofo-table-cell-line-height));
  line-height: var(--ofo-table-cell-line-height);
  white-space: normal;
  overflow: hidden;
  text-overflow: ellipsis;
}

.perpetua-page .perpetua-managed-table:not(.order-items-table) th:has(input[type="checkbox"]),
.perpetua-page .perpetua-managed-table:not(.order-items-table) td:has(input[type="checkbox"]),
.finance-content-body table.table th:has(input[type="checkbox"]),
.finance-content-body table.table td:has(input[type="checkbox"]),
.tc-content table:not(.pr-table) th:has(input[type="checkbox"]),
.tc-content table:not(.pr-table) td:has(input[type="checkbox"]) {
  text-align: center !important;
  vertical-align: middle !important;
}

.perpetua-page .perpetua-managed-table:not(.order-items-table) th input[type="checkbox"],
.perpetua-page .perpetua-managed-table:not(.order-items-table) td input[type="checkbox"],
.finance-content-body table.table th input[type="checkbox"],
.finance-content-body table.table td input[type="checkbox"],
.tc-content table:not(.pr-table) th input[type="checkbox"],
.tc-content table:not(.pr-table) td input[type="checkbox"] {
  display: block;
  width: 1rem;
  height: 1rem;
  margin-left: auto !important;
  margin-right: auto !important;
}

/* Desktop table headers: sticky only on real desktop-height layouts. The
   sticky element remains inside its table wrapper, so it releases when that
   table ends instead of covering the next card/form/table. */
@media (min-width: 1101px) and (min-height: 561px) {
  .perpetua-page .table-wrapper,
  .perpetua-page .list-table-wrapper,
  .perpetua-page .table-responsive,
  .tc-content .table-wrapper,
  .tc-content .list-table-wrapper,
  .tc-content .table-responsive,
  .tc-content .ts-scroll,
  .finance-content-body .table-responsive {
    position: relative;
    overflow-y: visible !important;
  }

  .perpetua-page .perpetua-managed-table,
  .tc-content table,
  .finance-content-body table {
    border-collapse: separate !important;
    border-spacing: 0 !important;
  }

  .perpetua-page .perpetua-managed-table thead,
  .tc-content table thead,
  .finance-content-body table thead {
    position: relative;
    z-index: 2;
  }

  .perpetua-page .perpetua-managed-table thead th,
  .tc-content table thead th,
  .finance-content-body table thead th {
    position: sticky !important;
    top: calc(var(--header-h, 0px) + .25rem) !important;
    z-index: 3 !important;
    background-color: #fff !important;
    background-clip: padding-box;
    box-shadow: 0 -12px 0 12px #fff, inset 0 -1px 0 #dee2e6, 0 1px 0 #dee2e6;
  }
}

/* Tablet, phone, and short layouts keep natural scrolling. Sticky table
   headers in horizontal scroll wrappers were the root cause of headers
   appearing midway down tables on small screens. */
@media (max-width: 1100px), (max-height: 560px) {
  .perpetua-page .perpetua-managed-table thead,
  .perpetua-page .perpetua-managed-table thead th,
  .tc-content table thead,
  .tc-content table thead th,
  .finance-content-body table thead,
  .finance-content-body table thead th {
    position: static !important;
    top: auto !important;
    z-index: auto !important;
  }
}

.perpetua-page .table-wrapper,
.perpetua-page .list-table-wrapper,
.perpetua-page .table-responsive,
.tc-content .table-wrapper,
.tc-content .list-table-wrapper,
.tc-content .table-responsive,
.tc-content .ts-scroll {
  overflow-y: visible !important;
}

/* Modals/overlays: keep them inside tablet/phone screens. */
.modal-dialog,
.perpetua-page .modal-dialog,
.perpetua-page .modal-content,
.perpetua-page .overlay,
.perpetua-page .dialog,
.perpetua-page .drawer,
.perpetua-page .offcanvas {
  max-width: calc(100vw - 1rem);
}

.perpetua-page .modal-body,
.perpetua-page .overlay-body,
.perpetua-page .dialog-body,
.perpetua-page .drawer-body {
  max-height: calc(100dvh - 9rem);
  overflow: auto;
  -webkit-overflow-scrolling: touch;
}

/* Tablet and below */
@media (max-width: 991.98px) {
  html, body {
    height: auto;
    min-height: 100%;
    overflow-x: hidden;
    overflow-y: auto;
  }

  .perpetua-shell {
    height: auto;
    min-height: 100dvh;
    overflow: visible;
    padding: .75rem !important;
  }

  .perpetua-page {
    height: auto;
    min-height: calc(100dvh - 1.5rem);
    overflow: visible;
    border-radius: .5rem;
  }

  .perpetua-page-body,
  .list-page,
  .list-table-wrapper {
    height: auto !important;
    min-height: 0 !important;
    overflow: visible !important;
  }

  .perpetua-page-header,
  .perpetua-page-controls,
  .page-sticky-header,
  .sticky-top {
    position: static !important;
    top: auto !important;
  }

  .perpetua-page-header,
  .perpetua-page-controls {
    padding: .65rem !important;
  }

  .perpetua-page-header .row,
  .perpetua-page-controls .row,
  .perpetua-page .row.align-items-center,
  .perpetua-page .row.justify-content-between {
    row-gap: .5rem;
  }

  .perpetua-page-header h1,
  .perpetua-page-header h2,
  .perpetua-page > h1,
  .perpetua-page > h2 {
    font-size: clamp(1.25rem, 3vw, 1.75rem) !important;
    line-height: 1.15 !important;
    overflow-wrap: anywhere;
  }

  .perpetua-page .btn-group {
    display: flex;
  }

  .perpetua-page .btn-group > .btn,
  .perpetua-page .btn-group > .btn-group {
    flex: 1 1 auto;
    border-radius: .375rem !important;
  }

  .perpetua-page .nav-tabs,
  .perpetua-page .nav-pills,
  .perpetua-page .tabs,
  .perpetua-page .tab-row {
    flex-wrap: nowrap !important;
    overflow-x: auto;
    overflow-y: hidden;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: thin;
  }

  .perpetua-page .nav-tabs .nav-link,
  .perpetua-page .nav-pills .nav-link,
  .perpetua-page .tabs a,
  .perpetua-page .tab-row a,
  .perpetua-page .tabs button,
  .perpetua-page .tab-row button {
    white-space: nowrap;
    flex: 0 0 auto;
  }

  .perpetua-page table {
    min-width: max-content;
  }

  .perpetua-page .perpetua-list-table {
    table-layout: auto !important;
  }

  .perpetua-page .perpetua-list-table th,
  .perpetua-page .perpetua-list-table td {
    white-space: nowrap;
    overflow: visible;
    text-overflow: clip;
  }

  .perpetua-page .card,
  .perpetua-page .panel,
  .perpetua-page .box {
    overflow-wrap: anywhere;
  }
}

/* Phones */
@media (max-width: 575.98px) {
  :root {
    --perpetua-title-size: 1.35rem;
  }

  .perpetua-shell {
    padding: .5rem !important;
  }

  .perpetua-page {
    border-left: 0;
    border-right: 0;
    border-radius: .35rem;
  }

  .perpetua-page-header,
  .perpetua-page-controls,
  .perpetua-page-body,
  .card-body,
  .modal-body {
    padding-left: .6rem !important;
    padding-right: .6rem !important;
  }

  .perpetua-page .row {
    --bs-gutter-x: .75rem;
    --bs-gutter-y: .6rem;
  }

  /* Force Bootstrap grid columns to stack on phones unless a page explicitly uses table cells. */
  .perpetua-page .row > [class*="col-"] {
    flex: 0 0 100% !important;
    max-width: 100% !important;
    width: 100% !important;
  }

  .perpetua-page .d-flex,
  .perpetua-page form.d-flex,
  .perpetua-page .input-group,
  .perpetua-page .btn-toolbar,
  .perpetua-page .button-row,
  .perpetua-page .actions,
  .perpetua-page .action-row,
  .perpetua-page .page-actions,
  .perpetua-page .toolbar,
  .perpetua-page .filter-row,
  .perpetua-page .filters,
  .perpetua-page .search-row,
  .perpetua-page .controls {
    flex-wrap: wrap !important;
  }

  .perpetua-page .input-group > .form-control,
  .perpetua-page .input-group > .form-select,
  .perpetua-page .input-group > .btn,
  .perpetua-page .btn-toolbar > .btn,
  .perpetua-page .button-row > .btn,
  .perpetua-page .actions > .btn,
  .perpetua-page .action-row > .btn,
  .perpetua-page .page-actions > .btn,
  .perpetua-page .toolbar > .btn,
  .perpetua-page .filter-row > .btn,
  .perpetua-page .filters > .btn,
  .perpetua-page .search-row > .btn,
  .perpetua-page .controls > .btn {
    flex: 1 1 100%;
    width: 100%;
  }

  .perpetua-page .btn,
  .perpetua-page button.btn,
  .perpetua-page a.btn {
    width: auto;
    min-height: 2.55rem;
    padding: .5rem .65rem;
    font-size: .95rem;
  }

  .perpetua-page .btn-sm,
  .perpetua-page .btn.btn-sm {
    min-height: 2.25rem;
    padding: .35rem .5rem;
  }

  .perpetua-page .modal-dialog {
    margin: .5rem auto;
  }

  .perpetua-page .modal-content {
    max-height: calc(100dvh - 1rem);
  }

  .perpetua-page .modal-footer,
  .perpetua-page .modal-header {
    flex-wrap: wrap;
    gap: .5rem;
  }

  .perpetua-page .modal-footer .btn {
    flex: 1 1 100%;
  }

  pre, code {
    white-space: pre-wrap;
    word-break: break-word;
  }
}

/* Short-height landscape phones/tablets. Width alone is misleading here:
   these screens often look "desktop wide" but have very little vertical room.
   Prefer natural page scroll, non-sticky headers, horizontally pannable tables,
   and scrollable modal sheets. */
@media (orientation: landscape) and (max-height: 560px) and (max-width: 1100px) {
  html,
  body {
    height: auto !important;
    min-height: 100% !important;
    overflow-x: hidden !important;
    overflow-y: auto !important;
  }

  body {
    display: block !important;
  }

  .perpetua-shell,
  .perpetua-page,
  .perpetua-page-body,
  .finance-content-body,
  .tc-content {
    height: auto !important;
    min-height: 0 !important;
    max-height: none !important;
    overflow: visible !important;
  }

  .perpetua-shell {
    padding: .5rem !important;
  }

  .page-sticky-header,
  .perpetua-page-header,
  .perpetua-page-controls,
  .sticky-top {
    position: static !important;
    top: auto !important;
    height: auto !important;
    min-height: 0 !important;
    flex-wrap: wrap !important;
  }

  .page-sticky-actions,
  .page-sticky-left,
  .perpetua-page .toolbar,
  .perpetua-page .filter-row,
  .perpetua-page .actions,
  .perpetua-page form.d-flex,
  .finance-content-body form.d-flex,
  .tc-content .table-toolbar,
  .tc-content .ts-jump {
    flex-wrap: wrap !important;
    gap: .45rem !important;
    min-width: 0 !important;
  }

  .page-sticky-actions .form-control,
  .page-sticky-actions .form-select,
  .finance-content-body .form-control,
  .finance-content-body .form-select,
  .tc-content .form-control,
  .tc-content .form-select {
    width: auto !important;
    max-width: 100% !important;
    min-width: 0 !important;
    flex: 1 1 180px;
  }

  .perpetua-page .table-wrapper,
  .perpetua-page .table-responsive,
  .finance-content-body .table-responsive,
  .tc-content .ts-scroll,
  .tc-content .table-responsive {
    overflow-x: auto !important;
    overflow-y: visible !important;
    max-width: 100% !important;
    -webkit-overflow-scrolling: touch;
  }

  .perpetua-page .table-responsive table,
  .finance-content-body .table-responsive table.table {
    min-width: 640px;
  }

  .modal,
  .perpetua-page .modal,
  .tc-content .overlay-modal {
    overflow-y: auto !important;
    align-items: flex-start !important;
    padding: .35rem !important;
    -webkit-overflow-scrolling: touch;
  }

  .modal-dialog,
  .perpetua-page .modal-dialog,
  .tc-content .overlay-card,
  .perpetua-page .overlay-card,
  .perpetua-page .dialog,
  .perpetua-page .drawer {
    width: calc(100vw - .7rem) !important;
    max-width: calc(100vw - .7rem) !important;
    max-height: calc(100dvh - .7rem) !important;
    margin: .35rem auto !important;
  }

  .modal-content,
  .perpetua-page .modal-content,
  .tc-content .overlay-card {
    max-height: calc(100dvh - .7rem) !important;
    display: flex;
    flex-direction: column;
  }

  .modal-body,
  .perpetua-page .modal-body,
  .tc-content .overlay-body,
  .perpetua-page .overlay-body,
  .perpetua-page .dialog-body,
  .perpetua-page .drawer-body {
    overflow-y: auto !important;
    max-height: none !important;
    min-height: 0 !important;
    -webkit-overflow-scrolling: touch;
  }

  .modal-footer,
  .perpetua-page .modal-footer {
    flex-wrap: wrap !important;
    gap: .45rem !important;
  }
}

/* ============================================================
   Finance + Timeclock-admin responsive patches (added 2026-05-27).
   These modules have their own scoped CSS (.finance-content-body
   from finance_base.html, .tc-content from timeclock/admin_base.html)
   whose specificity beats the generic .perpetua-page rules above.
   Mirror the needed responsive treatments inside those scopes.
   Revert: delete from here to the end of file.
   ============================================================ */

/* --- Finance lists & forms: wrap toolbars + scroll wide tables ------- */
.finance-content-body form.d-flex,
.finance-content-body .d-flex.flex-nowrap,
.finance-content-body .btn-toolbar {
  flex-wrap: wrap !important;
  gap: .5rem;
  min-width: 0;
}

.finance-content-body .table-responsive {
  max-width: 100%;
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
}

@media (max-width: 1024px) {
  /* Inline-width inputs in finance toolbars (style="width:320px") shrink
     gracefully; ensure the input-group / form-control also drop the inline
     fixed widths on narrow screens. */
  .finance-content-body .form-control,
  .finance-content-body .form-select,
  .finance-content-body .input-group {
    max-width: 100%;
    min-width: 0;
  }
  .finance-content-body .form-control[style*="width"],
  .finance-content-body .form-select[style*="width"] {
    width: auto !important;
    flex: 1 1 200px;
    max-width: 100%;
  }
  /* Keep finance tables readable: stop ellipsis-squeeze, allow horizontal
     pan inside the wrapper. */
  .finance-content-body .table-responsive table.table {
    min-width: 720px;
  }
}

@media (max-width: 575.98px) {
  .finance-content-body .table-responsive table.table {
    min-width: 560px;
  }
  /* Action buttons in finance toolbars span the full width on phone so
     they're never cropped. */
  .finance-content-body form.d-flex > .btn,
  .finance-content-body form.d-flex > input.form-control,
  .finance-content-body form.d-flex > .form-select {
    flex: 1 1 100%;
    width: 100%;
  }
}

/* --- Timeclock admin: timesheets/payroll/tasks ------------------------ */

/* Buttons inside .tc-content set their own padding/font that beats the
   global .perpetua-page .btn rules. Re-assert touch-friendly sizing on
   tablet/phone. */
@media (max-width: 991.98px) {
  .tc-content .btn {
    min-height: var(--ofo-touch-min);
    padding: .5rem .75rem;
    white-space: normal;
    overflow-wrap: anywhere;
  }
  .tc-content .btn.small {
    min-height: 2.1rem;
    padding: .35rem .55rem;
  }
}

/* Wide payroll/timesheet table needs to scroll inside its own wrapper at
   tablet/phone widths. On desktop the .ts-scroll element is intentionally
   `overflow: visible` (single-page-scroll model from base.html); below
   1024px we switch it to a pan container so the dense grid doesn't force
   the whole page body to side-scroll. */
@media (max-width: 1024px) {
  .tc-content .ts-scroll {
    overflow-x: auto !important;
    -webkit-overflow-scrolling: touch;
    max-width: 100%;
  }
  .tc-content .ts-scroll .timesheet-table,
  .tc-content .ts-scroll .ts-weeks-table {
    /* min-width:1100px is baked in the page CSS; keep it so columns stay
       readable while the wrapper handles the pan. */
  }
  /* Metric tiles: 3-up / 4-up collapses to 2 cols on iPad portrait. */
  .tc-content .metric-grid.three-up,
  .tc-content .metric-grid.four-up {
    grid-template-columns: repeat(2, 1fr);
  }
  /* Pay-period header row + jump-to-day stack cleanly. */
  .tc-content .table-toolbar {
    flex-wrap: wrap;
    gap: .5rem;
  }
  .tc-content .ts-jump {
    flex-wrap: wrap;
  }
  /* Print dropdown popover: pinning to `right:0` clips off-screen on the
     narrowest tablets when the actions row wraps. Anchor to the start of
     its container and cap width to the viewport. */
  .tc-content .ts-print-pop {
    right: auto;
    left: 0;
    max-width: calc(100vw - 1rem);
  }
}

@media (max-width: 575.98px) {
  /* Single column on phone for all metric grids. */
  .tc-content .metric-grid.two-up,
  .tc-content .metric-grid.three-up,
  .tc-content .metric-grid.four-up {
    grid-template-columns: 1fr;
  }
  /* 2-col and 3-col editor grids inside the timesheet modal collapse so
     time + note inputs aren't cut off. */
  .tc-content .timesheet-editor-grid,
  .tc-content .add-punch-form .form-grid {
    grid-template-columns: 1fr;
  }
  /* Detail rows / section heads inside cards wrap their label/value. */
  .tc-content .detail-row,
  .tc-content .section-head {
    flex-wrap: wrap;
    gap: .35rem;
  }
  /* Modal/overlay: tc-content overlay-card uses width:min(90vw,640px),
     which already shrinks; tighten its body padding so the form fields
     have room. */
  .tc-content .overlay-card {
    width: calc(100vw - 1rem);
    max-height: calc(100dvh - 2rem);
  }
  .tc-content .overlay-body {
    padding: .75rem .75rem;
  }
  /* Legend wraps tighter on phone. */
  .tc-content .ts-legend {
    gap: .6rem .9rem;
  }
}
