/* Django port additions.

   design-system.css is a byte-for-byte copy of the approved prototype and is
   NOT edited — so the look cannot drift. Everything here exists only because a
   thing that was a <div> with a JavaScript handler in the prototype is a real
   <a href> here, and a browser underlines links.
*/
a.sb-link,
a.stat-card,
a.gate-tile,
a.role-tab,
.filter-bar a,
.table-actions a,
.view-head-actions a,
.panel-body a.btn { text-decoration: none; color: inherit; }

a.stat-card:hover, a.gate-tile:hover { text-decoration: none; }

/* Tabs on Master Data — the prototype's .role-tab as a link */
a.role-tab { display: inline-flex; align-items: center; gap: 8px; }

/* Type identity — hues validated in the prototype with the dataviz skill's six
   checks. Identity is NEVER colour alone: every chip carries its text label,
   which is also what keeps it legible for colour-vision deficiency. */
.badge.type-visitor      { background:#EAF1F8; color:#2C6FB0; }
.badge.type-trailer      { background:#FDF3E0; color:#A86A00; }
.badge.type-raw_material { background:#E8F6EE; color:#1E8A56; }

/* Photo grid on the drill-down */
.photo-grid { display:grid; grid-template-columns:repeat(auto-fill,minmax(150px,1fr)); gap:12px; }
.photo-grid figure { margin:0; cursor:zoom-in; }
.photo-grid img { width:100%; aspect-ratio:4/3; object-fit:cover; border-radius:10px;
                  border:1px solid var(--concrete-200); display:block; }
.photo-grid figcaption { font-size:11.5px; color:var(--text-2); margin-top:6px; line-height:1.4; }
.photo-grid figcaption b { display:block; color:var(--text-1); font-size:12px; }

/* ---------------------------------------------------------------- language
   design-system.css sets the Devanagari face only on `.t` and `:lang(hi)`,
   because in the prototype those were the ONLY translated elements. Now that a
   whole screen can be Hindi, the face has to apply at body level — otherwise
   Inter has no Devanagari glyphs and the browser silently substitutes whatever
   the operating system happens to have, which differs on every gate PC.
   ⚠ This rule lives HERE and not in design-system.css, which is a byte-for-byte
   copy of the approved prototype and is never edited. */
body[data-lang="hi"] {
  font-family: 'Noto Sans Devanagari', 'Inter', sans-serif;
}
body[data-lang="hi"] h1,
body[data-lang="hi"] h2,
body[data-lang="hi"] h3,
body[data-lang="hi"] .display {
  /* Barlow Condensed has no Devanagari either. Keep the condensed face for the
     Latin that remains (plate numbers, IDs) and let Noto carry the rest. */
  font-family: 'Barlow Condensed', 'Noto Sans Devanagari', sans-serif;
}
/* Identifiers stay monospace and Latin in both languages — a vehicle plate or a
   staff ID must look identical to every guard, whatever the interface says. */
body[data-lang="hi"] .mono,
body[data-lang="hi"] input,
body[data-lang="hi"] select { font-family: inherit; }
body[data-lang="hi"] .mono { font-family: 'JetBrains Mono', monospace; }

/* The login screen carries its own switch, top right. */
.login-lang { position: absolute; top: 18px; right: 20px; z-index: 5; }
#login-screen { position: relative; }

/* The topbar's sign-out. It was a 34px icon-only circle and people did not find
   it; his call, 24 Aug 2026 — bigger, and it says what it does.
   ⚠ design-system.css is a byte-for-byte copy of the approved prototype and is
   never edited, so this lives here and reuses .btn / .btn-outline rather than
   inventing a fourth button style. */
.tb-logout {
  gap: 8px;
  padding: 9px 16px;
  font-size: 13.5px;
  white-space: nowrap;
}
/* Devanagari sets taller and wider than Latin — give the word room so the
   button never crops "लॉग आउट". */
body[data-lang="hi"] .tb-logout { padding: 8px 14px; }

/* ── A ROW ACTION SITS IN A CELL, AND A CELL IS NOT A FLEX CONTAINER ────────
   26 Aug 2026. design-system.css gives `.table-actions` display:flex, which is
   right on the <div> it was written for and wrong on the <td> nine templates
   use it on. A <td> that is display:flex stops being a table cell: the row's
   height is decided by the flex container instead of by the tallest cell, and
   `vertical-align:middle` — which only applies to table cells — stops applying
   at all. On a row whose left column wraps to three lines the button floats to
   the top and the cell's own border-bottom lands mid-row.

   His diagnosis, and it was right: "the grid expands but doesn't expand as per
   the grid and expands as per the button."

   Fixed ONCE, here, rather than nine times: design-system.css is a
   byte-for-byte copy of the approved prototype and is not edited, and the
   .table-actions class stays flex everywhere it is used on a <div>. */
td.table-actions,
th.table-actions {
  display: table-cell;
  vertical-align: middle;
  white-space: nowrap;
}
/* Losing the flex container also loses its gap, so the space between two
   actions in one cell is restored explicitly. */
td.table-actions > form { display: inline-block; }
td.table-actions > * + * { margin-left: 6px; }

/* ---- D52 · the error pages and the sign-out confirmation ----------------
   One shared shape for 404, the CSRF 403 and the logout confirmation: a
   centred card, in the application's own palette, on the plain body (no
   sidebar — the person may not be signed in, and the 404 in particular
   renders for strangers who mistyped the /visit/ address).
   ⚠ 500.html does NOT use these classes on purpose: that page must not
   depend on a stylesheet loading. Its styles are inline in the template. */
.error-page {
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--bg, #f4f5f7);
}
.error-card {
  background: var(--white, #fff);
  border: 1px solid var(--line, #e2e5e9);
  border-radius: 10px;
  padding: 40px 44px;
  max-width: 520px;
  margin: 24px;
  text-align: center;
  box-shadow: 0 2px 10px rgba(20, 24, 31, .06);
}
.error-code {
  font-size: 13px;
  font-weight: 700;
  letter-spacing: .18em;
  color: var(--steel-700, #444a52);
}
.error-card h1 { font-size: 22px; margin: 10px 0 12px; }
.error-card p  { font-size: 14.5px; line-height: 1.55; color: var(--steel-700, #444a52); }
.error-actions { margin-top: 20px; display: flex; gap: 10px; justify-content: center; flex-wrap: wrap; }

/* ---- D53 · THE GRID MUST SURVIVE BROWSER ZOOM -------------------------
   His observation, 26 Aug 2026: "I was pressing control plus and the grid
   broke — UI elements are displaced."

   MEASURED, not guessed. Ctrl+ makes CSS pixels bigger, so the LAYOUT
   VIEWPORT SHRINKS: a 1440px window at 125% is 1152 CSS px, at 150% it is
   960, at 200% it is 720. `table.data-table{width:100%}` sits directly in
   .panel-body with nothing to scroll, and a table has a min-content width it
   cannot go below — Hosts is 951px because of its two inline <input>s. Below
   that the table pushed the PAGE wide, which shoved the whole shell sideways,
   and .panel's overflow clipped the action buttons off the right edge.

   Broken at 125% on Hosts and at 150% on Log Activity, Users, All Records and
   Locations. Everything a Superadmin uses, at a zoom level people really use.

   TWO LAYERS, because one is not enough:
     · let what CAN shrink shrink (inputs, long header words);
     · scroll the TABLE, never the page, as the backstop.
   ⚠ design-system.css is the approved prototype byte-for-byte and is not
   edited — the fix lives here, as with the row-action alignment fix above. */
.table-wrap {
  overflow-x: auto;
  /* ⚠ overflow-y stays visible. Setting overflow-x alone makes the browser
     compute overflow-y as auto, which would clip a dropdown or a focus ring
     out of the row. `clip` on the block axis keeps the horizontal scroll
     without trapping anything vertically. */
  overflow-y: clip;
  -webkit-overflow-scrolling: touch;
}
/* A table narrower than its panel must still fill it, not shrink to content. */
.table-wrap > table.data-table { min-width: 100%; }

/* The inline inputs on the Hosts master are what make that table the widest
   thing in the application. They may shrink; `min-width:0` is the part that
   actually lets them, because a form control's default min-width is auto.
   ⚠ These were INLINE STYLES on the elements (`min-width:170px`), which beat
   any stylesheet — the table stayed 951px however narrow the window got, and
   that alone is why Hosts broke a full zoom step before every other screen.
   Widths belong in a class precisely so they can be answered here. */
.data-table input,
.data-table select {
  min-width: 0;
  max-width: 100%;
}
.cell-input { width: 100%; }
.cell-input-email { min-width: 170px; }
.cell-input-mobile { width: 132px; }
@media (max-width: 1100px) {
  .cell-input-email { min-width: 120px; }
  .cell-input-mobile { width: 100px; }
}
/* Headers may wrap once the room is gone — a two-line heading is better than
   a scrollbar, and the scrollbar is still there when wrapping is not enough. */
@media (max-width: 1100px) {
  table.data-table thead th { white-space: normal; }
}

/* ---- D53 · THE ROW SWITCHES ------------------------------------------
   Three settings are changed by a switch rather than an edit form, because
   🔒 A32 forbids any screen that could change a master's NAME: a switch can
   only ever touch the one setting it names. They were `btn-ghost` —
   transparent background, transparent border — so they read as grey text and
   he went looking for one, did not find it, and used Remove instead. A
   control the Superadmin cannot find is not a control.

   The switch now carries the state and the words say what the state IS; the
   action ("Weigh this at check-out") is the accessible name, so the control
   reads as a switch to a screen reader rather than as a button whose label
   contradicts the badge beside it. */
.switch-cell { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.switch-cell form { display: inline-flex; margin: 0; }

.switch {
  --switch-w: 38px;
  --switch-h: 22px;
  display: inline-flex;
  align-items: center;
  padding: 0;
  border: 0;
  background: none;
  cursor: pointer;
  line-height: 0;
}
.switch .track {
  width: var(--switch-w);
  height: var(--switch-h);
  border-radius: 999px;
  background: var(--concrete-200, #d8dce1);
  border: 1px solid var(--concrete-300, #c2c8ce);
  position: relative;
  transition: background .15s ease, border-color .15s ease;
}
.switch .knob {
  position: absolute;
  top: 2px;
  left: 2px;
  width: calc(var(--switch-h) - 6px);
  height: calc(var(--switch-h) - 6px);
  border-radius: 50%;
  background: var(--white, #fff);
  box-shadow: 0 1px 3px rgba(20, 24, 31, .35);
  transition: transform .15s ease;
}
.switch[aria-checked="true"] .track {
  background: var(--steel-900, #14532d);
  border-color: var(--steel-900, #14532d);
}
.switch[aria-checked="true"] .knob {
  transform: translateX(calc(var(--switch-w) - var(--switch-h)));
}
.switch:hover .track { border-color: var(--steel-700, #444a52); }
.switch:focus-visible { outline: 2px solid var(--steel-700, #444a52); outline-offset: 3px; border-radius: 999px; }

/* The action wording stays in the DOM for screen readers and for the QA
   harnesses that click by name — visible only to them. */
.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* ---------------------------------------------------------------- typeahead
   D59 — a long dropdown you can type into. The native <select> is still in the
   form and still carries the value; it is moved out of sight, NOT set to
   `display:none`, because a hidden-by-display control is skipped by some
   browsers' form restoration and by the accessibility tree in ways that make a
   "required" select impossible to report on.

   ⚠ `position:absolute` on the list is load-bearing. A list that took part in
   layout would widen its column, and a table screen whose column widens pushes
   the whole PAGE sideways at 150% zoom — already paid for once, by an inline
   min-width on one input that broke a full zoom step on the Hosts table. */
.typeahead { position: relative; }
/* ⚠ THE SELECTOR IS DELIBERATELY MORE SPECIFIC THAN IT LOOKS. `.field select`
   already sets `width:100%` and beats a bare `.typeahead-native` on
   specificity — so the hidden select kept its full width, and because it is
   absolutely positioned it escaped its column and pushed the PAGE 324px wide
   at every zoom level. Caught by qa/run-zoom-check.sh, which is the third time
   this project has been bitten by a width it did not state: an inline
   min-width once broke the Hosts table a whole zoom step before every other
   screen. `!important` would also work and is not used — the rule that wins
   should win by being the more specific description of the thing. */
.typeahead select.typeahead-native {
  position: absolute;
  width: 1px; height: 1px; min-width: 0; max-width: 1px;
  padding: 0; margin: -1px; border: 0;
  clip-path: inset(50%);
  overflow: hidden;
}
.typeahead-list {
  position: absolute;
  z-index: 60;
  top: 100%; left: 0; right: 0;
  margin: 4px 0 0;
  padding: 4px;
  max-height: 260px;
  overflow-y: auto;
  list-style: none;
  background: var(--surface, #fff);
  border: 1px solid var(--border);
  border-radius: 6px;
  box-shadow: 0 8px 24px rgba(0, 0, 0, .14);
}
.typeahead-list li {
  padding: 7px 10px;
  border-radius: 4px;
  font-size: 13.5px;
  cursor: pointer;
}
.typeahead-list li.active,
.typeahead-list li:hover { background: var(--surface-2, #EEF2F5); }
.typeahead-list li.typeahead-empty { color: var(--text-3); cursor: default; }
.typeahead-list li.typeahead-empty:hover { background: transparent; }

/* ------------------------------------------------------- the removal warning
   D59, finding 7. Its own overlay rather than a shared modal, because it is
   the only dialog on this screen and a screen that pulls in the gate's modal
   markup for one dialog inherits the gate's modal JavaScript with it. */
.confirm-remove-backdrop {
  position: fixed; inset: 0; z-index: 200;
  background: rgba(16, 22, 28, .55);
  display: flex; align-items: center; justify-content: center;
  padding: 20px;
}
.confirm-remove-backdrop[hidden] { display: none; }
.confirm-remove {
  background: var(--surface, #fff);
  border-radius: 8px;
  padding: 22px 24px;
  max-width: 460px; width: 100%;
  box-shadow: 0 18px 50px rgba(0, 0, 0, .28);
}
.confirm-remove h3 { margin: 0 0 10px; font-size: 17px; }
.confirm-remove p { margin: 0 0 10px; font-size: 13.5px; line-height: 1.55; color: var(--text-2); }
.confirm-remove .cr-count { font-weight: 700; color: var(--text-1); }
.confirm-remove .cr-count-warn { color: var(--amber-700, #8A5A00); }
.confirm-remove .cr-actions { display: flex; gap: 10px; justify-content: flex-end; margin-top: 16px; }
