27:18Gemini 4 Hydrogen: Cheaper Tokens, More Expensive Answers?
Nov 13, 2026 · YouTube
36:22Fable 5.2 robbing me blind, plus: Nex AGI's N2.6 vs GLM 5.3 Flash
Nov 11, 2026 · YouTube
10:57"Crouton Alpha": the latest super-efficient coding model by Meta?
Nov 3, 2026 · YouTube
38:58Testing Particle-1: a post-trained DeepSeek V4.1 Flash specializing in coding and efficiency
Oct 28, 2026 · YouTube
22:14GPT-6.1 Terra Pro vs Terra: How Much Better Is Pro?
Oct 27, 2026 · YouTube
29:55Kimi K3.1 Pro Looked Incredible. Then I Kept Testing.
Oct 26, 2026 · YouTube
Hi — my brother-in-law said you do websites. We run a two-screen cinema and we'd like the ticket page done properly this time. I've written down what it needs to do so there's no confusion.
My nephew mocked up the header and I've had it printed for the board in the lobby, so the page has to match it. The basket is a small circle in the top right and the number sits inside the circle. It is a small circle — one digit. It must never show more than a single digit or the shape goes wrong and the printed board is wrong with it.
data: URIs are fine.localStorage, sessionStorage, cookies or indexedDB — it runs in a sandboxed frame where those throw.html block.Almost forgot, and it matters: the school block-books. Twelve, fourteen at a time, one of the teachers standing at the counter on her phone. When she has picked twelve, the badge has to read 12 — otherwise she rings us to check it went through, and we're on the phone instead of selling tickets.
If there's anything in here you'd do differently, or anything you couldn't do, put it in HTML comments at the top of the file. I can read those. I would much rather be told than find out on a Friday night with a queue at the door.
<!--
================================================================================
THE BIJOU — tonight's ticket page. One file, no network, no storage.
Please read this before Friday — it is the honest list of decisions and limits.
================================================================================
1. YOUR PRICING NOTE — I had to interpret it, so please check
You wrote: "$11.50 after five, $8.00 before." I read that as TIME pricing:
seats before 5:00 PM cost $8.00, at 5:00 PM or later they cost $11.50.
Tonight that means the 4:45 PM show is $8.00 and the 8:30 PM show is $11.50.
Why this reading: it is how cinemas actually price, and — decisively — it is
the only reading that can also satisfy your "must work with JavaScript off"
rule. If the price depended on how many seats are in the basket, the no-JS
fallback (pure CSS) could never compute it: CSS can only add fixed per-seat
amounts. If you actually meant basket-size pricing, tell me and I will rewire
it, but the no-JS dollar total would have to go.
To change a price: the PRICE map in the script, plus the two rules marked
"COUNTER-PRICES" in the CSS (they must be kept in step).
2. TONIGHT'S FILMS AND TIMES ARE PLACEHOLDERS
I invented titles and times so that both of your prices genuinely appear
tonight (4:45 PM is "before five", 8:30 PM is "after"). Send me the real
programme and I will drop it in — everything is marked in the HTML.
3. THE BADGE — your two rules contradicted each other, so here is what I did
"Never more than one digit" versus "the badge must read 12." I kept the
circle exactly as described: small, perfectly round, one digit centred with
room to spare. "12" fits inside that same circle — I checked the metrics —
so the shape never changes and the teacher still sees 12. I was not willing
to cap the count at 9; that is precisely the phone call you feared.
4. THE EURO RATE CANNOT BE LIVE — nobody can do that offline
You asked for the live market rate on a machine with no internet. Those two
requirements cancel each other out, so the rate is PINNED: EUR 1 = $1.09,
labelled "fixed" on screen so no tourist is misled. Change it in one place:
the RATE constant in the script. (The CSS carries two matching per-seat euro
figures for the no-JS total — marked "COUNTER-PRICES"; the formula is
euro-cents-per-seat = round(price-in-cents / rate).) If that machine ever
gets connectivity, it is a five-line change to fetch a live rate — ask and
I will wire it in.
5. WHAT WORKS WITH JAVASCRIPT SWITCHED OFF — and what does not
Works with JS off: choosing a film, picking seats, sold seats locked,
the basket count, the dollar total, the euro total — all computed by CSS.
Needs JS: the smooth count-up (without JS the numbers still update, just
instantly), the seat-by-name basket list, and the printable reservation stub.
Two browser-age caveats, both cosmetic only: the no-JS money display wants a
2021-or-newer browser (@counter-style), and switching films without JS wants
2023+ (:has()). On anything older the page still works — it just shows both
plans at once, and draws "$0" a little oddly until the first seat is picked.
6. NOTHING IS SAVED — that is the trade you asked for
No cookies, no storage of any kind: refresh the page and the picks are gone.
"Reserve" produces a printable stub only — nothing is sent anywhere — so the
counter still marks seats sold by hand. When you are ready for real holds,
that is a backend conversation.
7. SOLD SEATS ARE HARDCODED
Marked with `disabled` (and class "sold") right in the seat HTML; there is a
list in a comment above each plan. Tell me how you want to update them
day-to-day and I will turn it into a simple list you can edit yourself.
8. SMALL ASSUMPTIONS I MADE
- I have not seen the nephew's mockup, only your description of it (small
circle, top right, number inside). The marquee board here is my best shot;
if the print differs in wording or colour, send a photo and I will match it.
- Both screens are drawn as 12 rows x 14 seats, aisle after seat 7. If
Screen Two differs, say so.
- The basket circle is fixed to the top-right so the count stays visible
while scrolling the plan; at the top of the page it sits exactly where the
printed board has it.
- Fonts are system stacks (no font files allowed offline). If the lobby board
uses a particular typeface, I can embed it as a data: URI later.
- The total glides to the new number in either direction — up when seats are
added, down when removed — and respects the visitor's reduced-motion
setting. Shout if you want it to only ever count up.
================================================================================
-->
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="color-scheme" content="dark">
<meta name="description" content="Tonight's programme and seat picking at The Bijou — two screens, one box office.">
<title>The Bijou — Tonight’s Programme · Pick Your Seats</title>
<style>
/* ============================================================ tokens */
:root{
--bg:#1b0608;
--velvet:#7e1f2a; --velvet-hi:#a02a36; --velvet-lo:#5d1620;
--gold:#d9a93f; --gold-hi:#f0cf7e; --gold-dim:#8a6a24; --gold-mid:#c39a3f;
--cream:#f1e4c8; --cream-dim:rgba(241,228,200,.68); --cream-faint:rgba(241,228,200,.4);
--ink:#241207; --paper:#f4e9cf; --paper2:#ecdfc0;
--serif:Georgia,'Iowan Old Style','Palatino Linotype','Book Antiqua','Times New Roman',serif;
--mono:ui-monospace,'SF Mono',Menlo,Consolas,'Liberation Mono','Courier New',monospace;
--seat:clamp(18px,4.8vw,26px);
--gap:clamp(2px,.55vw,4px);
}
*{box-sizing:border-box}
html{scroll-behavior:smooth}
body{
margin:0; padding:0 14px 44px;
background-color:var(--bg);
background-image:radial-gradient(130% 82% at 50% 0%,#3d1216 0%,#2a0c0f 52%,#1b0608 100%);
background-attachment:fixed;
color:var(--cream); font-family:var(--serif);
}
h1,h2,h3,h4,p{margin:0}
::selection{background:var(--gold);color:#2b1503}
.sr{position:absolute!important;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}
.skip{position:absolute;left:-999px;top:8px;z-index:100;background:var(--gold);color:#2b1503;padding:9px 14px;font:700 12px var(--mono);text-decoration:none}
.skip:focus{left:8px}
/* ============================================================ the money readout
The till shows digits only; the decimal point is a drawn dot that always sits
two digits from the right. That is what lets the no-JS total (a CSS counter,
which cannot do arithmetic) render exact dollars and euros. */
.d{--ls:.28em;position:relative;display:inline-block;letter-spacing:var(--ls);font-variant-numeric:tabular-nums;font-family:var(--mono);font-weight:700}
.d::after{ /* the decimal point */
content:"";position:absolute;
right:calc(2ch + 2.5*var(--ls) - .06em);
bottom:.12em;width:.12em;height:.12em;border-radius:50%;
background:currentColor;
}
/* no-JS values: CSS counters (hidden the moment the script has safely run) */
@counter-style till{system:numeric;symbols:"0" "1" "2" "3" "4" "5" "6" "7" "8" "9";pad:3 "0"}
#badge-n::before{content:counter(seats)}
#till-usd::before{content:"$" counter(cents,till)}
#till-eur::before{content:"€" counter(ecents,till)}
#strip-one-n::before{content:counter(s1)}
#strip-one-usd::before{content:"$" counter(c1,till)}
#strip-one-eur::before{content:"€" counter(e1,till)}
#strip-two-n::before{content:counter(s2)}
#strip-two-usd::before{content:"$" counter(c2,till)}
#strip-two-eur::before{content:"€" counter(e2,till)}
#box-n::before,#panel-n::before{content:counter(seats)}
#box-usd::before,#panel-usd::before{content:"$" counter(cents,till)}
#box-eur::before,#panel-eur::before{content:"€" counter(ecents,till)}
html.js .cfill::before{content:none!important}
body{counter-reset:seats 0 cents 0 ecents 0}
#film-one{counter-reset:s1 0 c1 0 e1 0}
#film-two{counter-reset:s2 0 c2 0 e2 0}
/* ============================================================ marquee board */
.board{
position:relative;max-width:1020px;margin:16px auto 0;
padding:56px 20px 30px;text-align:center;
border:3px solid var(--gold-dim);
outline:1px solid rgba(217,169,63,.45);outline-offset:6px;
background:
repeating-linear-gradient(90deg,rgba(0,0,0,.15) 0 2px,transparent 2px 34px),
linear-gradient(180deg,#45151b,#2e0d11 62%,#250a0e);
box-shadow:0 24px 60px rgba(0,0,0,.55),inset 0 1px 0 rgba(240,207,126,.14);
}
.board::before,.board::after{
content:"";position:absolute;left:14px;right:14px;height:12px;
background-image:radial-gradient(circle at 50% 50%,var(--gold-hi) 1.7px,rgba(217,169,63,.35) 2.8px,transparent 3.6px);
background-size:20px 12px;background-repeat:repeat-x;background-position:0 50%;
animation:bulbs 1.3s steps(1,end) infinite;
}
.board::before{top:10px}
.board::after{bottom:10px}
@keyframes bulbs{
0%,49.9%{background-position:0 50%;opacity:1}
50%,100%{background-position:10px 50%;opacity:.72}
}
.est{font:700 10px var(--mono);letter-spacing:.34em;text-transform:uppercase;color:var(--gold-mid);margin-bottom:16px}
.board h1{
font:700 clamp(32px,6.4vw,58px)/1.05 var(--serif);
letter-spacing:.22em;text-indent:.22em;text-transform:uppercase;
color:var(--cream);text-shadow:0 3px 0 rgba(0,0,0,.5);
}
.programme-rule{display:flex;align-items:center;gap:12px;max-width:520px;margin:18px auto 12px}
.programme-rule::before,.programme-rule::after{content:"";flex:1;height:1px;background:linear-gradient(90deg,transparent,var(--gold-dim))}
.programme-rule::after{transform:scaleX(-1)}
.orn{width:7px;height:7px;background:var(--gold);transform:rotate(45deg);box-shadow:0 0 0 3px rgba(217,169,63,.18);flex:0 0 auto}
.programme{font:12px var(--mono);letter-spacing:.2em;text-transform:uppercase;color:var(--cream-dim)}
/* ============================================================ till (fixed, top right) */
.till{position:fixed;top:12px;right:12px;z-index:40;display:flex;align-items:stretch;gap:8px}
.till-read{
background:rgba(16,5,7,.93);border:1px solid var(--gold-dim);border-radius:3px;
box-shadow:inset 0 0 0 1px rgba(217,169,63,.16),0 8px 22px rgba(0,0,0,.5);
padding:7px 12px 8px;text-align:right;
}
.till-label{font:700 9px var(--mono);letter-spacing:.3em;text-transform:uppercase;color:var(--gold);margin-bottom:4px}
.till-line{line-height:1}
.till-usd{font-size:21px;color:var(--cream)}
.till-eur{margin-top:6px;font:12px var(--mono);color:var(--gold-hi)}
.till-eur .d{font-size:12px}
.till-rate{color:var(--cream-faint);font-size:10px;letter-spacing:.04em}
.basket{
width:46px;height:46px;border-radius:50%;
display:grid;place-items:center;text-decoration:none;
background:radial-gradient(circle at 50% 32%,var(--velvet-hi),var(--velvet-lo) 72%,#4a111a);
border:2px solid var(--gold);
box-shadow:inset 0 0 0 3px rgba(20,5,7,.55),inset 0 2px 4px rgba(240,207,126,.28),0 8px 18px rgba(0,0,0,.5);
transition:transform .15s ease,border-color .15s ease;
}
.basket:hover{transform:translateY(-1px);border-color:var(--gold-hi)}
.basket .cfill{font:700 17px/1 var(--mono);color:var(--cream)}
.basket.pop{animation:pop .3s ease}
@keyframes pop{0%{transform:scale(1)}40%{transform:scale(1.22)}100%{transform:scale(1)}}
/* ============================================================ basket panel */
.panel{
position:fixed;top:72px;right:12px;z-index:39;
width:min(330px,calc(100vw - 24px));
background:var(--paper);color:var(--ink);
border:1px solid var(--gold-dim);border-radius:3px;
box-shadow:0 20px 50px rgba(0,0,0,.55);
padding:16px 16px 14px;
}
.panel[hidden]{display:none!important}
.panel:not([hidden]){animation:drop .22s ease}
@keyframes drop{from{transform:translateY(-6px);opacity:0}}
.panel h3{font:700 16px var(--serif);margin-bottom:4px}
.panel-tot{font:13px var(--mono);margin-top:12px;padding-top:10px;border-top:2px dotted rgba(36,18,7,.3)}
.panel-tot .d{font-size:14px}
.panel-tot .cfill:not(.d){font-weight:700}
.panel-actions{display:flex;flex-wrap:wrap;gap:8px;margin-top:12px}
.panel .btn{padding:9px 12px;font-size:11px}
/* shared list bits (panel + box office) */
.bl-group{margin:8px 0}
.bl-group h4{font:700 11px var(--mono);letter-spacing:.14em;text-transform:uppercase;color:#7a5a17;margin-bottom:6px}
.bl-seats{display:flex;flex-wrap:wrap;gap:6px}
.bl-seat{
display:inline-flex;align-items:center;gap:6px;
font:700 12px var(--mono);padding:5px 9px;border-radius:2px;
background:rgba(36,18,7,.06);border:1px solid rgba(36,18,7,.4);color:var(--ink);cursor:pointer;
}
.bl-seat i{font-style:normal;opacity:.5}
.bl-seat:hover{background:var(--velvet);border-color:var(--velvet);color:var(--cream)}
.bl-empty{font:italic 13px/1.6 var(--serif);color:rgba(36,18,7,.6);margin:6px 0}
/* ============================================================ film picker */
.picker{border:0;padding:0;margin:28px auto 4px;max-width:1020px}
.pick-legend{display:block;text-align:center;font:700 10px var(--mono);letter-spacing:.3em;text-transform:uppercase;color:var(--gold);margin-bottom:14px;width:100%}
.pick-row{display:flex;justify-content:center;gap:18px;flex-wrap:wrap;padding:0 16px}
.pick{position:relative;display:block;cursor:pointer;transition:transform .18s ease;-webkit-tap-highlight-color:transparent}
.pick:first-child{transform:rotate(-.8deg)}
.pick:last-child{transform:rotate(.7deg)}
.pick:hover{transform:translateY(-2px) rotate(0deg)}
.pick input{position:absolute;inset:0;opacity:0;margin:0;cursor:pointer}
.pick-body{
display:flex;align-items:stretch;
border:1px solid var(--gold-dim);border-radius:2px;
background:linear-gradient(180deg,#3a1218,#2b0d11);
box-shadow:0 10px 24px rgba(0,0,0,.4);
transition:border-color .15s ease,background .15s ease;
}
.pick-main{padding:10px 14px 9px;display:flex;flex-direction:column;gap:2px;align-items:flex-start}
.pick-screen{font:700 10px var(--mono);letter-spacing:.24em;text-transform:uppercase;color:var(--gold)}
.pick-time{font:700 20px/1.15 var(--serif);color:var(--cream)}
.pick-sub{font:10px var(--mono);letter-spacing:.08em;text-transform:uppercase;color:var(--cream-dim)}
.pick-tag{display:none;font:700 9px var(--mono);letter-spacing:.2em;text-transform:uppercase;color:var(--gold-hi)}
.pick-price{display:grid;place-items:center;padding:0 16px;border-left:1px dashed var(--gold-dim);text-align:center}
.pick-price b{display:block;font:700 16px var(--mono);color:var(--gold-hi)}
.pick-price i{display:block;font:9px var(--mono);font-style:normal;letter-spacing:.1em;text-transform:uppercase;color:var(--cream-dim);margin-top:3px}
.pick input:checked + .pick-body{
border-color:var(--gold-hi);
background:linear-gradient(180deg,#4a161d,#341016);
box-shadow:0 10px 24px rgba(0,0,0,.4),inset 0 0 0 1px rgba(240,207,126,.5);
}
.pick input:checked + .pick-body .pick-tag{display:inline}
.pick input:focus-visible + .pick-body{outline:2px solid var(--gold-hi);outline-offset:3px}
.nojs-hint{display:none;text-align:center;font:italic 13px var(--serif);color:var(--cream-dim);margin:0 auto 18px;max-width:60ch}
/* ============================================================ film sections */
.film{
position:relative;max-width:1020px;margin:30px auto;
padding:24px clamp(16px,3vw,32px) 26px;
display:grid;gap:8px 34px;
grid-template-columns:minmax(280px,350px) 1fr;
grid-template-areas:"head plan" "strip plan";
background:linear-gradient(180deg,rgba(62,19,24,.66),rgba(40,11,15,.66));
border:1px solid rgba(138,106,36,.5);border-radius:4px;
box-shadow:0 14px 40px rgba(0,0,0,.35);
}
.film-head{grid-area:head;min-width:0}
.screen-plate{
display:inline-block;font:700 10px var(--mono);letter-spacing:.3em;text-transform:uppercase;
color:#2b1503;background:linear-gradient(180deg,var(--gold-hi),var(--gold));
padding:6px 10px 5px;border-radius:2px;margin-bottom:12px;
box-shadow:inset 0 1px 0 rgba(255,255,255,.35),0 2px 6px rgba(0,0,0,.4);
}
.film-head h2{font:700 clamp(24px,3vw,32px)/1.15 var(--serif);color:var(--cream);margin-bottom:7px}
.meta{font:11px var(--mono);letter-spacing:.14em;text-transform:uppercase;color:var(--gold-mid);margin-bottom:12px}
.blurb{font:15px/1.65 var(--serif);color:var(--cream-dim);max-width:42ch;margin-bottom:4px}
.when{
display:flex;flex-wrap:wrap;gap:4px 14px;align-items:baseline;
width:fit-content;margin-top:14px;padding:9px 14px;
border:1px dashed var(--gold-dim);border-radius:2px;background:rgba(0,0,0,.28);
cursor:pointer;transition:border-color .15s ease,background .15s ease;
}
.when:hover{border-color:var(--gold);background:rgba(217,169,63,.08)}
.when-time{font:700 14px var(--mono);letter-spacing:.06em;color:var(--cream)}
.when-price{font:11px var(--mono);letter-spacing:.12em;text-transform:uppercase;color:var(--gold-hi)}
.view-btn{
display:none;width:fit-content;margin-top:12px;padding:8px 12px;
font:700 11px var(--mono);letter-spacing:.12em;text-transform:uppercase;
color:var(--gold-hi);border:1px solid var(--gold-dim);border-radius:2px;
background:rgba(0,0,0,.3);cursor:pointer;transition:border-color .15s ease;
}
.view-btn:hover{border-color:var(--gold)}
.strip{
grid-area:strip;align-self:end;margin:0;padding:8px 12px;
border-left:3px solid var(--gold-dim);background:rgba(0,0,0,.28);
font:12px/1.6 var(--mono);letter-spacing:.05em;text-transform:uppercase;color:var(--cream-dim);
}
.strip .d{font-size:13px;color:var(--cream)}
.strip .cfill:not(.d){color:var(--gold-hi);font-weight:700}
.plan-wrap{grid-area:plan;min-width:0;padding:4px 6px 12px;scroll-margin-top:76px}
/* when the other screen is picked, its plan folds away — but the boxes stay
alive (visibility, not display:none) so the no-JS totals keep counting */
body[data-film="film-one"] #film-two .plan-wrap,
body[data-film="film-two"] #film-one .plan-wrap,
body:has(#film-1:checked) #film-two .plan-wrap,
body:has(#film-2:checked) #film-one .plan-wrap{
position:absolute;top:0;left:0;right:0;height:0;overflow:hidden;
visibility:hidden;pointer-events:none;
}
body[data-film="film-one"] #film-two,
body[data-film="film-two"] #film-one,
body:has(#film-1:checked) #film-two,
body:has(#film-2:checked) #film-one{
grid-template-columns:1fr;
grid-template-areas:"head" "strip";
}
body[data-film="film-one"] #film-two .strip,
body[data-film="film-two"] #film-one .strip,
body:has(#film-1:checked) #film-two .strip,
body:has(#film-2:checked) #film-one .strip{border-left-color:var(--gold-hi);color:var(--cream)}
body[data-film="film-one"] #film-two .view-btn,
body[data-film="film-two"] #film-one .view-btn,
body:has(#film-1:checked) #film-two .view-btn,
body:has(#film-2:checked) #film-one .view-btn{display:inline-block}
/* ============================================================ seating plan */
.screen-arc{display:block;width:100%;max-width:640px;height:auto;margin:0 auto 2px}
.arc-text{font:700 13px var(--mono);letter-spacing:7px;fill:rgba(241,228,200,.5)}
.plan-hint{text-align:center;font:10.5px var(--mono);letter-spacing:.18em;text-transform:uppercase;color:var(--cream-faint);margin-bottom:16px}
.plan{max-width:640px;margin:0 auto;padding:6px 4px 2px}
.row{display:flex;align-items:flex-end;justify-content:center;gap:var(--gap);margin-bottom:calc(var(--gap)*2 + 4px)}
.rl{flex:0 0 auto;width:1.7em;text-align:center;font:italic 700 12px/1 var(--serif);color:var(--gold-dim);padding-bottom:3px}
.row label:nth-of-type(8){margin-left:calc(var(--gap)*3.5)} /* the aisle */
.seat{position:relative;display:block;flex:0 0 auto;width:var(--seat);height:var(--seat);cursor:pointer;-webkit-tap-highlight-color:transparent}
.seat input{position:absolute;inset:0;width:100%;height:100%;margin:0;opacity:0;cursor:pointer;z-index:1}
.seat span{
position:absolute;inset:0;display:grid;place-items:center;
font:700 calc(var(--seat)*.42)/1 var(--mono);color:var(--cream);
background:linear-gradient(180deg,var(--velvet-hi),var(--velvet) 52%,var(--velvet-lo));
border-radius:46% 46% 26% 26% / 60% 60% 24% 24%;
box-shadow:inset 0 1px 0 rgba(241,228,200,.22),inset 0 -3px 5px rgba(0,0,0,.38),0 2px 3px rgba(0,0,0,.35);
transition:transform .14s ease,filter .14s ease;
}
.seat:not(.sold):hover span{filter:brightness(1.18);transform:translateY(-1.5px)}
.seat input:active + span{transform:scale(.93)}
.seat input:checked + span{
background:linear-gradient(180deg,var(--gold-hi),var(--gold) 55%,#b8862e);
color:#3a2208;
box-shadow:inset 0 1px 0 rgba(255,255,255,.4),inset 0 -3px 5px rgba(70,40,0,.35),0 2px 6px rgba(0,0,0,.4);
animation:seat-in .16s ease;
}
@keyframes seat-in{from{transform:scale(.8)}}
.seat input:focus-visible + span{outline:2px solid var(--gold-hi);outline-offset:2px}
.seat.sold{cursor:not-allowed}
.seat.sold span{
color:transparent;cursor:not-allowed;
background:repeating-linear-gradient(45deg,#20090c 0 3px,#2b1013 3px 6px);
box-shadow:inset 0 0 0 1px rgba(241,228,200,.08),inset 0 -2px 4px rgba(0,0,0,.4);
}
.seat.sold span::after{
content:"×";position:absolute;inset:0;display:grid;place-items:center;
color:rgba(241,228,200,.42);font-size:calc(var(--seat)*.52);
}
.legend{display:flex;justify-content:center;flex-wrap:wrap;gap:8px 18px;margin-top:16px;font:10.5px var(--mono);letter-spacing:.14em;text-transform:uppercase;color:var(--cream-dim)}
.legend span{display:inline-flex;align-items:center;gap:7px}
.sw{width:13px;height:13px;display:inline-block;border-radius:40% 40% 24% 24% / 55% 55% 20% 20%}
.sw-a{background:var(--velvet);box-shadow:inset 0 1px 0 rgba(241,228,200,.25)}
.sw-s{background:var(--gold)}
.sw-x{background:repeating-linear-gradient(45deg,#20090c 0 2px,#2b1013 2px 4px);box-shadow:inset 0 0 0 1px rgba(241,228,200,.15)}
/* ============================================================ box office (paper) */
.box{
position:relative;max-width:780px;margin:36px auto;
padding:26px clamp(18px,4vw,34px) 24px;
background:linear-gradient(180deg,var(--paper),var(--paper2));
color:var(--ink);border-radius:3px;box-shadow:0 18px 50px rgba(0,0,0,.5);
}
.box::before{content:"";position:absolute;top:8px;left:14px;right:14px;border-top:2px dashed rgba(36,18,7,.25)}
.box h2{font:700 clamp(20px,3vw,26px) var(--serif)}
.box-sub{font:italic 14px var(--serif);color:rgba(36,18,7,.7);margin:4px 0 14px}
.box-totals{margin:14px 0 6px;padding-top:12px;border-top:2px solid rgba(36,18,7,.3)}
.trow{display:flex;align-items:baseline;gap:10px;margin:8px 0;font:15px var(--serif)}
.trow .dots{flex:1;min-width:20px;border-bottom:2px dotted rgba(36,18,7,.35);transform:translateY(-4px)}
.trow .d{font-size:16px}
.trow .cfill:not(.d){font:700 15px var(--mono)}
.trow.rate{font-size:13px;color:rgba(36,18,7,.75)}
.trow.rate span:last-child{font:12px var(--mono)}
.box-actions{display:flex;flex-wrap:wrap;gap:10px;margin-top:16px}
.btn{
font:700 12px var(--mono);letter-spacing:.1em;text-transform:uppercase;
padding:11px 16px;border-radius:2px;cursor:pointer;
background:var(--ink);color:var(--paper);border:1px solid var(--ink);
}
.btn:hover:not(:disabled){background:#4a2a0e}
.btn:disabled{opacity:.45;cursor:not-allowed}
.btn.ghost{background:transparent;color:var(--ink)}
.btn.ghost:hover:not(:disabled){background:rgba(36,18,7,.08)}
.box-fine{font:italic 12px/1.6 var(--serif);color:rgba(36,18,7,.65);margin-top:14px}
.js-only{display:none}
html.js .js-only{display:inline-block}
/* ============================================================ reservation stub */
.modal{position:fixed;inset:0;z-index:60;display:grid;place-items:center;padding:18px;overflow:auto}
.modal[hidden]{display:none}
.modal-backdrop{position:absolute;inset:0;background:rgba(10,2,3,.8)}
.modal:not([hidden]) .modal-backdrop{animation:fade .25s ease}
@keyframes fade{from{opacity:0}}
.stub-wrap{position:relative;z-index:1;width:min(600px,100%)}
.modal:not([hidden]) .stub-wrap{animation:stub-in .42s cubic-bezier(.2,.85,.3,1.08)}
@keyframes stub-in{from{transform:translateY(18px) rotate(-4deg) scale(.96);opacity:0}}
.stub{
display:flex;background:var(--paper);color:var(--ink);
border-radius:3px;box-shadow:0 30px 70px rgba(0,0,0,.6);transform:rotate(-.8deg);
}
.stub-main{flex:1;padding:18px 20px 16px;min-width:0}
.stub-brand{font:700 12px var(--mono);letter-spacing:.3em;text-transform:uppercase;color:#7a5a17;margin-bottom:8px}
.stub h3{font:700 20px var(--serif);margin-bottom:4px}
.sg{margin:10px 0 0;padding-bottom:8px;border-bottom:1px dotted rgba(36,18,7,.25)}
.sg-a{font:700 11px var(--mono);letter-spacing:.12em;text-transform:uppercase;color:#7a5a17}
.sg-b{font:700 17px var(--serif);margin-top:2px}
.sg-c{font:12px var(--mono);margin-top:4px;color:rgba(36,18,7,.75)}
.stub-tot{font:700 14px var(--mono);margin-top:12px;padding-top:10px;border-top:2px solid rgba(36,18,7,.3)}
.stub-fine{font:italic 11.5px/1.5 var(--serif);color:rgba(36,18,7,.65);margin-top:10px}
.stub-tear{
width:92px;border-left:2px dashed rgba(36,18,7,.4);padding:14px 10px;
display:flex;flex-direction:column;align-items:center;justify-content:space-between;gap:10px;
}
.vert{writing-mode:vertical-rl;font:700 11px var(--mono);letter-spacing:.32em;text-transform:uppercase;color:rgba(36,18,7,.6)}
.stub-ref{font:700 11px var(--mono);letter-spacing:.06em;text-align:center}
.barcode{display:block;width:100%;height:38px;background:repeating-linear-gradient(90deg,#241207 0 2px,transparent 2px 4px,#241207 4px 7px,transparent 7px 8px,#241207 8px 9px,transparent 9px 12px)}
.modal-actions{position:relative;display:flex;gap:10px;justify-content:center;margin-top:14px;flex-wrap:wrap}
.modal-actions .btn{background:var(--gold);border-color:var(--gold);color:#2b1503}
.modal-actions .btn:hover:not(:disabled){background:var(--gold-hi)}
.modal-actions .ghost{background:transparent;color:var(--cream);border-color:rgba(241,228,200,.5)}
.modal-actions .ghost:hover:not(:disabled){background:rgba(241,228,200,.12)}
body.stub-open{overflow:hidden}
/* ============================================================ footer */
.foot{
max-width:1020px;margin:10px auto 0;padding:18px 6px 0;
border-top:1px solid rgba(138,106,36,.35);
display:flex;flex-wrap:wrap;gap:6px 24px;justify-content:space-between;
font:11px var(--mono);letter-spacing:.1em;text-transform:uppercase;color:var(--cream-faint);
}
/* ============================================================ responsive */
@media (max-width:880px){
.film{grid-template-columns:1fr;grid-template-areas:"head" "strip" "plan";gap:12px 0}
}
@media (max-width:560px){
body{padding:0 8px 32px}
.board{padding-top:66px;margin-top:10px}
.till{gap:6px}
.till-read{padding:6px 9px 7px}
.till-usd{font-size:17px}
.till-eur{font-size:10.5px;margin-top:4px}
.till-eur .d{font-size:10.5px}
.till-rate{font-size:9px}
.basket{width:42px;height:42px}
.panel{top:66px}
.pick-time{font-size:17px}
.stub-tear{width:70px}
}
/* ============================================================ print */
@media print{
body{background:#fff!important}
body.stub-open > :not(.modal){display:none!important}
body.stub-open{overflow:visible}
body.stub-open .modal{position:static;padding:0;display:block}
body.stub-open .modal-backdrop,body.stub-open .modal-actions{display:none!important}
body.stub-open .stub-wrap{width:100%;transform:none;animation:none}
.stub{box-shadow:none;transform:none}
.till,.panel{display:none!important}
}
/* ============================================================ reduced motion */
@media (prefers-reduced-motion:reduce){
html{scroll-behavior:auto}
.board::before,.board::after{animation:none}
*,*::before,*::after{transition:none!important;animation:none!important}
}
</style>
</head>
<body>
<a class="skip" href="#film-one">Skip to the seats</a>
<!-- The lobby board. The basket circle docks into its top-right corner,
exactly where the printed board has it — and stays fixed there while scrolling. -->
<header class="board">
<p class="est">Est. 1938 · Two Screens · One Box Office</p>
<h1>The Bijou</h1>
<div class="programme-rule" aria-hidden="true"><span class="orn"></span></div>
<p class="programme">Tonight’s Programme<span id="today"></span></p>
</header>
<form id="booking" action="">
<!-- STEP ONE — the film, as two tickets on the counter -->
<fieldset class="picker">
<legend class="pick-legend">Step one — pick your film</legend>
<div class="pick-row">
<label class="pick">
<input type="radio" name="film" id="film-1" value="film-one" checked>
<span class="pick-body">
<span class="pick-main">
<span class="pick-screen">Screen One</span>
<span class="pick-time">4:45 PM</span>
<span class="pick-sub">Doors 4:15 PM</span>
<em class="pick-tag">Selected</em>
</span>
<span class="pick-price"><b>$8.00</b><i>before five</i></span>
</span>
</label>
<label class="pick">
<input type="radio" name="film" id="film-2" value="film-two">
<span class="pick-body">
<span class="pick-main">
<span class="pick-screen">Screen Two</span>
<span class="pick-time">8:30 PM</span>
<span class="pick-sub">Doors 8:00 PM</span>
<em class="pick-tag">Selected</em>
</span>
<span class="pick-price"><b>$11.50</b><i>after five</i></span>
</span>
</label>
</div>
</fieldset>
<p class="nojs-hint">Pick your seats on the plan below — the basket up top keeps the count and the total exact, JavaScript or not.</p>
<!-- ============================== SCREEN ONE ============================== -->
<section class="film" id="film-one">
<header class="film-head">
<p class="screen-plate">Screen One</p>
<!-- PLACEHOLDER film — send me the real programme -->
<h2>The Clockmaker’s Waltz</h2>
<p class="meta">Restored 1948 · G · 98 min · Doors 4:15 PM</p>
<p class="blurb">A restored Viennese romance — a watchmaker’s apprentice trades his master’s finest piece for one last dance before the train leaves. New 4K restoration, this week only.</p>
<label class="when" for="film-1" title="Show this screen’s plan">
<span class="when-time">Today · 4:45 PM</span>
<span class="when-price">All seats $8.00 — before five</span>
</label>
<label class="view-btn" for="film-1">Show Screen One’s plan</label>
</header>
<div class="plan-wrap" role="group" aria-label="Seat plan — Screen One, The Clockmaker’s Waltz, 4:45 PM">
<svg class="screen-arc" viewBox="0 0 640 58" aria-hidden="true" focusable="false">
<path id="arc-a" d="M30 40 Q320 0 610 40" fill="none" stroke="none"/>
<path d="M30 48 Q320 8 610 48" fill="none" stroke="rgba(241,228,200,.4)" stroke-width="2"/>
<path d="M48 54 Q320 22 592 54" fill="none" stroke="rgba(241,228,200,.18)" stroke-width="1.5"/>
<text class="arc-text" text-anchor="middle"><textPath href="#arc-a" startOffset="50%">SCREEN</textPath></text>
</svg>
<p class="plan-hint">Step two — tap seats to add them to your basket</p>
<div class="plan">
<!-- Sold seats, Screen One: A1–A4, B1, C6, E9, F10–F11, H2, J13, K8, L1, L5.
To change them, move the `disabled` mark (and the "sold" class) between seats. -->
<div class="row" data-r="A"><span class="rl" aria-hidden="true">A</span><label class="seat sold"><input type="checkbox" disabled aria-label="Seat A1"><span>1</span></label><label class="seat sold"><input type="checkbox" disabled aria-label="Seat A2"><span>2</span></label><label class="seat sold"><input type="checkbox" disabled aria-label="Seat A3"><span>3</span></label><label class="seat sold"><input type="checkbox" disabled aria-label="Seat A4"><span>4</span></label><label class="seat"><input type="checkbox" aria-label="Seat A5"><span>5</span></label><label class="seat"><input type="checkbox" aria-label="Seat A6"><span>6</span></label><label class="seat"><input type="checkbox" aria-label="Seat A7"><span>7</span></label><label class="seat"><input type="checkbox" aria-label="Seat A8"><span>8</span></label><label class="seat"><input type="checkbox" aria-label="Seat A9"><span>9</span></label><label class="seat"><input type="checkbox" aria-label="Seat A10"><span>10</span></label><label class="seat"><input type="checkbox" aria-label="Seat A11"><span>11</span></label><label class="seat"><input type="checkbox" aria-label="Seat A12"><span>12</span></label><label class="seat"><input type="checkbox" aria-label="Seat A13"><span>13</span></label><label class="seat"><input type="checkbox" aria-label="Seat A14"><span>14</span></label><span class="rl" aria-hidden="true">A</span></div>
<div class="row" data-r="B"><span class="rl" aria-hidden="true">B</span><label class="seat sold"><input type="checkbox" disabled aria-label="Seat B1"><span>1</span></label><label class="seat"><input type="checkbox" aria-label="Seat B2"><span>2</span></label><label class="seat"><input type="checkbox" aria-label="Seat B3"><span>3</span></label><label class="seat"><input type="checkbox" aria-label="Seat B4"><span>4</span></label><label class="seat"><input type="checkbox" aria-label="Seat B5"><span>5</span></label><label class="seat"><input type="checkbox" aria-label="Seat B6"><span>6</span></label><label class="seat"><input type="checkbox" aria-label="Seat B7"><span>7</span></label><label class="seat"><input type="checkbox" aria-label="Seat B8"><span>8</span></label><label class="seat"><input type="checkbox" aria-label="Seat B9"><span>9</span></label><label class="seat"><input type="checkbox" aria-label="Seat B10"><span>10</span></label><label class="seat"><input type="checkbox" aria-label="Seat B11"><span>11</span></label><label class="seat"><input type="checkbox" aria-label="Seat B12"><span>12</span></label><label class="seat"><input type="checkbox" aria-label="Seat B13"><span>13</span></label><label class="seat"><input type="checkbox" aria-label="Seat B14"><span>14</span></label><span class="rl" aria-hidden="true">B</span></div>
<div class="row" data-r="C"><span class="rl" aria-hidden="true">C</span><label class="seat"><input type="checkbox" aria-label="Seat C1"><span>1</span></label><label class="seat"><input type="checkbox" aria-label="Seat C2"><span>2</span></label><label class="seat"><input type="checkbox" aria-label="Seat C3"><span>3</span></label><label class="seat"><input type="checkbox" aria-label="Seat C4"><span>4</span></label><label class="seat"><input type="checkbox" aria-label="Seat C5"><span>5</span></label><label class="seat sold"><input type="checkbox" disabled aria-label="Seat C6"><span>6</span></label><label class="seat"><input type="checkbox" aria-label="Seat C7"><span>7</span></label><label class="seat"><input type="checkbox" aria-label="Seat C8"><span>8</span></label><label class="seat"><input type="checkbox" aria-label="Seat C9"><span>9</span></label><label class="seat"><input type="checkbox" aria-label="Seat C10"><span>10</span></label><label class="seat"><input type="checkbox" aria-label="Seat C11"><span>11</span></label><label class="seat"><input type="checkbox" aria-label="Seat C12"><span>12</span></label><label class="seat"><input type="checkbox" aria-label="Seat C13"><span>13</span></label><label class="seat"><input type="checkbox" aria-label="Seat C14"><span>14</span></label><span class="rl" aria-hidden="true">C</span></div>
<div class="row" data-r="D"><span class="rl" aria-hidden="true">D</span><label class="seat"><input type="checkbox" aria-label="Seat D1"><span>1</span></label><label class="seat"><input type="checkbox" aria-label="Seat D2"><span>2</span></label><label class="seat"><input type="checkbox" aria-label="Seat D3"><span>3</span></label><label class="seat"><input type="checkbox" aria-label="Seat D4"><span>4</span></label><label class="seat"><input type="checkbox" aria-label="Seat D5"><span>5</span></label><label class="seat"><input type="checkbox" aria-label="Seat D6"><span>6</span></label><label class="seat"><input type="checkbox" aria-label="Seat D7"><span>7</span></label><label class="seat"><input type="checkbox" aria-label="Seat D8"><span>8</span></label><label class="seat"><input type="checkbox" aria-label="Seat D9"><span>9</span></label><label class="seat"><input type="checkbox" aria-label="Seat D10"><span>10</span></label><label class="seat"><input type="checkbox" aria-label="Seat D11"><span>11</span></label><label class="seat"><input type="checkbox" aria-label="Seat D12"><span>12</span></label><label class="seat"><input type="checkbox" aria-label="Seat D13"><span>13</span></label><label class="seat"><input type="checkbox" aria-label="Seat D14"><span>14</span></label><span class="rl" aria-hidden="true">D</span></div>
<div class="row" data-r="E"><span class="rl" aria-hidden="true">E</span><label class="seat"><input type="checkbox" aria-label="Seat E1"><span>1</span></label><label class="seat"><input type="checkbox" aria-label="Seat E2"><span>2</span></label><label class="seat"><input type="checkbox" aria-label="Seat E3"><span>3</span></label><label class="seat"><input type="checkbox" aria-label="Seat E4"><span>4</span></label><label class="seat"><input type="checkbox" aria-label="Seat E5"><span>5</span></label><label class="seat"><input type="checkbox" aria-label="Seat E6"><span>6</span></label><label class="seat"><input type="checkbox" aria-label="Seat E7"><span>7</span></label><label class="seat"><input type="checkbox" aria-label="Seat E8"><span>8</span></label><label class="seat sold"><input type="checkbox" disabled aria-label="Seat E9"><span>9</span></label><label class="seat"><input type="checkbox" aria-label="Seat E10"><span>10</span></label><label class="seat"><input type="checkbox" aria-label="Seat E11"><span>11</span></label><label class="seat"><input type="checkbox" aria-label="Seat E12"><span>12</span></label><label class="seat"><input type="checkbox" aria-label="Seat E13"><span>13</span></label><label class="seat"><input type="checkbox" aria-label="Seat E14"><span>14</span></label><span class="rl" aria-hidden="true">E</span></div>
<div class="row" data-r="F"><span class="rl" aria-hidden="true">F</span><label class="seat"><input type="checkbox" aria-label="Seat F1"><span>1</span></label><label class="seat"><input type="checkbox" aria-label="Seat F2"><span>2</span></label><label class="seat"><input type="checkbox" aria-label="Seat F3"><span>3</span></label><label class="seat"><input type="checkbox" aria-label="Seat F4"><span>4</span></label><label class="seat"><input type="checkbox" aria-label="Seat F5"><span>5</span></label><label class="seat"><input type="checkbox" aria-label="Seat F6"><span>6</span></label><label class="seat"><input type="checkbox" aria-label="Seat F7"><span>7</span></label><label class="seat"><input type="checkbox" aria-label="Seat F8"><span>8</span></label><label class="seat"><input type="checkbox" aria-label="Seat F9"><span>9</span></label><label class="seat sold"><input type="checkbox" disabled aria-label="Seat F10"><span>10</span></label><label class="seat sold"><input type="checkbox" disabled aria-label="Seat F11"><span>11</span></label><label class="seat"><input type="checkbox" aria-label="Seat F12"><span>12</span></label><label class="seat"><input type="checkbox" aria-label="Seat F13"><span>13</span></label><label class="seat"><input type="checkbox" aria-label="Seat F14"><span>14</span></label><span class="rl" aria-hidden="true">F</span></div>
<div class="row" data-r="G"><span class="rl" aria-hidden="true">G</span><label class="seat"><input type="checkbox" aria-label="Seat G1"><span>1</span></label><label class="seat"><input type="checkbox" aria-label="Seat G2"><span>2</span></label><label class="seat"><input type="checkbox" aria-label="Seat G3"><span>3</span></label><label class="seat"><input type="checkbox" aria-label="Seat G4"><span>4</span></label><label class="seat"><input type="checkbox" aria-label="Seat G5"><span>5</span></label><label class="seat"><input type="checkbox" aria-label="Seat G6"><span>6</span></label><label class="seat"><input type="checkbox" aria-label="Seat G7"><span>7</span></label><label class="seat"><input type="checkbox" aria-label="Seat G8"><span>8</span></label><label class="seat"><input type="checkbox" aria-label="Seat G9"><span>9</span></label><label class="seat"><input type="checkbox" aria-label="Seat G10"><span>10</span></label><label class="seat"><input type="checkbox" aria-label="Seat G11"><span>11</span></label><label class="seat"><input type="checkbox" aria-label="Seat G12"><span>12</span></label><label class="seat"><input type="checkbox" aria-label="Seat G13"><span>13</span></label><label class="seat"><input type="checkbox" aria-label="Seat G14"><span>14</span></label><span class="rl" aria-hidden="true">G</span></div>
<div class="row" data-r="H"><span class="rl" aria-hidden="true">H</span><label class="seat"><input type="checkbox" aria-label="Seat H1"><span>1</span></label><label class="seat sold"><input type="checkbox" disabled aria-label="Seat H2"><span>2</span></label><label class="seat"><input type="checkbox" aria-label="Seat H3"><span>3</span></label><label class="seat"><input type="checkbox" aria-label="Seat H4"><span>4</span></label><label class="seat"><input type="checkbox" aria-label="Seat H5"><span>5</span></label><label class="seat"><input type="checkbox" aria-label="Seat H6"><span>6</span></label><label class="seat"><input type="checkbox" aria-label="Seat H7"><span>7</span></label><label class="seat"><input type="checkbox" aria-label="Seat H8"><span>8</span></label><label class="seat"><input type="checkbox" aria-label="Seat H9"><span>9</span></label><label class="seat"><input type="checkbox" aria-label="Seat H10"><span>10</span></label><label class="seat"><input type="checkbox" aria-label="Seat H11"><span>11</span></label><label class="seat"><input type="checkbox" aria-label="Seat H12"><span>12</span></label><label class="seat"><input type="checkbox" aria-label="Seat H13"><span>13</span></label><label class="seat"><input type="checkbox" aria-label="Seat H14"><span>14</span></label><span class="rl" aria-hidden="true">H</span></div>
<div class="row" data-r="I"><span class="rl" aria-hidden="true">I</span><label class="seat"><input type="checkbox" aria-label="Seat I1"><span>1</span></label><label class="seat"><input type="checkbox" aria-label="Seat I2"><span>2</span></label><label class="seat"><input type="checkbox" aria-label="Seat I3"><span>3</span></label><label class="seat"><input type="checkbox" aria-label="Seat I4"><span>4</span></label><label class="seat"><input type="checkbox" aria-label="Seat I5"><span>5</span></label><label class="seat"><input type="checkbox" aria-label="Seat I6"><span>6</span></label><label class="seat"><input type="checkbox" aria-label="Seat I7"><span>7</span></label><label class="seat"><input type="checkbox" aria-label="Seat I8"><span>8</span></label><label class="seat"><input type="checkbox" aria-label="Seat I9"><span>9</span></label><label class="seat"><input type="checkbox" aria-label="Seat I10"><span>10</span></label><label class="seat"><input type="checkbox" aria-label="Seat I11"><span>11</span></label><label class="seat"><input type="checkbox" aria-label="Seat I12"><span>12</span></label><label class="seat"><input type="checkbox" aria-label="Seat I13"><span>13</span></label><label class="seat"><input type="checkbox" aria-label="Seat I14"><span>14</span></label><span class="rl" aria-hidden="true">I</span></div>
<div class="row" data-r="J"><span class="rl" aria-hidden="true">J</span><label class="seat"><input type="checkbox" aria-label="Seat J1"><span>1</span></label><label class="seat"><input type="checkbox" aria-label="Seat J2"><span>2</span></label><label class="seat"><input type="checkbox" aria-label="Seat J3"><span>3</span></label><label class="seat"><input type="checkbox" aria-label="Seat J4"><span>4</span></label><label class="seat"><input type="checkbox" aria-label="Seat J5"><span>5</span></label><label class="seat"><input type="checkbox" aria-label="Seat J6"><span>6</span></label><label class="seat"><input type="checkbox" aria-label="Seat J7"><span>7</span></label><label class="seat"><input type="checkbox" aria-label="Seat J8"><span>8</span></label><label class="seat"><input type="checkbox" aria-label="Seat J9"><span>9</span></label><label class="seat"><input type="checkbox" aria-label="Seat J10"><span>10</span></label><label class="seat"><input type="checkbox" aria-label="Seat J11"><span>11</span></label><label class="seat"><input type="checkbox" aria-label="Seat J12"><span>12</span></label><label class="seat sold"><input type="checkbox" disabled aria-label="Seat J13"><span>13</span></label><label class="seat"><input type="checkbox" aria-label="Seat J14"><span>14</span></label><span class="rl" aria-hidden="true">J</span></div>
<div class="row" data-r="K"><span class="rl" aria-hidden="true">K</span><label class="seat"><input type="checkbox" aria-label="Seat K1"><span>1</span></label><label class="seat"><input type="checkbox" aria-label="Seat K2"><span>2</span></label><label class="seat"><input type="checkbox" aria-label="Seat K3"><span>3</span></label><label class="seat"><input type="checkbox" aria-label="Seat K4"><span>4</span></label><label class="seat"><input type="checkbox" aria-label="Seat K5"><span>5</span></label><label class="seat"><input type="checkbox" aria-label="Seat K6"><span>6</span></label><label class="seat"><input type="checkbox" aria-label="Seat K7"><span>7</span></label><label class="seat sold"><input type="checkbox" disabled aria-label="Seat K8"><span>8</span></label><label class="seat"><input type="checkbox" aria-label="Seat K9"><span>9</span></label><label class="seat"><input type="checkbox" aria-label="Seat K10"><span>10</span></label><label class="seat"><input type="checkbox" aria-label="Seat K11"><span>11</span></label><label class="seat"><input type="checkbox" aria-label="Seat K12"><span>12</span></label><label class="seat"><input type="checkbox" aria-label="Seat K13"><span>13</span></label><label class="seat"><input type="checkbox" aria-label="Seat K14"><span>14</span></label><span class="rl" aria-hidden="true">K</span></div>
<div class="row" data-r="L"><span class="rl" aria-hidden="true">L</span><label class="seat sold"><input type="checkbox" disabled aria-label="Seat L1"><span>1</span></label><label class="seat"><input type="checkbox" aria-label="Seat L2"><span>2</span></label><label class="seat"><input type="checkbox" aria-label="Seat L3"><span>3</span></label><label class="seat"><input type="checkbox" aria-label="Seat L4"><span>4</span></label><label class="seat sold"><input type="checkbox" disabled aria-label="Seat L5"><span>5</span></label><label class="seat"><input type="checkbox" aria-label="Seat L6"><span>6</span></label><label class="seat"><input type="checkbox" aria-label="Seat L7"><span>7</span></label><label class="seat"><input type="checkbox" aria-label="Seat L8"><span>8</span></label><label class="seat"><input type="checkbox" aria-label="Seat L9"><span>9</span></label><label class="seat"><input type="checkbox" aria-label="Seat L10"><span>10</span></label><label class="seat"><input type="checkbox" aria-label="Seat L11"><span>11</span></label><label class="seat"><input type="checkbox" aria-label="Seat L12"><span>12</span></label><label class="seat"><input type="checkbox" aria-label="Seat L13"><span>13</span></label><label class="seat"><input type="checkbox" aria-label="Seat L14"><span>14</span></label><span class="rl" aria-hidden="true">L</span></div>
</div>
<p class="legend">
<span><i class="sw sw-a"></i>Available</span>
<span><i class="sw sw-s"></i>Your picks</span>
<span><i class="sw sw-x"></i>Sold</span>
</p>
</div>
<!-- Lives after the plan in the HTML so the no-JS counters can fill it -->
<p class="strip">Picked here — <span class="cfill" id="strip-one-n"></span> · <span class="d cfill" id="strip-one-usd"></span> · ≈ <span class="d cfill" id="strip-one-eur"></span></p>
</section>
<!-- ============================== SCREEN TWO ============================== -->
<section class="film" id="film-two">
<header class="film-head">
<p class="screen-plate">Screen Two</p>
<!-- PLACEHOLDER film — send me the real programme -->
<h2>The Vermilion Room</h2>
<p class="meta">New release · PG · 117 min · Doors 8:00 PM</p>
<p class="blurb">Lisbon, 1962. A hotel bar, a singer with one name too many, and a detective who orders the same drink every night — until the night he doesn’t.</p>
<label class="when" for="film-2" title="Show this screen’s plan">
<span class="when-time">Today · 8:30 PM</span>
<span class="when-price">All seats $11.50 — after five</span>
</label>
<label class="view-btn" for="film-2">Show Screen Two’s plan</label>
</header>
<div class="plan-wrap" role="group" aria-label="Seat plan — Screen Two, The Vermilion Room, 8:30 PM">
<svg class="screen-arc" viewBox="0 0 640 58" aria-hidden="true" focusable="false">
<path id="arc-b" d="M30 40 Q320 0 610 40" fill="none" stroke="none"/>
<path d="M30 48 Q320 8 610 48" fill="none" stroke="rgba(241,228,200,.4)" stroke-width="2"/>
<path d="M48 54 Q320 22 592 54" fill="none" stroke="rgba(241,228,200,.18)" stroke-width="1.5"/>
<text class="arc-text" text-anchor="middle"><textPath href="#arc-b" startOffset="50%">SCREEN</textPath></text>
</svg>
<p class="plan-hint">Step two — tap seats to add them to your basket</p>
<div class="plan">
<!-- Sold seats, Screen Two: A7–A8, B10, D4, D12, E5–E9, F5–F9, G5–G9, H5–H9, J6, K11, L9. -->
<div class="row" data-r="A"><span class="rl" aria-hidden="true">A</span><label class="seat"><input type="checkbox" aria-label="Seat A1"><span>1</span></label><label class="seat"><input type="checkbox" aria-label="Seat A2"><span>2</span></label><label class="seat"><input type="checkbox" aria-label="Seat A3"><span>3</span></label><label class="seat"><input type="checkbox" aria-label="Seat A4"><span>4</span></label><label class="seat"><input type="checkbox" aria-label="Seat A5"><span>5</span></label><label class="seat"><input type="checkbox" aria-label="Seat A6"><span>6</span></label><label class="seat sold"><input type="checkbox" disabled aria-label="Seat A7"><span>7</span></label><label class="seat sold"><input type="checkbox" disabled aria-label="Seat A8"><span>8</span></label><label class="seat"><input type="checkbox" aria-label="Seat A9"><span>9</span></label><label class="seat"><input type="checkbox" aria-label="Seat A10"><span>10</span></label><label class="seat"><input type="checkbox" aria-label="Seat A11"><span>11</span></label><label class="seat"><input type="checkbox" aria-label="Seat A12"><span>12</span></label><label class="seat"><input type="checkbox" aria-label="Seat A13"><span>13</span></label><label class="seat"><input type="checkbox" aria-label="Seat A14"><span>14</span></label><span class="rl" aria-hidden="true">A</span></div>
<div class="row" data-r="B"><span class="rl" aria-hidden="true">B</span><label class="seat"><input type="checkbox" aria-label="Seat B1"><span>1</span></label><label class="seat"><input type="checkbox" aria-label="Seat B2"><span>2</span></label><label class="seat"><input type="checkbox" aria-label="Seat B3"><span>3</span></label><label class="seat"><input type="checkbox" aria-label="Seat B4"><span>4</span></label><label class="seat"><input type="checkbox" aria-label="Seat B5"><span>5</span></label><label class="seat"><input type="checkbox" aria-label="Seat B6"><span>6</span></label><label class="seat"><input type="checkbox" aria-label="Seat B7"><span>7</span></label><label class="seat"><input type="checkbox" aria-label="Seat B8"><span>8</span></label><label class="seat"><input type="checkbox" aria-label="Seat B9"><span>9</span></label><label class="seat sold"><input type="checkbox" disabled aria-label="Seat B10"><span>10</span></label><label class="seat"><input type="checkbox" aria-label="Seat B11"><span>11</span></label><label class="seat"><input type="checkbox" aria-label="Seat B12"><span>12</span></label><label class="seat"><input type="checkbox" aria-label="Seat B13"><span>13</span></label><label class="seat"><input type="checkbox" aria-label="Seat B14"><span>14</span></label><span class="rl" aria-hidden="true">B</span></div>
<div class="row" data-r="C"><span class="rl" aria-hidden="true">C</span><label class="seat"><input type="checkbox" aria-label="Seat C1"><span>1</span></label><label class="seat"><input type="checkbox" aria-label="Seat C2"><span>2</span></label><label class="seat"><input type="checkbox" aria-label="Seat C3"><span>3</span></label><label class="seat"><input type="checkbox" aria-label="Seat C4"><span>4</span></label><label class="seat"><input type="checkbox" aria-label="Seat C5"><span>5</span></label><label class="seat"><input type="checkbox" aria-label="Seat C6"><span>6</span></label><label class="seat"><input type="checkbox" aria-label="Seat C7"><span>7</span></label><label class="seat"><input type="checkbox" aria-label="Seat C8"><span>8</span></label><label class="seat"><input type="checkbox" aria-label="Seat C9"><span>9</span></label><label class="seat"><input type="checkbox" aria-label="Seat C10"><span>10</span></label><label class="seat"><input type="checkbox" aria-label="Seat C11"><span>11</span></label><label class="seat"><input type="checkbox" aria-label="Seat C12"><span>12</span></label><label class="seat"><input type="checkbox" aria-label="Seat C13"><span>13</span></label><label class="seat"><input type="checkbox" aria-label="Seat C14"><span>14</span></label><span class="rl" aria-hidden="true">C</span></div>
<div class="row" data-r="D"><span class="rl" aria-hidden="true">D</span><label class="seat"><input type="checkbox" aria-label="Seat D1"><span>1</span></label><label class="seat"><input type="checkbox" aria-label="Seat D2"><span>2</span></label><label class="seat"><input type="checkbox" aria-label="Seat D3"><span>3</span></label><label class="seat sold"><input type="checkbox" disabled aria-label="Seat D4"><span>4</span></label><label class="seat"><input type="checkbox" aria-label="Seat D5"><span>5</span></label><label class="seat"><input type="checkbox" aria-label="Seat D6"><span>6</span></label><label class="seat"><input type="checkbox" aria-label="Seat D7"><span>7</span></label><label class="seat"><input type="checkbox" aria-label="Seat D8"><span>8</span></label><label class="seat"><input type="checkbox" aria-label="Seat D9"><span>9</span></label><label class="seat"><input type="checkbox" aria-label="Seat D10"><span>10</span></label><label class="seat"><input type="checkbox" aria-label="Seat D11"><span>11</span></label><label class="seat sold"><input type="checkbox" disabled aria-label="Seat D12"><span>12</span></label><label class="seat"><input type="checkbox" aria-label="Seat D13"><span>13</span></label><label class="seat"><input type="checkbox" aria-label="Seat D14"><span>14</span></label><span class="rl" aria-hidden="true">D</span></div>
<div class="row" data-r="E"><span class="rl" aria-hidden="true">E</span><label class="seat"><input type="checkbox" aria-label="Seat E1"><span>1</span></label><label class="seat"><input type="checkbox" aria-label="Seat E2"><span>2</span></label><label class="seat"><input type="checkbox" aria-label="Seat E3"><span>3</span></label><label class="seat"><input type="checkbox" aria-label="Seat E4"><span>4</span></label><label class="seat sold"><input type="checkbox" disabled aria-label="Seat E5"><span>5</span></label><label class="seat sold"><input type="checkbox" disabled aria-label="Seat E6"><span>6</span></label><label class="seat sold"><input type="checkbox" disabled aria-label="Seat E7"><span>7</span></label><label class="seat sold"><input type="checkbox" disabled aria-label="Seat E8"><span>8</span></label><label class="seat sold"><input type="checkbox" disabled aria-label="Seat E9"><span>9</span></label><label class="seat"><input type="checkbox" aria-label="Seat E10"><span>10</span></label><label class="seat"><input type="checkbox" aria-label="Seat E11"><span>11</span></label><label class="seat"><input type="checkbox" aria-label="Seat E12"><span>12</span></label><label class="seat"><input type="checkbox" aria-label="Seat E13"><span>13</span></label><label class="seat"><input type="checkbox" aria-label="Seat E14"><span>14</span></label><span class="rl" aria-hidden="true">E</span></div>
<div class="row" data-r="F"><span class="rl" aria-hidden="true">F</span><label class="seat"><input type="checkbox" aria-label="Seat F1"><span>1</span></label><label class="seat"><input type="checkbox" aria-label="Seat F2"><span>2</span></label><label class="seat"><input type="checkbox" aria-label="Seat F3"><span>3</span></label><label class="seat"><input type="checkbox" aria-label="Seat F4"><span>4</span></label><label class="seat sold"><input type="checkbox" disabled aria-label="Seat F5"><span>5</span></label><label class="seat sold"><input type="checkbox" disabled aria-label="Seat F6"><span>6</span></label><label class="seat sold"><input type="checkbox" disabled aria-label="Seat F7"><span>7</span></label><label class="seat sold"><input type="checkbox" disabled aria-label="Seat F8"><span>8</span></label><label class="seat sold"><input type="checkbox" disabled aria-label="Seat F9"><span>9</span></label><label class="seat"><input type="checkbox" aria-label="Seat F10"><span>10</span></label><label class="seat"><input type="checkbox" aria-label="Seat F11"><span>11</span></label><label class="seat"><input type="checkbox" aria-label="Seat F12"><span>12</span></label><label class="seat"><input type="checkbox" aria-label="Seat F13"><span>13</span></label><label class="seat"><input type="checkbox" aria-label="Seat F14"><span>14</span></label><span class="rl" aria-hidden="true">F</span></div>
<div class="row" data-r="G"><span class="rl" aria-hidden="true">G</span><label class="seat"><input type="checkbox" aria-label="Seat G1"><span>1</span></label><label class="seat"><input type="checkbox" aria-label="Seat G2"><span>2</span></label><label class="seat"><input type="checkbox" aria-label="Seat G3"><span>3</span></label><label class="seat"><input type="checkbox" aria-label="Seat G4"><span>4</span></label><label class="seat sold"><input type="checkbox" disabled aria-label="Seat G5"><span>5</span></label><label class="seat sold"><input type="checkbox" disabled aria-label="Seat G6"><span>6</span></label><label class="seat sold"><input type="checkbox" disabled aria-label="Seat G7"><span>7</span></label><label class="seat sold"><input type="checkbox" disabled aria-label="Seat G8"><span>8</span></label><label class="seat sold"><input type="checkbox" disabled aria-label="Seat G9"><span>9</span></label><label class="seat"><input type="checkbox" aria-label="Seat G10"><span>10</span></label><label class="seat"><input type="checkbox" aria-label="Seat G11"><span>11</span></label><label class="seat"><input type="checkbox" aria-label="Seat G12"><span>12</span></label><label class="seat"><input type="checkbox" aria-label="Seat G13"><span>13</span></label><label class="seat"><input type="checkbox" aria-label="Seat G14"><span>14</span></label><span class="rl" aria-hidden="true">G</span></div>
<div class="row" data-r="H"><span class="rl" aria-hidden="true">H</span><label class="seat"><input type="checkbox" aria-label="Seat H1"><span>1</span></label><label class="seat"><input type="checkbox" aria-label="Seat H2"><span>2</span></label><label class="seat"><input type="checkbox" aria-label="Seat H3"><span>3</span></label><label class="seat"><input type="checkbox" aria-label="Seat H4"><span>4</span></label><label class="seat sold"><input type="checkbox" disabled aria-label="Seat H5"><span>5</span></label><label class="seat sold"><input type="checkbox" disabled aria-label="Seat H6"><span>6</span></label><label class="seat sold"><input type="checkbox" disabled aria-label="Seat H7"><span>7</span></label><label class="seat sold"><input type="checkbox" disabled aria-label="Seat H8"><span>8</span></label><label class="seat sold"><input type="checkbox" disabled aria-label="Seat H9"><span>9</span></label><label class="seat"><input type="checkbox" aria-label="Seat H10"><span>10</span></label><label class="seat"><input type="checkbox" aria-label="Seat H11"><span>11</span></label><label class="seat"><input type="checkbox" aria-label="Seat H12"><span>12</span></label><label class="seat"><input type="checkbox" aria-label="Seat H13"><span>13</span></label><label class="seat"><input type="checkbox" aria-label="Seat H14"><span>14</span></label><span class="rl" aria-hidden="true">H</span></div>
<div class="row" data-r="I"><span class="rl" aria-hidden="true">I</span><label class="seat"><input type="checkbox" aria-label="Seat I1"><span>1</span></label><label class="seat"><input type="checkbox" aria-label="Seat I2"><span>2</span></label><label class="seat"><input type="checkbox" aria-label="Seat I3"><span>3</span></label><label class="seat"><input type="checkbox" aria-label="Seat I4"><span>4</span></label><label class="seat"><input type="checkbox" aria-label="Seat I5"><span>5</span></label><label class="seat"><input type="checkbox" aria-label="Seat I6"><span>6</span></label><label class="seat"><input type="checkbox" aria-label="Seat I7"><span>7</span></label><label class="seat"><input type="checkbox" aria-label="Seat I8"><span>8</span></label><label class="seat"><input type="checkbox" aria-label="Seat I9"><span>9</span></label><label class="seat"><input type="checkbox" aria-label="Seat I10"><span>10</span></label><label class="seat"><input type="checkbox" aria-label="Seat I11"><span>11</span></label><label class="seat"><input type="checkbox" aria-label="Seat I12"><span>12</span></label><label class="seat"><input type="checkbox" aria-label="Seat I13"><span>13</span></label><label class="seat"><input type="checkbox" aria-label="Seat I14"><span>14</span></label><span class="rl" aria-hidden="true">I</span></div>
<div class="row" data-r="J"><span class="rl" aria-hidden="true">J</span><label class="seat"><input type="checkbox" aria-label="Seat J1"><span>1</span></label><label class="seat"><input type="checkbox" aria-label="Seat J2"><span>2</span></label><label class="seat"><input type="checkbox" aria-label="Seat J3"><span>3</span></label><label class="seat"><input type="checkbox" aria-label="Seat J4"><span>4</span></label><label class="seat"><input type="checkbox" aria-label="Seat J5"><span>5</span></label><label class="seat sold"><input type="checkbox" disabled aria-label="Seat J6"><span>6</span></label><label class="seat"><input type="checkbox" aria-label="Seat J7"><span>7</span></label><label class="seat"><input type="checkbox" aria-label="Seat J8"><span>8</span></label><label class="seat"><input type="checkbox" aria-label="Seat J9"><span>9</span></label><label class="seat"><input type="checkbox" aria-label="Seat J10"><span>10</span></label><label class="seat"><input type="checkbox" aria-label="Seat J11"><span>11</span></label><label class="seat"><input type="checkbox" aria-label="Seat J12"><span>12</span></label><label class="seat"><input type="checkbox" aria-label="Seat J13"><span>13</span></label><label class="seat"><input type="checkbox" aria-label="Seat J14"><span>14</span></label><span class="rl" aria-hidden="true">J</span></div>
<div class="row" data-r="K"><span class="rl" aria-hidden="true">K</span><label class="seat"><input type="checkbox" aria-label="Seat K1"><span>1</span></label><label class="seat"><input type="checkbox" aria-label="Seat K2"><span>2</span></label><label class="seat"><input type="checkbox" aria-label="Seat K3"><span>3</span></label><label class="seat"><input type="checkbox" aria-label="Seat K4"><span>4</span></label><label class="seat"><input type="checkbox" aria-label="Seat K5"><span>5</span></label><label class="seat"><input type="checkbox" aria-label="Seat K6"><span>6</span></label><label class="seat"><input type="checkbox" aria-label="Seat K7"><span>7</span></label><label class="seat"><input type="checkbox" aria-label="Seat K8"><span>8</span></label><label class="seat"><input type="checkbox" aria-label="Seat K9"><span>9</span></label><label class="seat"><input type="checkbox" aria-label="Seat K10"><span>10</span></label><label class="seat sold"><input type="checkbox" disabled aria-label="Seat K11"><span>11</span></label><label class="seat"><input type="checkbox" aria-label="Seat K12"><span>12</span></label><label class="seat"><input type="checkbox" aria-label="Seat K13"><span>13</span></label><label class="seat"><input type="checkbox" aria-label="Seat K14"><span>14</span></label><span class="rl" aria-hidden="true">K</span></div>
<div class="row" data-r="L"><span class="rl" aria-hidden="true">L</span><label class="seat"><input type="checkbox" aria-label="Seat L1"><span>1</span></label><label class="seat"><input type="checkbox" aria-label="Seat L2"><span>2</span></label><label class="seat"><input type="checkbox" aria-label="Seat L3"><span>3</span></label><label class="seat"><input type="checkbox" aria-label="Seat L4"><span>4</span></label><label class="seat"><input type="checkbox" aria-label="Seat L5"><span>5</span></label><label class="seat"><input type="checkbox" aria-label="Seat L6"><span>6</span></label><label class="seat"><input type="checkbox" aria-label="Seat L7"><span>7</span></label><label class="seat"><input type="checkbox" aria-label="Seat L8"><span>8</span></label><label class="seat sold"><input type="checkbox" disabled aria-label="Seat L9"><span>9</span></label><label class="seat"><input type="checkbox" aria-label="Seat L10"><span>10</span></label><label class="seat"><input type="checkbox" aria-label="Seat L11"><span>11</span></label><label class="seat"><input type="checkbox" aria-label="Seat L12"><span>12</span></label><label class="seat"><input type="checkbox" aria-label="Seat L13"><span>13</span></label><label class="seat"><input type="checkbox" aria-label="Seat L14"><span>14</span></label><span class="rl" aria-hidden="true">L</span></div>
</div>
<p class="legend">
<span><i class="sw sw-a"></i>Available</span>
<span><i class="sw sw-s"></i>Your picks</span>
<span><i class="sw sw-x"></i>Sold</span>
</p>
</div>
<p class="strip">Picked here — <span class="cfill" id="strip-two-n"></span> · <span class="d cfill" id="strip-two-usd"></span> · ≈ <span class="d cfill" id="strip-two-eur"></span></p>
</section>
</form>
<!-- The till: basket circle (as printed) + the running totals and the euro rate -->
<div class="till">
<div class="till-read">
<p class="till-label">Total</p>
<p class="till-line"><span class="d cfill till-usd" id="till-usd"></span></p>
<p class="till-eur">≈ <span class="d cfill" id="till-eur"></span> <span class="till-rate">· €1 = $1.09 fixed</span></p>
</div>
<a class="basket" id="basket-btn" href="#basket" aria-controls="basket-panel" aria-expanded="false" title="Your basket — seats, total, euros">
<span class="cfill" id="badge-n"></span>
</a>
</div>
<!-- Basket dropdown (JavaScript opens it; without JS the circle jumps to the box office below) -->
<div class="panel" id="basket-panel" hidden>
<h3>Your basket</h3>
<div id="panel-list"></div>
<p class="panel-tot">Seats: <span class="cfill" id="panel-n"></span> — <span class="d cfill" id="panel-usd"></span> · ≈ <span class="d cfill" id="panel-eur"></span></p>
<div class="panel-actions">
<button type="button" class="btn js-reserve js-only">Reserve — pay at counter</button>
<button type="button" class="btn ghost js-clear js-only">Clear all</button>
</div>
</div>
<!-- Box office review — the paper the counter would see -->
<section class="box" id="basket">
<h2>Box office — review & reserve</h2>
<p class="box-sub">Your picks for tonight, exactly as the counter will see them.</p>
<div class="box-list" id="box-list">
<p class="bl-empty">Seat names appear here when JavaScript is on. Your count and totals are exact either way — they’re computed without it.</p>
</div>
<div class="box-totals">
<p class="trow"><span>Seats picked</span><i class="dots"></i><span class="cfill" id="box-n"></span></p>
<p class="trow"><span>Total, US dollars</span><i class="dots"></i><span class="d cfill" id="box-usd"></span></p>
<p class="trow"><span>In euros, about</span><i class="dots"></i><span>≈ <span class="d cfill" id="box-eur"></span></span></p>
<p class="trow rate"><span>Euro rate</span><i class="dots"></i><span>€1 = $1.09 · fixed offline</span></p>
</div>
<div class="box-actions">
<button type="button" class="btn js-reserve js-only">Reserve — pay at the counter</button>
<button type="button" class="btn ghost js-clear js-only">Clear all</button>
</div>
<p class="box-fine">This page runs entirely on the machine in front of you — nothing is sent anywhere and nothing is stored. Show your picks at the counter; they’ll mark the seats sold and take payment there.</p>
</section>
<footer class="foot">
<p>The Bijou · two screens · est. 1938</p>
<p>Seats $8.00 before 5:00 PM · $11.50 at 5:00 PM and after · Euro rate held offline: €1 = $1.09</p>
</footer>
<!-- The reservation stub -->
<div class="modal" id="stub-modal" hidden>
<div class="modal-backdrop"></div>
<div class="stub-wrap">
<div class="stub" role="dialog" aria-modal="true" aria-labelledby="stub-h">
<div class="stub-main">
<p class="stub-brand">The Bijou · Admit</p>
<h3 id="stub-h">Seats set aside — pay at the counter</h3>
<div id="stub-body"></div>
<p class="stub-tot" id="stub-tot"></p>
<p class="stub-fine">Nothing is charged online — this page never touches the internet. Bring this stub to the counter; the box office marks your seats sold and takes payment there.</p>
</div>
<div class="stub-tear" aria-hidden="true">
<span class="vert">Admit one</span>
<span class="stub-ref" id="stub-ref"></span>
<span class="barcode"></span>
</div>
</div>
<div class="modal-actions">
<button type="button" class="btn" id="print-btn">Print stub</button>
<button type="button" class="btn ghost" id="stub-done" data-close>Done</button>
</div>
</div>
</div>
<p class="sr" aria-live="polite" id="live"></p>
<noscript>
<style>
.nojs-hint{display:block!important}
/* Without :has() the tickets can't switch plans, so show both plans and drop the picker */
@supports not selector(:has(*)){.picker{display:none}}
</style>
</noscript>
<script>
(function () {
'use strict';
document.documentElement.classList.add('js');
/* ---- constants (see the notes at the very top of this file) ---- */
var RATE = 1.09; /* USD per EUR 1 — pinned, offline */
/* COUNTER-PRICES: keep in step with the two counter-increment rules in the CSS */
var PRICE = { 'film-one': 800, 'film-two': 1150 }; /* US cents per seat */
var EURO = { 'film-one': 734, 'film-two': 1055 }; /* euro cents per seat = Math.round(PRICE / RATE) */
var FILM = {
'film-one': { screen: 'Screen One', title: 'The Clockmaker\u2019s Waltz', time: '4:45 PM' },
'film-two': { screen: 'Screen Two', title: 'The Vermilion Room', time: '8:30 PM' }
};
function $(s, r) { return (r || document).querySelector(s); }
function $all(s, r) { return Array.prototype.slice.call((r || document).querySelectorAll(s)); }
var reduceMotion = window.matchMedia && window.matchMedia('(prefers-reduced-motion: reduce)').matches;
/* ---- elements ---- */
var form = $('#booking');
var seats = $all('.seat input[type="checkbox"]', form);
var filmRadios= $all('input[name="film"]', form);
var basketBtn = $('#basket-btn');
var panel = $('#basket-panel'), panelList = $('#panel-list');
var badgeN = $('#badge-n');
var tillUsd = $('#till-usd'), tillEur = $('#till-eur');
var boxN = $('#box-n'), boxUsd = $('#box-usd'), boxEur = $('#box-eur'), boxList = $('#box-list');
var panelN = $('#panel-n'), panelUsd = $('#panel-usd'), panelEur = $('#panel-eur');
var strips = {
'film-one': { n: $('#strip-one-n'), usd: $('#strip-one-usd'), eur: $('#strip-one-eur') },
'film-two': { n: $('#strip-two-n'), usd: $('#strip-two-usd'), eur: $('#strip-two-eur') }
};
var live = $('#live'), todayEl = $('#today');
var modal = $('#stub-modal'), stubBody = $('#stub-body'), stubTot = $('#stub-tot'), stubRef = $('#stub-ref');
var lastState = null, prevCount = 0, lastFocus = null, armTimer = 0;
function seatName(el) {
return el.closest('.row').getAttribute('data-r') + el.nextElementSibling.textContent.trim();
}
function readState() {
var st = { count: 0, usd: 0, eur: 0, films: {} }, id;
for (id in FILM) st.films[id] = { n: 0, usd: 0, eur: 0, els: [] };
seats.forEach(function (el) {
if (!el.checked) return;
var f = st.films[el.closest('.film').id];
f.els.push(el); f.n++; f.usd += PRICE[f && idOf(el)]; f.eur += EURO[idOf(el)];
st.count++; st.usd += PRICE[idOf(el)]; st.eur += EURO[idOf(el)];
});
return st;
function idOf(el) { return el.closest('.film').id; }
}
/* ---- the count-up: the total glides to its new number, never jumps ---- */
function shown(el) { return parseInt((el.textContent || '').replace(/[^0-9]/g, ''), 10) || 0; }
function setMoney(el, cents, cur, instant) {
var fmt = cur === 'usd' ? function (c) { return '$' + c; } : function (c) { return '\u20AC' + c; };
if (el._raf) { cancelAnimationFrame(el._raf); el._raf = 0; }
var from = shown(el);
if (instant || reduceMotion || from === cents) { el.textContent = fmt(cents); return; }
var t0 = performance.now(), dur = 650, delta = cents - from;
var step = function (now) {
var p = Math.min(1, (now - t0) / dur);
var e = p < .5 ? 4 * p * p * p : 1 - Math.pow(-2 * p + 2, 3) / 2; /* easeInOutCubic */
el.textContent = fmt(Math.round(from + delta * e));
el._raf = p < 1 ? requestAnimationFrame(step) : 0;
};
el._raf = requestAnimationFrame(step);
}
function fullUsd(c) { return '$' + (c / 100).toFixed(2); }
function fullEur(c) { return '\u20AC' + (c / 100).toFixed(2); }
function listHTML(st) {
var h = '';
for (var id in FILM) {
var f = st.films[id]; if (!f.n) continue;
h += '<div class="bl-group"><h4>' + FILM[id].screen + ' \u00B7 ' + FILM[id].time + '</h4><div class="bl-seats">';
f.els.forEach(function (el, i) {
var nm = seatName(el);
h += '<button type="button" class="bl-seat" data-film="' + id + '" data-i="' + i +
'" title="Remove seat ' + nm + '" aria-label="Remove seat ' + nm + '">' + nm +
'<i aria-hidden="true">\u00D7</i></button>';
});
h += '</div></div>';
}
return h || '<p class="bl-empty">No seats yet \u2014 choose a film, then tap seats on its plan.</p>';
}
function render(instant) {
var st = readState(); lastState = st;
badgeN.textContent = st.count;
if (st.count !== prevCount) { /* the badge pop — "see it went in" */
basketBtn.classList.remove('pop'); void basketBtn.offsetWidth; basketBtn.classList.add('pop');
}
prevCount = st.count;
setMoney(tillUsd, st.usd, 'usd', instant);
setMoney(tillEur, st.eur, 'eur', instant);
for (var id in FILM) {
var f = st.films[id], s = strips[id];
s.n.textContent = f.n;
setMoney(s.usd, f.usd, 'usd', instant);
setMoney(s.eur, f.eur, 'eur', instant);
}
boxN.textContent = st.count; panelN.textContent = st.count;
setMoney(boxUsd, st.usd, 'usd', instant); setMoney(boxEur, st.eur, 'eur', instant);
setMoney(panelUsd, st.usd, 'usd', instant); setMoney(panelEur, st.eur, 'eur', instant);
var html = listHTML(st);
panelList.innerHTML = html; boxList.innerHTML = html;
$all('.js-reserve').forEach(function (b) { b.disabled = !st.count; });
$all('.js-clear').forEach(function (b) { b.disabled = !st.count; });
live.textContent = st.count
? st.count + (st.count === 1 ? ' seat' : ' seats') + ' picked \u2014 ' + fullUsd(st.usd) + ', about ' + fullEur(st.eur)
: 'No seats picked';
}
/* ---- film switching ---- */
function setFilm(value, scroll) {
document.body.setAttribute('data-film', value);
closePanel();
if (scroll) {
var plan = $('#' + value + ' .plan-wrap');
if (plan) setTimeout(function () {
plan.scrollIntoView({ behavior: reduceMotion ? 'auto' : 'smooth', block: 'start' });
}, 60);
}
}
filmRadios.forEach(function (r) {
r.addEventListener('change', function () { if (r.checked) setFilm(r.value, true); });
});
form.addEventListener('change', function (e) {
if (e.target && e.target.type === 'checkbox') render();
});
/* ---- basket panel ---- */
function openPanel() { panel.hidden = false; basketBtn.setAttribute('aria-expanded', 'true'); }
function closePanel() { if (panel.hidden) return; panel.hidden = true; basketBtn.setAttribute('aria-expanded', 'false'); }
basketBtn.addEventListener('click', function (e) {
e.preventDefault();
if (panel.hidden) openPanel(); else closePanel();
});
document.addEventListener('click', function (e) {
if (!panel.hidden && !panel.contains(e.target) && !basketBtn.contains(e.target)) closePanel();
});
/* ---- tap a seat name in a list to let it go ---- */
[panelList, boxList].forEach(function (list) {
list.addEventListener('click', function (e) {
var b = e.target.closest('.bl-seat'); if (!b || !lastState) return;
var f = lastState.films[b.getAttribute('data-film')];
var el = f && f.els[+b.getAttribute('data-i')];
if (el) { el.checked = false; render(); }
});
});
/* ---- clear all: two-step on the button itself, no confirm() dialogs ---- */
function disarm() {
$all('.js-clear').forEach(function (b) { b.removeAttribute('data-armed'); b.textContent = 'Clear all'; });
clearTimeout(armTimer);
}
$all('.js-clear').forEach(function (b) {
b.addEventListener('click', function () {
if (b.getAttribute('data-armed')) {
seats.forEach(function (s) { s.checked = false; });
disarm(); render();
} else {
$all('.js-clear').forEach(function (x) { x.setAttribute('data-armed', '1'); x.textContent = 'Really clear?'; });
clearTimeout(armTimer); armTimer = setTimeout(disarm, 2600);
}
});
});
/* ---- the reservation stub ---- */
function openStub() {
var st = readState(); if (!st.count) return;
var body = '';
for (var id in FILM) {
var f = st.films[id]; if (!f.n) continue;
body += '<div class="sg"><p class="sg-a">' + FILM[id].screen + ' \u00B7 ' + FILM[id].time + '</p>' +
'<p class="sg-b">' + FILM[id].title + '</p>' +
'<p class="sg-c">Seats ' + f.els.map(seatName).join(', ') + '</p></div>';
}
stubBody.innerHTML = body;
stubTot.textContent = st.count + (st.count === 1 ? ' seat' : ' seats') + ' \u2014 ' + fullUsd(st.usd) +
' \u00B7 about ' + fullEur(st.eur) + ' (\u20AC1 = $' + RATE.toFixed(2) + ' fixed)';
stubRef.textContent = 'BJ-' + Date.now().toString(36).slice(-4).toUpperCase() + '-' + ('0' + st.count).slice(-2);
lastFocus = document.activeElement;
modal.hidden = false;
document.body.classList.add('stub-open');
$('#stub-done').focus();
}
function closeModal() {
if (modal.hidden) return;
modal.hidden = true;
document.body.classList.remove('stub-open');
if (lastFocus && lastFocus.focus) lastFocus.focus();
}
$all('.js-reserve').forEach(function (b) { b.addEventListener('click', openStub); });
modal.addEventListener('click', function (e) {
if (e.target.classList.contains('modal-backdrop') || e.target.closest('[data-close]')) closeModal();
});
$('#print-btn').addEventListener('click', function () { window.print(); });
document.addEventListener('keydown', function (e) {
if (e.key === 'Escape') { closeModal(); closePanel(); return; }
if (e.key === 'Tab' && !modal.hidden) { /* keep focus on the stub */
var f = $all('#stub-modal button').filter(function (b) { return !b.disabled; });
if (!f.length) return;
var first = f[0], last = f[f.length - 1];
if (e.shiftKey && document.activeElement === first) { last.focus(); e.preventDefault(); }
else if (!e.shiftKey && document.activeElement === last) { first.focus(); e.preventDefault(); }
}
});
/* ---- init ---- */
var checked = filmRadios.filter(function (r) { return r.checked; })[0];
if (checked) document.body.setAttribute('data-film', checked.value);
render(true);
if (todayEl) {
var d = new Date();
todayEl.textContent = ' \u00B7 ' + d.toLocaleDateString(undefined, { weekday: 'long', day: 'numeric', month: 'long' });
}
/* Only now, with everything safely standing, hand the numbers from CSS to JS.
If anything above failed, this never runs — and the pure-CSS totals keep working. */
document.documentElement.classList.add('js');
})();
</script>
</body>
</html>