/* =====================================================================
   Responsive layer for the signed-in app (dashboard.html, settings.html).
   Loaded after every other stylesheet so it settles the layout questions
   the older rules left open. Two jobs:

   1. Desktop: give the invoice list room. The stat cards and the two
      filter cards used to eat the viewport, and the list card's floor
      (280px) was shorter than its own header, filter band, column header
      and pager, so on a window under ~1040px tall it showed no rows at
      all and none could be scrolled to.
   2. Mobile, down to 320px: one long vendor name used to stretch every
      invoice card past the screen and push the amount out of sight, the
      header took three lines, the stat cards filled the first screen,
      the menu could not scroll, and Settings trapped its content in a
      231px box.

   Keep changes here rather than in the page's own <style> blocks: those
   are edited by several people at once, and a later block there would
   quietly defeat a fix made earlier in the same file.
   ===================================================================== */

/* ---------------------------------------------------------------------
   1. Desktop and tablet: density
   ------------------------------------------------------------------ */
@media (min-width: 770px) {
  /* The three tiles are a glance, not the subject of the page. */
  #view-dashboard .stats-grid {
    gap: 1rem !important;
    margin-bottom: 1rem !important;
    padding: 0 !important;
  }

  #view-dashboard .stat-card {
    padding: 1rem 1.25rem !important;
    border-radius: 16px;
  }

  #view-dashboard .stat-header {
    margin-bottom: 0.35rem;
  }

  #view-dashboard .stat-icon {
    width: 36px !important;
    height: 36px !important;
    border-radius: 10px;
    font-size: 0.95rem !important;
  }

  #view-dashboard .stat-value {
    font-size: clamp(1.45rem, 1.9vw, 1.9rem) !important;
    margin-bottom: 0 !important;
  }

  /* The tiles take the height the list does not need (fitDashboardPanels). */
  #view-dashboard .stat-card {
    display: flex;
    flex-direction: column;
    justify-content: center;
  }

  /* The view is the scroller, so a tile lifting on hover was clipped against
     its top edge. This is the room that lift and its shadow need. */
  #view-dashboard.view-section.active {
    padding-top: 10px;
  }

  /* Grown tiles: the label sits at the top, the figure takes the middle, and
     the icon moves up beside the label instead of everything huddling in the
     centre of a much taller card. */
  #view-dashboard .stats-grid[data-grown="true"] .stat-card {
    justify-content: flex-start;
    padding: 1.35rem 1.5rem !important;
  }

  #view-dashboard .stats-grid[data-grown="true"] .stat-header {
    margin-bottom: 0;
  }

  #view-dashboard .stats-grid[data-grown="true"] .stat-value {
    display: flex;
    flex: 1;
    align-items: center;
    font-size: clamp(1.8rem, 2.6vw, 2.6rem) !important;
  }

  #view-dashboard .stats-grid[data-grown="true"] .stat-icon {
    width: 44px !important;
    height: 44px !important;
    font-size: 1.1rem !important;
  }

  #view-dashboard .stats-grid[data-grown="true"] .stat-label {
    font-size: 0.82rem;
  }

  /* Both filter cards carried a 102px floor to stop a load-time jump.
     The floor is no longer needed now that they size to one row. */
  #view-dashboard .currency-filter-container,
  #view-dashboard .type-filter-container {
    min-height: 0 !important;
    padding: 0.75rem 1rem !important;
    margin-bottom: 1rem !important;
  }

  #view-dashboard .currency-filter-label,
  #view-dashboard .type-filter-label {
    margin-bottom: 0.5rem;
  }

  #view-dashboard .table-header {
    padding: 1rem 1.5rem;
  }

  /* Row height sets how many receipts fit; 1.25rem top and bottom was
     more air than the 40px thumbnail needs. */
  #view-dashboard .scan-table:not(.team-table) td,
  #view-invoices .scan-table:not(.team-table) td {
    padding-top: 0.8rem;
    padding-bottom: 0.8rem;
  }

  /* The old floor (280px) was shorter than the card's own header, filter
     band, column header and pager, so a short window left nothing for the
     rows and none could be scrolled to. This floor covers that chrome
     plus about three rows; when the window cannot give the card that
     much, the view scrolls instead of the rows disappearing. */
  #view-dashboard .table-container {
    min-height: 33rem !important;
  }
}

/* Wide enough for the two filter cards to share a row, which buys the
   list another ~100px without hiding anything. */
@media (min-width: 1100px) {
  #view-dashboard.view-section.active {
    display: grid !important;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    /* minmax(0, ...) so the row tracks the window rather than growing to
       the full length of the list; the card's own floor handles a window
       too short to show rows. */
    grid-template-rows: auto auto minmax(0, 1fr);
    column-gap: 1rem;
  }

  #view-dashboard.view-section.active > .stats-grid,
  #view-dashboard.view-section.active > .table-container {
    grid-column: 1 / -1;
  }
}

/* ---------------------------------------------------------------------
   2. Phones and small tablets (<= 769px)
   ------------------------------------------------------------------ */
@media (max-width: 769px) {
  /* --- Page header: one line, always --- */
  body .app-header {
    flex-wrap: nowrap !important;
    align-items: center;
    gap: 0.75rem;
    padding: 0.85rem 1rem !important;
  }

  body .app-header > div:first-child {
    width: auto !important;
    flex: 1 1 auto;
    min-width: 0;
    gap: 0.75rem;
    margin-bottom: 0 !important;
  }

  /* The title block must be allowed to shrink for its text to ellipsis. */
  body .app-header > div:first-child > div {
    min-width: 0;
  }

  body .app-header h1 {
    font-size: 1.3rem !important;
    margin-bottom: 0.1rem;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }

  body .app-header p {
    font-size: 0.78rem !important;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }

  body .header-actions {
    width: auto !important;
    margin-top: 0 !important;
    flex: 0 0 auto;
    gap: 0.5rem;
  }

  /* A squeezed hamburger stopped being a 44px target at 320px. */
  .mobile-menu-btn {
    flex: 0 0 44px;
    width: 44px !important;
    height: 44px !important;
  }

  body.business-mode #company-badge {
    max-width: 38vw;
    overflow: hidden;
  }

  body.business-mode #company-code-display {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  /* --- Room for the floating scan button at the end of a view ---
     Sized to what the button actually covers rather than a guess: it is
     50px tall sitting 1rem up (see the rule below, which holds for the whole
     of this range), so 66px plus a little air. Every view pays this at the
     bottom of its scroll, so it is kept as tight as it can honestly be. */
  body:not(.aichat-active) .content-area {
    padding-bottom: 3.5rem !important;
  }

  /* One size for the button across phones and small tablets, so the room
     left for it above is right at every width in this range. */
  .fab {
    width: 50px !important;
    height: 50px !important;
    right: 1rem !important;
    bottom: calc(1rem + env(safe-area-inset-bottom, 0px)) !important;
    font-size: 1.3rem !important;
  }

  /* While receipts are selected the action bar covers the foot of the page;
     without this the last row cannot be scrolled out from under it. */
  body.has-selection:not(.aichat-active) .content-area {
    padding-bottom: calc(8rem + env(safe-area-inset-bottom, 0px)) !important;
  }

  /* The view adds its own 1.5rem on top of that. */
  body:not(.aichat-active) .view-section.active {
    padding-bottom: 1rem;
  }

  /* Reports and Analytics carry a desktop's trailing padding as well (80px
     and 48px, plus their own inner padding), which on a phone reads as a
     screenful of nothing after the last card. Every tab should end the
     same way. */
  #view-reports.view-section.active,
  #view-analytics.view-section.active {
    padding-bottom: 1rem !important;
  }

  #view-reports .reports-grid {
    margin-bottom: 0 !important;
    padding-bottom: 0 !important;
  }

  /* This element carries the name as an id, not a class. */
  #view-analytics #analytics-content {
    padding-bottom: 0 !important;
  }

  /* --- The drawer has to scroll --- */
  .app-sidebar {
    width: min(280px, 86vw);
    overflow-y: auto;
    overscroll-behavior: contain;
  }

  /* Its nav was the only scroller, so on a 640px screen the menu showed
     two of its twelve links inside a 125px box. */
  .app-sidebar > nav {
    flex: 0 0 auto !important;
    overflow: visible !important;
  }

  /* Keep the profile and sign-out block at the bottom when there is room. */
  .app-sidebar > div:last-child {
    margin-top: auto;
  }

  .workspace-display-container {
    padding: 1rem !important;
    margin-bottom: 1.25rem !important;
  }

  /* --- Stat tiles: spend across the top, the two counts beneath --- */
  #view-dashboard .stats-grid {
    grid-template-columns: 1fr 1fr !important;
    gap: 0.6rem !important;
    margin-bottom: 1rem !important;
    padding: 0 !important;
  }

  #view-dashboard .stat-card {
    padding: 0.75rem 0.85rem !important;
    border-radius: 14px;
    display: grid !important;
    grid-template-columns: auto minmax(0, 1fr);
    grid-template-areas:
      "icon label"
      "icon value";
    column-gap: 0.7rem;
    row-gap: 2px;
    align-items: center;
  }

  #view-dashboard .stat-card .stat-header {
    display: contents !important;
  }

  #view-dashboard .stat-card .stat-icon {
    grid-area: icon;
    width: 34px !important;
    height: 34px !important;
    border-radius: 10px;
    font-size: 0.9rem !important;
    animation: none;
  }

  /* "TOTAL SCANS" does not fit on one line in a half-width tile, and a
     truncated label reads worse than a wrapped one. */
  #view-dashboard .stat-card .stat-label {
    grid-area: label;
    font-size: 0.62rem;
    letter-spacing: 0.04em;
    line-height: 1.15;
    white-space: normal;
    min-width: 0;
  }

  #view-dashboard .stat-card .stat-value {
    grid-area: value;
    font-size: 1.3rem !important;
    line-height: 1.15;
    margin: 0 !important;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    min-width: 0;
  }

  /* Total spend is the number people come for, so it gets the full width
     and the larger type. */
  #view-dashboard .stat-card.stat-green {
    grid-column: 1 / -1;
    order: -1;
  }

  #view-dashboard .stat-card.stat-green .stat-value {
    font-size: 1.55rem !important;
  }

  /* --- Filter cards: shorter, and their chips scroll sideways --- */
  .currency-filter-container,
  .type-filter-container {
    min-height: 0 !important;
    padding: 0.6rem 0.8rem !important;
    margin-bottom: 0.6rem !important;
    border-radius: 12px;
  }

  .currency-filter-label,
  .type-filter-label {
    margin-bottom: 0.4rem;
    font-size: 0.7rem;
  }

  .currency-filter-buttons,
  .type-filter-buttons {
    flex-wrap: nowrap;
    overflow-x: auto;
    scrollbar-width: none;
    margin: 0 -0.85rem;
    padding: 0 0.85rem 2px;
  }

  .currency-filter-buttons::-webkit-scrollbar,
  .type-filter-buttons::-webkit-scrollbar {
    display: none;
  }

  .currency-filter-btn,
  .type-filter-btn {
    flex: 0 0 auto;
    min-height: 36px;
    padding: 0.4rem 0.85rem;
  }

  /* --- Invoice cards: the amount must stay on screen ---
     Each row is its own grid; a 1fr vendor column still refuses to go
     below the width of an unwrapped vendor name, so one long name made
     every card 457px wide inside a 270px list. */
  .scan-table:not(.team-table) tbody {
    padding: 0.6rem !important;
  }

  .scan-table:not(.team-table) tr:not(.group-header-row):not(.group-more-row) {
    grid-template-columns: 26px 44px minmax(0, 1fr) auto !important;
    gap: 0.2rem 0.65rem !important;
    padding: 0.75rem !important;
    margin-bottom: 0.55rem;
    border-radius: 14px;
  }

  .scan-table:not(.team-table) td[data-label="Vendor"] {
    min-width: 0;
    max-width: none;
    font-size: 0.95rem;
  }

  .scan-table:not(.team-table) td[data-label="Category"] {
    min-width: 0;
  }

  .scan-table:not(.team-table) td[data-label="Category"] .category-badge {
    display: inline-block;
    max-width: 100%;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  .scan-table:not(.team-table) td[data-label="Amount"] {
    font-size: 1rem;
    white-space: nowrap;
  }

  .scan-table:not(.team-table) td[data-label="Date"] {
    font-size: 0.75rem;
    white-space: nowrap;
  }

  .scan-table:not(.team-table) td[data-label="Image"] > img,
  .scan-table:not(.team-table) .manual-entry-thumb-badge,
  .scan-table:not(.team-table) .gmail-sync-thumb-badge {
    width: 44px !important;
    height: 44px !important;
  }

  .scan-table:not(.team-table) .gmail-sync-thumb-badge img {
    width: 22px !important;
    height: 22px !important;
    border: none !important;
    border-radius: 0 !important;
    box-shadow: none !important;
    background: transparent !important;
  }

  /* --- List card chrome --- */
  .table-header {
    padding: 0.9rem 1rem !important;
    gap: 0.6rem;
  }

  .table-header-tools > .btn {
    padding: 0.5rem 0.75rem;
    min-height: 38px;
    font-size: 0.8rem;
  }

  /* 16px keeps iOS from zooming the page when the field takes focus. */
  .table-search-wrap input {
    font-size: 16px;
  }

  .invoice-list-controls {
    padding: 0.75rem 1rem !important;
  }

  /* One scrolling row of chips instead of four stacked rows. */
  .group-chips {
    flex-wrap: nowrap !important;
    max-width: 100%;
    overflow-x: auto;
    scrollbar-width: none;
    margin: 0 -1rem;
    padding: 0 1rem 2px;
  }

  .group-chips::-webkit-scrollbar {
    display: none;
  }

  .group-chip {
    flex: 0 0 auto;
    min-height: 36px;
  }

  .list-controls-right {
    width: 100%;
  }

  .list-select {
    width: 100%;
  }

  .icon-btn {
    width: 36px;
    height: 36px;
  }

  /* --- Views beyond the dashboard --- */

  /* Job cards asked for 320px columns, which is wider than a 320px
     screen once the page padding is taken off, so the page scrolled
     sideways. */
  #batch-jobs-list {
    grid-template-columns: repeat(auto-fit, minmax(min(320px, 100%), 1fr)) !important;
  }

  .analytics-metric-label {
    font-size: 0.72rem !important;
  }

  .add-ws-btn {
    width: 36px !important;
    height: 36px !important;
  }

  /* Four stacked full-width buttons took the bottom half of the receipt
     popup on a phone. */
  #invoice-modal .modal-footer {
    display: grid !important;
    grid-template-columns: 1fr 1fr;
    gap: 0.5rem;
    padding: 0.85rem 1rem !important;
  }

  #invoice-modal .modal-footer .btn {
    width: 100%;
    min-height: 42px;
    padding: 0.6rem 0.5rem;
    font-size: 0.82rem;
  }

  #invoice-modal .modal-footer #edit-invoice-btn-trigger {
    grid-column: 1 / -1;
    order: 1;
  }

  #invoice-modal .modal-footer #push-xero-btn-trigger,
  #invoice-modal .modal-footer #push-sage-btn-trigger {
    order: 2;
  }

  #invoice-modal .modal-footer #delete-invoice-btn {
    grid-column: 1 / -1;
    order: 3;
  }
}

/* ---------------------------------------------------------------------
   3. Ultra narrow (<= 400px)
   ------------------------------------------------------------------ */
@media (max-width: 400px) {
  body:not(.aichat-active) .content-area {
    padding: 1rem 0.85rem 3.5rem !important;
  }

  body .app-header {
    padding: 0.75rem 0.85rem !important;
  }

  body .app-header h1 {
    font-size: 1.15rem !important;
  }

  /* An icon-only Refresh keeps the title and the button on one line.
     The label stays in the accessibility tree for screen readers. */
  body .refresh-btn {
    width: 40px;
    padding: 0 !important;
    justify-content: center;
    gap: 0;
    font-size: 0 !important;
  }

  body .refresh-btn i {
    font-size: 0.95rem;
  }

  /* The zero-sized label still contributes a couple of pixels of scroll
     width to the header, which is enough for a stray sideways scroll. */
  body .refresh-btn,
  body .app-header {
    overflow: hidden;
  }

  .table-header,
  .invoice-list-controls,
  .list-pager {
    padding-left: 0.85rem !important;
    padding-right: 0.85rem !important;
  }

  /* Same trick for Export list: icon only, label still announced. */
  #export-list-btn,
  #all-invoices-export-btn {
    font-size: 0 !important;
    gap: 0;
    padding: 0.5rem 0.7rem;
  }

  #export-list-btn i,
  #all-invoices-export-btn i {
    font-size: 0.9rem;
  }

  .scan-table:not(.team-table) tr:not(.group-header-row):not(.group-more-row) {
    grid-template-columns: 22px 38px minmax(0, 1fr) auto !important;
    gap: 0.15rem 0.55rem !important;
    padding: 0.65rem !important;
  }

  .scan-table:not(.team-table) td[data-label="Image"] > img,
  .scan-table:not(.team-table) .manual-entry-thumb-badge,
  .scan-table:not(.team-table) .gmail-sync-thumb-badge {
    width: 38px !important;
    height: 38px !important;
  }

  .scan-table:not(.team-table) .gmail-sync-thumb-badge img {
    width: 20px !important;
    height: 20px !important;
    border: none !important;
    border-radius: 0 !important;
    box-shadow: none !important;
    background: transparent !important;
  }

  .scan-table:not(.team-table) td[data-label="Vendor"] {
    font-size: 0.88rem;
  }

  .scan-table:not(.team-table) td[data-label="Amount"] {
    font-size: 0.92rem;
  }

  .scan-table:not(.team-table) td[data-label="Category"] .category-badge {
    font-size: 0.62rem;
    padding: 0.2rem 0.45rem;
  }

  .group-chips {
    margin: 0 -0.85rem;
    padding: 0 0.85rem 2px;
  }

}

/* Short phones in landscape, and small screens generally: the drawer's
   own chrome must not crowd out the links. */
@media (max-height: 700px) and (max-width: 1400px) {
  .app-sidebar {
    padding: 1.25rem 1rem;
  }

  .workspace-display-container {
    padding: 0.85rem !important;
    margin-bottom: 1rem !important;
  }

  .app-sidebar .nav-item {
    padding: 0.7rem 0.9rem;
    margin-bottom: 0.3rem;
  }
}

/* ---------------------------------------------------------------------
   4. Settings page
   ------------------------------------------------------------------ */
@media (max-width: 769px) {
  /* The page was pinned to the viewport, so its content scrolled inside
     a 231px box beneath a header and tab strip that took 380px of a
     640px screen. Let the page itself scroll instead. */
  body.settings-page {
    overflow-y: auto !important;
    height: auto !important;
    min-height: 100vh;
  }

  body.settings-page .settings-container {
    height: auto !important;
    min-height: 100vh;
    padding: 1rem !important;
  }

  body.settings-page .settings-grid {
    height: auto !important;
    min-height: 0 !important;
    grid-template-rows: auto auto !important;
    gap: 1rem !important;
  }

  body.settings-page .settings-content,
  body.settings-page .settings-nav {
    height: auto !important;
    max-height: none !important;
    overflow-y: visible !important;
  }

  body.settings-page .settings-nav {
    overflow-x: auto !important;
    position: sticky;
    top: 0.5rem;
    z-index: 20;
  }

  body.settings-page .settings-content {
    padding: 1.25rem !important;
  }

  body.settings-page .settings-header {
    padding: 1.1rem !important;
    margin-bottom: 1rem !important;
    border-radius: 18px;
  }

  body.settings-page .settings-header h1 {
    font-size: 1.5rem !important;
    margin-bottom: 0.15rem;
  }

  body.settings-page .settings-header p {
    font-size: 0.85rem;
  }

  body.settings-page .header-content {
    flex-direction: row !important;
    align-items: center !important;
    gap: 0.75rem;
  }

  body.settings-page .header-content .btn {
    flex: 0 0 auto;
    padding: 0.55rem 0.8rem;
  }
}

/* ---------------------------------------------------------------------
   5. The edit-invoice dialog on a phone
   ------------------------------------------------------------------ */
@media (max-width: 769px) {
  /* The dialog was a desktop dialog shrunk to 95% of the screen, while its
     form kept a desktop's minimum width: the fields ran about 200px past the
     right edge with no way to scroll or reach them. */
  .modal-overlay .edit-invoice-dialog-container,
  .edit-invoice-dialog-container {
    width: calc(100vw - 12px) !important;
    max-width: none !important;
    max-height: 94vh !important;
    max-height: 94dvh !important;
    border-radius: 18px !important;
  }

  .edit-modal-header {
    padding: 0.9rem 1rem !important;
  }

  /* Let the flex column decide the height. The fixed calc() could exceed
     what was left after the header and footer, which is the other half of
     why the bottom of the form was unreachable. */
  .modal-wide .edit-modal-body,
  .edit-modal-body {
    flex: 1 1 auto !important;
    min-height: 0 !important;
    max-height: none !important;
    padding: 1rem !important;
    overflow-y: auto !important;
    overflow-x: hidden !important;
  }

  /* A 1fr track will not go below the minimum width of what is inside it,
     so the single-column form still measured a desktop's width. */
  .edit-invoice-grid,
  .edit-form-grid-2col,
  .edit-form-grid-3col {
    grid-template-columns: minmax(0, 1fr) !important;
  }

  .edit-invoice-grid > *,
  .edit-form-column,
  .edit-reference-column,
  .edit-section-card,
  .edit-section-header,
  .edit-form-group,
  .custom-input-wrapper,
  .custom-select-wrapper {
    min-width: 0 !important;
  }

  .edit-section-card {
    padding: 1rem !important;
  }

  /* 16px stops iOS zooming the page when a field takes focus. */
  .edit-invoice-dialog-container .custom-input,
  .edit-invoice-dialog-container .custom-select {
    font-size: 16px !important;
  }

  /* Two stacked full-width buttons took 137px of a screen that needed it
     for the form. */
  .edit-modal-footer {
    display: grid !important;
    grid-template-columns: 1fr 1fr !important;
    gap: 0.5rem !important;
    padding: 0.75rem 1rem !important;
  }

  .edit-modal-footer .btn {
    width: 100%;
    margin: 0 !important;
  }
}
