/*
 * Cross-cutting interface polish for the admin pages.
 *
 * Every view carries its own inline <style>, so before this file there was nowhere to put
 * a rule that should hold everywhere. It is loaded from views/partials/sidebar.ejs, which
 * all 21 admin pages already include, so a page added later inherits this automatically.
 *
 * Deliberately narrow: it fixes things that were wrong or missing on every page rather
 * than restyling anything. Nothing here changes a page's colours or layout on desktop.
 */

/* ------------------------------------------------------------------ 1. Press feedback
 *
 * Feedback belonged on pointer-DOWN, not on release -- waiting for the click to show
 * anything reads as lag even when the handler is instant. Scale is the cheapest honest
 * acknowledgement, and it is compositor-only so it cannot cost a frame.
 *
 * :active only, so it never fights a page's own hover styles.
 */
button:not(:disabled):active,
.btn:not(:disabled):active,
.pbtn:not(:disabled):active,
[onclick]:active {
  transform: scale(0.97);
}

button, .btn, .pbtn, [onclick] {
  transition: transform 90ms cubic-bezier(0.2, 0, 0.2, 1);
  /* Stops the double-tap-to-zoom delay swallowing the first 300ms of every tap. */
  touch-action: manipulation;
}

/* A pressed row/card should acknowledge too, but far more gently than a button. */
tr[onclick]:active,
.card[onclick]:active {
  transform: scale(0.995);
}

/* ------------------------------------------------------------------ 2. Touch targets
 *
 * Scoped to coarse pointers on purpose. A finger needs ~44px; a mouse does not, and
 * forcing 44px on desktop would wreck the density of the order and inventory tables.
 */
@media (pointer: coarse) {
  button,
  .btn,
  .pbtn,
  a.btn,
  select,
  input[type="checkbox"],
  input[type="radio"] {
    min-height: 44px;
  }

  /* A browser-default checkbox is 13x13, which is far under a fingertip. Only applies
     to controls that are actually visible -- a pattern that hides the real input behind
     a styled label (the catering form's veg/non-veg choice does this) is left alone,
     since there the label is the hit target and is already large. */
  input[type="checkbox"]:not([hidden]),
  input[type="radio"]:not([hidden]) {
    min-width: 22px;
    width: 22px;
    height: 22px;
  }
  /* Visually-hidden inputs must keep their own geometry. */
  input[type="checkbox"][style*="opacity"],
  input[type="radio"][style*="opacity"],
  .choices input,
  .sr-only {
    min-width: 0;
  }

  /* Icon-only buttons are square, so a min-height alone leaves them a thin strip. */
  button:not(:disabled) {
    min-width: 44px;
  }

  /* ...except where the button is inside a dense row of them, which would then wrap. */
  td button, .actions button, .row-actions button {
    min-width: 38px;
    min-height: 38px;
  }

  /* The sidebar close affordance was a 15x24 glyph. */
  .close-sidebar-btn {
    width: 44px;
    height: 44px;
    display: flex !important;
    align-items: center;
    justify-content: center;
  }
}

/* ------------------------------------------------------- 3. Horizontal overflow safety
 *
 * A page wider than the viewport is the most common responsive failure here: the whole
 * document slides sideways and fixed chrome detaches. Wide content must scroll inside
 * its own container instead of widening the page.
 */
@media (max-width: 900px) {
  .table-container,
  .section,
  .panel,
  .tbl-wrap,
  .data-card,
  .report-card {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
  }

  /* Filter/toolbar rows are flex+nowrap in several views and cannot shrink. */
  .filters,
  .custom,
  .toolbar,
  .topbar-right {
    flex-wrap: wrap;
  }

  /* Tab strips scroll rather than push the page wide. */
  .tabs,
  .tabs-container,
  .nav-tabs {
    display: flex;
    overflow-x: auto;
    flex-wrap: nowrap;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
  }
  .tabs::-webkit-scrollbar,
  .tabs-container::-webkit-scrollbar,
  .nav-tabs::-webkit-scrollbar { display: none; }
  .tabs > *,
  .tabs-container > *,
  .nav-tabs > * { flex: 0 0 auto; }
}

/* ------------------------------------------------------------------ 4. Reduced motion
 *
 * 24 views animate; exactly one honoured this. Reduced motion does not mean no feedback
 * -- opacity and colour still convey state. What goes is travel, spring and parallax,
 * which is what actually provokes vestibular discomfort.
 */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
  /* Keep the press acknowledgement, just without the movement. */
  button:not(:disabled):active,
  .btn:not(:disabled):active,
  .pbtn:not(:disabled):active,
  [onclick]:active {
    transform: none;
    filter: brightness(0.94);
  }
}

/* --------------------------------------------------- 5. Transparency / contrast prefs
 *
 * Several views use translucent bars. When the reader has asked for solid surfaces or
 * more contrast, a blur is a legibility problem rather than a material.
 */
@media (prefers-reduced-transparency: reduce) {
  .topbar,
  .sidebar,
  header {
    backdrop-filter: none !important;
    -webkit-backdrop-filter: none !important;
  }
}

@media (prefers-contrast: more) {
  button, .btn, .pbtn, input, select, textarea {
    border: 1px solid currentColor;
  }
  .panel, .card, .section, .table-container {
    border: 1px solid #94a3b8;
  }
}

/* --------------------------------------------------------------------- 6. Focus rings
 *
 * Keyboard users had nothing consistent to follow. :focus-visible keeps it off mouse
 * clicks, so this costs pointer users nothing.
 */
:focus-visible {
  outline: 2px solid #0f766e;
  outline-offset: 2px;
  border-radius: 6px;
}

/* ------------------------------------------------------------------------ 6b. Top bar
 *
 * Five views (categories, coupons, parcel, reports, takeaway) hand-roll their own
 * .topbar instead of including partials/topbar.ejs, so fixing the partial alone left
 * them ~80px wider than a phone. The rule belongs here, where it reaches every page.
 *
 * A flex item defaults to min-width:auto and so refuses to shrink below its content;
 * that is what pushed the bar past the viewport.
 */
.topbar { min-width: 0; }
.topbar > * { min-width: 0; }
.topbar h1 {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

@media (max-width: 640px) {
  .topbar { padding-left: 14px; padding-right: 14px; gap: 10px; }
  .topbar h1 { font-size: 18px; }
  /* Decorative context in a top bar ("Menu Hierarchy" and friends) is the first thing
     to go on a phone -- the title and the action have to fit first. */
  .topbar-meta, .user-details { display: none !important; }
}

/* ------------------------------------------------------------------- 7. Form controls
 *
 * iOS zooms the page when a focused input's text is under 16px. That zoom then leaves
 * the layout shifted, which reads as the page breaking on tap.
 */
@media (max-width: 900px) {
  input, select, textarea {
    font-size: 16px;
  }
}

/* A select sizes itself to its longest option, so a wordy one ("Purchases (opening +
 * buys - closing)") can be wider than the phone. Nothing may exceed its container. */
input, select, textarea {
  max-width: 100%;
}

/* Toolbar cells are flex items and inherit min-width:auto, so a wide control inside one
 * pushes the row instead of the row shrinking. */
.fld, .filters > *, .toolbar > * {
  min-width: 0;
}

/* ------------------------------------------------------------------- 8. Long content
 *
 * Dish names, customer names and addresses are user-typed and occasionally have no
 * spaces; without this one of them can widen a whole table.
 *
 * `break-word`, NOT `anywhere`: `anywhere` also shrinks the element's intrinsic
 * min-content width, so a squeezed table column collapses to one character per line and
 * headings render vertically. `break-word` only breaks when a word genuinely cannot fit.
 */
td, th, .panel-title, .card .val {
  overflow-wrap: break-word;
}

/* A table in a scroll container must keep a usable width instead of being crushed into
 * one-letter columns -- the container is there precisely so it can scroll. */
@media (max-width: 900px) {
  .table-container > table,
  .tbl-wrap > table,
  .section > table {
    min-width: 560px;
  }
}
