/* =====================================================================
   booking-grid.css — the lane-by-time grid.

   One stylesheet, two pages: the customer's booking page and the admin's
   Bookings tab draw the same grid from the same markup, so a square can
   never mean one thing to a customer and another to the staff looking at
   it. Anything that differs between them is scoped to .grid-admin.
   ===================================================================== */

.gridwrap{overflow-x:auto;-webkit-overflow-scrolling:touch}

table.cal{border-collapse:separate;border-spacing:0;width:100%;
  table-layout:fixed;background:var(--panel)}
table.cal th,table.cal td{border-right:1px solid var(--line);
  border-bottom:1px solid var(--line);padding:0;height:46px;
  text-align:center;font-size:12px}
table.cal thead th{background:var(--panel-2);font-family:"DM Sans",sans-serif;
  font-weight:700;font-size:11px;letter-spacing:.06em;color:var(--muted);
  height:34px;width:54px;border-top:1px solid var(--line)}
table.cal tr td:first-child,table.cal tr th:first-child{border-left:1px solid var(--line)}

/* On a phone the day is wider than the screen, so the grid scrolls
   sideways. The lane names stay pinned to the left edge — otherwise you
   scroll to closing time and can no longer tell which row is which. */
table.cal thead th.lanehead{width:132px;text-align:left;padding-left:12px;
  letter-spacing:.1em;position:sticky;left:0;z-index:3}
td.lane-name{background:var(--ink);color:#f2efe8;font-family:"Bebas Neue",sans-serif;
  font-size:18px;letter-spacing:1px;padding:0 12px;text-align:left;
  position:sticky;left:0;z-index:2}
td.lane-name .lane-sub{display:block;font-family:"DM Sans",sans-serif;
  font-size:10px;letter-spacing:.08em;text-transform:uppercase;
  color:rgba(242,239,232,.6);line-height:1;margin-top:-2px}

/* A square you can have. */
td.cell{background:var(--panel);cursor:pointer;
  transition:background .08s,box-shadow .08s}
td.cell:hover{background:#eef3ef}
td.cell.sel{background:var(--red);box-shadow:inset 0 0 0 1px var(--red-deep)}

/* A square outside opening hours for that particular board. */
td.cell.shut{background:repeating-linear-gradient(135deg,
  var(--panel-2),var(--panel-2) 5px,#efeade 5px,#efeade 10px);cursor:default}
td.cell.shut:hover{background:repeating-linear-gradient(135deg,
  var(--panel-2),var(--panel-2) 5px,#efeade 5px,#efeade 10px)}

/* A square somebody has. */
td.blk{color:#fff;font-family:"DM Sans",sans-serif;font-weight:700;font-size:11px;
  letter-spacing:.06em;text-transform:uppercase;padding:0 6px;white-space:nowrap;
  overflow:hidden;text-overflow:ellipsis}
/* a half-hour booking has one narrow square to say its piece in */
td.blk[colspan="1"]{font-size:9px;letter-spacing:0;padding:0 2px}
/* Colour says one thing only: has the money arrived. Where the booking
   came from is in the label and on the record — it is not what staff are
   scanning the grid for. */
td.blk.b-paid{background:var(--green)}
td.blk.b-pending{background:var(--red)}
td.blk.b-walkin{background:#3a4147}   /* legacy class, no longer emitted */
/* The customer's grid paints every square somebody else has the same
   colour, whatever its status. Staff need to tell a paid booking from an
   unpaid one; a customer must not be able to tell a five-minute hold from
   a firm booking, or they would sit and wait for it to lapse. */
td.blk.b-taken{background:#3a4147}
td.blk.b-tester{background:var(--green)}
td.blk.b-held{background:#7b8288}
/* A block-out: lanes taken off sale for a tournament, maintenance or an
   event. Grey and hatched on both grids, carrying the label staff gave it
   (TOURNAMENT, MAINTENANCE) — a sign on the door, not a customer. */
td.blk.b-block{background:repeating-linear-gradient(135deg,
  #8f949a,#8f949a 6px,#9a9ea3 6px,#9a9ea3 12px);color:#fff;letter-spacing:.1em;
  text-shadow:0 1px 0 rgba(0,0,0,.25)}
td.blk.b-mine{background:var(--red-deep);box-shadow:inset 0 0 0 2px #f2efe8}

.grid-admin td.blk{cursor:pointer}

/* The admin grid sits inside the shell with the nav rail beside it, so it
   has less room than the customer's and the day is squeezed to fit. */
.grid-admin table.cal thead th{width:44px;font-size:10.5px}
.grid-admin table.cal thead th.lanehead{width:112px}
.grid-admin td.lane-name{font-size:16px;padding:0 9px}
.grid-admin td.blk{font-size:10px}
.grid-admin td.blk[colspan="1"]{font-size:8.5px}

/* ---------- legend ---------- */
.cal-legend{display:flex;gap:14px;align-items:center;font-size:12.5px;
  color:var(--muted);flex-wrap:wrap;margin:0 0 14px}
.cal-legend span{display:inline-flex;align-items:center;gap:6px}
.cal-dot{width:12px;height:12px;border-radius:3px;display:inline-block}

/* ---------- the day bar ---------- */
.cal-bar{display:flex;gap:10px;align-items:center;flex-wrap:wrap;margin-bottom:14px}
.cal-bar .daylabel{font-family:"Bebas Neue",sans-serif;font-size:22px;
  letter-spacing:1px;margin-left:4px}
/* ---------- the day picker ----------
   A row rather than a wall calendar: back a day, a date box, forward a day,
   and Today. The box is the browser's own date control, so the calendar that
   opens out of it is the one the person already knows from every other site,
   is drawn by the phone at the size the phone wants, and does not depend on
   this stylesheet having arrived to be usable at all. */
.daybar{display:flex;gap:8px;align-items:center;flex-wrap:wrap;margin-bottom:14px}
.daybar form{display:inline-flex;gap:8px;align-items:center;margin:0}
.daybar input[type=date]{width:auto;margin:0;padding:9px 12px;font-size:14px;
  font-family:"DM Sans",sans-serif;background:var(--panel);border:1px solid var(--line-strong);
  border-radius:4px;color:var(--ink)}
.daybar .btn{text-decoration:none}
/* A step that would land in the past is left in place but plainly not on,
   rather than removed, so the row does not shuffle sideways day to day. */
.daybar .btn.off{opacity:.35;pointer-events:none}
.daybar .daylabel{font-family:"Bebas Neue",sans-serif;font-size:22px;letter-spacing:1.4px;
  text-transform:uppercase;color:var(--ink);margin-left:4px}
/* On a phone the four controls belong on one line with the day named
   underneath, rather than spilling onto three lines and pushing the grid
   itself off the bottom of the screen before it has been seen at all. */
@media (max-width:520px){
  .daybar{gap:6px}
  .daybar .btn{padding:9px 12px}
  .daybar input[type=date]{padding:8px 8px;font-size:13px}
  .daybar .daylabel{flex:1 0 100%;margin-left:0;font-size:19px}
}

/* ---------- the selection bar ---------- */
.selbar{position:sticky;bottom:0;z-index:40;background:var(--ink);color:#f2efe8;
  border-radius:4px;margin-top:16px;padding:14px 18px;display:flex;
  gap:14px;align-items:center;flex-wrap:wrap}
.selbar .sb-main{flex:1;min-width:200px}
.selbar .sb-count{font-family:"Bebas Neue",sans-serif;font-size:22px;letter-spacing:1px}
.selbar .sb-detail{font-size:12.5px;color:rgba(242,239,232,.72);line-height:1.4}
.selbar .sb-warn{font-size:12.5px;color:#f0c27a;line-height:1.4;margin-top:2px}
.selbar .sb-price{font-family:"Bebas Neue",sans-serif;font-size:26px;letter-spacing:1px}
.selbar.idle .sb-price,.selbar.idle .btn-clear,.selbar.idle .btn-go{display:none}
.selbar .btn-clear{background:transparent;color:rgba(255,255,255,.8);
  border:1px solid rgba(255,255,255,.35);border-radius:3px;padding:11px 18px;
  font-family:"DM Sans",sans-serif;font-size:12px;font-weight:700;
  letter-spacing:.1em;text-transform:uppercase;cursor:pointer}
.selbar .btn-clear:hover{background:rgba(255,255,255,.1)}
.selbar .btn-go{background:var(--red);color:#fff;border:0;border-radius:3px;
  padding:13px 26px;font-family:"DM Sans",sans-serif;font-size:13px;font-weight:700;
  letter-spacing:.1em;text-transform:uppercase;cursor:pointer}
.selbar .btn-go:hover{background:#b73a2e}

/* ---------- the countdown ---------- */
.holdbar{display:flex;align-items:center;gap:12px;background:#2b2013;color:#f7e6c8;
  border-radius:4px;padding:13px 18px;margin-bottom:18px;flex-wrap:wrap}
.holdbar .clock{font-family:"Bebas Neue",sans-serif;font-size:30px;letter-spacing:1px;
  color:#fff;line-height:1}
.holdbar .hb-text{flex:1;min-width:200px;font-size:13.5px;line-height:1.45}
.holdbar.out{background:#5c1a14;color:#ffd9d4}

@media (max-width:760px){
  table.cal th,table.cal td{height:42px}
  .selbar{padding:12px 14px}
}

/* ---------- pre-order drinks, in sections ----------
   A full bar list read as one column of forty rows and pushed the details
   form off the bottom of a phone. Each category is a fold instead, shut on
   arrival, so the shape of the page does not depend on how many drinks the
   bar happens to stock. A shut <details> still posts the inputs inside it,
   so nothing chosen is ever lost by closing a section — but a shut section
   could hide a change, so a section with something in it says how many. */
.dsec-offer{background:#eaf3ec;border:1px solid #bcd9c4;border-left:3px solid var(--green);
  border-radius:4px;padding:10px 12px;margin:0 0 12px;font-size:13.5px;
  line-height:1.45;color:#1b3a26}

/* Built to the same pattern as the admin panel's drinks list, so the two
   screens read as one system: a boxed fold per category, a drawn caret, the
   category in Bebas, and how many drinks are inside it in quiet grey. */
.dsecs{display:flex;flex-direction:column;gap:10px;margin-bottom:4px}
.dsec{border:1px solid var(--line);border-radius:4px;background:var(--panel-2);
  overflow:hidden}
.dsec > summary{display:flex;align-items:center;gap:10px;padding:12px 14px;
  cursor:pointer;list-style:none;user-select:none}
.dsec > summary::-webkit-details-marker{display:none}
.dsec > summary::marker{content:''}
.dsec > summary:hover{background:var(--panel)}
/* The caret is drawn rather than typed so no font or emoji is involved:
   two borders of an empty box, turned forty-five degrees. */
.ds-caret{flex:0 0 auto;width:9px;height:9px;border-right:2px solid var(--muted);
  border-bottom:2px solid var(--muted);transform:rotate(-45deg);
  margin:0 3px 2px 2px;transition:transform .12s ease}
.dsec[open] > summary .ds-caret{transform:rotate(45deg);margin-bottom:5px}
.ds-nm{font-family:"Bebas Neue",sans-serif;font-size:17px;letter-spacing:1px;
  text-transform:uppercase;color:var(--ink)}
.ds-menu{font-size:12.5px;color:var(--muted-dim);white-space:nowrap}
/* How many have been chosen, which staff do not need and a customer does.
   Red so it reads as a number they put there, not part of the menu. */
.ds-count{font-family:"DM Sans",sans-serif;font-size:11px;font-weight:700;
  letter-spacing:.06em;color:#fff;background:var(--red);border-radius:10px;
  padding:2px 8px;line-height:1.5;white-space:nowrap}
.ds-tag{flex:0 0 auto;font-size:10.5px;letter-spacing:.08em;text-transform:uppercase;
  border:1px solid var(--green);border-radius:3px;padding:2px 7px;
  color:var(--green);white-space:nowrap}
.ds-body{padding:0 14px 14px;background:var(--panel)}

/* One line per drink: the name takes what is left, the price sits against
   the box it is being bought in, and the box is the last thing on the row.
   Stacking these made a phone scroll through pairs of lines to reach a
   number that was already on screen. */
.ds-row{display:flex;align-items:center;gap:12px;padding:10px 0;
  border-bottom:1px solid var(--line)}
.ds-row:last-child{border-bottom:0}
.ds-drink{flex:1;min-width:0;font-size:14.5px;font-weight:600;color:var(--ink);
  line-height:1.3}
.ds-price{flex:0 0 auto;font-size:14px;color:var(--muted);white-space:nowrap;
  font-variant-numeric:tabular-nums}
.ds-row input[type=number]{flex:0 0 auto;width:72px;margin:0;padding:8px 6px;
  text-align:center;font-size:14px}
/* The spinner arrows eat most of a narrow box and leave the number nowhere
   to sit; the quantity is typed, the same as on the admin side. */
.ds-row input[type=number]{-moz-appearance:textfield;appearance:textfield}
.ds-row input[type=number]::-webkit-outer-spin-button,
.ds-row input[type=number]::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}

/* On a narrow phone the category name can want two lines; the count and the
   offer tag must not be squeezed out by it. */
@media (max-width:420px){
  .dsec > summary{gap:7px;padding:11px 12px;flex-wrap:wrap}
  /* Squeeze the heading rather than let the longest category name push the
     offer tag onto a line of its own. */
  .ds-nm{font-size:15.5px;letter-spacing:.8px}
  .ds-menu{font-size:11.5px}
  /* On the longest category names there is not room on a phone for the name,
     the count and the offer tag all three. The count is the one to drop: it
     repeats what opening the fold shows anyway, whereas the tag is the only
     place the offer is named at all. Browsers too old for :has() simply wrap
     as before, which is untidy rather than broken. */
  .dsec > summary:has(.ds-tag) .ds-menu{display:none}
  .ds-tag{font-size:9.5px;padding:2px 6px}
  .ds-body{padding:0 12px 12px}
  .ds-row{gap:9px}
  .ds-row input[type=number]{width:64px}
}


/* ---------- how they would like to pay ----------------------------------
   Three boxed choices in the price panel, built to the same pattern as the
   drink folds above so the page still reads as one system: a bordered box,
   the choice named in Bebas, a quiet second line saying what it means, and
   the money that leaves the card now against the right edge.

   The whole box is the label, so the thing being tapped is a box rather
   than a dot the width of a fingernail. */
.payhead{font-family:"Bebas Neue",sans-serif;font-size:19px;letter-spacing:1px;
  text-transform:uppercase;color:var(--ink);margin:18px 0 10px}
.payopts{display:flex;flex-direction:column;gap:8px}
/* The box is a <label>, and the global label rule makes labels small, grey,
   letter-spaced and upper case. All four have to be undone here or the
   sentence explaining the choice arrives shouting. */
.payopt{display:flex;align-items:flex-start;gap:11px;padding:12px 13px;
  background:var(--panel-2);border:1px solid var(--line);border-radius:4px;
  cursor:pointer;transition:border-color .12s, background .12s;
  margin:0;font-family:"DM Sans",sans-serif;font-weight:400;font-size:15px;
  letter-spacing:normal;text-transform:none;color:var(--ink)}
.payopt:hover{background:var(--panel);border-color:var(--line-strong)}
.payopt input{flex:0 0 auto;width:auto;min-width:0;margin:3px 0 0;padding:0}
/* Which one is chosen has to be readable without hunting for a filled dot,
   because it decides what comes off a card. Browsers without :has() still
   show the radio itself, so this is emphasis rather than the only signal. */
.payopt:has(input:checked){background:var(--panel);border-color:var(--red);
  box-shadow:inset 0 0 0 1px var(--red)}
.po-main{flex:1;min-width:0;display:flex;flex-direction:column;gap:3px}
.po-nm{font-family:"Bebas Neue",sans-serif;font-size:16.5px;letter-spacing:.8px;
  text-transform:uppercase;color:var(--ink);line-height:1.15}
.po-note{font-size:12.5px;color:var(--muted);line-height:1.35;
  letter-spacing:normal;text-transform:none;font-weight:400}
.po-amt{flex:0 0 auto;font-family:"DM Sans",sans-serif;font-weight:700;font-size:15px;
  color:var(--ink);white-space:nowrap;font-variant-numeric:tabular-nums;padding-top:1px}
/* "Nothing now" is words where the others are money, so it is set quieter
   rather than pretending to be a figure. */
.po-amt.po-none{font-weight:600;font-size:13px;color:var(--muted-dim);
  letter-spacing:normal;text-transform:none}

/* ---------- pay.php ----------------------------------------------------
   The page a customer lands on if they back out of the Stripe page. The
   clock is the same red as everything else on this site that is running
   out, and it is the largest thing on the card because it is the only
   thing on it with a deadline. */
.payclock{font-family:"Bebas Neue",sans-serif;font-size:40px;letter-spacing:.02em;
  color:var(--red);line-height:1}
.paysplit{display:flex;flex-wrap:wrap;gap:12px;margin-top:18px}

@media (max-width:420px){
  .payopt{padding:11px 12px;gap:9px}
  .po-nm{font-size:15.5px;letter-spacing:.6px}
  .po-amt{font-size:14px}
}
