/* guest.css — the diner's booking page.
 *
 * Deliberately its own stylesheet, sharing nothing with the restaurant's
 * screens: this one is loaded by strangers on phones outside a restaurant, and
 * it must not inherit a change made for a manager on a tablet.
 *
 * Mobile first, and mobile ONLY in the sense that matters — a thumb, one hand,
 * daylight on a screen. Nothing here is below 44px if it can be tapped.
 *
 * SHARING NOTHING IS ABOUT RULES, NOT ABOUT COLOUR. This file still declares
 * every one of its own classes and inherits none of the staff screens' — that
 * is the isolation the header above is about, and it is unchanged. What it no
 * longer does is keep a private palette: the nine NetronEats colours are locked,
 * and a diner looking at the booking page is looking at the same brand as the
 * owner looking at the dashboard. This is also the surface where a venue's own
 * colour will one day land — the design system allows that on the ACTION role
 * and on diner-facing pages only — which is exactly `--brand` below.
 */
@import url("/reserve/static/netron-tokens.css");

:root {
  --ink: var(--nt-ink);
  --muted: var(--nt-ink-2);
  --line: var(--nt-line);
  --bg: var(--nt-bg);
  --card: var(--nt-surface);
  /* The one a venue may replace. Was #14181f, a near-black that read as "no
     brand chosen yet"; a booking page's single call to action is the action
     colour. */
  --brand: var(--nt-action);
  --on-brand: #FFFFFF;
  --bad: var(--nt-failed-text);
  --ok: var(--nt-paid-text);
  /* A closed day and a taken hour. Mixed into the surface rather than into
     `transparent`, so they follow the theme instead of taking their contrast
     from whatever happens to be behind them. */
  --shut-bg: color-mix(in srgb, var(--nt-failed) 8%, var(--nt-surface));
  --shut-line: color-mix(in srgb, var(--nt-failed) 32%, var(--nt-surface));
  --raised: var(--nt-raised);

  /* TWO MEASUREMENTS THE STYLESHEET CANNOT TAKE, declared here with the answer
     for a page that never needs them and overwritten by `guest.js` when it
     does. Neither is a colour and neither belongs to the design system; they
     are here so the guard in `design-tokens.test.mjs` can still prove every
     variable this page uses resolves. */

  /* The on-screen keyboard's height. iOS does not shrink the layout viewport
     for a keyboard, so a banner at `bottom: 0` renders behind it. */
  --kb: 0px;
  /* How much room the docked banner needs. Measured, because core can relay a
     longer sentence than any of ours and a large system font makes every one
     of them taller. This is the value for the frame before it is measured. */
  --dock-h: 9rem;
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font: 16px/1.5 -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Arial, sans-serif;
  /* 16px minimum on inputs or iOS zooms the whole page on focus — which on a
     one-hand form reads as the page breaking. */
  -webkit-text-size-adjust: 100%;
}

.wrap {
  max-width: 34rem;
  margin: 0 auto;
  padding: 1rem 1rem calc(2rem + env(safe-area-inset-bottom));
}

/* ROOM FOR THE DOCKED BANNER, and only when there is one. The banner is fixed
   to the bottom of the screen, so without this it sits on top of whatever the
   step's own button is — and being out of flow, the page cannot then be
   scrolled past it to reach one.
   `--dock-h` is declared at the top of this file and overwritten by
   `guest.js` from the banner it actually drew. */
.wrap.has-banner {
  padding-bottom: calc(var(--dock-h) + env(safe-area-inset-bottom));
}

.card {
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: 14px;
  padding: 1.25rem;
}

h1 { font-size: 1.4rem; margin: 0 0 .15rem; }
h2 { font-size: 1.1rem; margin: 1.25rem 0 .5rem; }
.muted { color: var(--muted); font-size: .92rem; margin: .35rem 0; }

/* ── the app chrome: a way out at the top left, a banner at the bottom ──────
   NET-348, Nihat 2026-08-11: "it must feel like an app". The steps did not
   move; the frame around them did. */

/* A NAV ROW OF ITS OWN, above the title — not beside it. Beside it, the title
   started 48px further right on every step that has a way back and at the card
   edge on the ones that do not, so the restaurant's name jumped sideways as a
   diner moved through the booking. A phone app's back control sits on its own
   line and the content below it never moves. */
.top { margin-bottom: .25rem; }

.back {
  display: inline-flex;
  align-items: center;
  gap: .1rem;
  /* 44px of tappable height, pulled left so the WORD lines up with the card's
     padding rather than the button's box — an inset back button reads as
     floating in the middle of nowhere. */
  min-height: 44px;
  padding: 0 .4rem 0 .1rem;
  margin: -.55rem 0 .1rem -.3rem;
  background: none;
  border: 0;
  border-radius: 10px;
  color: var(--ink);
  font: inherit;
  font-size: .95rem;
  cursor: pointer;
}
.back:focus-visible { outline: 2px solid var(--brand); outline-offset: 1px; }
.back-chev { font-size: 1.5rem; line-height: 1; margin-top: -.15rem; }

.note {
  background: var(--raised);
  border: 1px solid var(--line);
  border-radius: 10px;
  padding: .7rem .85rem;
  margin: .85rem 0;
  font-size: .95rem;
}
.note.bad { background: var(--shut-bg); border-color: var(--shut-line); color: var(--bad); }

/* THE BANNER, AT THE BOTTOM OF THE SCREEN. Above the content rather than
   inside it: nothing on the page moves when a message appears or goes, which
   is the whole complaint — a banner between the title and the form shoved the
   form down the moment anything went wrong. */
.dock {
  position: fixed;
  left: 0;
  right: 0;
  /* Lifted clear of the on-screen keyboard — see `--kb` at the top of this
     file. 0 on every desktop browser and wherever `visualViewport` is
     missing, which is the same thing as `bottom: 0`. */
  bottom: var(--kb);
  z-index: 20;
  background: var(--bg);
  border-top: 1px solid var(--line);
  padding: .6rem 1rem calc(.6rem + env(safe-area-inset-bottom));
}
.dock .note { max-width: 34rem; margin: 0 auto; }

/* WHO IS BOOKING. Quiet on purpose — it answers a question rather than asking
   one, so it sits at the raised surface with no border shouting for attention.
   It is the first thing above the form because a diner who sees their own name
   already knows they will not be asked for a code. */
.who {
  display: flex;
  align-items: center;
  gap: .75rem;
  background: var(--raised);
  border-radius: 10px;
  padding: .6rem .85rem;
  margin: .85rem 0 .25rem;
}
.who-name { font-weight: 600; font-size: .95rem; }
.who-num { color: var(--muted); font-size: .88rem; margin-top: .1rem; }

.field { display: block; margin: 1rem 0; }
.lab {
  display: block;
  font-size: .82rem;
  letter-spacing: .02em;
  text-transform: uppercase;
  color: var(--muted);
  margin-bottom: .35rem;
}

.in {
  width: 100%;
  min-height: 48px;
  padding: .6rem .75rem;
  font-size: 1rem;
  color: var(--ink);
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: 10px;
}
.in:focus-visible { outline: 2px solid var(--brand); outline-offset: 1px; }

.row { display: flex; gap: .5rem; }
.cc { width: 5.5rem; flex: 0 0 auto; }

/* The calendar. BIG — a diner picks the day with a thumb, and a day the venue
   never opens has to be legible as unavailable at arm's length, not merely
   un-tappable. An un-tappable day with no explanation reads as a broken page. */
/* FULL WIDTH, and square cells, so the month is the thing on the page a thumb
   reaches for. */
.cal { margin: .4rem 0 1.25rem; width: 100%; }
.cal-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: .5rem;
}
.cal-month { font-weight: 600; }
.cal-nav {
  min-width: 44px;
  min-height: 44px;
  font-size: 1.3rem;
  background: none;
  border: 1px solid var(--line);
  border-radius: 10px;
  color: var(--ink);
  cursor: pointer;
}
.cal-dow {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: 4px;
  margin-bottom: 4px;
}
.cal-dow div {
  text-align: center;
  font-size: .72rem;
  color: var(--muted);
  text-transform: uppercase;
  letter-spacing: .03em;
}
.cal-grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 4px; }
.cal-pad { aspect-ratio: 1 / 1; }
.cal-day {
  aspect-ratio: 1 / 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 1px;
  padding: 2px;
  background: var(--card);
  color: var(--ink);
  border: 1px solid var(--line);
  border-radius: 10px;
  cursor: pointer;
  overflow: hidden;
}
.cal-n { font-size: clamp(.85rem, 3.4vw, 1.05rem); font-weight: 600; line-height: 1.1; }
/* The WORD, small but present — and it must FIT. Uppercase with letter-spacing
   clipped it to "UNAVAILABL" on a 1080px phone, which reads as a rendering
   fault rather than a label. Sentence case, tight tracking, and it shrinks with
   the cell so it survives a narrower screen too. */
.cal-x {
  font-size: clamp(6px, 1.7vw, 9px);
  line-height: 1.05;
  width: 100%;
  text-align: center;
  color: var(--muted);
  letter-spacing: -.02em;
  white-space: nowrap;
}
.cal-day.on { background: var(--brand); border-color: var(--brand); color: var(--on-brand); }
.cal-day.on .cal-x { color: var(--on-brand); }
/* UNAVAILABLE IS RED (Nihat's wireframe). Not grey — grey reads as "disabled
   for now", red reads as "not happening", and the word underneath removes the
   last doubt. */
.cal-day.shut {
  background: var(--shut-bg);
  color: var(--bad);
  border-color: var(--shut-line);
  cursor: not-allowed;
}
.cal-day.shut .cal-x { color: var(--bad); }
.cal-day.past { opacity: .3; cursor: not-allowed; }

/* The times. A grid of real buttons, because a <select> of forty times is a
   scrolling wheel on a phone and nobody can see what else was available. */
.slots {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(5.2rem, 1fr));
  gap: .5rem;
  margin: .5rem 0 1rem;
}
.slot {
  min-height: 48px;
  padding: .55rem .3rem;
  font-size: .95rem;
  background: var(--card);
  color: var(--ink);
  border: 1px solid var(--line);
  border-radius: 10px;
  cursor: pointer;
}
.slot.on {
  background: var(--brand);
  border-color: var(--brand);
  color: var(--on-brand);
  font-weight: 600;
}
/* A TAKEN HOUR IS SHOWN, in red, struck through — never removed. Missing tells
   a diner nothing; struck through tells them to try the next one. */
.slot.gone {
  background: var(--shut-bg);
  border-color: var(--shut-line);
  color: var(--bad);
  text-decoration: line-through;
  cursor: not-allowed;
}

.chosen-day {
  margin: 1.25rem 0 .5rem;
  font-size: 1.05rem;
}

.note-in {
  min-height: 92px;
  resize: vertical;
  font: inherit;
}

.go {
  display: block;
  width: 100%;
  min-height: 52px;
  margin-top: 1.25rem;
  font-size: 1.02rem;
  font-weight: 600;
  color: var(--on-brand);
  background: var(--brand);
  border: 0;
  border-radius: 12px;
  cursor: pointer;
}
.go[disabled] { opacity: .45; cursor: default; }

.link {
  display: block;
  width: 100%;
  min-height: 44px;
  margin-top: .5rem;
  background: none;
  border: 0;
  color: var(--muted);
  font-size: .95rem;
  text-decoration: underline;
  cursor: pointer;
}

.review { margin: .5rem 0 0; }
.review dt {
  font-size: .82rem;
  text-transform: uppercase;
  letter-spacing: .02em;
  color: var(--muted);
  margin-top: .7rem;
}
.review dd { margin: .1rem 0 0; }

.booking-reference {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  margin: 1rem 0;
  padding: .8rem 1rem;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--raised);
}
.booking-reference span { color: var(--muted); }
.booking-reference strong { letter-spacing: .04em; white-space: nowrap; }

/* The hand-written dark theme that used to live here is GONE, not moved. It was
   eleven overrides and eight hexes of its own — a second palette that had to be
   kept in step with the first by remembering to. Every variable above is a token
   now, and the tokens ship both themes, so dark is whatever the design system
   says dark is. Nothing on this page needs to know which one is on. */

/* Same reason as the staff stylesheet: where `color-mix` is unsupported the
   property resolves to `unset`, not to a previous value, so a closed day would
   lose its red ground entirely. It drops to the locked colour instead — louder
   than the tint, and a diner still cannot tap a day that is shut. */
@supports not (color: color-mix(in srgb, red 50%, blue)) {
  :root {
    --shut-bg: var(--nt-surface);
    --shut-line: var(--nt-failed);
  }
}

/* Day and month side by side — two short boxes read as one question, where a
   stacked pair reads as two. */
.bday-pair { display: flex; gap: .5rem; }
.bday-pair .in { width: 100%; }
