/* ============================================================
   Reaction ERP — every screen it might be opened on.
   ============================================================
   A site engineer photographs a pour on a phone, a project manager reads the
   critical path on a laptop, and the chairman opens the portfolio on
   whatever is nearest. The same application has to work on all three, and
   "works" means the buttons are reachable with a thumb and no two things ever
   sit on top of each other.

   Four sizes, and the reason each one exists:

     ≤ 1180px  the menu gives up its labels — the content column matters more
     ≤ 900px   the menu leaves the page entirely and becomes a drawer
     ≤ 680px   one column everywhere; rows of controls become stacks
     ≤ 420px   the smallest phone still in use; nothing may overflow it

   Written last in the cascade so it can correct anything above it without
   fighting specificity, and grouped by what it fixes rather than by selector.
   ============================================================ */

/* ============================================================
   ≤ 1180 — the menu stops spelling itself out
   ============================================================ */
@media (max-width: 1180px) {
  .sidebar { width: 66px; }
  .sidebar .sb-org { justify-content: center; }
  .sidebar .sb-org .txt,
  .sidebar .sb-group .txt,
  .sidebar .sb-item .txt,
  .sidebar .sb-user .info { display: none; }
  .sidebar .sb-group { padding: 11px 4px 3px; text-align: center; }
  .sidebar .sb-group::after { content: "·"; }
  .sidebar .sb-item { justify-content: center; padding: 10px 0; }
  .sidebar .sb-item.on::before { left: -6px; }
  .sidebar .sb-user { flex-direction: column; gap: 8px; }
  .view { padding: 16px 16px; }
}

/* ============================================================
   ≤ 900 — the menu becomes a drawer
   ------------------------------------------------------------
   Below this width a permanent menu is not a menu, it is a wall: it takes a
   fifth of the screen to show icons nobody can read. So it slides out over
   the content when it is asked for, and gets out of the way the moment a
   route is chosen.
   ============================================================ */
@media (max-width: 900px) {
  .sidebar {
    position: fixed; inset: 0 auto 0 0; z-index: 60;
    width: 268px; max-width: 84vw;
    transform: translateX(-100%);
    transition: transform .2s ease;
    box-shadow: 8px 0 28px rgba(10, 20, 32, .28);
  }
  /* Inside the drawer the labels come back — there is room for them now */
  .sidebar .sb-org { justify-content: flex-start; }
  .sidebar .sb-org .txt,
  .sidebar .sb-group .txt,
  .sidebar .sb-item .txt,
  .sidebar .sb-user .info { display: block; }
  .sidebar .sb-group { padding: 14px 9px 5px; text-align: left; }
  .sidebar .sb-group::after { content: none; }
  .sidebar .sb-item { justify-content: flex-start; padding: 11px 12px; }
  .sidebar .sb-user { flex-direction: row; gap: 10px; }

  #app-root.nav-open .sidebar { transform: translateX(0); }
  #app-root.nav-open .nav-scrim { opacity: 1; pointer-events: auto; }

  .nav-scrim {
    position: fixed; inset: 0; z-index: 55;
    background: rgba(12, 20, 30, .5); backdrop-filter: blur(2px);
    opacity: 0; pointer-events: none; transition: opacity .2s ease;
    border: none; padding: 0; margin: 0;
  }

  /* The topbar carries the way back to the menu */
  .topbar { padding: 0 12px; gap: 8px; }
  .topbar .title { font-size: 14px; }
  .topbar .btn-refresh span,
  .topbar .btn-refresh { font-size: 0; padding: 7px 9px; }
  .topbar .btn-refresh svg { width: 16px; height: 16px; }
  /* The search takes the room the title gave up, and everything to the right
     of it keeps its size — a clipped language switch is worse than a short
     search box. */
  .gsearch { flex: 1 1 auto; min-width: 0; }
  .gsearch input { width: 100%; min-width: 0; }
  .tb-switches, .bell, .topbar .btn-refresh, #tb-collapse { flex: none; }
}
/* The scrim only exists on small screens */
@media (min-width: 901px) { .nav-scrim { display: none; } }

/* ============================================================
   ≤ 680 — one column, and every row of controls becomes a stack
   ============================================================ */
@media (max-width: 680px) {
  .view { padding: 12px 12px 26px; }
  .section { padding: 13px 13px; border-radius: 12px; }
  .section > h2 { font-size: 14px; flex-wrap: wrap; gap: 7px; }
  .section > h2 .muted { flex-basis: 100%; }

  /* Cards: one per row, and big enough to read at arm's length */
  .cards, .cards.tight, .cards.evm-cards { grid-template-columns: 1fr 1fr; gap: 9px; }
  .cards .card { padding: 12px; }
  .card .big, .cards.tight .card .big { font-size: 19px; }
  .evm-card .big { font-size: 17px; }

  /* Tabs scroll sideways instead of stacking into five rows */
  .tabs {
    flex-wrap: nowrap; overflow-x: auto; overflow-y: hidden;
    scrollbar-width: none; -webkit-overflow-scrolling: touch;
    margin: 0 -12px 14px; padding: 0 12px;
  }
  .tabs::-webkit-scrollbar { display: none; }
  .tab { flex: none; padding: 10px 12px; font-size: 12.5px; }

  /* The second tier scrolls the same way. Both rows bleed to the edge of the
     screen so a half-cut chip shows there is more to swipe to — a row that
     ends flush at the margin reads as the whole list. */
  .tabs.grouped { margin-bottom: 0; }
  .subtabs { margin: 9px 0 14px; }
  .subtab-row {
    flex-wrap: nowrap; overflow-x: auto; scrollbar-width: none;
    -webkit-overflow-scrolling: touch; margin: 0 -12px; padding: 2px 12px;
  }
  .subtab-row::-webkit-scrollbar { display: none; }
  .subtab { flex: none; min-height: 34px; }

  /* The header of a record */
  .detail-head { flex-wrap: wrap; gap: 10px; }
  .detail-head .detail-title h1 { font-size: 19px; }
  .detail-head .detail-actions { width: 100%; }
  .detail-head .detail-actions .btn { flex: 1; justify-content: center; }

  /* Anything that was a row of buttons beside text */
  .a-head { flex-wrap: wrap; }
  .a-actions { width: 100%; }
  .a-actions .btn { flex: 1 1 46%; justify-content: center; }

  .toolbar, .cf-range, .gt-tools, .gt-actions { flex-wrap: wrap; gap: 8px; }
  .gt-actions { width: 100%; }
  .gt-actions .btn { flex: 1 1 46%; justify-content: center; }
  .cf-dates { flex-wrap: wrap; }
  .seg { flex-wrap: wrap; }

  /* Tables stay tables — they scroll, and they never squash a number */
  table.table thead th, table.table tbody td { padding: 7px 9px; font-size: 12px; }
  table.data thead th, table.data tbody td { padding: 8px 10px; font-size: 12.5px; }

  /* A modal on a phone is a sheet from the bottom, not a floating box */
  .modal-backdrop { align-items: flex-end; padding: 0; }
  .modal, .modal.wide {
    width: 100%; max-width: 100%; max-height: 92vh;
    border-radius: 16px 16px 0 0; margin: 0;
  }
  .modal-foot { flex-wrap: wrap; }
  .modal-foot .btn { flex: 1 1 40%; justify-content: center; }

  /* The pinned name column on the Gantt gives up half its width */
  .gt-wrap { --label-w: 150px !important; }
  .gt-label { font-size: 11px; padding: 0 6px; }
  .gt-who { display: none; }

  .chart-legend { gap: 10px; font-size: 11px; }
  .detail-grid { grid-template-columns: 1fr; }
  .hero { flex-wrap: wrap; gap: 12px; }
  .hero-stats { width: 100%; justify-content: space-between; }
  .mini-stats { grid-template-columns: 1fr 1fr; }
  .form-grid { grid-template-columns: 1fr; }
  .form-grid .span2 { grid-column: span 1; }

  /* Touch targets: 40px is the smallest a thumb hits reliably */
  .btn, .icon-btn, .sb-item, .tab { min-height: 38px; }
  .btn.small, .btn.sm { min-height: 34px; }
  input.input, select.input, textarea.input { font-size: 16px; }   /* iOS: no zoom-on-focus */
}

/* ============================================================
   ≤ 420 — the smallest phone still in use
   ============================================================ */
@media (max-width: 420px) {
  .cards, .cards.tight, .cards.evm-cards, .mini-stats { grid-template-columns: 1fr; }
  .topbar .title { display: none; }
  .tb-switches .lang-seg { display: none; }
  .a-actions .btn, .gt-actions .btn { flex: 1 1 100%; }
  /* Cancel and Save stay side by side even here: stacking them costs a row of
     screen on the smallest device, which is where rows cost most. */
  .modal-foot .btn { flex: 1 1 42%; }
  .detail-head .detail-avatar { width: 42px; height: 42px; }
  .gt-wrap { --label-w: 124px !important; }
  /* On the narrowest screen the group's explanation is a paragraph in the way
     of the page. The tab it hangs under still carries it as a tooltip. */
  .tab-note { display: none; }
}

/* ============================================================
   Pointer-coarse: phones and tablets, whatever their width
   ------------------------------------------------------------
   A tooltip that appears on hover is invisible on a touch screen, and a
   hover state that sticks after a tap looks like a selection. Both go.
   ============================================================ */
@media (hover: none) {
  .table.data tbody tr:hover, table.table tbody tr:hover { background: inherit; }
  .btn:hover, .icon-btn:hover { transform: none; }
}

/* ============================================================
   Short windows — a laptop with the browser half-height
   ============================================================ */
@media (max-height: 560px) {
  .modal { max-height: 94vh; }
  .aon-scroll { max-height: 52vh; }
}

/* ============================================================
   ≤ 680 — a table on a phone is a list of cards
   ------------------------------------------------------------
   A twelve-column register scrolled sideways on a 390px screen is a table
   nobody reads: the identifying column disappears the moment you scroll to
   the column you wanted. So below this width each row becomes a card, the
   first column becomes its heading, and every other cell wears the name of
   its column. Same DOM, same sorting, same search — only the shape changes.
   ============================================================ */
@media (max-width: 680px) {
  .table-wrap, .table-scroll { overflow-x: visible; border: none; background: none; box-shadow: none; }

  /* `.table-scroll table.data` carries min-width 520px for the scrolling
     layout; it outranks the bare selector, so the card layout has to repeat
     itself at the same strength or every card is 520px wide with its values
     pushed off the right edge of the screen. */
  table.data, .table-scroll table.data, .table-wrap table.data { min-width: 0; }
  table.data { display: block; background: none; }
  table.data thead { display: none; }
  table.data tbody { display: flex; flex-direction: column; gap: 9px; }

  table.data tbody tr {
    display: block; background: var(--surface);
    border: 1px solid var(--border); border-radius: 12px;
    padding: 11px 12px; box-shadow: var(--shadow-sm);
  }
  table.data tbody tr:hover { background: var(--surface); }

  table.data tbody td {
    display: flex; gap: 10px; align-items: baseline; justify-content: space-between;
    border: none; padding: 3px 0; max-width: none; white-space: normal;
    font-size: 12.5px; text-align: right;
  }
  table.data tbody td::before {
    content: attr(data-label);
    flex: none; color: var(--text-dim); font-size: 11px; font-weight: 700;
    text-transform: uppercase; letter-spacing: .04em; text-align: left;
  }
  /* An empty cell earns no line at all */
  table.data tbody td:empty { display: none; }

  /* The first column is the record's name, so it reads as the card's title */
  table.data tbody td.cell-primary {
    display: block; text-align: left; font-size: 14.5px; font-weight: 700;
    color: var(--heading); padding: 0 0 6px; margin-bottom: 5px;
    border-bottom: 1px solid var(--border);
  }
  table.data tbody td.cell-primary::before { content: none; }

  table.data tbody td.cell-actions {
    justify-content: flex-end; gap: 6px; padding-top: 9px; margin-top: 6px;
    border-top: 1px solid var(--border);
  }
  table.data tbody td.cell-actions::before { margin-right: auto; }
  table.data tbody td.cell-actions .icon-btn { width: 36px; height: 36px; }

  table.data tbody tr.empty-row { text-align: center; }
  table.data tbody tr.empty-row td { display: block; text-align: center; }
  table.data tbody tr.empty-row td::before { content: none; }

  /* The report tables (compact, totals at the foot) keep their shape but get
     out of the way of the thumb: they scroll inside their own box. */
  .table-scroll { overflow-x: auto; }
  table.table { min-width: 560px; }
}

/* ============================================================
   Reachable without a mouse, and calm for people who ask for calm
   ============================================================ */

/* Everything that can be clicked shows where the keyboard is. :focus-visible
   rather than :focus, so a mouse click does not leave a ring behind it. */
:focus-visible {
  outline: 2px solid var(--c-main);
  outline-offset: 2px;
  border-radius: 6px;
}
tr.clickable:focus-visible,
.gt-label:focus-visible,
.wx-day:focus-visible { outline-offset: -2px; }

/* A row that can be opened says so on hover as well as on focus */
table.table tbody tr[role="link"] { cursor: pointer; }

/* Icon buttons stay hittable: 24px is the smallest square WCAG 2.2 accepts,
   and a thumb wants more than the minimum. */
.icon-btn { min-width: 28px; min-height: 28px; }
@media (max-width: 680px) { .icon-btn { min-width: 38px; } }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
    scroll-behavior: auto !important;
  }
}
