/* ============================================================
   GateLog — factory gate log
   Direction: the gate itself. Deep slate chrome, concrete canvas,
   and one signature device: the hazard-stripe barrier rule.
   Built mobile-first; the guard works on a phone at the barrier.
   ============================================================ */

/* Tokens live in tokens.css, loaded first by gl_header(). This file styles
   components and reads those variables; it defines none of its own. */

/* --------------------------------------------------------------- Reset --
   The global icon floor. An inline <svg> with only a viewBox has no intrinsic
   size and will expand to its container — this is the rule that makes that
   impossible anywhere in the app, including in components written later that
   forget to size their own icon. Component rules below override it by
   specificity; nothing can exceed its container regardless. */
svg {
  width: var(--icon-md);
  height: var(--icon-md);
  max-width: 100%;
  max-height: var(--icon-illus-max);
  flex: none;
}

*, *::before, *::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  font-family: var(--font);
  background: var(--concrete);
  color: var(--ink);
  font-size: var(--fs-body);
  line-height: var(--lh-body);
  font-variant-numeric: tabular-nums;
  -webkit-font-smoothing: antialiased;
}

/* --- The signature: a boom-barrier chevron band ------------------------- */
.barrier {
  height: 6px;
  background: repeating-linear-gradient(
    -45deg,
    var(--amber) 0 12px,
    #ffffff 12px 24px
  );
  flex: none;
}

/* ------------------------------------------------------------- Header --- */
.app-header {
  position: sticky;
  top: 0;
  z-index: 40;
  background: var(--ink);
  color: #fff;
}
.app-header__bar {
  height: var(--header-h);
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  /* Full-bleed, NOT a centred 1180px container. The centred version left the
     brand and the user block floating at arbitrary points with ~860px of dead
     space between them, aligned to nothing — least of all to the sidebar rail
     directly beneath the brand. */
  padding-inline: var(--sp-4);
}
/* From the desktop tier the brand occupies exactly the rail's width, so it
   caps the sidebar instead of hovering near it. */
@media (min-width: 1024px) {
  .app-header__bar { padding-inline: 0 var(--sp-5); }
  .brand {
    width: var(--sidebar-w);
    padding-inline: calc(var(--sidebar-pad) + var(--sp-3));
    flex: none;
  }
}
.brand {
  display: flex;
  align-items: center;
  gap: 10px;
  font-weight: 800;
  font-size: var(--fs-section);
  letter-spacing: .04em;
  color: #fff;
  text-decoration: none;
}
.brand__mark {
  width: 30px; height: 30px;
  border-radius: var(--r-sm);
  background: var(--amber);
  display: grid; place-items: center;
  color: var(--ink);
  flex: none;
}
.brand__mark svg { width: var(--icon-brand); height: var(--icon-brand); display: block; }

.header-user {
  margin-inline-start: auto;
  display: flex;
  align-items: center;
  gap: 10px;
  min-width: 0;
}
.header-user__meta { text-align: start; min-width: 0; line-height: 1.25; }
.header-user__name {
  font-size: var(--fs-label); font-weight: 700;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  max-width: 34vw;
}
.header-user__role {
  font-size: var(--fs-eyebrow); font-weight: 600; letter-spacing: .08em;
  color: var(--amber);
}
.btn-logout {
  display: grid; place-items: center;
  width: var(--tap); height: var(--tap);
  border: 1px solid rgba(255,255,255,.16);
  border-radius: var(--r-sm);
  background: transparent;
  color: #fff;
  cursor: pointer;
  flex: none;
}
.btn-logout svg { width: 20px; height: 20px; }
.btn-logout:hover { background: rgba(255,255,255,.09); }


.page-head { margin: 0 0 20px; }
.eyebrow {
  font-size: .7rem;
  font-weight: 700;
  letter-spacing: .16em;
  color: var(--muted);
  margin: 0 0 4px;
}
.page-title {
  font-size: var(--fs-page-title);
  font-weight: 800;
  letter-spacing: -.01em;
  line-height: var(--lh-tight);
  margin: 0;
}
.page-sub { color: var(--muted); margin: 6px 0 0; font-size: var(--fs-body); }

/* ==========================================================================
   SHELL — one layout, three tiers.
   <768px   : bottom navigation bar (guard, one-handed, 56px targets)
   768–1023 : off-canvas collapsible sidebar + header toggle
   >=1024px : fixed full-height right rail (RTL), content fills the rest
   ========================================================================== */

.shell {
  min-height: calc(100vh - var(--chrome-h));
}

.main {
  padding: var(--sp-5) var(--sp-4) calc(var(--nav-h) + var(--sp-6) + env(safe-area-inset-bottom, 0px));
  min-width: 0;
  max-width: var(--content-max);
  margin-inline: auto;
}

/* Vertical rhythm: every direct child of .main is separated by one step. */
.main > * + * { margin-block-start: var(--sp-5); }
/* No child may widen the page; wide content scrolls inside its own box. */
.main > * { min-width: 0; }

/* Single-purpose screens — entry, exit, change password. One task, one column.
   Left at the full 1100px content width these read as a lone box stranded in
   the top quarter of the viewport; narrowed and pushed toward the optical
   centre they read as the one thing the screen is for. margin-block:auto
   centres only when there IS slack, so the tall states (the entry form, the
   ticket confirmation) still start at the top and never clip. */
.main--focus { display: flex; flex-direction: column; }
.main--focus > .focus-col {
  width: 100%;
  max-width: var(--focus-max);
  margin-inline: auto;
  margin-block: auto;
}
.main--focus > .focus-col > * + * { margin-block-start: var(--sp-4); }

/* --- Nav toggle (tablet only) ------------------------------------------- */
.nav-toggle {
  display: none;
  place-items: center;
  width: var(--tap); height: var(--tap);
  border: 1px solid rgba(255,255,255,.16);
  border-radius: var(--r-sm);
  background: transparent;
  color: #fff;
  cursor: pointer;
  flex: none;
  margin-inline-end: 2px;
}
.nav-toggle svg { width: 22px; height: 22px; }
.nav-toggle:hover { background: rgba(255,255,255,.09); }

.nav-backdrop {
  display: none;
  position: fixed;
  inset: 0;
  z-index: 44;
  background: rgba(16, 21, 28, .5);
}
.nav-backdrop.is-open { display: block; }

/* --- Tier 1: phone — bottom bar ----------------------------------------- */
.nav {
  position: fixed;
  inset-inline: 0;
  bottom: 0;
  z-index: 45;
  background: var(--surface);
  border-top: 1px solid var(--line);
  padding-bottom: env(safe-area-inset-bottom, 0px);
}
.nav__head { display: none; }
.nav__list {
  display: flex;
  margin: 0;
  padding: 0;
  list-style: none;
}
/* The <li> is the flex item, not the <a> — putting flex on the link instead
   leaves each cell at its label's width, which is how the bar ended up with
   an 87px target next to a 44px one. min-width:0 lets them share evenly. */
.nav__list > li { flex: 1 1 0; min-width: 0; display: flex; }
.nav__link {
  width: 100%;
  min-width: 0;
  min-height: var(--nav-h);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 3px;
  padding: 6px 2px;
  text-decoration: none;
  color: var(--muted);
  font-size: .68rem;
  font-weight: 600;
  text-align: center;
  position: relative;
}
.nav__link svg { width: 23px; height: 23px; flex: none; }
.nav__label {
  line-height: 1.2;
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.nav__label--full { display: none; }

/* Active marker: the barrier stripe, the one signature device. */
.nav__link.is-active { color: var(--ink); }
.nav__link.is-active::before {
  content: '';
  position: absolute;
  top: 0; inset-inline: 22%;
  height: 3px;
  border-radius: var(--r-pill);
  background: var(--amber-deep);
}

/* --- Tier 2: tablet — off-canvas collapsible sidebar -------------------- */
@media (min-width: 768px) {
  .nav-toggle { display: grid; }

  .nav {
    position: fixed;
    top: var(--chrome-h);
    bottom: 0;
    inset-inline: 0 auto;      /* RTL: inline-start is the RIGHT edge */
    width: var(--sidebar-w);
    z-index: 46;
    border-top: 0;
    border-inline-end: 1px solid var(--line);   /* edge facing the content */
    /* A real inner gutter. Without it the rail sits flush on the viewport
       edge and the active item's stripe lands ON that edge, reading as a
       stray sliver outside the sidebar rather than as part of it. */
    padding: 0 var(--sidebar-pad) var(--sp-3);
    overflow-x: hidden;
    display: flex;
    flex-direction: column;
    overflow-y: auto;
    overscroll-behavior: contain;
    transform: translateX(100%);
    transition: transform .22s ease;
    box-shadow: var(--shadow-2);
  }
  .nav.is-open { transform: translateX(0); }

  .nav__head {
    display: block;
    padding: var(--sp-4) var(--sp-3) var(--sp-2);
    font-size: .68rem;
    font-weight: 700;
    letter-spacing: .16em;
    color: var(--muted);
  }
  .nav__list { flex-direction: column; }
  .nav__list > li { flex: none; display: block; }
  .nav__link {
    flex: none;
    flex-direction: row;
    justify-content: flex-start;
    gap: 12px;
    min-height: var(--tap);
    padding: 11px 14px;
    font-size: var(--fs-nav);
    text-align: start;
    border-radius: var(--r-md);
    position: relative;
    overflow: hidden;            /* the stripe is clipped to the pill */
  }
  .nav__label--full  { display: block; }
  .nav__label--short { display: none; }
  .nav__link.is-active { background: var(--amber-wash); font-weight: 700; }
  /* A SOLID bar, not the hazard stripe. A 45-degree repeating gradient needs
     width to read as a pattern; squeezed into 4px and clipped by the pill's
     radius it broke into disconnected orange chunks that looked like render
     artefacts escaping the sidebar. The barrier motif keeps its one home —
     the full-width rule under the header, where it has room to be legible. */
  .nav__link.is-active::before {
    top: 6px; bottom: 6px;
    inset-inline: auto;
    inset-inline-start: 0;
    width: 3px; height: auto;
    border-radius: var(--r-pill);
    background: var(--amber-deep);
  }

  .main {
    padding: var(--sp-6) var(--sp-5) var(--sp-7);
  }
}

/* --- Tier 3: desktop — fixed rail, always visible ----------------------- */
@media (min-width: 1024px) {
  .nav-toggle { display: none; }
  .nav-backdrop, .nav-backdrop.is-open { display: none; }

  .nav {
    transform: none;
    transition: none;
    box-shadow: none;
  }
  .shell { padding-inline-start: var(--sidebar-w); }
  .main {
    padding: var(--sp-6) var(--sp-6) var(--sp-7);
    max-width: var(--content-max);
    margin-inline: auto;
  }
}

/* ---------------------------------------------------------------- Card -- */
.card {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-1);
  padding: 22px;
}
.card + .card { margin-top: 16px; }

.stub {
  text-align: center;
  padding: 44px 22px;
}
.stub__badge {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  background: #fdf3dc;
  color: var(--amber-deep);
  border: 1px solid #f3dfab;
  border-radius: 999px;
  padding: 6px 16px;
  font-weight: 700;
  font-size: .85rem;
}
.stub__title { font-size: 1.25rem; font-weight: 800; margin: 18px 0 6px; }
.stub__text { color: var(--muted); margin: 0; max-width: 44ch; margin-inline: auto; }

/* ------------------------------------------------------------ Tiles ----- */
.tiles {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 12px;
  margin-bottom: 18px;
}
.tile {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  padding: 16px;
  box-shadow: var(--shadow-1);
}
.tile__label { font-size: .75rem; font-weight: 700; color: var(--muted); letter-spacing: .06em; }
.tile__value { font-size: 1.9rem; font-weight: 800; line-height: 1.2; margin-top: 2px; }
.tile--accent { border-inline-start: 4px solid var(--amber); }

/* ------------------------------------------------------- Quick actions -- */
.quick {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 12px;
  /* No margin-bottom: .main's rhythm rule owns the gap between sections, and
     setting both here produced a 42px step where every other gap was 24px. */
}
.quick__btn {
  min-height: 88px;
  border-radius: var(--r-md);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 6px;
  text-decoration: none;
  font-weight: 700;
  font-size: 1rem;
  border: 1px solid transparent;
  box-shadow: var(--shadow-1);
}
.quick__btn svg { width: 26px; height: 26px; }
.quick__btn--in  { background: var(--ink);   color: #fff; }
.quick__btn--out { background: var(--surface); color: var(--ink); border-color: var(--line); }

/* On a phone these are the two things the guard reaches for, so they stay big.
   On a desktop the same 88px slabs read as a hero band above the real content,
   so they shrink to a row of actions and stop competing with the KPI cards. */
@media (min-width: 1024px) {
  .quick { grid-template-columns: repeat(2, minmax(0, 232px)); }
  .quick__btn {
    min-height: 56px;
    flex-direction: row;
    gap: 10px;
    font-size: .95rem;
  }
  .quick__btn svg { width: 20px; height: 20px; }
}

/* --------------------------------------------------------------- Forms -- */
.field { margin-bottom: 16px; }
.label {
  display: block;
  font-weight: 700;
  font-size: var(--fs-label);
  margin-bottom: 6px;
}
.input {
  width: 100%;
  min-height: var(--tap);
  padding: 10px 14px;
  font: inherit;
  font-size: var(--fs-body-lg);
  color: var(--ink);
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
}
.input:focus {
  outline: 3px solid rgba(242, 166, 0, .45);
  outline-offset: 1px;
  border-color: var(--amber-deep);
}
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  min-height: var(--tap);
  padding: 10px 20px;
  font: inherit;
  font-weight: 700;
  font-size: var(--fs-body);
  border-radius: var(--r-md);
  border: 1px solid transparent;
  cursor: pointer;
  text-decoration: none;
  /* Without both of these an inline icon takes its intrinsic size and shoves
     the label onto a second line — which is exactly how «تصدير Excel» broke. */
  white-space: nowrap;
}
.btn svg { width: 18px; height: 18px; flex: none; }
.btn--lg svg { width: 20px; height: 20px; }
.btn--primary { background: var(--ink); color: #fff; }
.btn--primary:hover { background: var(--steel); }
.btn--block { width: 100%; }

/* --------------------------------------------------------------- Alert -- */
.alert {
  border-radius: var(--r-md);
  padding: 12px 16px;
  font-size: .92rem;
  font-weight: 600;
  margin-bottom: 16px;
  border: 1px solid;
}
.alert--error { background: #fdeceb; color: #9c2020; border-color: #f3c4c2; }
.alert--info  { background: #eaf3fb; color: #1b4f7d; border-color: #c3ddf2; }

/* --------------------------------------------------------------- Login -- */
.login-page {
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
  background: var(--ink);
}
.login-page .barrier { order: -1; }
.login-wrap {
  flex: 1;
  display: grid;
  place-items: center;
  padding: 28px 18px 40px;
}
.login-card {
  width: 100%;
  max-width: 390px;
  background: var(--surface);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-2);
  padding: 30px 26px 28px;
}
.login-brand {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
  margin-bottom: 22px;
}
.login-brand__mark {
  width: 54px; height: 54px;
  border-radius: 14px;
  background: var(--ink);
  color: var(--amber);
  display: grid; place-items: center;
}
.login-brand__mark svg { width: 30px; height: 30px; }
.login-brand__name {
  font-size: 1.5rem; font-weight: 800; letter-spacing: .05em;
}
.login-brand__tag { font-size: .85rem; color: var(--muted); font-weight: 600; }
.login-foot {
  text-align: center;
  color: rgba(255,255,255,.5);
  font-size: .78rem;
  padding-bottom: 22px;
}

/* --------------------------------------------------------------- Denied - */
.denied { text-align: center; padding: 40px 20px; }
.denied__code { font-size: 3rem; font-weight: 800; color: var(--red); line-height: 1; }


/* ---------------------------------------------------------- A11y floor -- */
a:focus-visible, button:focus-visible, .nav__link:focus-visible {
  outline: 3px solid var(--amber);
  outline-offset: 2px;
}
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important;
    transition-duration: .01ms !important;
  }
}

.stub__badge svg { width: 18px; height: 18px; flex: none; }

/* ============================================================
   Entry / exit / open-visits screens
   ============================================================ */

/* --- Big plate field: the guard's first touch, one-handed ---------------- */
.plate-field { position: relative; }
.input--plate {
  font-size: var(--fs-plate);
  font-weight: 800;
  letter-spacing: .06em;
  text-align: center;
  min-height: 62px;
  padding: 8px 46px 8px 14px;
}
.plate-field__spinner {
  position: absolute;
  inset-inline-start: 14px;
  top: 50%;
  transform: translateY(-50%);
  width: 18px; height: 18px;
  border: 2px solid var(--line);
  border-top-color: var(--amber);
  border-radius: 50%;
  animation: gl-spin .7s linear infinite;
  display: none;
}
.plate-field.is-busy .plate-field__spinner { display: block; }
@keyframes gl-spin { to { transform: translateY(-50%) rotate(360deg); } }

.plate-norm-hint {
  margin: 8px 2px 0;
  font-size: .82rem;
  color: var(--muted);
  min-height: 1.2em;
}
.plate-norm-hint b {
  color: var(--ink);
  font-weight: 700;
  letter-spacing: .05em;
}

/* --- Tappable result rows ----------------------------------------------- */
.results { margin-top: 14px; display: grid; gap: 10px; }
.result {
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
  min-height: 68px;
  padding: 12px 14px;
  text-align: start;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  box-shadow: var(--shadow-1);
  cursor: pointer;
  font: inherit;
  color: inherit;
}
.result:hover { border-color: var(--amber-deep); }
.result__body { flex: 1; min-width: 0; }
.result__plate {
  font-size: 1.12rem;
  font-weight: 800;
  letter-spacing: .04em;
}
.result__meta {
  font-size: .82rem;
  color: var(--muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.result__chev { color: var(--muted); flex: none; }
.result__chev svg { width: 18px; height: 18px; display: block; }
.result--inside { border-inline-start: 4px solid var(--red); }
.result__flag {
  font-size: .72rem;
  font-weight: 700;
  color: var(--red);
}

.empty-hint {
  margin-top: 14px;
  padding: 18px;
  border: 1px dashed var(--line);
  border-radius: var(--r-md);
  text-align: center;
  color: var(--muted);
  background: #fbfcfd;
}
.empty-hint strong { color: var(--ink); display: block; margin-bottom: 8px; }

/* --- Selected vehicle banner -------------------------------------------- */
.picked {
  display: flex;
  align-items: center;
  gap: 12px;
  background: var(--ink);
  color: #fff;
  border-radius: var(--r-md);
  padding: 14px 16px;
  margin-bottom: 18px;
}
.picked__body { flex: 1; min-width: 0; }
.picked__plate { font-size: 1.25rem; font-weight: 800; letter-spacing: .05em; }
.picked__meta { font-size: .8rem; color: rgba(255,255,255,.66); }
.picked__change {
  background: rgba(255,255,255,.12);
  color: #fff;
  border: 0;
  border-radius: var(--r-sm);
  min-height: 40px;
  padding: 0 14px;
  font: inherit;
  font-weight: 700;
  font-size: .85rem;
  cursor: pointer;
  flex: none;
}
.picked__change:hover { background: rgba(255,255,255,.2); }

/* --- Picker (searchable dropdown with inline create) -------------------- */
.picker {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  min-height: var(--tap);
  padding: 10px 14px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  font: inherit;
  font-size: 1rem;
  text-align: start;
  cursor: pointer;
  color: var(--muted);
}
.picker.is-set { color: var(--ink); font-weight: 600; }
.picker__value { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.picker__clear {
  flex: none;
  width: 30px; height: 30px;
  border-radius: 50%;
  border: 0;
  background: var(--concrete);
  color: var(--muted);
  cursor: pointer;
  font: inherit;
  line-height: 1;
  display: none;
}
.picker.is-set .picker__clear { display: block; }
.picker__caret { flex: none; color: var(--muted); }
.picker__caret svg { width: 16px; height: 16px; display: block; }

/* --- Bottom sheet -------------------------------------------------------- */
.sheet-backdrop {
  position: fixed;
  inset: 0;
  background: rgba(16,21,28,.55);
  z-index: 80;
  display: none;
}
.sheet-backdrop.is-open { display: block; }
.sheet {
  position: fixed;
  inset-inline: 0;
  bottom: 0;
  z-index: 81;
  background: var(--surface);
  border-radius: var(--r-lg) var(--r-lg) 0 0;
  max-height: 86dvh;
  display: none;
  flex-direction: column;
  padding-bottom: env(safe-area-inset-bottom, 0px);
}
.sheet.is-open { display: flex; }
.sheet__head {
  padding: 14px 18px 10px;
  border-bottom: 1px solid var(--line);
}
.sheet__title { font-weight: 800; font-size: 1.05rem; margin: 0 0 10px; }
.sheet__list {
  overflow-y: auto;
  padding: 10px 14px;
  display: grid;
  gap: 8px;
  flex: 1;
}
.sheet__opt {
  width: 100%;
  min-height: var(--tap);
  padding: 10px 14px;
  text-align: start;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  font: inherit;
  font-size: 1rem;
  cursor: pointer;
  color: inherit;
}
.sheet__opt:hover { background: #f7f9fb; border-color: var(--amber-deep); }
.sheet__opt small { display: block; color: var(--muted); font-size: .78rem; }
.sheet__foot {
  border-top: 1px solid var(--line);
  padding: 12px 14px calc(12px + env(safe-area-inset-bottom, 0px));
  display: grid;
  gap: 8px;
}
.sheet__empty { color: var(--muted); text-align: center; padding: 18px 6px; }

@media (min-width: 768px) {
  .sheet {
    inset: auto;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    inset-inline: auto;
    width: min(520px, 92vw);
    border-radius: var(--r-lg);
    max-height: 78vh;
  }
}

/* --- Segmented purpose control ------------------------------------------ */
.segment {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 8px;
}
.segment__btn {
  min-height: var(--tap);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  background: var(--surface);
  font: inherit;
  font-weight: 700;
  font-size: .95rem;
  cursor: pointer;
  color: var(--muted);
}
.segment__btn[aria-pressed="true"] {
  background: var(--ink);
  border-color: var(--ink);
  color: #fff;
}

/* --- Sticky submit ------------------------------------------------------ */
.submit-bar { margin-top: 22px; }
.btn--lg { min-height: 58px; font-size: 1.1rem; }
.btn--danger { background: var(--red); color: #fff; }
.btn--ghost { background: var(--surface); color: var(--ink); border-color: var(--line); }
.btn:disabled { opacity: .55; cursor: not-allowed; }

/* --- Success confirmation ----------------------------------------------- */
.done { text-align: center; padding: 26px 20px 30px; }
.done__check {
  width: 62px; height: 62px;
  margin: 0 auto 14px;
  border-radius: 50%;
  background: #e6f6f0;
  color: var(--green);
  display: grid; place-items: center;
}
.done__check svg { width: 34px; height: 34px; }
.done__label {
  font-size: .78rem;
  font-weight: 700;
  letter-spacing: .16em;
  color: var(--muted);
}
.done__ticket {
  font-size: clamp(2.1rem, 11vw, 3.4rem);
  font-weight: 800;
  letter-spacing: .02em;
  line-height: 1.15;
  margin: 2px 0 18px;
  word-break: break-all;
}
.done__rows {
  display: grid;
  gap: 1px;
  background: var(--line);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  overflow: hidden;
  text-align: start;
  margin-bottom: 22px;
}
.done__row {
  display: flex;
  gap: 12px;
  background: var(--surface);
  padding: 11px 14px;
}
.done__row dt { color: var(--muted); font-size: .88rem; margin: 0; flex: none; min-width: 92px; }
.done__row dd { margin: 0; font-weight: 700; flex: 1; }

/* --- Open-visit rows ---------------------------------------------------- */
.visit-list { display: grid; gap: 12px; }
.visit {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  box-shadow: var(--shadow-1);
  padding: 14px 16px;
}
.visit--overdue {
  border-color: #eebfbf;
  border-inline-start: 5px solid var(--red);
  background: #fffafa;
}
.visit__top {
  display: flex;
  align-items: baseline;
  gap: 10px;
  flex-wrap: wrap;
  margin-bottom: 6px;
}
.visit__ticket {
  font-weight: 800;
  font-size: 1.05rem;
  letter-spacing: .03em;
}
.visit__plate {
  font-weight: 700;
  background: var(--concrete);
  border-radius: var(--r-sm);
  padding: 2px 9px;
  font-size: .92rem;
}
.visit__grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(130px, 1fr));
  gap: 4px 14px;
  margin: 8px 0 12px;
  font-size: .88rem;
}
.visit__cell span { color: var(--muted); }
.visit__elapsed {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-weight: 700;
  font-size: .88rem;
}
.visit--overdue .visit__elapsed { color: var(--red); }
.visit__elapsed svg { width: 16px; height: 16px; }
.visit__actions { display: flex; gap: 8px; flex-wrap: wrap; }
.visit__actions .btn { flex: 1 1 auto; min-width: 120px; padding: 10px 14px; }

.counter-bar {
  display: flex;
  align-items: center;
  gap: 10px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-inline-start: 4px solid var(--amber);
  border-radius: var(--r-md);
  padding: 14px 16px;
  margin-bottom: 16px;
  font-weight: 700;
}
.counter-bar__n { font-size: 1.5rem; font-weight: 800; }
.counter-bar__warn { margin-inline-start: auto; color: var(--red); font-size: .85rem; font-weight: 700; }

/* --- Admin master-data tables ------------------------------------------- */
.toolbar {
  display: flex;
  gap: 10px;
  margin-bottom: 16px;
  flex-wrap: wrap;
}
.toolbar .input { flex: 1 1 220px; }
.toolbar .btn { flex: none; }

.table-wrap { overflow-x: auto; border-radius: var(--r-md); }
.table {
  width: 100%;
  border-collapse: collapse;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  font-size: .92rem;
}
.table th, .table td {
  padding: 11px 14px;
  text-align: start;
  border-bottom: 1px solid var(--line);
  white-space: nowrap;
}
.table th {
  background: #f7f9fb;
  font-weight: 700;
  font-size: .8rem;
  color: var(--muted);
  letter-spacing: .04em;
}
.table tr:last-child td { border-bottom: 0; }
/* The report table carries ten columns. Dense padding is what lets the status
   badge stay on screen at 1440 instead of hiding past the scroll edge. */
.table--dense th, .table--dense td { padding: 9px 10px; font-size: .87rem; }
.table--dense .plate-tag { font-size: .85rem; padding: 1px 6px; }
/* Long Arabic values wrap rather than widen the table; only the identifiers
   that must be read as one token keep nowrap. */
.table--dense td { white-space: normal; }
.table--dense td.keep { white-space: nowrap; }
.stamp { display: inline-block; white-space: nowrap; line-height: 1.4; }
.stamp__d, .stamp__t { display: block; }
.stamp__t { color: var(--muted); font-size: .82rem; }
.table tr.is-off td { color: var(--muted); background: #fbfbfc; }
.table td.wrap { white-space: normal; min-width: 180px; }
.table .btn { min-height: 38px; padding: 6px 14px; font-size: .85rem; }
.row-actions { display: flex; gap: 6px; }

.badge {
  display: inline-block;
  border-radius: 999px;
  padding: 2px 11px;
  font-size: .75rem;
  font-weight: 700;
}
.badge--on  { background: #e6f6f0; color: var(--green); }
.badge--off { background: #f0f2f4; color: var(--muted); }

.mono-plate { font-weight: 800; letter-spacing: .05em; }

/* --- Hub cards (settings) ------------------------------------------------ */
.hub {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
  gap: 12px;
}
.hub__card {
  display: flex;
  align-items: center;
  gap: 12px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  box-shadow: var(--shadow-1);
  padding: 16px;
  min-height: 76px;
  text-decoration: none;
  color: inherit;
}
.hub__card:hover { border-color: var(--amber-deep); }
.hub__icon {
  width: 40px; height: 40px;
  border-radius: var(--r-sm);
  background: var(--concrete);
  color: var(--ink);
  display: grid; place-items: center;
  flex: none;
}
.hub__icon svg { width: 21px; height: 21px; }
.hub__title { font-weight: 700; }
.hub__sub { font-size: .8rem; color: var(--muted); }

/* --- Utility ------------------------------------------------------------ */
[hidden] { display: none !important; }
.stack > * + * { margin-top: 16px; }
.muted { color: var(--muted); }
.text-center { text-align: center; }
.form-grid { display: grid; gap: 14px; }
@media (min-width: 700px) {
  .form-grid--2 { grid-template-columns: 1fr 1fr; }
  .form-grid--2 .full { grid-column: 1 / -1; }
}

/* ==========================================================================
   Reports, dashboard, users, audit — components built on the spacing scale.
   ========================================================================== */

/* --- Section heading ----------------------------------------------------- */
.section__title {
  font-size: var(--fs-section);
  font-weight: 800;
  margin: 0 0 var(--sp-3);
  display: flex;
  align-items: center;
  gap: var(--sp-2);
}
.section__title svg { width: 19px; height: 19px; color: var(--muted); flex: none; }
.muted { color: var(--muted); }

/* --- KPI cards: one grid, one size, one alignment ------------------------ */
.kpis {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
  gap: var(--sp-3);
}
.kpi {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  padding: var(--sp-4);
  box-shadow: var(--shadow-1);
  display: flex;
  flex-direction: column;
  gap: var(--sp-1);
  min-height: 108px;
  text-align: start;
}
.kpi__label {
  font-size: .74rem;
  font-weight: 700;
  color: var(--muted);
  letter-spacing: .06em;
  line-height: 1.35;
}
.kpi__value {
  font-size: 1.85rem;
  font-weight: 800;
  line-height: 1.15;
  margin-top: auto;
}
.kpi__value--sm { font-size: 1.15rem; line-height: 1.35; }
.kpi--accent { border-inline-start: 4px solid var(--amber); }
.kpi--alert  { border-inline-start: 4px solid var(--red); }

/* --- Filter panel -------------------------------------------------------- */
.filters { display: grid; gap: var(--sp-4); }
.filters__quick { display: flex; flex-wrap: wrap; gap: var(--sp-2); }
.chip {
  min-height: 40px;
  padding: 0 var(--sp-4);
  border: 1px solid var(--line);
  border-radius: 999px;
  background: var(--surface);
  font: inherit;
  font-size: .88rem;
  font-weight: 700;
  color: var(--ink);
  cursor: pointer;
  display: inline-flex;
  align-items: center;
}
.chip:hover { border-color: var(--amber-deep); }
.chip.is-on { background: var(--ink); color: #fff; border-color: var(--ink); }

.filters__grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: var(--sp-3);
  align-items: end;
}
.filters__grid .field { margin-bottom: 0; }
.filters__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-2);
  padding-top: var(--sp-1);
}
.filters__actions .btn { flex: 0 1 auto; }
select.input {
  appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%235f6c7b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: left 12px center;
  background-size: 18px;
  padding-inline-end: 40px;
}

/* --- Licence plate: set like the real thing ------------------------------ */
.plate-tag {
  display: inline-block;
  padding: 2px 8px;
  border: 1.5px solid var(--ink);
  border-radius: 4px;
  background: #fff;
  font-weight: 800;
  letter-spacing: .08em;
  white-space: nowrap;
  font-size: .92rem;
}

/* --- Tables -------------------------------------------------------------- */
.table th a {
  color: inherit;
  text-decoration: none;
  display: inline-flex;
  align-items: center;
  gap: 4px;
  white-space: nowrap;
}
.table th a:hover { color: var(--amber-deep); }
.sort-caret { font-size: .7rem; color: var(--amber-deep); }
.table tfoot td { font-weight: 800; background: #f7f9fb; }
.num { font-variant-numeric: tabular-nums; }

.badge--open   { background: #fff4e0; color: var(--amber-deep); }
.badge--closed { background: #e6f6f0; color: var(--green); }
.badge--forced { background: #fdecec; color: var(--red); }
.badge--role   { background: #eaf0f7; color: var(--steel); }

/* --- Pagination ---------------------------------------------------------- */
.pager {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--sp-3);
  margin-top: var(--sp-4);
}
.pager__info { color: var(--muted); font-size: .88rem; }
.pager__links { display: flex; gap: var(--sp-2); margin-inline-start: auto; }
.pager__link {
  min-height: 42px;
  min-width: 44px;
  padding: 0 var(--sp-4);
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
  background: var(--surface);
  color: var(--ink);
  text-decoration: none;
  font-weight: 700;
  font-size: .88rem;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.pager__link:hover { border-color: var(--amber-deep); }
.pager__link.is-disabled { opacity: .45; pointer-events: none; }

/* --- Breakdowns + charts ------------------------------------------------- */
.breakdowns {
  display: grid;
  /* minmax(0, 1fr), never a bare 1fr: a grid item defaults to min-width:auto,
     which lets a wide table inside push the whole track — and the page — past
     the viewport on a phone. The scrollbar belongs to .table-wrap, not <body>. */
  grid-template-columns: minmax(0, 1fr);
  gap: var(--sp-4);
}
.breakdowns > * { min-width: 0; }
@media (min-width: 1280px) {
  .breakdowns { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .breakdowns > .card--wide { grid-column: 1 / -1; }
}
.chart-box {
  position: relative;
  height: 260px;
  margin-bottom: var(--sp-4);
}
.chart-box canvas { max-width: 100%; }

/* --- Forms --------------------------------------------------------------- */
.form-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: var(--sp-3);
}
.form-grid .field { margin-bottom: 0; }
.form-grid .field--full { grid-column: 1 / -1; }
.hint { font-size: var(--fs-hint); color: var(--muted); margin: var(--sp-1) 0 0; }
.alert--ok { background: #e6f6f0; color: #0d6f52; border-color: #b9e4d5; }
.card--narrow { max-width: 560px; }

/* --- Empty state --------------------------------------------------------- */
.empty {
  text-align: center;
  padding: var(--sp-7) var(--sp-4);
  color: var(--muted);
}
.empty svg { width: 40px; height: 40px; opacity: .5; }
.empty strong { display: block; color: var(--ink); margin: var(--sp-3) 0 var(--sp-1); font-size: 1.05rem; }

/* --- Toolbar above a table ---------------------------------------------- */
.table-head {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--sp-3);
  margin-bottom: var(--sp-3);
}
.table-head .section__title { margin: 0; }
.table-head__actions { margin-inline-start: auto; display: flex; gap: var(--sp-2); flex-wrap: wrap; }

/* --- Step indicator ------------------------------------------------------
   Used only on entry.php, where the guard genuinely moves through three
   ordered stages on one screen. The numbers carry real sequence — which is
   the only reason they are numbers and not decoration. */
.steps {
  display: flex;
  align-items: stretch;
  gap: var(--sp-2);
  counter-reset: step;
}
.steps__item {
  flex: 1 1 0;
  min-width: 0;
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  padding: var(--sp-2) var(--sp-3);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  background: var(--surface);
  font-size: var(--fs-hint);
  font-weight: 700;
  color: var(--muted);
}
.steps__n {
  flex: none;
  width: 22px; height: 22px;
  border-radius: var(--r-pill);
  background: var(--concrete);
  color: var(--muted);
  display: grid; place-items: center;
  font-size: var(--fs-eyebrow);
  font-weight: 800;
}
.steps__label { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.steps__item.is-on {
  border-color: var(--amber-deep);
  background: var(--amber-wash);
  color: var(--ink);
}
.steps__item.is-on .steps__n { background: var(--ink); color: #fff; }
.steps__item.is-done .steps__n { background: var(--green); color: #fff; }
.steps__item.is-done { color: var(--ink); }

@media (max-width: 519px) {
  /* On a phone the labels do not fit three across; the numbers still track
     position, so the labels drop rather than truncating to nothing. */
  .steps__label { display: none; }
  .steps__item { justify-content: center; padding: var(--sp-2); }
}

/* --- "what happens next" note under a focus card ------------------------ */
.next-up {
  border: 1px dashed var(--line);
  border-radius: var(--r-md);
  background: var(--surface);
  padding: var(--sp-4);
  color: var(--muted);
  font-size: var(--fs-hint);
}
.next-up__title {
  display: flex; align-items: center; gap: var(--sp-2);
  font-size: var(--fs-label);
  font-weight: 700;
  color: var(--ink);
  margin: 0 0 var(--sp-2);
}
.next-up ol { margin: 0; padding-inline-start: 1.15em; }
.next-up li + li { margin-top: 4px; }

/* --- Live gate counter in the header ------------------------------------
   The header had ~860px of dead centre. Rather than shrink the bar back into
   a container that aligns with nothing, the space now carries the one number
   anybody at a gate wants from every screen: how many vehicles are inside. */
.gate-now {
  display: none;
  align-items: center;
  gap: var(--sp-2);
  margin-inline: auto;
  padding: 5px var(--sp-3);
  border: 1px solid rgba(255,255,255,.16);
  border-radius: var(--r-pill);
  color: #fff;
  text-decoration: none;
  font-size: var(--fs-label);
  font-weight: 700;
  white-space: nowrap;
}
.gate-now:hover { background: rgba(255,255,255,.08); }
.gate-now svg { color: var(--amber); }
.gate-now__n {
  font-weight: 800;
  font-size: var(--fs-body-lg);
  line-height: 1;
}
.gate-now__label { color: rgba(255,255,255,.72); font-weight: 600; }
.gate-now--alert { border-color: rgba(242,166,0,.55); background: rgba(242,166,0,.12); }
@media (min-width: 700px) { .gate-now { display: inline-flex; } }

/* --- Page-level empty state ---------------------------------------------
   A list screen with nothing in it should still look like a screen. Without
   the min-height the emptied open.php collapsed to a third of the viewport. */
.empty--page {
  min-height: 340px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--sp-2);
}
.empty--page svg { width: var(--icon-illus); height: var(--icon-illus); color: var(--line); }
.empty--page .btn { margin-top: var(--sp-3); }

/* --- Compact stat strip for the focus screens --------------------------- */
.mini-stats {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--sp-2);
}
.mini-stat {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  padding: var(--sp-3) var(--sp-4);
}
.mini-stat__icon {
  width: 34px; height: 34px; flex: none;
  border-radius: var(--r-sm);
  background: var(--concrete);
  color: var(--muted);
  display: grid; place-items: center;
}
.mini-stat__n { font-size: var(--fs-section); font-weight: 800; line-height: 1.1; }
.mini-stat__label { font-size: var(--fs-hint); color: var(--muted); }
.mini-stat--alert .mini-stat__icon { background: var(--amber-wash); color: var(--amber-deep); }
