/* responsive.css — ALL breakpoint rules. Single breakpoint: 1100px.
   Scoped to `screen` so print output is never affected.
   Loaded LAST (after form.css) on every page. */

/* Bottom nav is mobile-screen-only. Hidden by default; the
   max-width:1100px media query re-enables .mnav (display:flex). */
.mnav, .mnav-sheet-mask { display: none; }
@media print { .mnav, .mnav-sheet-mask { display: none !important; } }

.mlist-sort { display: none; }
@media print { .mlist-sort { display: none !important; } }

/* ---- App loading splash ----
   Lives in body markup on every page; visible by default at every viewport
   width so it shows during the initial HTML parse / Babel compile, then
   hidden by mobile-loader.js once React replaces the #root skeleton.
   Re-shown when the user clicks an in-app nav link (so it bridges the
   white flash between full-page navigations on both desktop and phones).
   Transition rules are asymmetric on purpose: showing applies visibility
   instantly so the user sees the splash the moment they tap a nav link,
   while hiding waits for the 320ms opacity fade before flipping visibility
   so the splash actually fades out instead of disappearing abruptly. */
.ml-loader {
  display: flex; align-items: center; justify-content: center;
  position: fixed; inset: 0; z-index: 10000;
  background: #FFFFFF;
  color: var(--ink-700);
  opacity: 1; visibility: visible;
  transition: opacity 320ms ease, visibility 0s linear 0s;
}
.ml-loader.ml-loader--hidden {
  opacity: 0; visibility: hidden;
  pointer-events: none;
  transition: opacity 320ms ease, visibility 0s linear 320ms;
}
@media print { .ml-loader { display: none !important; } }

@keyframes ml-loader-bar {
  0%   { transform: translateX(-100%); }
  100% { transform: translateX(350%); }
}

.ml-loader-inner {
  display: flex; flex-direction: column; align-items: center;
  gap: 22px; padding: 24px;
  /* nudge the block slightly above true centre — feels more balanced on phones */
  transform: translateY(-4vh);
}
.ml-loader-logo {
  width: min(58%, 280px); height: auto; display: block;
  user-select: none; -webkit-user-drag: none;
  /* Fade the image's rectangular bounding box into the white backdrop so
     any non-pure-white pixels at the PNG's edges don't show as a visible
     square halo. The navy logo PNG carries a ~2.4% teal wash at its upper
     corners; the mask below fades those edges symmetrically into the white
     background.
     Composite two linear gradients to feather each edge independently:
     - horizontal mask fades 8% on each side
     - vertical mask fades 14% on each side
     The intersection (mask-composite: intersect) keeps the centre fully
     opaque and tapers all four edges smoothly into the white background. */
  -webkit-mask-image:
    linear-gradient(to right, transparent 0%, #000 8%, #000 92%, transparent 100%),
    linear-gradient(to bottom, transparent 0%, #000 14%, #000 86%, transparent 100%);
          mask-image:
    linear-gradient(to right, transparent 0%, #000 8%, #000 92%, transparent 100%),
    linear-gradient(to bottom, transparent 0%, #000 14%, #000 86%, transparent 100%);
  -webkit-mask-repeat: no-repeat;
          mask-repeat: no-repeat;
  -webkit-mask-composite: source-in;        /* Safari / older Chromium */
          mask-composite: intersect;        /* standard */
}
.ml-loader-bar {
  width: min(60%, 240px); height: 2px;
  background: var(--ink-100);
  border-radius: 999px; overflow: hidden;
}
.ml-loader-bar-fill {
  width: 30%; height: 100%;
  background: var(--navy); border-radius: 999px;
  animation: ml-loader-bar 1.4s infinite cubic-bezier(0.4, 0, 0.2, 1);
}
.ml-loader-text {
  font-family: var(--font-mono);
  font-size: 11px; letter-spacing: 0.22em;
  color: var(--ink-500);
  text-transform: uppercase;
  text-align: center;
}

@keyframes mnav-slide { from { transform: translateY(40px); opacity: 0; } to { transform: translateY(0); opacity: 1; } }

@media screen and (max-width: 1100px) {
  .app {
    min-width: 0;                          /* lift the hard 1100px desktop floor */
    width: 100%;                           /* never exceed the viewport width */
    grid-template-columns: 1fr;            /* sidebar column removed (nav moves to bottom bar) */
    grid-template-rows: 52px 1fr;
    height: 100dvh;
    overflow: hidden;                      /* shell is fixed; the scroll region is .main (matches the desktop .main{overflow:auto} design) */
  }
  /* Desktop sidebar hidden on mobile (replaced by the bottom tab bar in a
     later task). !important: Sidebar.jsx sets an inline style={{display:'flex'}}
     which a normal rule can't override. */
  .app > .sidebar { display: none !important; }
  .topbar { grid-column: 1 / -1; }
  .main {
    grid-column: 1 / -1;
    padding: 14px 14px calc(60px + env(safe-area-inset-bottom, 0px));
  }
  /* Anything that hard-codes a wide min-width must not force page scroll
     here; list wide-mode min-widths are neutralised in a later task. */
  body { overflow-x: hidden; }

  /* ---- Mobile bottom tab bar ---- */
  .mnav {
    display: flex;
    position: fixed; left: 0; right: 0; bottom: 0; z-index: 90;
    background: var(--navy-deep); color: rgba(255,255,255,.7);
    padding-bottom: env(safe-area-inset-bottom, 0px);
    border-top: 1px solid #000;
  }
  .mnav-item {
    flex: 1; display: flex; flex-direction: column; align-items: center;
    justify-content: center; gap: 3px; min-height: 56px;
    font: 600 9.5px/1.1 var(--font-ui); color: inherit;
    text-decoration: none; background: transparent; border: 0;
  }
  .mnav-item.active { color: #fff; }
  .mnav-item.active svg { color: var(--sky); }
  .mnav-sheet-mask {
    position: fixed; inset: 0; z-index: 95; background: rgba(6,16,34,.45);
    display: flex; align-items: flex-end;
  }
  .mnav-sheet {
    width: 100%; background: var(--surface);
    border-radius: 14px 14px 0 0; padding: 8px 10px
      calc(12px + env(safe-area-inset-bottom, 0px));
    max-height: 70vh; overflow: auto;
    animation: mnav-slide var(--dur-slow, 280ms) var(--ease-out, ease);
  }
  .mnav-sheet-grip {
    width: 36px; height: 4px; border-radius: 999px;
    background: var(--ink-200); margin: 6px auto 10px;
  }
  .mnav-sheet-row {
    display: flex; align-items: center; gap: 10px; padding: 12px 10px;
    font-size: 14px; color: var(--ink-900); text-decoration: none;
    border-radius: 8px;
  }
  .mnav-sheet-row.active { background: var(--ink-50); font-weight: 600; }
  .mnav-sheet-user {
    display: flex; align-items: center; gap: 8px; padding: 12px 10px 4px;
    margin-top: 6px; border-top: 1px solid var(--ink-200); color: var(--ink-500);
    font-size: 12px;
  }
  .mnav-sheet-user .avt {
    width: 26px; height: 26px; border-radius: 999px; background: var(--navy);
    color: #fff; display: inline-flex; align-items: center;
    justify-content: center; font-size: 11px; font-weight: 600;
  }
  .mnav-sheet-user .sub { display: block; font-size: 10px; opacity: .7; }

  /* ---- Compact top bar ---- */
  .topbar { padding: 0 10px; gap: 8px; }
  .tb-back span { display: none; }                 /* icon-only back */
  .tb-back { padding: 0 8px; }
  .tb-search {
    flex: 0 0 auto; max-width: none; width: 36px;
    padding: 0; justify-content: center; overflow: hidden;
  }
  .tb-search span, .tb-search kbd { display: none; }/* collapse to the icon */
  .tb-actions { gap: 4px; }

  /* ---- List page header: stack title block above the Insert button.
     Desktop puts the title and the Insert button on the same flex row
     (.cases-head{align-items:flex-end;justify-content:space-between}).
     On a phone that constrains the title block to ~210px (after the
     button's ~128px + 24px gap), forcing long EN/EL titles like
     "Δελτία τελωνειακής αποθήκευσης" to wrap onto 2 lines and the
     subtitle onto 2 more, leaving an awkward 85px header with a button
     floating in the bottom-right. Stack vertically so the title gets
     the full content width and the action sits on its own line. */
  .cases-head {
    flex-direction: column;
    align-items: stretch;
    gap: 10px;
    margin-bottom: 12px;
  }
  .cases-head h1 { font-size: 19px; line-height: 1.2; }
  .cases-head .sub { margin-top: 2px; }
  .cases-head .btn { align-self: flex-start; }

  /* Toolbar: tighter gap so the 4 wrapped rows aren't so airy. */
  .cases-toolbar { gap: 8px; padding: 10px 12px; }

  /* ---- Forms: single column, labels on top (pref unchanged) ---- */
  .multi, .multi.cols-2, .multi.cols-3 { grid-template-columns: 1fr !important; }
  .fgrid { grid-template-columns: 1fr !important; }
  .row-detail .dl-grid,
  .dl-grid.dn-grid,
  .dl-grid.vat-grid,
  .row-detail .dl-grid.stock-grid { grid-template-columns: 1fr !important; }
  /* The single-column rule above already wins (it beats form.css's
     equal-specificity `.row-detail .dl-grid.stock-grid` because it carries
     !important and loads later). BUT StockListPage.jsx puts inline
     `style={{gridColumn:'span 2'|'span 3'}}` on several `.it` cells. With
     only one explicit column a `span 3` cell forces CSS Grid to create 2
     *implicit* columns (grid-auto-columns:auto → 0px), so the computed
     template was "242px 0px 0px" and any cell/combo landing in a 0px
     implicit track collapsed. Neutralise the inline span so every cell
     occupies the single column. !important beats the non-important inline
     style; this is the actual fix for the collapsed inline-edit combo. */
  .row-detail .dl-grid.stock-grid > .it { grid-column: auto !important; }
  /* Force top labels regardless of the side/top pref (override only).
     The default .field is 130px 1fr (side layout); override to single-col.
     Also beats the higher-specificity body[data-labels="top"] .field rule in form.css, so !important is required here. */
  .field { grid-template-columns: 1fr !important; align-items: flex-start !important; gap: 6px !important; }
  .field > .lab { padding: 0 0 4px !important; text-align: left !important; }
  /* Combo popover → full content width on mobile.
     Form-field combos sit inside .formcard (28px pad + 1px border each
     side); negative offsets let the absolutely-positioned panel escape
     that inset to the content edges. */
  .formcard .combo .panel {
    left: -29px !important; right: -29px !important;
    width: auto !important; max-width: none !important;
  }
  /* Stock List inline-edit combo lives in a grid cell (.row-edit-combo),
     not a .formcard. Give the combo a real width so its panel fills the
     (single-column on mobile) cell — no magic offset needed. */
  .row-edit-combo .combo { width: 100%; }
  .row-edit-combo .combo .panel {
    left: 0 !important; right: 0 !important;
    width: 100% !important; max-width: none !important;
  }
  /* PrefillPicker is a position:fixed modal (not a floating popover) —
     no left/right override needed. No sticky form footer exists in form.css
     (.formfoot is static, not sticky/fixed), so no bottom-offset rule added. */

  /* ---- Lists become stacked cards (compact cells only) ---- */
  /* Force compact even if pref/markup is wide; neutralise wide min-widths. */
  .cases-list.is-wide, .cases-list.is-wide .case-row,
  .cusl-list.is-wide,  .cusl-list.is-wide .cusl-row,
  .dn-list.is-wide,    .dn-list.is-wide .dn-row,
  .stock-list.is-wide, .stock-list.is-wide .stock-row,
  .vat-list.is-wide,   .vat-list.is-wide .vat-row { min-width: 0 !important; }

  /* Hide the column header row — labels move into each card.
     Every list header carries .cl-head (that alone hides all six); the
     per-list modifier classes are listed for accuracy/robustness. */
  .cl-head, .tcols,
  .cusl-head-grid, .cusl-head-grid-wide,
  .dn-head-grid, .stock-head, .vat-head-grid { display: none !important; }

  /* Row → card */
  .case-row, .cusl-row, .dn-row, .stock-row, .vat-row, .inv-row, .trow {
    display: block !important;
    grid-template-columns: none !important;
    min-width: 0 !important;
    border: 1px solid var(--ink-200);
    border-radius: 8px;
    margin: 0 0 8px;
    padding: 10px 12px;
    background: var(--surface);
  }
  .case-row > .row-main { display: block !important; }

  /* Each cell → "Label  value" line.
     `display: flex !important` because several list pages set their own
     `display:` on individual cells (e.g. Invoices.html sets
     `.inv-row .row-main .consignee { display: -webkit-box }` for the
     desktop 3-line clamp). Those page-level rules have 3-class specificity
     and beat `.case-row [data-label]` without !important, breaking the
     mobile card layout (the `::before` label collapses against the value
     because the cell never becomes a flex container).
     Truncation props (white-space:nowrap, overflow:hidden, text-overflow,
     -webkit-line-clamp) are reset for the same reason — desktop cells
     ellipsize one line; in card mode the value should wrap. */
  .case-row [data-label], .cusl-row [data-label], .dn-row [data-label],
  .stock-row [data-label], .vat-row [data-label], .inv-row [data-label] {
    display: flex !important; justify-content: space-between; gap: 12px;
    align-items: baseline; padding: 3px 0; min-width: 0; width: auto;
    text-align: right;
    white-space: normal !important;
    overflow: visible !important;
    text-overflow: clip !important;
    -webkit-line-clamp: none !important;
    -webkit-box-orient: initial !important;
    overflow-wrap: anywhere;
  }
  .case-row [data-label]::before, .cusl-row [data-label]::before,
  .dn-row [data-label]::before, .stock-row [data-label]::before,
  .vat-row [data-label]::before, .inv-row [data-label]::before {
    content: attr(data-label);
    color: var(--ink-500); font-size: 10px; font-weight: 600;
    text-transform: uppercase; letter-spacing: .04em;
    text-align: left; flex: 0 0 42%; white-space: nowrap;
  }
  .case-row [data-label=""]::before, .cusl-row [data-label=""]::before,
  .dn-row [data-label=""]::before, .stock-row [data-label=""]::before,
  .vat-row [data-label=""]::before, .inv-row [data-label=""]::before { content: none; }
  .case-row [data-label=""], .cusl-row [data-label=""],
  .dn-row [data-label=""], .stock-row [data-label=""],
  .vat-row [data-label=""], .inv-row [data-label=""] {
    display: block !important; text-align: left; padding: 6px 0 2px;
  }

  /* checkbox + actions sit full width, no label */
  .case-row .checkcell, .vat-row .checkcell,
  .case-row .row-actions, .cusl-row .row-actions, .dn-row .row-actions,
  .stock-row .row-actions, .vat-row .row-actions, .inv-row .row-actions {
    display: flex !important; justify-content: flex-start; padding-top: 6px; }

  /* ---- Mobile sort control ---- */
  .mlist-sort {
    display: flex; align-items: center; gap: 8px; margin: 0 0 10px;
    font-size: 12px; color: var(--ink-500);
  }
  .mlist-sort label { white-space: nowrap; }
  .mlist-sort select {
    flex: 1; height: 34px; border: 1px solid var(--ink-200);
    border-radius: 6px; background: var(--surface); padding: 0 8px;
    font: inherit; color: var(--ink-900);
  }
  .mlist-sort-dir {
    height: 34px; min-width: 34px; border: 1px solid var(--ink-200);
    border-radius: 6px; background: var(--surface); color: var(--ink-900);
  }
}
