/* Public event page (U-011): one column, phone first. Colours come from the app's tokens (styles.css). */
.tn{max-width:560px;margin:0 auto;padding:20px 16px 48px;display:grid;gap:16px}
.tn-brand{display:flex;align-items:center;gap:10px;font-weight:600}
.tn-brand .brand-mark{width:32px;height:32px;font-size:19px;border-radius:9px}
.light .tn-brand .brand-mark{background:var(--brand);color:#fff}
.tn-event h1{font-size:30px;letter-spacing:-.8px;margin:4px 0 8px}
.tn-event p{color:var(--muted);font-size:13px}
.tn-event .tn-club{color:var(--accent-text);font-weight:600;font-size:12px;letter-spacing:.3px;text-transform:uppercase}
.tn-ref{margin-top:6px}
/* «Te invita …» (visual-publico-19, 2026-10-26): the RRPP's name links to their page. */
.tn-ref .tn-link{display:inline-block;min-height:24px;padding-block:3px}
/* The event's sheet (V-02, N-10): poster, description, music, dress code, where and a phone. */
.tn-poster{display:block;width:100%;max-width:360px;aspect-ratio:1;object-fit:cover;border-radius:14px;margin:0 0 14px;background:var(--panel)}
.tn-age{display:inline-block;padding:1px 7px;border:1px solid var(--line);border-radius:999px;color:var(--text);font-weight:600}
.tn-sheet{display:grid;gap:6px;margin-top:10px}
.tn-sheet p{margin:0}
.tn-event .tn-desc{color:var(--text);white-space:pre-line}
.tn-tags{list-style:none;margin:2px 0;padding:0;display:flex;flex-wrap:wrap;gap:6px}
.tn-tags li{padding:3px 10px;border:1px solid var(--line);border-radius:999px;font-size:12px;color:var(--muted)}
.tn-tags .tn-artist{color:var(--text);font-weight:600}
.tn-card{background:var(--panel);border:1px solid var(--line);border-radius:14px;padding:18px;display:grid;gap:14px}
.tn-card h2{font-size:18px}
.tn-zones{list-style:none;margin:0;padding:0;display:grid;gap:8px}
.tn-zones li{display:flex;align-items:center;gap:12px;padding:10px 12px;border:1px solid var(--line);border-radius:10px}
.tn-zones li>div{flex:1;min-width:0;display:grid;gap:2px}
.tn-zones small{color:var(--muted)}
.tn-zones b{font-size:12px;white-space:nowrap}
.tn-zones b.tn-full{color:var(--danger)}
.tn-dot{width:10px;height:10px;border-radius:50%;background:var(--zone,var(--accent));flex:none}
.tn-form{display:grid;gap:12px}
.tn-form .field input,.tn-form .field select{width:100%;font-size:15px}
.tn-check{display:flex;gap:10px;align-items:flex-start;font-size:13px}
.tn-check input{width:18px;height:18px;margin-top:2px;accent-color:var(--accent);flex:none}
.tn-check span,.tn-help,.tn-foot{color:var(--muted);font-size:12px}
.tn-conditions{font-size:12px;color:var(--muted)}
/* Consent on every form (2026-10-25): the boxes, then the club's privacy policy one tap away. */
.tn-consent{display:grid;gap:10px}
.tn-privacy{margin:0;font-size:12px}
.tn-privacy .tn-link{display:inline-block;min-height:24px;padding-block:3px}
.tn-form .form-error{margin:0;min-height:0}
.tn-form .form-error:empty{display:none}
/* What to correct in a field (2026-10-28), right under it: half the form's gap from the field it belongs to, whose edge
   takes the error colour while it is marked invalid; the words say it, the colour only backs them up. */
.tn-form .field-error{margin-top:-6px}
.tn-form .field input[aria-invalid="true"]{border-color:var(--danger)}
.tn-done{border-color:var(--accent);text-align:center}
.tn-done h2:focus{outline:none}
.tn-qr{display:grid;place-items:center}
.tn-qr svg{width:180px;height:180px;background:#fff;padding:10px;border-radius:10px}
.tn-code{font-size:22px;letter-spacing:3px;font-weight:650;color:var(--accent-text)}
/* A table request's state before its QR (2026-10-25), in words; the colour only backs them up. */
.tn-state{justify-self:center;margin:0;padding:6px 12px;border:1px solid color-mix(in srgb,var(--tn-state) 60%,var(--line));border-radius:999px;background:color-mix(in srgb,var(--tn-state) 12%,var(--panel));color:var(--text);font-size:14px;font-weight:700}
.tn-state.pending,.tn-state.due{--tn-state:var(--warn)}
.tn-state.confirmed{--tn-state:var(--ok)}
/* Keeping the entry (visual-publico-09 and visual-publico-16, 2026-10-25): under the result, its link, the calendar and
   the way there; at the top of the event's and the club's page, the codes this browser remembers, each with its ticket. */
.tn-keep{display:flex;flex-wrap:wrap;justify-content:center;gap:8px}
.tn-keep .btn{flex:1 1 200px}
.tn-keep-url{margin:0;overflow-wrap:anywhere}
.tn-keep-url span{color:var(--text);user-select:all}
.tn-mine{padding:12px 14px;gap:8px}
.tn-mine ul{list-style:none;margin:0;padding:0;display:grid;gap:8px}
.tn-mine li{display:flex;align-items:center;gap:12px}
.tn-mine li+li{padding-top:8px;border-top:1px solid var(--line)}
.tn-mine li>div{flex:1;min-width:0;display:grid;gap:2px}
.tn-mine small{color:var(--muted);font-size:12px;overflow-wrap:anywhere}
.tn-mine-code{color:var(--text);font-weight:650;letter-spacing:1px}
.tn-mine .btn{flex:none;min-height:40px}
/* A line's state from its ticket (review of block 23, 2026-10-25), in words; the dot only backs them up. */
.tn-mine-state{color:var(--text);font-weight:650}
.tn-mine-state::before{content:'';display:inline-block;width:8px;height:8px;margin-right:6px;border-radius:50%;background:var(--tn-state,var(--off));vertical-align:1px}
.tn-mine-state.pending,.tn-mine-state.due{--tn-state:var(--warn)}
.tn-mine-state.confirmed{--tn-state:var(--ok)}
.tn-mine-state.out{--tn-state:var(--err)}
/* Club page and table picker (U-016) */
.tn-events{list-style:none;margin:0;padding:0;display:grid;gap:10px}
.tn-event-link{display:flex;align-items:center;gap:14px;text-decoration:none;color:inherit}
.tn-event-link:hover{border-color:var(--accent)}
.tn-event-link small{display:block;color:var(--muted);margin-top:2px}
.tn-date{display:grid;place-items:center;min-width:52px;padding:6px 0;border-radius:10px;background:var(--raised);font-size:11px;text-transform:uppercase;color:var(--muted)}
.tn-date b{font-size:20px;color:var(--text);line-height:1.1}
.tn-link{border:0;background:none;padding:0;color:var(--accent-text);text-decoration:underline;font:inherit;cursor:pointer}
.tn-plan{display:grid;gap:8px}
/* The plan (visual-publico-11, 2026-10-26): tienda.js places and sizes each table in % of the part of the floor it
   draws (SPOT), zoomed to the chosen zone when its tables would be under 44 px; the zoomed map clips its edges. */
.tn-map{position:relative;aspect-ratio:3/3.6;width:100%;background:var(--ink);border:1px solid var(--line);border-radius:12px}
.tn-map.zoom{overflow:hidden}
/* By shape, as on the staff's plans; the map is dark in both themes (--map-*). Free: the outline of its zone's colour.
   Chosen: filled with that colour inside a 3 px white ring, with «✓». Not available: striped, with light stripes and a
   3:1 edge of its own (--map-stripes, --map-off-line), as the staff's stripes vanish on its dark fill (2026-10-28). */
.tn-spot{position:absolute;display:flex;align-items:center;justify-content:center;gap:1px;padding:0;border:2px solid var(--zone);border-radius:4px;background:color-mix(in srgb,var(--zone) 14%,var(--ink));color:var(--map-text);font-size:11px;font-weight:700;min-width:24px;min-height:24px}
.tn-spot.round{border-radius:50%}
.tn-spot.off{border:1px solid var(--map-off-line);background:var(--map-off) var(--map-stripes);color:var(--map-off-text);opacity:1}
.tn-spot.on{background:var(--zone);color:var(--ink);box-shadow:0 0 0 3px var(--map-text)}
.tn-spot.on::after,.tn-legend i.on::after{content:"✓"}
.tn-spot:focus-visible{outline:3px solid var(--accent-text);outline-offset:3px}
/* Its legend: the same three looks; under the map the ring follows the text, so it shows on a light panel too. */
.tn-legend{display:flex;flex-wrap:wrap;gap:6px 14px;margin:0;padding:0;list-style:none;font-size:12px;color:var(--muted)}
.tn-legend i{display:inline-grid;place-items:center;width:16px;height:16px;margin-right:6px;border-radius:4px;vertical-align:-3px;font-size:11px;font-style:normal;font-weight:700}
.tn-legend i.free{border:2px solid var(--zone);background:color-mix(in srgb,var(--zone) 14%,var(--ink))}
.tn-legend i.on{background:var(--zone);color:var(--ink);box-shadow:0 0 0 2px var(--text)}
.tn-legend i.off{border:1px solid var(--map-off-line);background:var(--map-off) var(--map-stripes)}
/* When a zone's tables do not fit the plan on this screen: its free ones as 48 px chips, as on the staff's sheet. */
.tn-picks{display:flex;flex-wrap:wrap;gap:8px}
.tn-pick{display:grid;place-items:center;min-width:48px;height:48px;padding:0 8px;border:2px solid var(--zone);border-radius:12px;background:none;color:var(--text);font:inherit;line-height:1.1;cursor:pointer}
.tn-pick b{font-size:16px;font-weight:700}
.tn-pick small{font-size:11px;color:var(--muted)}
.tn-pick[aria-pressed=true]{border-color:var(--text);background:var(--zone);color:var(--ink)}
.tn-pick[aria-pressed=true] small{color:inherit}
.tn-pick[aria-pressed=true] b::after{content:" ✓"}
.tn-pick:focus-visible{outline:2px solid var(--accent-text);outline-offset:2px}

/* Anti-bot widget (antibot.mjs): room for it so the form does not jump when it loads. */
.tn-antibot{margin:10px 0;min-height:65px}

/* Inside a club's website (N-11): compact, without Velador's brand bar and footer. */
body.embed .tn-brand,body.embed .tn-foot{display:none}
/* Nor who invites (2026-10-26): the RRPP's page does not open inside another website's frame. */
body.embed .tn-ref{display:none}
body.embed .tn{padding-top:8px}

/* Help with a ticket (soporte.mjs): folded until the customer needs it. The flex summary loses the native marker, so a
   chevron says it unfolds and turns with [open], over a line that says what for (visual-escritorio-22, 2026-10-29). */
.tn-support summary{display:flex;align-items:center;gap:12px;min-height:32px;cursor:pointer;font-weight:600}
.tn-support-what{flex:1;display:grid;gap:2px}
.tn-support-what small{color:var(--muted);font-size:12px;font-weight:400}
.tn-chevron{flex:none;font-size:20px;line-height:1;color:var(--muted);transform:rotate(90deg);transition:transform .15s}
.tn-support[open] .tn-chevron{transform:rotate(-90deg)}
@media(prefers-reduced-motion:reduce){.tn-chevron{transition:none}}
.tn-support[open] summary{margin-bottom:10px}
.tn-support textarea{width:100%;font:inherit}

/* Menus and plans as documents on the club's page (2026-10-22). */
.tn-docs{list-style:none;margin:0;padding:0;display:grid;gap:8px}
.tn-docs small{color:var(--muted)}
/* Preview of an unpublished event (2026-10-22): a strip above the page. */
.tn-preview{margin:0 0 14px;padding:10px 14px;border:1px dashed var(--line);border-radius:12px;background:var(--panel)}
/* How many people (2026-10-23): a big − / + around the number. */
.tn-stepper{display:grid;grid-template-columns:48px minmax(0,1fr) 48px;gap:8px;align-items:center}
.tn-stepper input{text-align:center;font-size:20px;font-weight:700}
.tn-step-btn{height:48px;border:1px solid var(--line);border-radius:12px;background:var(--panel);color:var(--text);font:inherit;font-size:24px;line-height:1;cursor:pointer}
.tn-step-btn:focus-visible{outline:2px solid var(--accent-text);outline-offset:2px}
/* The tickets' live total under their counter (2026-10-25). */
.tn-total{margin:0;font-size:14px;color:var(--text)}
.tn-total b{font-weight:700}
/* The club's month with each night's poster (2026-10-23). */
.tn-views{display:flex;gap:6px;margin:0 0 12px}
.tn-views button{flex:1;min-height:40px;border:1px solid var(--line);border-radius:10px;background:var(--panel);color:var(--muted);font:inherit;cursor:pointer}
.tn-views button[aria-pressed=true]{color:var(--text);border-color:var(--accent);font-weight:600}
.tn-cal-nav{display:flex;align-items:center;gap:8px}
.tn-cal-nav h2{flex:1;margin:0;font-size:16px;text-align:center}
.tn-cal-nav button{width:40px;height:40px;border:1px solid var(--line);border-radius:10px;background:none;color:var(--text);font-size:22px;cursor:pointer}
.tn-cal-nav button:disabled{opacity:.4;cursor:default}
.tn-cweek,.tn-cgrid{list-style:none;margin:0;padding:0;display:grid;grid-template-columns:repeat(7,minmax(0,1fr));gap:4px}
.tn-cweek li{text-align:center;font-size:12px;color:var(--muted)}
.tn-cday{aspect-ratio:3/4;min-width:0;border-radius:8px;background:var(--panel);position:relative;overflow:hidden;font-size:12px}
.tn-cday.out{background:transparent}
.tn-cday>span,.tn-cday a>span{position:absolute;top:3px;left:5px;z-index:1;font-weight:600}
.tn-cday a{display:block;width:100%;height:100%;color:var(--text);text-decoration:none;background:var(--raised)}
.tn-cday a>span{background:var(--bg);border-radius:4px;padding:0 4px}
.tn-cday img{width:100%;height:100%;object-fit:cover}
.tn-cday b{position:absolute;inset:0;display:grid;place-items:center;font-size:14px}
.tn-cday i{position:absolute;right:3px;bottom:3px;font-style:normal;font-size:11px;background:var(--bg);border-radius:4px;padding:0 4px}
.tn-cday.on{overflow:visible}
.tn-cday a{border-radius:8px;overflow:hidden;position:relative}
.tn-cday a:focus-visible{outline:2px solid var(--accent-text);outline-offset:2px}
/* The club's own page (2026-10-23): its header, cover, posters and, on a wide screen, its information beside them. */
.tn-clubhead a{display:flex;align-items:center;gap:10px;color:inherit;text-decoration:none}
.tn-logo{width:36px;height:36px;border-radius:50%;object-fit:cover;background:var(--raised)}
.tn-cover{width:100%;border-radius:14px;overflow:hidden;aspect-ratio:3/1;max-height:280px;background:var(--raised)}
.tn-cover img{width:100%;height:100%;object-fit:cover;display:block}
.tn-sr{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}
.tn-cols{display:grid;gap:16px}
.tn-main{display:grid;gap:12px;min-width:0}
.tn-next-head{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:8px}
.tn-next-head h2{margin:0;font-size:18px}
.tn-next-head .tn-views{margin:0}
.tn-posters{grid-template-columns:repeat(auto-fill,minmax(min(160px,100%),1fr));gap:12px}
/* The agenda by night (visual-publico-13, 2026-10-26): «Esta noche», «Mañana»… each over its posters. */
.tn-when{display:grid;gap:10px}
.tn-when h2{margin:0;font-size:18px}
.tn-pcard{display:flex;flex-direction:column;align-items:stretch;gap:0;height:100%;border:1px solid var(--line);border-radius:12px;overflow:hidden;background:var(--panel);color:inherit;text-decoration:none}
.tn-pcard:hover{border-color:var(--accent)}
.tn-pimg{display:grid;place-items:center;aspect-ratio:4/5;background:var(--raised);font-size:28px;color:var(--muted)}
.tn-pimg img{width:100%;height:100%;object-fit:cover;display:block}
/* A night without a poster (visual-publico-13, 2026-10-26): one of type, the day big and the name at 22 px, on a gradient
   of the club's colour (--club, set on the card) mixed into the page's surfaces, so the text keeps its contrast whatever
   the colour is; its flag goes in the flow, under the day. */
.tn-ptype{display:flex;flex-direction:column;align-items:flex-start;gap:8px;padding:12px;background:var(--raised) linear-gradient(160deg,color-mix(in srgb,var(--club,var(--raised)) 30%,var(--raised)),var(--panel) 85%);color:var(--text);text-align:left}
.tn-pday{display:grid;line-height:1}
.tn-pday small{font-size:14px;font-weight:700;letter-spacing:.12em;color:var(--text)}
.tn-pday b{font-size:44px;font-weight:800;letter-spacing:-.02em}
.tn-pname{margin-top:auto;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:3;overflow:hidden;font-size:22px;font-weight:800;line-height:1.1;overflow-wrap:anywhere}
.tn-ptype .tn-flag{position:static}
.tn-pbody{display:grid;gap:3px;padding:10px 12px 12px}
.tn-pdate{justify-self:start;font-size:12px;padding:2px 8px;border-radius:6px;background:var(--raised)}
.tn-ptime{font-size:12px;color:var(--muted)}
.tn-pbody strong{overflow-wrap:anywhere}
.tn-pbody small{color:var(--muted);overflow-wrap:anywhere}
.tn-side{display:grid;gap:12px;align-content:start}
.tn-place p{margin:6px 0 0}
.tn-social{list-style:none;margin:8px 0 0;padding:0;display:flex;flex-wrap:wrap;gap:8px}
.tn-social a{display:inline-flex;align-items:center;min-height:40px;padding:0 14px;border:1px solid var(--line);border-radius:999px;color:var(--text);text-decoration:none}
.tn-social a:hover{border-color:var(--accent)}
@media(min-width:900px){.tn-site{max-width:1100px}.tn-cols{grid-template-columns:minmax(0,1fr) 300px;align-items:start}.tn-side{position:sticky;top:16px}}
/* A club's privacy policy (2026-10-25): who keeps the data, then the text, one readable column. */
.tn-who{display:grid;gap:8px;margin:0}
.tn-who div{display:grid;grid-template-columns:100px minmax(0,1fr);gap:10px;align-items:baseline}
.tn-who dt{color:var(--muted);font-size:13px}
.tn-who dd{margin:0;overflow-wrap:anywhere}
.tn-who .tn-link{display:inline-block;min-height:24px;padding-block:3px}
.tn-policy-text p{margin:0;white-space:pre-line}
.tn-policy-text h3{margin:6px 0 0;font-size:15px}
/* The cookie banner of a club with measurement tags (G5, 2026-10-31): above the page, not over it, so it never hides a
   form or the bar at the bottom; «Cookies» at the foot asks again. */
.tn-cookies{display:grid;gap:10px;max-width:760px;margin:12px auto 0;padding:16px;border:1px solid var(--line);border-radius:16px;background:var(--panel);color:var(--text)}
.tn-cookies h2{margin:0;font-size:16px}
.tn-cookies p{margin:0;font-size:14px;color:var(--soft)}
.tn-cookies-actions{display:flex;flex-wrap:wrap;gap:8px;justify-content:flex-end}
.tn-cookies-actions .btn,.tn-cookies-pick .btn{min-height:44px}
.tn-cookies-pick summary{min-height:44px;display:flex;align-items:center;cursor:pointer;font-weight:600;color:var(--accent-text)}
.tn-cookies-pick{display:grid;gap:8px}
.tn-cookies-pick[open]{padding-bottom:4px}
.tn-cookies-pick .tn-check small{display:block;color:var(--muted);font-size:12px}
.tn-cookies-again{text-align:center;margin:0 0 24px}
.tn-cookies-again .tn-link{min-height:44px;background:none;border:0;font:inherit;cursor:pointer}
@media(max-width:640px){.tn-cookies{margin:10px 12px 0}.tn-cookies-actions .btn{flex:1}}
/* How a night stands, on its poster card (2026-10-23). */
.tn-pimg{position:relative}
.tn-flag{position:absolute;top:8px;left:8px;font-style:normal;font-size:12px;font-weight:700;padding:3px 8px;border-radius:6px;background:var(--bg);color:var(--text);border:1px solid var(--line)}
.tn-flag.out{color:var(--danger)}
.tn-from{color:var(--text)!important;font-weight:600}

/* A promoter's public page (perfil-promotor.md, 2026-10-24): the club page's layout with the person's name. */
.tn-promoter .tn-links{list-style:none;margin:0;padding:0;display:grid;gap:6px}
.tn-foot{margin-top:24px;color:var(--muted);font-size:12px}

/* What sells (2026-10-24): the hero with its facts and calls to action, the sticky bar on phones, zones by touch. */
.tn-hero{position:relative;padding:18px;border:1px solid var(--line);border-radius:16px;background:linear-gradient(160deg,color-mix(in srgb,var(--accent) 22%,var(--panel)),var(--panel) 70%)}
.tn-hero.has-poster{display:grid;grid-template-columns:minmax(0,1fr);gap:12px}
.tn-hero .tn-poster{margin:0;max-width:100%;aspect-ratio:4/5;max-height:340px}
.tn-hero h1{font-size:32px;line-height:1.05}
.tn-facts{list-style:none;margin:10px 0 0;padding:0;display:flex;flex-wrap:wrap;gap:6px}
.tn-facts li{padding:5px 10px;border:1px solid var(--line);border-radius:999px;background:var(--bg);color:var(--text);font-size:13px;font-weight:600}
/* «Esta noche» / «Mañana» is a fact, not a button (2026-10-25): outlined in --accent-text, never filled with the action blue. */
.tn-facts li.hot{border-color:var(--accent-text);background:var(--raised);color:var(--accent-text)}
.tn-facts li.full{color:var(--danger)}
.tn-ctas{display:flex;flex-wrap:wrap;gap:8px;margin-top:14px}
.tn-cta{display:inline-flex;align-items:center;justify-content:center;min-height:46px;padding:0 18px;border-radius:12px;font-size:15px;font-weight:600;text-decoration:none}
.tn-ctas .tn-cta{flex:1 1 160px}
/* After a request (2026-10-25) the hero stops inviting to book again, as the sticky bar already did. */
.tn:has(.tn-done) .tn-ctas{display:none}
/* Página pública A (2026-10-25): the whole card is the choice. */
.tn-zone-cards li:has(.tn-zone-pick){padding:0;border:0}
.tn-zone-pick{position:relative;display:flex;align-items:center;gap:10px;width:100%;min-height:56px;padding:12px;border:1px solid var(--line);border-radius:12px;background:var(--panel);color:var(--text);font:inherit;text-align:left;cursor:pointer}
.tn-zone-pick:hover{border-color:color-mix(in srgb,var(--accent) 60%,var(--line))}
.tn-zone-pick[aria-pressed=true]{border:2px solid var(--accent-text);padding:11px;background:color-mix(in srgb,var(--accent) 14%,var(--panel))}
/* Chosen is not said by colour alone: a check mark too, on the corner (2026-10-25) so the zone's line keeps its width. */
.tn-zone-pick[aria-pressed=true]::after{content:"✓";position:absolute;top:-8px;right:-8px;display:grid;place-items:center;width:22px;height:22px;border-radius:50%;background:var(--accent);color:var(--on-accent);font-size:13px;font-weight:800}
.tn-zone-pick[aria-pressed=true] b{color:var(--accent-text)}
.tn-zone-pick:focus-visible{outline:2px solid var(--accent-text);outline-offset:2px}
.tn-zone-text{flex:1;min-width:0;display:grid;gap:2px}
.tn-zone-text small{font-size:12px}
.tn-zone-free{white-space:nowrap}
/* The price is what a guest compares (2026-10-25): big on the right, with what it is under it. */
.tn-zone-price{flex:none;display:grid;justify-items:end;text-align:right;line-height:1.2}
.tn-zone-price b{font-size:17px;font-weight:700}
.tn-zone-price small{font-size:11px}
/* A full zone's card opens its waitlist (visual-publico-12, 2026-10-25), and says so in a line of its own. */
.tn-zone-wait span{color:var(--accent-text);font-weight:600}
.tn-zone-pick .tn-zone-wait b.tn-full{color:var(--danger)}
/* After a request (2026-10-25) the tables fold into one line; «Reservar otra» opens them again. */
.tn-again{display:none;margin:0;font-size:13px;color:var(--muted)}
.tn-again .tn-link{min-height:24px;padding-block:3px}
.tn-folded>:not(h2):not(.tn-again){display:none}
.tn-folded .tn-again{display:block}
/* The table form: inline from 600 px, a sheet that rises from the bottom on a phone. */
.tn-book{position:static;display:block;width:auto;max-width:none;max-height:none;margin:0;padding:0;border:0;border-radius:0;background:none;color:inherit;box-shadow:none;overflow:visible}
.tn-book-head{display:flex;align-items:flex-start;gap:12px}
.tn-book-head>div{flex:1;min-width:0}
.tn-book-head h3{margin:0;font-size:17px;font-weight:800}
/* On desktop the title takes focus when a zone is picked (2026-10-29): moved for the reader, no ring to draw. */
.tn-book-head h3:focus{outline:none}
.tn-book-head .tn-help{margin:2px 0 0}
#tn-plan-box button.tn-link{min-height:24px;padding-block:3px}
.tn-grip,.tn-book-close{display:none}
/* The sheet holds the table form or a full zone's waitlist, one at a time (visual-publico-12, 2026-10-25). */
.tn-book form[hidden]{display:none}
/* What the party pays, the button and «No se cobra nada ahora» (visual-publico-01, 2026-10-25): together at the end of
   the form, and on a phone fixed to the bottom of the sheet, so they stay in view with the plan open. */
.tn-book-foot{display:grid;gap:10px}
.tn-book-sum{margin:0;display:grid;gap:2px;font-size:13px;color:var(--text)}
.tn-book-sum b{font-weight:700}
.tn-sum-more{font-size:12px;color:var(--muted)}
@media(max-width:599px){
  .tn-book:not([open]){display:none}
  .tn-book[open]{position:fixed;inset:auto 0 0 0;width:100%;max-height:88dvh;overflow:auto;overscroll-behavior:contain;scroll-padding-bottom:180px;border-top:1px solid var(--line);border-radius:22px 22px 0 0;background:var(--panel);box-shadow:0 -12px 40px #0008}
  .tn-book::backdrop{background:rgb(5 9 19 / .6)}
  .tn-book .tn-form{padding:8px 16px 0}
  .tn-book-foot{position:sticky;bottom:0;z-index:1;padding:10px 0 max(14px,env(safe-area-inset-bottom));border-top:1px solid var(--line);background:var(--panel)}
  .tn-book-head{position:sticky;top:0;z-index:1;flex-wrap:wrap;padding:6px 0 10px;background:var(--panel)}
  .tn-grip{display:block;flex:none;width:44px;height:5px;margin:0 calc(50% - 22px) 4px;border-radius:5px;background:var(--field-line)}
  .tn-book-close{display:grid;place-items:center;flex:none;width:44px;height:44px;border:1px solid var(--line);border-radius:12px;background:var(--raised);color:var(--text);font:inherit;font-size:22px;line-height:1;cursor:pointer}
  .tn-book-close:focus-visible{outline:2px solid var(--accent-text);outline-offset:2px}
  body.tn-book-on .tn-sticky{display:none}
}
/* The event page on a desktop (visual-escritorio-09, 2026-10-29): from 900 px it reuses .tn-cols — the cover, the
   offers and the zones on the left; the booking card on the right, sticky and scrolled inside itself, so the zone
   chosen, the form and its button are in the window without scrolling the page. Below 900 px the wrappers dissolve
   (display:contents): design A keeps its single column, the card right after the zones, and the phone's sheet is
   untouched. */
.tn-book-cols,.tn-book-flow,.tn-book-side,.tn-book-rest{display:contents}
@media(min-width:600px){
  /* Out of the zones' card the inline form needs card looks of its own. Empty (every zone full, none tapped yet) or
     with the tables folded after a request, the card is not there. */
  .tn-book-side .tn-book{border:1px solid var(--line);border-radius:14px;background:var(--panel)}
  .tn-book-side .tn-book:empty,.tn-book-cols:has(.tn-folded) .tn-book{display:none}
  .tn-book-side .tn-book .tn-form{padding:16px 18px}
}
@media(min-width:900px){
  /* The left column is two rows, the offers down to the tables and then the lists and the help, which the card spans:
     a page shorter than the card leaves its extra height under the left column (1fr), not between its cards. */
  .tn-site .tn-book-cols{display:grid;grid-template-columns:minmax(0,1fr) 380px;grid-template-rows:auto 1fr}
  .tn-site .tn-book-flow,.tn-site .tn-book-rest{display:grid;gap:16px;min-width:0;grid-column:1}
  .tn-site .tn-book-flow{grid-row:1}
  .tn-site .tn-book-rest{grid-row:2}
  .tn-site .tn-book-side{display:grid;grid-column:2;grid-row:1 / span 2}
  /* 88px ≈ the page's padding plus the club header over the columns: the card fits the window from the first paint,
     and its foot (the total, the button and «No se cobra nada…») sticks to its bottom, as on the phone's sheet. Its
     scroll padding keeps a field reached with Tab above that foot, never under it. At its end the wheel goes on to the
     page, which moves under the sticky card. */
  .tn-book-side .tn-book{max-height:calc(100dvh - 88px);overflow:auto;scroll-padding-bottom:180px}
  .tn-book-side .tn-book .tn-form{padding-bottom:0}
  .tn-book-side .tn-book-foot{position:sticky;bottom:0;z-index:1;padding:10px 0 16px;border-top:1px solid var(--line);background:var(--panel)}
}
.tn-sticky{display:none}
@media(max-width:599px){
  .tn{padding-bottom:88px}
  .tn-sticky{display:block;position:fixed;left:0;right:0;bottom:0;z-index:30;padding:10px 16px max(10px,env(safe-area-inset-bottom));background:color-mix(in srgb,var(--bg) 92%,transparent);border-top:1px solid var(--line);backdrop-filter:blur(8px)}
  .tn-sticky .tn-cta{width:100%}
  .tn-sticky.tn-sticky-away{display:none}
  .tn:has(.tn-done) .tn-sticky,body.embed .tn-sticky{display:none}
}
@media(min-width:600px){.tn-hero.has-poster{grid-template-columns:200px minmax(0,1fr);align-items:start}.tn-hero .tn-poster{max-height:none}}

/* The club's gallery on its public page (G8, 2026-10-30): up to 8 photos of the venue, two per row on a phone. */
.tn-gallery ul{display:grid;grid-template-columns:repeat(auto-fill,minmax(150px,1fr));gap:8px;margin:12px 0 0;padding:0;list-style:none}
.tn-gallery img{display:block;width:100%;aspect-ratio:4/3;object-fit:cover;border-radius:10px;background:var(--panel,#110e1b)}
.tn-wa{margin-bottom:10px}

/* A club with its public sales paused (G8, 2026-10-30): the notice above everything else. */
.tn-paused{border-color:#eab308;background:color-mix(in srgb,#eab308 10%,transparent)}
.tn-paused h2{margin:0 0 6px}
