/* Anadi UI theme — prototype trial (IBM Plex Sans, #2B59C3). Revert this commit for the old look. */
@import url('https://fonts.googleapis.com/css2?family=IBM+Plex+Sans:wght@400;500;600;700&display=swap');
:root {
  --brand: #2B59C3;
  --brand-soft: #EAF0FC;
  --bg: #F5F6F8;
  --card: #ffffff;
  --ink: #1d2433;
  --line: #E3E6EC;
  --muted: #6B7280;
  --danger: #B23A3A;
  --amber-soft: #FFF3DC;
  --teal: #0F9D8A;
  --teal-soft: #E6F7F3;
  --danger-soft: #FDEAEA;
  --divider: #cbd5e1;
  --ok: #2c7a4b;
  --amber: #8A5A00;
  --mono: ui-monospace, "Cascadia Mono", Consolas, monospace;

  /* Scales. Before these there were 9 ad-hoc margin values, 15 font sizes and 9 radii —
     nudges rather than decisions. Reach for a step; add one only if none fits. */
  --s1: .25rem; --s2: .5rem; --s3: .75rem; --s4: 1rem; --s5: 1.5rem;
  --fs-xs: .75rem; --fs-sm: .85rem; --fs-base: .95rem; --fs-lg: 1.1rem; --fs-xl: 1.35rem;
  --r-sm: 6px; --r-md: 10px; --r-pill: 999px;

  /* Row states were a hardcoded hex per page, and var(--hover, #f6f7f9) silently forked
     because --hover was never defined anywhere. */
  --row-hover: #f5f8fd;
  --row-selected: var(--brand-soft);
  --rail-w: 500px;
}
* { box-sizing: border-box; }
[hidden] { display: none !important; }  /* .row's display:flex would otherwise win */
body { margin: 0; font: 15px/1.5 "IBM Plex Sans", "Segoe UI", system-ui, sans-serif; background: var(--bg); color: var(--ink); }
/* Sizes, not just weight: without them h3/h4 and a bold paragraph all rendered ~15px, so
   a heading carried no more signal than the body text under it. */
h1, h2, h3, h4 { font-weight: 600; margin: var(--s4) 0 var(--s2); }
h1 { font-size: var(--fs-xl); }
h2 { font-size: var(--fs-xl); }
h3 { font-size: var(--fs-lg); }
h4 { font-size: var(--fs-base); color: var(--muted); }
/* A section title inside a card: the job the 11 <p><b> blocks in accounts.html were doing. */
.section { margin: var(--s4) 0 var(--s2); font-size: var(--fs-lg); font-weight: 600; }
.section:first-child { margin-top: 0; }
.stack > * + * { margin-top: var(--s2); }
header { background: var(--card); border-bottom: 1px solid var(--line);
  position: sticky; top: 0; z-index: 10; }
.hrow { display: flex; align-items: center; gap: 1rem; padding: 0 1.3rem; flex-wrap: wrap; min-height: 60px; }
.hrow.top { border-bottom: 1px solid var(--line); }
.hrow.menu { padding: .2rem 1.1rem .35rem; }
.userblock { display: flex; flex-direction: column; line-height: 1.15; text-align: right; }
.userblock .muted { font-size: .72rem; text-transform: capitalize; }
.iconlink { text-decoration: none; font-size: 1.1rem; color: var(--muted); }
.iconlink:hover { color: var(--brand); }
nav a .ico { margin-right: .4rem; opacity: .7; font-size: .95em; }
header .logo { font-family: inherit; font-weight: 700; font-size: 1.3rem; color: var(--brand);
  display: inline-flex; align-items: center; gap: .5rem; }
.brandmark { width: 28px; height: 28px; border-radius: 7px; object-fit: contain; }
.brandmark.fallback { background: var(--brand); color: #fff; display: inline-flex;
  align-items: center; justify-content: center; font-size: 1rem; line-height: 1; }
nav { display: flex; gap: .35rem; flex-wrap: wrap; }
/* Accounts has 9 areas to the flight module's 6, so it wrapped to a 3-row header first.
   A scrollable strip costs less vertical space than three stacked rows. */
@media (max-width: 1200px) {
  nav { flex-wrap: nowrap; overflow-x: auto; scrollbar-width: none; }
  nav::-webkit-scrollbar { display: none; }
  nav a { white-space: nowrap; }
}
nav a { color: var(--ink); text-decoration: none; padding: .35rem .75rem; border-radius: 999px; font-weight: 500; }
nav a.active { background: var(--brand-soft); color: var(--brand); }
nav a:hover:not(.active) { background: #f1f4f9; }
header .spacer { flex: 1; }
main { padding: 1.25rem 1rem; max-width: 1250px; margin: 0 auto; transition: margin .18s ease-out; }
/* Pages with a PERSISTENT rail (Accounts) opt out of centring entirely. Switching between
   centred and full-bleed per tab moved the content column ~240px sideways; holding one
   mode costs a little width and keeps everything still. Pages whose rail is an occasional
   drawer (the flight module) stay centred as they were. */
body.railed main { max-width: none; margin: 0 calc(var(--rail-open, 0px) + .5rem) 0 .5rem; }
/* drawer open: give the rail its own column instead of stacking on top of the worklist */
/* The rail's width is now a token main reads, so opening it shifts one margin instead of
   switching layout mode. Between ~900 and ~1300px a fixed 500px rail took more than half
   the window, so it tracks the viewport instead. */
body.railed .rail { width: min(var(--rail-w), 38vw); }
@media (max-width: 1100px) { body.railed .rail { width: min(var(--rail-w), 100vw); } }
body.railed.rail-open { --rail-open: min(var(--rail-w), 38vw); }
@media (max-width: 900px) { body.railed.rail-open { --rail-open: 0px; } }
/* the flight module's drawer keeps its original behaviour */
body:not(.railed).rail-open main { max-width: none; margin-left: .5rem;
  margin-right: calc(min(500px, 100vw) + .5rem); }
@media (max-width: 900px) { body:not(.railed).rail-open main { margin-right: .5rem; } }
.card { background: var(--card); border: 1px solid var(--line); border-radius: 10px;
  padding: 1.1rem; margin-bottom: 1rem; box-shadow: 0 1px 2px rgba(29, 36, 51, .05); }
table { width: 100%; border-collapse: collapse; }
th { color: var(--muted); font-weight: 600; font-size: .78rem; text-transform: uppercase; letter-spacing: .06em; }
th, td { text-align: left; padding: .55rem .6rem; border-bottom: 1px solid var(--line); }
/* A TOTAL is not a column label. Using <th> for both made the closing balance the
   smallest, greyest thing on screen — smaller than the figures it sums. */
tfoot th, tfoot td, th[scope=row], tr.total th, tr.total td {
  font-size: var(--fs-base); text-transform: none; letter-spacing: 0;
  color: var(--ink); font-weight: 600; border-top: 2px solid var(--ink); border-bottom: none; }
/* Hover feedback must mean "this does something". It used to apply to every row in the
   app, so six Accounts tabs glowed as if clickable when only a link inside was. */
tr.click:hover td, tr.click:focus-visible td { background: var(--row-hover); }
tr.click { cursor: pointer; }
.moneycol, th.n, td.n { white-space: nowrap; }
.mono { font-family: var(--mono); font-size: .92em; }
.pill { display: inline-flex; align-items: center; gap: .35rem; padding: .15rem .6rem;
  border-radius: 999px; background: var(--amber-soft); font-size: .85rem; font-weight: 500;
  text-transform: capitalize; }
.pill.locked { background: #f1eefb; text-transform: none; }
.pill.locked::before { background: #7a5af5; }
.pill::before { content: ""; width: .5em; height: .5em; border-radius: 50%; background: var(--amber); }
.pill.booked { background: #e8f4ec; } .pill.booked::before { background: var(--ok); }
.pill.sent { background: #e7f0fb; } .pill.sent::before { background: var(--brand); }
.pill.accepted { background: var(--teal-soft); } .pill.accepted::before { background: var(--teal); }
.pill.rejected { background: var(--danger-soft); } .pill.rejected::before { background: var(--danger); }
input, select, button, textarea { font: inherit; padding: .48rem .7rem;
  border: 1px solid var(--line); border-radius: 6px; background: #fff; color: var(--ink); }
/* --brand-soft is ~1.13:1 on white — a ring nobody can see. --brand clears 3:1 on both
   the card and the page, and :focus-visible keeps it off mouse clicks. */
input:focus-visible, select:focus-visible, textarea:focus-visible,
button:focus-visible, a:focus-visible, [tabindex]:focus-visible {
  outline: 2px solid var(--brand); outline-offset: 2px; border-color: var(--brand); }
input:focus, select:focus, textarea:focus { border-color: var(--brand); }
/* transparent border, not none: a borderless button was 2px shorter than every input
   beside it, so form rows had a ragged baseline. */
button { background: var(--brand); color: #fff; border: 1px solid transparent;
  cursor: pointer; font-weight: 500; }
button:hover { filter: brightness(1.08); }
button:disabled { opacity: .45; cursor: not-allowed; filter: none; }
button.secondary { background: var(--bg); color: var(--ink); border: 1px solid var(--line); }
/* A third level. With only primary and secondary, "Apply" shouted as loudly as
   "Create invoice"; a screen should have one primary action. */
button.ghost { background: transparent; color: var(--brand); border: 1px solid var(--line); }
button.ghost:hover { background: var(--brand-soft); }
button.danger { background: var(--danger); color: #fff; }

/* A toggle must not look like a call to action — the pivot's 15 dimension chips rendered
   as 2 primary and 13 secondary BUTTONS, reading as 15 things to click once. */
.chip { background: var(--bg); color: var(--ink); border: 1px solid var(--line);
  border-radius: var(--r-pill); padding: .2rem .7rem; font-size: var(--fs-sm); font-weight: 500; }
.chip[aria-pressed=true] { background: var(--brand-soft); color: var(--brand); border-color: #C7D8F6; }

/* One field row, used by panels and dialogs alike; they had two copies with 9rem and 8rem
   label columns, so a form in a card never lined up with a form in a modal. */
.field { display: flex; gap: var(--s2); align-items: center; margin: var(--s1) 0; }
.field > span.lbl { flex: 0 0 var(--label-col, 9rem); color: var(--muted); }
.field > :is(input, select, textarea) { flex: 0 1 var(--field-w, 18rem); min-width: 0; }
.field .fielderr { flex-basis: 100%; margin: 0 0 0 var(--label-col, 9rem);
  color: var(--danger); font-size: var(--fs-sm); }
input.bad, select.bad { border-color: var(--danger); }

/* A form opened inside a card is not a second card. */
.panel { border: 1px solid var(--line); border-radius: var(--r-sm); padding: var(--s3);
  background: var(--bg); margin: var(--s2) 0 var(--s4); }

/* Loading without destroying the page: the table stays, only rows are replaced. */
@keyframes pulse { 0%, 100% { opacity: 1 } 50% { opacity: .45 } }
.skeleton { background: var(--line); border-radius: var(--r-sm); height: .9em;
  animation: pulse 1.2s ease-in-out infinite; }

/* Empty states should read as an answer, not as a row that failed to load. */
.emptystate { padding: var(--s5) var(--s3); text-align: center; color: var(--muted); }
.emptystate td { border-bottom: none; }
/* tighter section rhythm inside the drawer */
.rail h4 { margin: .55rem 0 .3rem; }
/* consistent section-to-section rhythm regardless of which tab / how much content shows */
#inq_fields, #inq_actions, #rel_form, #inq_pax, #fares, #picked_note, #quotes, #bkg { margin-bottom: .75rem; }
#rel_form:empty, #picked_note:empty, #bkg:empty, #inq_pax_form:empty { margin-bottom: 0; }
/* the form's action row never leaves the viewport */
.formfoot { position: sticky; bottom: 0; background: var(--card);
  padding: .45rem 0; margin: .2rem 0 0; box-shadow: 0 -6px 8px -6px rgba(29,36,51,.15); }

/* passengers as chips (prototype): blue pill, actions inline */
.paxchip { display: inline-flex; align-items: center; gap: .3rem;
  background: var(--brand-soft); color: var(--brand);
  padding: .22rem .7rem; border-radius: 14px; font-size: .86rem; font-weight: 500; }
.paxchip b { color: var(--brand); }
.paxchip button, .paxchip button.secondary { background: none !important;
  border: none !important; color: var(--brand) !important;
  padding: 0 .12rem !important; box-shadow: none; font-size: .85rem; }
.paxchip button:hover { filter: none; opacity: .65; }

/* drawer tabs (prototype): text buttons with a blue underline */
.railtabs { display: flex; gap: 1.4rem; border-bottom: 1px solid var(--line); margin: .2rem 0 .8rem; }
.railtabs button { background: none; border: none; border-radius: 0; color: var(--muted);
  padding: .45rem .1rem .55rem; font-weight: 500; border-bottom: 2px solid transparent; }
.railtabs button.active { color: var(--brand); border-bottom-color: var(--brand); font-weight: 600; }
.railtabs button:disabled { opacity: .4; }
.railtabs button:hover:not(:disabled) { filter: none; color: var(--brand); }

.tabs { display: flex; gap: .25rem; background: var(--bg); border-radius: 999px; padding: .2rem; width: fit-content; }
.tabs button { background: transparent; color: var(--ink); border-radius: 999px; padding: .35rem .9rem; }
.tabs button.active { background: #fff; color: var(--ink); box-shadow: 0 1px 2px rgba(0,0,0,.08); }
.tabs .dot { display: inline-block; width: .5em; height: .5em; border-radius: 50%; margin-right: .4em; }
.tabs .dot.open { background: var(--amber); } .tabs .dot.booked { background: var(--ok); }
.tabs .dot.rejected { background: var(--danger); }
.tabs .count { background: #e8edf7; color: var(--brand); border-radius: 999px;
  padding: 0 .45em; font-size: .8em; font-weight: 600; margin-left: .3em; }
.tabs button.active .count { background: var(--brand); color: #fff; }
.tabs .count:empty { display: none; }  /* no blank pill when the count is zero */
.row { display: flex; gap: .5rem; flex-wrap: wrap; align-items: center; margin-bottom: .75rem; }
.error { color: var(--danger); }
.muted { color: var(--muted); font-size: .9em; }
.status-open { color: var(--amber); } .status-booked { color: var(--ok); } .status-rejected { color: var(--danger); }
.rail { position: fixed; top: 0; right: 0; height: 100%; width: min(500px, 100vw);
  background: var(--card); border-left: 1px solid var(--line);
  box-shadow: -8px 0 28px rgba(29, 36, 51, .12);
  transform: translateX(100%); transition: transform .18s ease-out; overflow-y: auto;
  scroll-behavior: smooth; padding: 1.1rem; z-index: 20; }
.rail.open { transform: none; }
.login-box { max-width: 360px; margin: 12vh auto; }
.login-box input { width: 100%; margin-bottom: .75rem; }
.login-box button { width: 100%; }
tr.overdue td { background: var(--danger-soft); }
@media (max-width: 640px) { th.opt, td.opt { display: none; } main { padding: .5rem; } }
.opbanner { display: flex; gap: .55rem; align-items: stretch; padding: .55rem 1.1rem;
  background: var(--card); border-bottom: 1px solid var(--line); overflow-x: auto; }
.opbanner:empty { display: none; }
.stat { flex: 1 1 0; min-width: 132px; border: 1px solid var(--line); border-radius: 10px;
  padding: .4rem .7rem .45rem; text-decoration: none; color: inherit; transition: border-color .12s; }
.stat:hover { border-color: var(--brand); }
.stat .k { font-size: .68rem; text-transform: uppercase; letter-spacing: .06em; color: var(--muted); }
.stat .v { font-size: 1.3rem; font-weight: 700; line-height: 1.2; }
.stat .v .u { font-size: .72rem; font-weight: 500; color: var(--muted); text-transform: none; }
.stat .s { font-size: .74rem; color: var(--muted); }
.stat.has-pending .v { color: var(--brand); }
/* lighter -> darker tints of the house blue, left to right */
.opbanner .stat:nth-child(1) { background: #f5f8fe; }
.opbanner .stat:nth-child(2) { background: #eff4fd; }
.opbanner .stat:nth-child(3) { background: #e9f0fb; }
.opbanner .stat:nth-child(4) { background: #e3ecfa; }
.opbanner .stat:nth-child(5) { background: #dce7f8; }
@media (max-width: 640px) { .stat { min-width: 118px; } }

/* Ready-message board: sticky notes in columns by category */
.kanban { display: flex; gap: 1rem; overflow-x: auto; padding-bottom: .5rem; }
.kanban .col { flex: 0 0 300px; }
.kanban h4 { color: var(--muted); font-size: .8rem; text-transform: uppercase;
  letter-spacing: .05em; margin: .3rem 0 .5rem; }
.sticky { background: var(--card); border: 1px solid var(--line); border-left: 3px solid var(--brand);
  border-radius: 8px; padding: .6rem .7rem; margin-bottom: .6rem; cursor: pointer;
  box-shadow: 0 1px 2px rgba(29,36,51,.05); transition: box-shadow .12s, border-color .12s; }
.sticky:hover { box-shadow: 0 2px 10px rgba(29,36,51,.10); border-left-color: var(--ink); }
.sticky .preview { display: -webkit-box; -webkit-line-clamp: 4; -webkit-box-orient: vertical;
  overflow: hidden; margin-top: .3rem; white-space: pre-wrap; }

/* request progress: derived, read-only steps */
.steps { display: flex; gap: .35rem; flex-wrap: wrap; margin: .4rem 0 .6rem; }
.step { font-size: .78rem; padding: .15rem .6rem; border-radius: 999px;
  background: var(--bg); color: var(--muted); border: 1px solid var(--line); }
.step.past { background: #e8f4ec; color: var(--ok); border-color: #cfe7d8; }
.step.now { background: var(--brand-soft); color: var(--brand); border-color: #c7d8f6; font-weight: 600; }

/* rupee fields: the spinner steps by 1, which is useless for fares */
input[type=number]::-webkit-inner-spin-button,
input[type=number]::-webkit-outer-spin-button { -webkit-appearance: none; margin: 0; }
input[type=number] { -moz-appearance: textfield; appearance: textfield; }
/* quotation prices line up in columns */
.pricegrid { display: grid;
  grid-template-columns: minmax(4.5rem, 1fr) minmax(5rem, 1.3fr) minmax(5rem, 1.3fr) minmax(3.5rem, .9fr) 2rem;
  gap: .4rem .5rem; align-items: center; margin-bottom: .6rem; }
.pricegrid button { padding: .2rem .45rem; }
.pricegrid input { width: 100%; }
.pricegrid label { font-weight: 500; }

/* type-ahead dropdown */
.ta-wrap { position: relative; display: inline-block; }
.ta-list { position: absolute; top: calc(100% + 2px); left: 0; min-width: 15rem; z-index: 40;
  background: var(--card); border: 1px solid var(--line); border-radius: 8px;
  box-shadow: 0 6px 18px rgba(29,36,51,.14); max-height: 16rem; overflow-y: auto; }
/* passenger create/edit stands apart from the surrounding booking fields */
.pax-form { border: 1px solid var(--line); border-radius: 10px; padding: .55rem .8rem;
  margin: .5rem 0; background: #f8fafc; }

input.bad { border-color: var(--danger); }
input.bad:focus { outline-color: var(--danger); }

.ta-item { padding: .4rem .6rem; cursor: pointer; }
.ta-item:hover, .ta-item.active { background: #f2f6fd; }
.ta-item.add { color: var(--brand); font-weight: 500; border-top: 1px solid var(--line); }
.ta-form { padding: .5rem .6rem; }

/* airport field: caption floats under the code so the field itself stays input-height —
   arrows and neighbours line up with the input, not with input+caption */
.apf { display: inline-flex; flex-direction: column; vertical-align: top; position: relative; }
.ap-cap { font-size: .7rem; line-height: 1.2; max-width: 108%;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; padding-left: .15rem;
  position: absolute; top: 100%; left: 0; }  /* clamped to the field so neighbours never collide */

/* quote-form journey: airport / date / time columns stay aligned across rows */
.jgrid { display: grid;
  grid-template-columns: minmax(7rem, 1.2fr) minmax(6.5rem, 1fr) minmax(4.5rem, .8fr) minmax(5rem, 1fr);
  gap: .6rem .6rem; align-items: start; margin: .3rem 0 .6rem; }
.jgrid input { width: 100%; box-sizing: border-box; }
.jgrid input[type=checkbox] { width: auto; }
.jgrid .apf { width: 100%; }
.jgrid .apf input { width: 100% !important; }  /* the field's inline 8.5rem must yield to the column */
/* no arrow to align in the grid — the caption flows in place so rows clear it */
.jgrid .ap-cap { position: static; }

.journey { border-left: 3px solid var(--brand-soft); padding: .25rem 0 .25rem .6rem; margin: .4rem 0 .6rem; }
.journey .leg { padding: .1rem 0; }

/* A printed invoice is the one artefact that leaves the building and reaches a customer,
   so strip the app chrome: nav, filters, the fixed totals strip and the rail. */
@media print {
  header, nav, #rail, #totals, .row, .dimchips, .modal-overlay { display: none !important; }
  main { max-width: none; margin: 0; padding: 0; }
  body { background: #fff; }
  .card { border: none; box-shadow: none; padding: 0; }
  table { page-break-inside: auto; }
  tr { page-break-inside: avoid; }
  @page { margin: 15mm; }
}

/* Rows that navigate must be reachable and visible to the keyboard, not just the mouse. */
tr.click { cursor: pointer; }
tr.click:focus-visible { outline: 2px solid var(--brand); outline-offset: -2px; }
th.srt:focus-visible { outline: 2px solid var(--brand); outline-offset: -2px; }
.visually-hidden { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }

/* Shared confirm/prompt replacement — native dialogs are unstyled and block the page. */
.modal-overlay { position: fixed; inset: 0; background: rgba(29, 36, 51, .35); z-index: 80;
  display: flex; align-items: center; justify-content: center; padding: 1rem; }
.modal-overlay .card { min-width: min(24rem, 100%); max-width: 32rem; max-height: 90vh;
  overflow-y: auto; background: var(--card); }
.modal-overlay h4 { margin-top: 0; }
