/* ============================================================================
   Public booking page.

   The opposite context from the gate terminal, and so the opposite design.
   This is a stranger on a phone in daylight, deciding whether to hand over
   ₱48,500 to a yard they may never have dealt with. It has to read as
   legitimate before it reads as anything else — which means light, plain,
   unhurried, and completely free of the dark-console aesthetic that would make
   a customer wonder what they had wandered into.

   NOTE ON SCOPE. Management's roadmap defers the customer-facing look and feel
   until after the stress tests ("then design the customer-facing UI's look and
   feel"). This is therefore built to be correct, legible and trustworthy, and
   deliberately not to be distinctive. The visual design pass is still owed.

   Three things it must never do, all from the security posture:
     · show any yard data beyond open / limited / full
     · take a price from the client
     · touch a card or wallet credential — checkout is hosted, elsewhere
   ========================================================================= */

/* THE PALETTE IS THE HOUSE PALETTE. This page carried its own greens and its
   own dark mode, from before there was a house set — so the one page a
   customer ever sees was the one page that did not look like the company.
   theme.css carries the colours and the dark mode now, and the six names it
   does not have are mapped onto the ones it does.

   The three yard states keep their own names on purpose. open / limited / full
   is the only yard information this page is allowed to show, and reading them
   as good / warning / bad is exactly right. */
:root {
  --paper:      var(--ground);
  --wash:       var(--accent-wash);
  --focus:      var(--accent);
  --open:       var(--success);
  --limited:    var(--warning);
  --limited-bg: var(--warning-soft);
  --full:       var(--critical);
  --full-bg:    var(--critical-soft);
}

* { box-sizing: border-box; }

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  /* The face is theme.css's. The size is this page's own and stays: a stranger
     reading this on a phone in daylight is not reading a console. */
  font-size: 16px;
  line-height: 1.6;
  padding: 0 20px 64px;
}

.wrap { max-width: 560px; margin: 0 auto; }

header { padding: 34px 0 22px; }
/* The mark and the name read as one thing, side by side. A logo alone asks
   a stranger to already know the company; the name alone wastes the mark. */
header .brand {
  display: flex; align-items: center; gap: 14px; margin-bottom: 16px;
}
header .mark { display: block; height: 72px; width: auto; flex: 0 0 auto; }

/* The company's name, in full and above the page's own title. On the one page
   a stranger sees before paying, the name of the company matters more than
   the name of the task. */
header .org {
  font-family: "Big Shoulders Display", "Arial Narrow", sans-serif;
  font-size: 25px; font-weight: 700; letter-spacing: .04em; line-height: 1.04;
  text-transform: uppercase; color: var(--accent);
}
/* On a phone the two words of the name do not fit beside a 72px mark, and a
   shrunken mark beside shrunken type is worse than stacking them. */
@media (max-width: 460px) {
  header .brand { gap: 11px; }
  header .mark { height: 56px; }
  header .org { font-size: 20px; }
}

/* --- the advisory ------------------------------------------------------
   Three weights, matching the yard's own vocabulary. The left bar does the
   work rather than a wash of colour across the whole block: this sits above
   a form somebody is about to type a container number into, and it should
   be impossible to miss without being the loudest thing on the page. */
.advisory {
  border-left: 4px solid var(--accent);
  background: var(--wash);
  color: var(--ink);
  border-radius: 0 10px 10px 0;
  padding: 13px 16px;
  margin-bottom: 16px;
  white-space: pre-line;
}
.advisory.warn { border-left-color: var(--limited); background: var(--limited-bg); }
.advisory.stop { border-left-color: var(--full);    background: var(--full-bg); }

/* --- the standing cards at the foot ------------------------------------ */
.standing { margin-top: 16px; }
.standing h2 {
  margin: 0 0 10px; font-size: 12px; font-weight: 700;
  letter-spacing: .1em; text-transform: uppercase; color: var(--muted);
}
.addr { margin: 0 0 8px; }
.contact { margin-top: 10px; white-space: pre-line; color: var(--ink); }
.maplink { font-weight: 600; }

.lookup label {
  display: block; margin-bottom: 6px;
  font-size: 13px; font-weight: 600; color: var(--muted);
}
.lookup-row { display: flex; gap: 8px; flex-wrap: wrap; }
.lookup-row input {
  flex: 1; min-width: 180px;
  font: inherit; padding: 11px 12px;
  border: 1px solid var(--line); border-radius: 9px;
  background: var(--paper); color: var(--ink);
}
/* Not full width. `.go` is the page's primary button and stretches, which is
   right for "Pay now" and wrong here: checking an old booking is the smallest
   thing on this page and should not look like the largest. */
.lookup-row .go { width: auto; flex: 0 0 auto; }

.lookup .hint { margin: 7px 0 0; font-size: 13px; color: var(--muted); }
.lookup .hint.bad { color: var(--full); }
.eir { margin: 16px 0 0; padding-top: 14px; border-top: 1px solid var(--line);
       font-size: 14px; color: var(--muted); }
.eir a { font-weight: 600; }
header h1 { margin: 12px 0 6px; }  /* size, weight and case: theme.css */
header p  { margin: 0; color: var(--muted); }

.step {
  background: var(--card); border: 1px solid var(--line);
  border-radius: 12px; padding: 22px; margin-bottom: 16px;
}
.step[hidden] { display: none; }
.step h2 {
  margin: 0 0 4px; font-size: 12px; font-weight: 700;
  letter-spacing: .1em; text-transform: uppercase; color: var(--muted);
}
.step .lede { margin: 0 0 16px; color: var(--muted); font-size: 14.5px; }

label { display: block; font-size: 14px; font-weight: 600; margin: 14px 0 6px; }
label:first-of-type { margin-top: 0; }

input, select {
  width: 100%; min-height: 48px;
  border: 1px solid var(--line); border-radius: 9px;
  padding: 0 13px; font: inherit; font-size: 16px;   /* 16px stops iOS zooming */
  background: var(--card); color: var(--ink);
}
input:focus, select:focus { outline: 2px solid var(--focus); outline-offset: 1px; border-color: var(--focus); }
.pair { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }

/* ---- windows: three words, never a number -------------------------------- */

.windows { display: flex; flex-direction: column; gap: 9px; }
.win {
  display: flex; align-items: center; gap: 12px;
  border: 1px solid var(--line); border-radius: 10px;
  padding: 13px 15px; background: var(--card);
  cursor: pointer; text-align: left; width: 100%; font: inherit; color: inherit;
}
.win:hover:not([disabled]) { border-color: var(--accent); }
.win[aria-pressed="true"] { border-color: var(--accent); border-width: 2px; background: var(--wash); }
.win[disabled] { cursor: not-allowed; opacity: .55; }
.win .time { font-weight: 600; }
.win .tag {
  margin-left: auto; font-size: 12px; font-weight: 700;
  letter-spacing: .04em; text-transform: uppercase;
  padding: 3px 9px; border-radius: 20px;
}
.tag.open    { color: var(--open); background: var(--wash); }
.tag.limited { color: var(--limited); background: var(--limited-bg); }
.tag.full    { color: var(--full); background: var(--full-bg); }

/* ---- the total, the one figure on the page ------------------------------- */

.total {
  display: flex; align-items: baseline; gap: 10px;
  border-top: 1px solid var(--line); margin-top: 18px; padding-top: 16px;
}
.total .label { color: var(--muted); font-size: 14px; }
.total .amount {
  margin-left: auto; font: 700 26px/1 "IBM Plex Mono", monospace;
  font-variant-numeric: tabular-nums;
}
.total .each { font-size: 13px; color: var(--muted); }

button.go {
  width: 100%; min-height: 54px; margin-top: 18px;
  background: var(--accent); color: var(--accent-ink);
  border: none; border-radius: 9px;
  font: 600 17px/1 inherit; cursor: pointer;
}
button.go:hover { filter: brightness(1.08); }
button.go:focus-visible { outline: 3px solid var(--focus); outline-offset: 2px; }
button.go[disabled] { opacity: .45; cursor: default; }
button.link {
  background: none; border: none; color: var(--accent);
  font: inherit; font-size: 14.5px; cursor: pointer; padding: 10px 0 0; text-decoration: underline;
}

.otp { letter-spacing: .5em; font: 600 24px/1 "IBM Plex Mono", monospace; text-align: center; }

.msg { border-radius: 9px; padding: 12px 14px; font-size: 14.5px; margin-top: 14px; }
.msg.bad  { background: var(--full-bg); color: var(--full); }
.msg.warn { background: var(--limited-bg); color: var(--limited); }
.msg[hidden] { display: none; }

.note { color: var(--muted); font-size: 13.5px; margin: 14px 0 0; }
.note strong { color: var(--ink); }

.qr {
  text-align: center; padding: 26px 18px;
  border: 2px solid var(--accent); border-radius: 12px; background: var(--wash);
}
.qr .ref { font: 600 14px/1.5 "IBM Plex Mono", monospace; word-break: break-all; color: var(--muted); }
.qr h3 { margin: 0 0 6px; font-size: 21px; }

footer { color: var(--muted); font-size: 13px; text-align: center; padding-top: 26px; }

/* ===========================================================================
   s1_097 — one page for both transactions.

   The page grew a first question (deposit or withdrawal), a class, three
   payment methods, and a confirmation that has to say what was bought. All of
   them are the same shape: a small set of mutually exclusive choices, big
   enough to press with a thumb at a gate.
   =========================================================================== */

.choices { display: grid; gap: 10px; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); }
.choices.tight { grid-template-columns: repeat(auto-fit, minmax(120px, 1fr)); }

.choice {
  display: flex; flex-direction: column; gap: 3px; text-align: left;
  padding: 14px 16px; border: 1.5px solid var(--line); border-radius: 10px;
  background: var(--card); color: inherit; font: inherit; cursor: pointer;
}
.choice:hover { border-color: var(--muted); }
.choice:focus-visible { outline: 3px solid var(--focus); outline-offset: 2px; }

/* Selected state carries a border AND a background, never colour alone —
   a choice distinguished only by hue is not distinguished for everyone. */
.choice.on { border-color: var(--accent); background: var(--wash); }
.choice.on .choice-title { color: var(--accent); }

.choice-title { font-weight: 700; font-size: 16px; }
.choice-sub { font-size: 13px; color: var(--muted); line-height: 1.35; }

label.spaced { margin-top: 18px; }
.opt { font-weight: 400; color: var(--muted); }

/* The window buttons gained a selected state for the same reason. */
.win.on { border-color: var(--accent); background: var(--wash); }

label.agree {
  display: flex; gap: 10px; align-items: flex-start; margin: 18px 0 0;
  font-weight: 400; font-size: 14px; line-height: 1.45;
}
label.agree input { width: auto; margin: 2px 0 0; flex: none; }

/* What is being bought, restated where it matters: before paying, and after.
   A confirmation that only says "paid" leaves the reader to remember what
   they paid for. */
.recap { border: 1px solid var(--line); border-radius: 10px; overflow: hidden; margin: 4px 0 0; }
.recap dl { display: grid; grid-template-columns: auto 1fr; margin: 0; }
.recap dt, .recap dd {
  margin: 0; padding: 9px 14px; font-size: 14px;
  border-bottom: 1px solid var(--line);
}
.recap dt { color: var(--muted); }
.recap dd { text-align: right; font-weight: 600; }
.recap dl > dt:nth-last-of-type(1), .recap dl > dd:nth-last-of-type(1) { border-bottom: 0; }

.total.tight-top { border-top: none; margin-top: 14px; padding-top: 0; }
.done-sub { margin: 0 0 14px; color: var(--muted); }

/* Waiting for a bank deposit is not success and must not look like it. */
.qr.pending { border-style: dashed; }

/* ===========================================================================
   s1_098 — the calendar.

   It replaces a date box and the sentence "Choose a date to see what is open",
   which asked the customer to guess and then told them they had guessed wrong.

   Status is carried by a dot AND by the cell's own state, never by colour
   alone: roughly one man in twelve cannot separate the red from the green, and
   "which days can I come" is not a question to answer only in hue. A full day
   is also disabled, and a closed day is also blank.
   =========================================================================== */

.cal { border: 1px solid var(--line); border-radius: 12px; padding: 12px; background: var(--card); }

.cal-head { display: flex; align-items: center; gap: 6px; margin-bottom: 8px; }
.cal-month { flex: 1; text-align: center; font-weight: 700; font-size: 15px; }
.cal-nav {
  width: 34px; height: 34px; border: 1px solid var(--line); border-radius: 8px;
  background: var(--paper); color: inherit; font-size: 18px; line-height: 1; cursor: pointer;
}
.cal-nav:hover:not([disabled]) { border-color: var(--muted); }
.cal-nav[disabled] { opacity: .35; cursor: default; }
.cal-nav:focus-visible { outline: 3px solid var(--focus); outline-offset: 2px; }

.cal-dow, .cal-grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 4px; }
.cal-dow { margin-bottom: 4px; }
.cal-dow span { text-align: center; font-size: 11px; font-weight: 600; color: var(--muted); }

.cal-day {
  position: relative; aspect-ratio: 1 / 1; min-height: 40px;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 3px;
  border: 1.5px solid transparent; border-radius: 8px;
  background: var(--paper); color: inherit; font: inherit; font-size: 14px; cursor: pointer;
}
.cal-day:hover:not([disabled]) { border-color: var(--muted); }
.cal-day:focus-visible { outline: 3px solid var(--focus); outline-offset: 1px; }
.cal-day[disabled] { cursor: default; color: var(--muted); opacity: .5; }
.cal-day.blank { visibility: hidden; }
.cal-day.on { border-color: var(--accent); background: var(--wash); font-weight: 700; }

/* The dot repeats what the cell's state already says. */
.cal-dot { width: 6px; height: 6px; border-radius: 50%; background: transparent; }
.cal-day.open    .cal-dot { background: var(--open); }
.cal-day.limited .cal-dot { background: var(--limited); }
.cal-day.full    .cal-dot { background: var(--full); }
.cal-day.limited { background: var(--limited-bg); }
.cal-day.full    { background: var(--full-bg); }
/* A closed day is not a day that sold out. It gets no dot and no colour. */
.cal-day.closed  { background: transparent; }

.cal-key { display: flex; flex-wrap: wrap; gap: 10px 14px; margin-top: 10px;
           font-size: 12px; color: var(--muted); }
.cal-key span { display: inline-flex; align-items: center; gap: 5px; }
.cal-key .k { width: 8px; height: 8px; border-radius: 50%; display: inline-block; }
.cal-key .k.open { background: var(--open); }
.cal-key .k.limited { background: var(--limited); }
.cal-key .k.full { background: var(--full); }
.cal-key .k.closed { background: transparent; border: 1.5px solid var(--line); }

/* The four legal loads sit on one row, or two rows of two when there is not
   room. Three-and-one reads as a group of three with an afterthought. */
#loads { grid-template-columns: repeat(4, 1fr); }
@media (max-width: 520px) { #loads { grid-template-columns: repeat(2, 1fr); } }

/* .amount is a large monospace figure, which is right for ₱27,000.00 and
   wrong for a sentence explaining that there is no figure yet. */
.total .amount.pending {
  font: 400 14px/1.4 "Source Sans 3", system-ui, sans-serif;
  color: var(--muted); text-align: right; max-width: 15em;
}

/* The container-number check speaks in words as well as colour — a tick that
   is only green says nothing to a reader who cannot see green. */
.checks { margin: 8px 0 0; }
.check { margin: 0 0 6px; font-size: 13px; line-height: 1.45; padding-left: 18px; position: relative; }
.check::before { position: absolute; left: 0; top: 0; font-weight: 700; }
.check.ok    { color: var(--muted); }
.check.ok::before   { content: "\2713"; color: var(--open); }
.check.warn  { color: var(--ink); }
.check.warn::before { content: "!"; color: var(--limited); }
.check.bad   { color: var(--ink); }
.check.bad::before  { content: "\00d7"; color: var(--full); }

/* What a disabled Continue is still waiting for. Sits above the button so it
   is read before the button is reached for, not after it fails to respond. */
.missing {
  margin: 16px 0 -6px; padding: 10px 12px;
  border-left: 3px solid var(--limited);
  background: var(--limited-bg);
  font-size: 13px; line-height: 1.5;
}

/* Paying by QR or bank deposit — the money leaves by a route this site cannot
   see, so the page's whole job is to say where to send it and to take the
   reference back. */
.pay-panel { margin-top: 16px; }

.qr-holder {
  display: flex; align-items: center; justify-content: center;
  min-height: 200px; padding: 14px;
  border: 1.5px dashed var(--line); border-radius: 12px; background: var(--paper);
}
.qr-holder img { display: block; width: 100%; max-width: 260px; height: auto; }

.pay-to { display: grid; grid-template-columns: auto 1fr; gap: 4px 14px; margin: 14px 0 0; }
.pay-to dt { color: var(--muted); font-size: 13px; }
.pay-to dd { margin: 0; font-weight: 600; font-size: 14px; text-align: right; }

/* F277 — the pass as a QR, drawn in the browser by qr.js.
   White ground and a quiet margin regardless of the page's own colours: a
   scanner reads contrast, and a code tinted to match a design is a code a
   phone cannot read in daylight. */
.pass-qr { display: flex; justify-content: center; margin: 6px 0 14px; }
.pass-qr svg { background: #fff; padding: 8px; border-radius: 10px; }

/* ---------------------------------------------------------------------------
   F281 — paper, for when a phone dies at the barrier.
   The yard runs on pre-printed EIR forms, so this is sized to travel WITH one:
   the pass, the QR, and ruled space for what the gate writes by hand when the
   screens cannot be reached.
   --------------------------------------------------------------------------- */
.done-acts { display: flex; gap: 18px; flex-wrap: wrap; align-items: center; }
.print-only { display: none; }

@media print {
  /* Everything that is not the pass. A printed booking page with a calendar
     and a payment panel on it wastes a sheet and buries the thing that matters. */
  /* The header is inside .wrap, not a child of body — hiding the wrong one
     costs the top third of the sheet and nobody notices until it is printed. */
  header, footer, .steps, .step, .done-acts, .note, #doneSub,
  #doneCarry, #doneNote { display: none !important; }
  .wrap { max-width: none; padding: 0; margin: 0; }

  /* ...except the pass itself. */
  #step-done, #step-done .qr, #step-done .recap { display: block !important; }
  #step-done { padding: 0; margin: 0; border: 0; box-shadow: none; }

  @page { size: A4; margin: 14mm; }
  html, body {
    background: #fff; color: #000;
    font: 11pt/1.45 "Source Sans 3", system-ui, sans-serif;
  }

  /* White, whatever the screen does: a tinted ground costs ink and gives a
     scanner less contrast to work with. */
  .qr { background: #fff !important; border: 1px solid #000; border-radius: 0;
        padding: 8mm; text-align: center; }
  #doneTitle { font-size: 15pt; margin: 0 0 4mm; }
  .pass-qr svg { width: 46mm; height: 46mm; padding: 0; }
  .ref { font-family: "IBM Plex Mono", monospace; font-size: 12pt; letter-spacing: .06em; }

  .recap { margin-top: 6mm; }
  .recap dt { color: #000; }

  .print-only { display: block !important; margin-top: 6mm; }
  .print-head { font-weight: 700; margin: 0 0 3mm; }
  .print-pairs { display: grid; grid-template-columns: auto 1fr; gap: 1mm 6mm; margin: 0 0 4mm; }
  .print-pairs dt { color: #444; }
  .print-pairs dd { margin: 0; font-weight: 600; }
  .print-note { font-size: 9.5pt; color: #333; margin: 0 0 4mm; }
  .print-lines { display: grid; grid-template-columns: 1fr 1fr; gap: 6mm 10mm; font-size: 10.5pt; }

  /* A pass is one sheet. */
  #step-done { page-break-inside: avoid; }
}
