:root{
  --bg-1:#141416; --bg-2:#0b0b0d; --bg-3:#17121a;
  --text:#f2ece6; --muted:#cfc7bf; --muted-2:rgba(242,236,230,.55);
  --accent:#d8a97a; --accent-hover:#f0c79b; --highlight:#FDC185;
  --gold:#e3c07f; --silver:#c9c9cf; --bronze:#c08a5e;
  --panel:rgba(255,255,255,.02); --panel-border:rgba(216,169,122,.35);
  --ok:#4fae6a; --err:#e0605a;
  --radius:16px;
  --font-display:'Anton','Impact','Arial Narrow',sans-serif;
  --font-head:'Barlow Condensed','Arial Narrow',sans-serif;
  --font-body:'Barlow','Segoe UI',Arial,sans-serif;
}

*{box-sizing:border-box}
html,body{height:100%}
body{
  margin:0;
  background:linear-gradient(160deg,var(--bg-1) 0%,var(--bg-2) 55%,var(--bg-3) 100%);
  color:var(--text);
  font-family:var(--font-body);
  line-height:1.55;
  min-height:100vh;
  -webkit-font-smoothing:antialiased;
  text-rendering:optimizeLegibility;
}
a{color:var(--accent);text-decoration:none}
a:hover{color:var(--accent-hover)}

.bg-texture{
  position:fixed;inset:0;width:100%;height:100%;object-fit:cover;
  opacity:.12;pointer-events:none;z-index:0;
}

/* El botón admin vive al final del <body> (después de <main>, ver base.html)
 * a propósito: position:fixed lo saca del flujo igual, pero así no compite
 * por espacio/orden visual con el header — flota solo, abajo a la derecha,
 * fuera del paso de cualquier otro contenido. */
.admin-entry{
  position:fixed;bottom:18px;right:18px;z-index:80;
  width:42px;height:42px;border-radius:50%;
  display:flex;align-items:center;justify-content:center;
  background:rgba(11,11,13,.6);border:1px solid var(--panel-border);
  font-size:18px;line-height:1;text-decoration:none;
  box-shadow:0 6px 18px rgba(0,0,0,.4);
  opacity:.6;transition:opacity .15s,transform .15s,background .15s,box-shadow .15s;
}
.admin-entry:hover{
  opacity:1;background:rgba(11,11,13,.9);transform:scale(1.08) translateY(-2px);
  box-shadow:0 10px 26px rgba(0,0,0,.5);
}

.shell{position:relative;z-index:1;min-height:100vh;display:flex;flex-direction:column}

header.topbar{
  display:flex;align-items:center;justify-content:space-between;gap:14px 28px;
  padding:16px 32px;border-bottom:1px solid var(--panel-border);
  flex-wrap:wrap;
}
/* Logo + nombre agrupados como un solo link a "/" arriba a la izquierda —
 * patrón estándar de header (identidad a la izquierda, navegación a la
 * derecha) en vez del logo suelto al fondo del todo como antes. */
header.topbar .brand-link{
  display:flex;align-items:center;gap:14px;min-width:0;
  text-decoration:none;color:inherit;
}
header.topbar img.logo{height:42px;width:auto;object-fit:contain;flex:none;transition:transform .2s}
header.topbar .brand-link:hover img.logo{transform:scale(1.06)}
header.topbar .brand{display:flex;flex-direction:column;gap:2px;min-width:0}
header.topbar .brand .title{
  font-family:var(--font-head);font-size:clamp(20px,15px + 1.6vw,34px);font-weight:700;
  letter-spacing:.02em;line-height:1;transition:color .15s;
}
header.topbar .brand-link:hover .brand .title{color:var(--accent-hover)}
header.topbar .brand .subtitle{
  font-family:var(--font-head);font-size:clamp(12px,10px + .5vw,16px);font-weight:600;letter-spacing:.06em;
  color:var(--accent);text-transform:uppercase;
}
header.topbar nav{display:flex;gap:4px;font-family:var(--font-head);
  font-size:clamp(14px,12px + .5vw,17px);letter-spacing:.03em;text-transform:uppercase;flex-wrap:wrap}
header.topbar nav a{
  padding:.45rem .9rem;border-radius:999px;color:var(--muted);
  transition:background .15s,color .15s;
}
header.topbar nav a:hover{background:rgba(216,169,122,.14);color:var(--accent-hover)}
header.topbar nav a.active{background:var(--accent);color:#1c130a}

/* Toggle ES/EN — vive fuera de {% block nav %} en base.html a propósito
 * (locked.html vacía ese bloque, pero el visitante sigue pudiendo cambiar de
 * idioma incluso en la pantalla de clave). */
.lang-switch{display:flex;gap:4px;flex:none}
.lang-switch button{
  background:transparent;border:1px solid var(--panel-border);color:var(--muted);
  border-radius:999px;padding:.3rem .65rem;font-family:var(--font-head);letter-spacing:.05em;
  cursor:pointer;font-size:12.5px;transition:background .15s,color .15s,border-color .15s;
}
.lang-switch button.active{background:var(--accent);color:#1c130a;border-color:var(--accent)}
.lang-switch button:hover:not(.active){background:rgba(216,169,122,.14);color:var(--accent-hover)}

main{flex:1;padding:24px 32px 72px;position:relative;z-index:1;min-width:0}

.card{
  border:1px solid var(--panel-border);border-radius:var(--radius);
  padding:18px 22px;background:var(--panel);min-width:0;
  box-shadow:0 4px 20px rgba(0,0,0,.22);
}

.btn{
  display:inline-flex;align-items:center;justify-content:center;gap:8px;
  background:var(--accent);color:#1c130a;border:none;border-radius:10px;
  padding:.65rem 1.3rem;font-family:var(--font-head);font-weight:700;
  font-size:clamp(14px,13px + .4vw,17px);letter-spacing:.03em;cursor:pointer;
  transition:transform .12s,background .15s,box-shadow .15s;
}
.btn:hover{background:var(--accent-hover);transform:translateY(-2px);box-shadow:0 6px 16px rgba(0,0,0,.3)}
.btn:active{transform:scale(.97);box-shadow:none}
.btn:disabled{opacity:.4;cursor:not-allowed;transform:none;box-shadow:none}
.btn.btn-lg{font-size:clamp(18px,15px + 1.6vw,26px);padding:1rem 2.2rem;border-radius:14px}
.btn.btn-ghost{background:transparent;border:1px solid var(--panel-border);color:var(--text)}
.btn.btn-ghost:hover{background:rgba(255,255,255,.06)}
.btn.btn-danger{background:var(--err);color:#fff}
.btn.btn-danger:hover{background:#f07a75}
.btn.btn-sm{font-size:13px;padding:.4rem .8rem;border-radius:8px}

.pill{display:inline-block;padding:.15rem .7rem;border-radius:99px;font-size:.8rem;font-weight:700;
  font-family:var(--font-head);letter-spacing:.05em}
.pill-gold{background:rgba(227,192,127,.18);color:var(--gold)}
.pill-silver{background:rgba(201,201,207,.18);color:var(--silver)}
.pill-bronze{background:rgba(192,138,94,.18);color:var(--bronze)}
.pill-libre{background:rgba(253,193,133,.22);color:var(--highlight)}

/* ---------- Rueda ----------
 * El tamaño real (--wheel-max, por inline style en cada template) es un
 * límite superior; min() la encoge en pantallas angostas sin dejar un hueco
 * vertical fijo (aspect-ratio la mantiene cuadrada en vez de usar height:Npx
 * como antes). El <canvas> dibuja siempre a su resolución interna (atributo
 * width/height del HTML) — esto solo cambia el tamaño en pantalla.
 *
 * 90% del CONTENEDOR, no vw: con vw, si el alto derivado de aspect-ratio
 * empuja la página a activar/desactivar el scrollbar vertical, vw cambia de
 * valor (el scrollbar resta ancho al viewport), lo que vuelve a cambiar el
 * ancho de la rueda → dispara el ResizeObserver de nuevo → bucle infinito de
 * redibujado que congela la pestaña (confirmado: así se rompió). % del
 * contenedor no tiene esa realimentación con la altura de la página. */
/* Sin flex: el único hijo en flujo normal es #wheelSpinner (los demás son
 * position:absolute y no participan del layout) — con flex + align-items,
 * un height:100% no se resuelve bien contra el aspect-ratio del padre. */
.wheel-wrap{
  position:relative;
  width:min(var(--wheel-max,520px),90%);aspect-ratio:1/1;margin:0 auto;
}
#wheelSpinner{width:100%;height:100%}
#wheelCanvas{
  display:block;width:100%;height:100%;
  filter:drop-shadow(0 8px 30px rgba(0,0,0,.5));
}
.wheel-pointer{
  position:absolute;top:-6px;left:50%;transform:translateX(-50%);
  width:0;height:0;border-left:18px solid transparent;border-right:18px solid transparent;
  border-top:30px solid var(--highlight);filter:drop-shadow(0 0 6px rgba(253,193,133,.6));
  z-index:3;
}
.wheel-hub{
  position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);
  width:12%;height:12%;min-width:40px;min-height:40px;max-width:70px;max-height:70px;
  border-radius:50%;
  background:radial-gradient(circle at 35% 30%,#3a2d20,#0b0b0d 70%);
  border:3px solid var(--accent);z-index:2;
  display:flex;align-items:center;justify-content:center;
}
.wheel-hub img{width:58%;height:58%;object-fit:contain}

.winner-banner{
  text-align:center;font-family:var(--font-display);letter-spacing:.02em;
  color:var(--highlight);text-shadow:0 0 28px rgba(253,193,133,.35);
  opacity:0;transform:translateY(10px);transition:opacity .3s,transform .3s;
}
.winner-banner.show{opacity:1;transform:translateY(0)}
.winner-banner .wname{font-size:clamp(28px,20px + 4vw,52px);line-height:1.05}
.winner-banner .wsub{font-family:var(--font-head);font-size:clamp(13px,11px + 1vw,20px);color:var(--muted);
  text-transform:uppercase;letter-spacing:.08em;margin-top:4px}

/* ---------- Tablero de premios ---------- */
/* Las 3 tiers (GOLD/SILVER/BRONZE) en columnas lado a lado en vez de
 * apiladas: apiladas, la suma de las 3 fácilmente pasaba la altura visible
 * de la pantalla en la vista de espectadores/proyección y BRONZE quedaba
 * cortado fuera de la "slide". En columnas, el alto total lo define el tier
 * más largo, no la suma de los tres — selectores con #prizeBoard (mayor
 * especificidad que .tier-block/.prize-grid solas) para que esto gane sin
 * depender de en qué orden del archivo esté cada regla. */
#prizeBoard{display:flex;align-items:flex-start}
#prizeBoard .tier-block{flex:1;min-width:0;margin-bottom:0;padding:0 14px}
#prizeBoard .tier-block:first-child{padding-left:0}
#prizeBoard .tier-block:last-child{padding-right:0}
#prizeBoard .tier-block + .tier-block{border-left:1px solid var(--panel-border)}
#prizeBoard .prize-grid{grid-template-columns:1fr;gap:8px}
/* Tarjetas más compactas que en la columna única de /overall o /setup:
 * en una sola columna angosta por tier, el tier con más premios (ej. 5
 * variantes de un mismo producto) puede acumular bastante alto — achicar
 * imagen y padding aquí es lo que evita que el tablero termine más alto que
 * la rueda y la página se pase de la pantalla visible en la proyección. */
#prizeBoard .prize-card{padding:8px 8px}
#prizeBoard .prize-card img{height:52px;padding:3px}
#prizeBoard .prize-card .pname{font-size:12.5px}
#prizeBoard .prize-card .pcount{font-size:12px}

.tier-block{margin-bottom:22px}
.tier-title{
  font-family:var(--font-head);font-size:clamp(17px,13px + 1.2vw,24px);font-weight:700;
  letter-spacing:.14em;margin-bottom:12px;
  display:flex;align-items:center;gap:10px;
}
/* Barrita de color antes del texto en vez del texto suelto — funciona como
 * un pequeño "badge" que separa visualmente cada tier sin necesitar más
 * marcado; currentColor la mantiene sincronizada con el color del tier. */
.tier-title::before{content:'';width:22px;height:3px;border-radius:2px;background:currentColor;flex:none}
.tier-title.t-gold{color:var(--gold)}
.tier-title.t-silver{color:var(--silver)}
.tier-title.t-bronze{color:var(--bronze)}

.prize-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(150px,1fr));gap:14px}
.prize-card{
  border:1px solid var(--panel-border);border-radius:14px;padding:14px 12px;
  display:flex;flex-direction:column;align-items:center;gap:8px;text-align:center;
  background:rgba(255,255,255,.025);cursor:default;position:relative;overflow:hidden;
  transition:border-color .15s,transform .15s,box-shadow .15s,background .15s;
}
/* El halo radial detrás de la imagen es lo que le da "cuerpo" a fotos de
 * producto en fondo transparente (la mayoría de los assets) — sin esto se
 * ven flotando sueltas contra el fondo oscuro de la tarjeta. */
.prize-card img{
  width:100%;height:76px;object-fit:contain;padding:6px;border-radius:10px;
  background:radial-gradient(circle,rgba(255,255,255,.07),transparent 72%);
}
.prize-card .pname{font-size:clamp(12.5px,11px + .4vw,15px);line-height:1.28;color:var(--text);font-weight:600}
.prize-card .pcount{font-family:var(--font-head);font-size:clamp(12px,11px + .3vw,14.5px);color:var(--muted);letter-spacing:.03em}
.prize-card:hover{transform:translateY(-3px);border-color:var(--accent);box-shadow:0 10px 22px rgba(0,0,0,.3)}
.prize-card.selectable{cursor:pointer;border-color:var(--accent)}
.prize-card.selectable:hover{border-color:var(--highlight);box-shadow:0 10px 24px rgba(253,193,133,.2)}
.prize-card.out{opacity:.35;filter:grayscale(1)}
.prize-card.out:hover{transform:none;box-shadow:none;border-color:var(--panel-border)}
/* content:attr(data-out-label) en vez de un string fijo: renderPrizeBoard
 * (common.js) escribe ese atributo con t("out_of_stock") para que el sello
 * salga traducido según el idioma activo (AGOTADO/SOLD OUT). */
.prize-card.out::after{
  content:attr(data-out-label);position:absolute;inset:0;display:flex;align-items:center;justify-content:center;
  font-family:var(--font-head);font-weight:700;letter-spacing:.08em;font-size:13px;
  background:rgba(0,0,0,.45);color:#fff;
}
/* Premio real, con stock, pero de otro tier al de la banda del ganador
 * pendiente (ver engine.assign_bandas / renderPrizeBoard restrictTier) —
 * distinto de "out" (agotado): acá el premio existe, solo que a este
 * ganador no le toca, así que se atenúa pero SIN el sello "AGOTADO". */
.prize-card.tier-locked{opacity:.4;cursor:not-allowed}
.prize-card.tier-locked:hover{transform:none;box-shadow:none;border-color:var(--panel-border)}

/* ---------- Setup ---------- */
.upload-drop{
  border:2px dashed var(--panel-border);border-radius:14px;padding:36px 20px;
  text-align:center;cursor:pointer;transition:border-color .15s,background .15s;
}
.upload-drop:hover, .upload-drop.drag{border-color:var(--accent);background:rgba(216,169,122,.06)}
table.datatable{width:100%;border-collapse:collapse;font-size:clamp(13px,12px + .3vw,15.5px)}
table.datatable th,table.datatable td{border-bottom:1px solid var(--panel-border);
  padding:.4rem .6rem;text-align:left}
table.datatable th{color:var(--accent);font-family:var(--font-head);letter-spacing:.03em;
  text-transform:uppercase;font-size:clamp(11px,10px + .3vw,13.5px)}
.warn-list{font-size:13px;color:var(--muted);max-height:160px;overflow:auto;
  border:1px solid var(--panel-border);border-radius:10px;padding:10px 14px;margin-top:8px}
.warn-list div{margin-bottom:4px}

input[type=text],input[type=number],input[type=file]{
  background:rgba(255,255,255,.04);border:1px solid var(--panel-border);color:var(--text);
  border-radius:8px;padding:.5rem .7rem;font-family:var(--font-body);font-size:14px;
}
label.field{display:flex;flex-direction:column;gap:4px;font-size:13px;color:var(--muted)}

.toast{
  position:fixed;bottom:22px;right:22px;background:var(--bg-3);border:1px solid var(--panel-border);
  border-radius:10px;padding:12px 18px;font-size:14px;z-index:50;box-shadow:0 6px 24px rgba(0,0,0,.4);
  opacity:0;transform:translateY(8px);transition:opacity .2s,transform .2s;
}
.toast.show{opacity:1;transform:translateY(0)}
.toast.err{border-color:var(--err);color:#ffd7d4}
.toast.ok{border-color:var(--ok);color:#d5f5df}

/* minmax(0,1fr) en vez de 1fr: sin el mínimo en 0, una columna de grid no
 * respeta el ancho del contenedor si su contenido (ej. una tabla ancha) pide
 * más espacio — el grid entero se estira y empuja la página a scroll
 * horizontal en vez de dejar que el overflow:auto interno de la tabla
 * scrollee solo. */
.grid-2col{display:grid;grid-template-columns:minmax(0,1fr) 420px;gap:24px;align-items:start}
@media (max-width: 980px){.grid-2col{grid-template-columns:minmax(0,1fr)}}

/* Rueda + tablero de premios (live.html, admin.html): a diferencia de
 * .grid-2col (columna derecha fija en 420px), acá las dos mitades se
 * reparten el ancho por igual — con la columna fija, el tablero quedaba
 * angosto y las 3 tiers apiladas verticalmente (GOLD+SILVER+BRONZE) se
 * pasaban de la altura visible de la pantalla/proyección.
 *
 * align-items:stretch (en vez de start) es lo que resuelve el "footer roto":
 * antes cada .card tomaba solo el alto de su propio contenido, y como la
 * rueda y el tablero casi nunca miden exactamente lo mismo, sus bordes
 * inferiores quedaban desalineados. Con stretch, ambas tarjetas siempre
 * miden lo mismo (el alto del contenido más alto) — el contenido de cada
 * una sigue empaquetado arriba (ninguna define justify-content), así que el
 * espacio de sobra queda como aire abajo, no mueve nada de lugar. En mobile
 * (una sola columna) esto no tiene efecto: cada tarjeta ocupa su propia fila
 * y no hay con qué alinear. */
.stage-grid{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:24px;align-items:stretch}
@media (max-width:980px){.stage-grid{grid-template-columns:minmax(0,1fr)}}

.speed-group{display:flex;gap:6px}
.speed-group button{
  background:transparent;border:1px solid var(--panel-border);color:var(--muted);
  border-radius:8px;padding:.35rem .7rem;font-family:var(--font-head);cursor:pointer;font-size:14px;
}
.speed-group button.active{background:var(--accent);color:#1c130a;border-color:var(--accent)}

/* Selector de banda manual (ver engine.banda_actual / bandas_disponibles en
 * app.py): por defecto sigue AUTO (el orden LIBRE→GOLD→SILVER→BRONZE), pero
 * el operador puede forzar cuál categoría gira a continuación. Los botones
 * de bandas ya agotadas o sin miembros se deshabilitan (no se ocultan, para
 * que quede claro por qué no están disponibles). */
.banda-select{display:flex;gap:6px;flex-wrap:wrap;justify-content:center}
.banda-select button{
  background:transparent;border:1px solid var(--panel-border);color:var(--muted);
  border-radius:8px;padding:.35rem .8rem;font-family:var(--font-head);letter-spacing:.03em;
  cursor:pointer;font-size:13px;transition:background .15s,color .15s,border-color .15s,opacity .15s;
}
.banda-select button:disabled{opacity:.3;cursor:not-allowed}
.banda-select button.active{background:var(--accent);color:#1c130a;border-color:var(--accent)}
.banda-select button[data-b="GOLD"].active{background:var(--gold);border-color:var(--gold)}
.banda-select button[data-b="SILVER"].active{background:var(--silver);border-color:var(--silver)}
.banda-select button[data-b="BRONZE"].active{background:var(--bronze);border-color:var(--bronze)}

.stat{
  display:flex;flex-direction:column;gap:2px;padding:8px 16px;border-radius:12px;
  border:1px solid transparent;transition:background .15s,border-color .15s,transform .15s;
}
.stat:hover{background:rgba(255,255,255,.035);border-color:var(--panel-border);transform:translateY(-2px)}
.stat .n{font-family:var(--font-display);font-size:clamp(22px,16px + 2vw,38px);color:var(--highlight);line-height:1;transition:color .15s}
.stat:hover .n{color:var(--accent-hover)}
.stat .l{font-size:clamp(10.5px,9px + .3vw,13px);color:var(--muted);text-transform:uppercase;letter-spacing:.05em}
.stats-row{display:flex;gap:6px;flex-wrap:wrap}

table.datatable tbody tr{transition:background .12s}
table.datatable tbody tr:hover{background:rgba(255,255,255,.035)}

/* ---------- Podio (leaderboard) ----------
 * order: reordena visualmente 2°-1°-3° (el 1er lugar queda al centro y más
 * alto) sin tocar el orden del DOM, que sigue siendo 1°,2°,3° — así el
 * marcado semántico coincide con el ranking real aunque se vea distinto. */
.podium{display:flex;align-items:flex-end;justify-content:center;gap:14px;padding-top:6px}
.podium-spot{
  flex:1;max-width:190px;display:flex;flex-direction:column;align-items:center;gap:6px;
  padding:22px 10px 0;border-radius:14px 14px 0 0;
  background:var(--panel);border:1px solid var(--panel-border);border-bottom:none;
  transition:transform .15s;
}
.podium-spot:hover{transform:translateY(-4px)}
.podium-spot .pname{
  font-family:var(--font-head);font-size:16px;font-weight:700;text-align:center;
  line-height:1.15;overflow-wrap:anywhere;min-height:2.3em;display:flex;align-items:center;
}
.podium-spot .pentradas{font-family:var(--font-display);font-size:24px;color:var(--highlight);line-height:1}
.podium-spot .pentradas-label{font-size:10.5px;color:var(--muted);text-transform:uppercase;letter-spacing:.05em;margin-bottom:8px}
.podium-spot .base{
  width:100%;display:flex;align-items:center;justify-content:center;
  font-family:var(--font-display);font-size:26px;border-radius:0 0 10px 10px;
}
.podium-1{order:2}
.podium-1 .base{height:80px;background:linear-gradient(180deg,rgba(227,192,127,.4),rgba(227,192,127,.14));color:var(--gold)}
.podium-2{order:1}
.podium-2 .base{height:58px;background:linear-gradient(180deg,rgba(201,201,207,.35),rgba(201,201,207,.1));color:var(--silver)}
.podium-3{order:3}
.podium-3 .base{height:42px;background:linear-gradient(180deg,rgba(192,138,94,.35),rgba(192,138,94,.1));color:var(--bronze)}

@media (max-width:640px){
  .podium{gap:8px}
  .podium-spot{padding:16px 6px 0}
  .podium-spot .pname{font-size:13px;min-height:2.1em}
  .podium-spot .pentradas{font-size:19px}
  .podium-1 .base{height:64px;font-size:21px}
  .podium-2 .base{height:46px;font-size:19px}
  .podium-3 .base{height:34px;font-size:17px}
}

/* ---------- Pantalla de espera (holder) ----------
 * Cubre la rueda mientras el evento no arrancó de verdad (ver holder_activo
 * en storage.py). En / es pantalla completa fija (nadie debe ver la rueda
 * "pelada" detrás); en /admin es un overlay recortado al círculo de la
 * propia rueda (--inline) para que el operador vea exactamente lo que ve el
 * público sin perder de vista el resto de la consola (stats, tablero). */
.holder-overlay{
  display:none;align-items:center;justify-content:center;text-align:center;
  background:linear-gradient(160deg,var(--bg-1) 0%,var(--bg-2) 60%,var(--bg-3) 100%);
  z-index:40;padding:24px;
}
.holder-overlay.show{display:flex}
.holder-overlay:not(.holder-overlay--inline){position:fixed;inset:0}
.holder-overlay--inline{position:absolute;inset:0;border-radius:50%;backdrop-filter:blur(2px)}
.holder-card{max-width:420px}
.holder-logo{height:54px;width:auto;object-fit:contain;margin-bottom:14px;opacity:.9}
.holder-msg{
  font-family:var(--font-head);font-weight:600;letter-spacing:.03em;
  font-size:clamp(15px,13px + 1vw,22px);color:var(--text);
}
/* min-width y gap en clamp() en vez de fijos: el overlay --inline vive
 * dentro del círculo de la rueda, que en mobile puede angostarse bastante
 * (min(var(--wheel-max),90vw)) — con valores fijos, el contador de 4 cajas
 * (cuando se muestran días) se desbordaba del círculo. Atado a vw porque el
 * tamaño real del círculo depende del viewport en el rango donde esto
 * importa (pantallas chicas); en desktop el clamp ya tocó su techo y se ve
 * igual que antes. */
.holder-countdown{display:flex;gap:clamp(4px,2vw,10px);align-items:baseline;justify-content:center;margin-top:16px}
.cd-box{
  display:flex;flex-direction:column;align-items:center;min-width:clamp(34px,9vw,52px);
  border:1px solid var(--panel-border);border-radius:10px;padding:6px 4px;background:rgba(255,255,255,.03);
}
.cd-box span{font-family:var(--font-display);font-size:clamp(22px,18px + 1.6vw,34px);color:var(--highlight);line-height:1}
.cd-box label{font-size:10px;color:var(--muted);text-transform:uppercase;letter-spacing:.06em;margin-top:2px}
.cd-sep{font-family:var(--font-display);font-size:clamp(20px,16px + 1.4vw,30px);color:var(--muted)}

.holder-admin-box{
  width:100%;border:1px solid var(--panel-border);border-radius:12px;padding:10px 14px;
  background:rgba(255,255,255,.02);display:flex;flex-direction:column;gap:8px;
}
.holder-admin-row{display:flex;gap:8px;align-items:center;flex-wrap:wrap}
.holder-admin-row input[type=number]{width:64px}
.holder-admin-row input[type=text]{flex:1;min-width:150px}
.pill-holder-on{background:rgba(253,193,133,.18);color:var(--highlight)}
.pill-holder-off{background:rgba(79,174,106,.18);color:var(--ok)}

/* ---------- Portal (panel de admin) ---------- */
.portal-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(220px,1fr));gap:14px}
.portal-card{
  display:flex;flex-direction:column;gap:6px;text-align:left;
  border:1px solid var(--panel-border);border-radius:14px;padding:16px 18px;
  background:rgba(255,255,255,.025);color:var(--text);
  transition:transform .15s,border-color .15s,box-shadow .15s,background .15s;
}
.portal-card:hover{
  transform:translateY(-3px);border-color:var(--accent);color:var(--text);
  box-shadow:0 10px 24px rgba(0,0,0,.3);background:rgba(255,255,255,.045);
}
.portal-card .picon{font-size:26px}
.portal-card .ptitle{font-family:var(--font-head);font-size:18px;font-weight:700;letter-spacing:.02em}
.portal-card .pdesc{font-size:13px;color:var(--muted);line-height:1.4}

/* ---------- Responsive ----------
 * Va al FINAL del archivo a propósito: en CSS, a igual especificidad gana
 * la regla que aparece más abajo en el archivo, sin importar si está o no
 * dentro de un @media. Estas reglas existían antes arriba del todo (justo
 * después del header) y por eso NUNCA se aplicaban de verdad en mobile: el
 * override venía ANTES que las reglas base de .card/.btn/.stat/.prize-card/
 * table.datatable/.winner-banner (definidas más abajo), así que la base
 * siempre ganaba y pisaba el ajuste mobile. Se mueve todo aquí, después de
 * absolutamente todo lo demás, para que gane siempre que corresponda. */
/* Los font-size que había acá (título, nav, stats, tier-title, prize-card,
 * tabla, winner-banner) se sacaron: ahora esos elementos usan clamp() en su
 * regla base y escalan solos con el ancho de pantalla, sin saltos por
 * breakpoint. Lo que queda abajo es layout puro (padding, tamaños de
 * imagen/ícono, wrap de flex/grid) — cosas que clamp() no resuelve. */
@media (max-width:900px){
  header.topbar nav{flex:1 1 100%;justify-content:space-between;gap:6px}
  header.topbar nav a{flex:1;text-align:center}
}
@media (max-width:640px){
  header.topbar{padding:14px 18px;gap:12px}
  header.topbar img.logo{height:36px}
  header.topbar nav a{padding:.55rem .5rem}
  main{padding:16px 14px 76px}
  .card{padding:14px 16px}
  .btn.btn-lg{padding:.85rem 1.6rem}
  .stats-row{gap:8px}
  /* Las 3 columnas de tier vuelven a apilarse en teléfono — en 3 columnas
     angostas las tarjetas quedan demasiado apretadas para leer. */
  #prizeBoard{flex-direction:column}
  #prizeBoard .tier-block{padding:0}
  #prizeBoard .tier-block + .tier-block{border-left:none;border-top:1px solid var(--panel-border);padding-top:16px}
  #prizeBoard .prize-grid{grid-template-columns:repeat(auto-fill,minmax(120px,1fr))}
  .stat{padding:8px 12px}
  .admin-entry{width:38px;height:38px;bottom:14px;right:14px;font-size:16px}
  /* El overlay --inline vive dentro del círculo de la rueda — su padding
     fijo de 24px le comía casi 50px de ancho útil justo en el rango donde
     el círculo ya viene angosto. Menos padding acá, el clamp() de
     .cd-box/.holder-countdown hace el resto (ver esas reglas base). */
  .holder-overlay{padding:12px}
  .cd-box{padding:4px 3px}
  .holder-msg{margin-bottom:2px}
}
@media (max-width:380px){
  header.topbar img.logo{height:30px}
  header.topbar nav a{padding:.5rem .35rem}
}
@media (max-width:560px){
  table.datatable th,table.datatable td{padding:.4rem .5rem}
  .prize-grid{grid-template-columns:repeat(auto-fill,minmax(120px,1fr));gap:10px}
  .prize-card{padding:10px 8px}
  .prize-card img{height:64px;padding:4px}
  .tier-title{margin-bottom:8px}
}
