/* =============================================================================
   Glooopp — lenguaje visual "dark luxury gaming" del área de cliente.
   Portado del prototipo de Claude Design (Glooopp Prototype), tokens incluidos.

   Sólo se aplica al área Consumer y sólo con Fase2.ConsumerDarkUI encendido.
   El área de administración NO usa nada de aquí.

   Todo lo que estaba dentro del marco de móvil del prototipo (.gl-screen a
   pantalla completa, overflow hidden) se ha adaptado a una página web normal:
   aquí el que hace scroll es el documento, no un div.
   ============================================================================= */

/* Glooopp — dark luxury gaming tokens */
:root {
  --bg-void: #06060A;
  --bg-canvas: #0D0D12;
  --bg-surface: #16161C;
  --bg-surface-2: #1B1B23;
  --bg-elevated: #1F1F27;
  --bg-wine: #1A0E11;

  --line-hair: #2A2A33;
  --line-gold: #3D3524;
  --line-wine: #3a1d23;

  --fg: #F5EFE0;
  --fg-2: #C7C0B0;
  --fg-3: #9E9A8E;
  --fg-4: #5D5A52;

  --gold: #D4A347;
  --gold-bright: #E8B64C;
  --gold-deep: #8C6A2B;
  --burgundy: #722F37;
  --burgundy-deep: #3a1820;

  --neon-purple: #9B4DFF;
  --neon-cyan: #00E5FF;

  --ok: #4ADE80;
  --warn: #F5B301;
  --danger: #EF4444;

  --radius-chip: 4px;
  --radius-card: 14px;
  --radius-sheet: 22px;

  --serif: 'Cormorant Garamond', 'Playfair Display', Georgia, serif;
  --ui: 'Space Grotesk', 'Inter', system-ui, -apple-system, sans-serif;
  --mono: 'JetBrains Mono', 'SF Mono', ui-monospace, monospace;
  --cinzel: 'Cinzel', 'Cormorant Garamond', serif;
}

* { box-sizing: border-box; -webkit-font-smoothing: antialiased; }
/* Sólo se tiñe el body cuando la vista pide el tema oscuro, para no arrastrar
   al resto de la aplicación. */
body.gl-dark {
  margin: 0; padding: 0;
  font-family: var(--ui);
  color: var(--fg);
  background: #0A0A0E;
  /* Le dice al navegador que esta página es oscura, y así los controles nativos
     —casillas, radios, selectores de fecha, barras de scroll— salen oscuros en
     vez de blancos. accent-color no basta: sólo tiñe la casilla MARCADA, y la
     vacía seguía siendo un cuadrado blanco. */
  color-scheme: dark;
}

/* Screen (inside phone frame) */
.gl-screen {
  width: 100%;
  min-height: 100vh;
  background:
    radial-gradient(120% 80% at 50% -10%, rgba(114, 47, 55, 0.22), transparent 60%),
    radial-gradient(100% 60% at 0% 100%, rgba(155, 77, 255, 0.10), transparent 60%),
    linear-gradient(180deg, #0A0A10 0%, #06060A 100%);
  color: var(--fg);
  font-family: var(--ui);
  position: relative;
}
.gl-screen::before {
  /* grano de película. fixed y no absolute: en una página larga, con absolute
     el grano sólo cubriría la primera pantalla. */
  content: '';
  position: fixed; inset: 0;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='160' height='160'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/><feColorMatrix values='0 0 0 0 1  0 0 0 0 1  0 0 0 0 1  0 0 0 0.08 0'/></filter><rect width='100%25' height='100%25' filter='url(%23n)'/></svg>");
  mix-blend-mode: overlay;
  opacity: 0.35;
  pointer-events: none;
  z-index: 1;
}

/* En el prototipo esto era el contenedor con scroll dentro del móvil. En web
   basta con que quede por encima del grano y con el ancho de lectura acotado. */
.gl-scroll { position: relative; z-index: 2; }
/* El hueco de abajo tiene que dejar sitio a la barra de navegación, al área
   segura del móvil y, si la pantalla la tiene, a la barra de acción fija.
   Con 96px la última fila quedaba tapada. */
.gl-wrap { max-width: 900px; margin: 0 auto;
           padding: 0 20px calc(130px + env(safe-area-inset-bottom)); }
.gl-wrap.con-cta { padding-bottom: calc(200px + env(safe-area-inset-bottom)); }

.serif { font-family: var(--serif); font-weight: 500; letter-spacing: 0.01em; }
.mono { font-family: var(--mono); }
.cinzel { font-family: var(--cinzel); font-weight: 700; letter-spacing: 0.12em; }

.hairline { border: 1px solid var(--line-hair); }
.gold-line { border: 1px solid var(--line-gold); }

/* Gold CTA with shimmer */
.btn-gold {
  position: relative;
  background: linear-gradient(180deg, #d9aa4e 0%, #b88729 100%);
  color: #1a0f02;
  font-family: var(--ui);
  font-weight: 600;
  letter-spacing: 0.02em;
  border: none;
  border-radius: 999px;
  padding: 14px 20px;
  cursor: pointer;
  box-shadow:
    0 0 0 1px rgba(232, 182, 76, 0.35),
    0 10px 30px -10px rgba(212, 163, 71, 0.55),
    inset 0 1px 0 rgba(255, 230, 170, 0.6);
  overflow: hidden;
  isolation: isolate;
}
.btn-gold::after {
  content: '';
  position: absolute; inset: 0;
  background: linear-gradient(110deg, transparent 35%, rgba(255,255,255,0.55) 50%, transparent 65%);
  transform: translateX(-120%);
  animation: shimmer 4.2s ease-in-out infinite;
  pointer-events: none;
}
@keyframes shimmer { 0%, 45% { transform: translateX(-120%);} 70%, 100% { transform: translateX(120%);} }

.btn-ghost {
  background: transparent;
  color: var(--fg);
  border: 1px solid var(--line-hair);
  border-radius: 999px;
  padding: 12px 18px;
  font-family: var(--ui);
  font-weight: 500;
  cursor: pointer;
}

.chip {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 4px 10px;
  border-radius: 999px;
  font-size: 11px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  font-weight: 600;
  font-family: var(--ui);
  border: 1px solid var(--line-hair);
  color: var(--fg-3);
  background: rgba(255,255,255,0.02);
}
.chip.gold { color: var(--gold-bright); border-color: var(--line-gold); background: rgba(212,163,71,0.08); }
.chip.wine { color: #e7a3ad; border-color: var(--line-wine); background: rgba(114,47,55,0.18); }
.chip.neon { color: var(--neon-cyan); border-color: rgba(0,229,255,0.35); background: rgba(0,229,255,0.08); }
.chip.purple { color: #c9a3ff; border-color: rgba(155,77,255,0.35); background: rgba(155,77,255,0.10); }
.chip.ok { color: var(--ok); border-color: rgba(74,222,128,0.35); background: rgba(74,222,128,0.08); }

.card {
  background: var(--bg-surface);
  border: 1px solid var(--line-hair);
  border-radius: var(--radius-card);
}
.card-elev { background: var(--bg-elevated); border: 1px solid var(--line-hair); border-radius: var(--radius-card); }
.card-gold { border-color: var(--line-gold); box-shadow: inset 0 0 0 1px rgba(212,163,71,0.12), 0 20px 40px -20px rgba(212,163,71,0.25); }

/* Scanlines gradient helper */
.bottle-ph {
  background:
    radial-gradient(60% 35% at 50% 18%, rgba(212,163,71,0.25), transparent 70%),
    linear-gradient(180deg, #1a0d10 0%, #0a0507 100%);
}

/* Gold glow */
.glow-gold { box-shadow: 0 0 0 1px rgba(232,182,76,0.35), 0 0 24px rgba(212,163,71,0.25); }
.glow-cyan { box-shadow: 0 0 0 1px rgba(0,229,255,0.35), 0 0 30px rgba(0,229,255,0.25); }
.glow-purple { box-shadow: 0 0 0 1px rgba(155,77,255,0.35), 0 0 30px rgba(155,77,255,0.25); }

/* XP particle */
@keyframes xpFly {
  0%   { transform: translate(var(--from-x, 0), var(--from-y, 0)) scale(1); opacity: 1; }
  60%  { opacity: 1; }
  100% { transform: translate(var(--to-x, 0), var(--to-y, 0)) scale(0.6); opacity: 0; }
}
.xp-float {
  position: absolute;
  font-family: var(--mono);
  font-weight: 600;
  color: #c9a3ff;
  text-shadow: 0 0 12px rgba(155,77,255,0.8);
  pointer-events: none;
  animation: xpFly 1.2s cubic-bezier(.2,.6,.2,1) forwards;
  z-index: 20;
}

/* Pulse for scanner laser */
@keyframes laser {
  0% { transform: translateY(0); opacity: 0.2; }
  50% { transform: translateY(180px); opacity: 1; }
  100% { transform: translateY(0); opacity: 0.2; }
}
.scanner-laser {
  position: absolute; left: 8%; right: 8%; height: 2px;
  background: linear-gradient(90deg, transparent, #E8B64C, transparent);
  box-shadow: 0 0 18px rgba(232,182,76,0.8);
  animation: laser 2.4s ease-in-out infinite;
}

/* Pulse dot */
@keyframes pulseDot { 0% { transform: scale(1); opacity: 1;} 100% { transform: scale(2.6); opacity: 0;} }

/* Bottle slow spin for wine detail */
@keyframes slowSpin { 0% { transform: rotate(-3deg);} 50% { transform: rotate(3deg);} 100% { transform: rotate(-3deg);} }

.bottle-sway { animation: slowSpin 6s ease-in-out infinite; transform-origin: 50% 85%; }

/* Copa fill animation on rate */
.copa { width: 26px; height: 34px; display: inline-block; }

/* Level up overlay */
@keyframes overlayIn { from { opacity: 0;} to { opacity: 1;} }
@keyframes letterIn { from { letter-spacing: 0.5em; opacity: 0;} to { letter-spacing: 0.15em; opacity: 1; } }
@keyframes badgePop { 0% { transform: scale(0.4); opacity: 0;} 60% { transform: scale(1.15); opacity: 1;} 100% { transform: scale(1);} }

/* Bottom nav */
.nav-item { display: flex; flex-direction: column; align-items: center; gap: 3px; font-size: 10px; color: var(--fg-4); letter-spacing: 0.05em; text-transform: uppercase; font-weight: 600; }
.nav-item.active { color: var(--gold-bright); }

/* Reduce motion */
@media (prefers-reduced-motion: reduce) {
  .btn-gold::after, .scanner-laser, .bottle-sway { animation: none !important; }
  .xp-float { animation-duration: 0.01s !important; }
}

/* ── Barra de navegación inferior ────────────────────────────────────────────
   En el prototipo flota dentro del marco del móvil. Aquí va fija abajo y
   respeta el área segura de los iPhone con notch. */
.gl-nav {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 30;
  padding: 10px 14px calc(14px + env(safe-area-inset-bottom));
  background: linear-gradient(180deg, rgba(6,6,10,0) 0%, rgba(6,6,10,.9) 40%, #06060A 100%);
}
.gl-nav-inner {
  max-width: 560px; margin: 0 auto;
  display: flex; justify-content: space-around; align-items: flex-end;
  background: rgba(22,22,28,.75);
  backdrop-filter: blur(20px);
  border: 1px solid var(--line-hair);
  border-radius: 28px;
  padding: 10px 8px 12px;
}
.gl-nav .nav-item { text-decoration: none; padding: 4px 8px; min-width: 56px; }
.gl-nav .nav-item i { font-size: 18px; }
.gl-nav .nav-item.active i { filter: drop-shadow(0 0 8px rgba(232,182,76,.5)); }

.nav-qr { text-decoration: none; display: flex; flex-direction: column; align-items: center; margin-top: -22px; }
.nav-qr-disc {
  width: 54px; height: 54px; border-radius: 50%;
  background: radial-gradient(circle at 30% 30%, #E8B64C, #8C6A2B 70%, #3d2910 100%);
  display: flex; align-items: center; justify-content: center;
  color: #1a0f02; font-size: 22px;
  box-shadow: 0 0 0 1px rgba(232,182,76,.5), 0 0 30px rgba(212,163,71,.45),
              inset 0 1px 0 rgba(255,230,170,.6);
}
.nav-qr-label { font-size: 10px; color: var(--gold-bright); margin-top: 6px;
                letter-spacing: .08em; text-transform: uppercase; font-weight: 600; }

/* ── Hero de la ficha de cata ─────────────────────────────────────────────── */
.gl-hero { position: relative; min-height: 46vh; display: flex; align-items: flex-end;
           background-size: cover; background-position: center; }
/* Oscuro sólo a la izquierda, donde va el texto; la derecha se ve entera (Victor, 2026-09-16). Abajo, una franja
   corta que funde con la página. */
.gl-hero::after { content: ''; position: absolute; inset: 0;
  background:
    linear-gradient(90deg, rgba(6,6,10,.82) 0%, rgba(6,6,10,.5) 38%, rgba(6,6,10,0) 68%),
    linear-gradient(180deg, rgba(6,6,10,0) 80%, #06060A 100%); }
@media (min-width: 900px) {
  .gl-hero::after { background:
    linear-gradient(90deg, rgba(6,6,10,.82) 0%, rgba(6,6,10,.5) 50%, rgba(6,6,10,0) 80%),
    linear-gradient(180deg, rgba(6,6,10,0) 80%, #06060A 100%); }
}
.gl-hero-body h1, .gl-hero-body .gl-pass-m, .gl-feat-b h3, .gl-feat-b .gl-pass-m { text-shadow: 0 1px 12px rgba(6,6,10,.9); }
.gl-hero-body { position: relative; z-index: 2; width: 100%;
                max-width: 900px; margin: 0 auto; padding: 0 20px 26px; }
.gl-hero h1 { font-family: var(--serif); font-weight: 600; font-size: clamp(30px, 6vw, 46px);
              line-height: 1.05; margin: 10px 0 6px; color: var(--fg); }
.gl-hero .lugar { color: var(--fg-3); font-size: 14px; }

.gl-meta { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 14px; }

/* ── Secciones y tarjetas de vino ─────────────────────────────────────────── */
.gl-sec { margin-top: 30px; }
.gl-sec-t { font-family: var(--serif); font-size: 22px; font-weight: 600;
            margin: 0 0 14px; color: var(--fg); }

.gl-wines { display: grid; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); gap: 12px; }
.gl-wine { display: flex; gap: 14px; padding: 14px; text-decoration: none; color: inherit;
           background: var(--bg-surface); border: 1px solid var(--line-hair);
           border-radius: var(--radius-card); transition: border-color .18s, transform .18s; }
.gl-wine:hover { border-color: var(--line-gold); transform: translateY(-2px); }
.gl-wine-ph { width: 58px; min-width: 58px; min-height: 96px; border-radius: 8px;
              display: flex; align-items: flex-end; justify-content: center;
              color: rgba(212,163,71,.55); font-size: 22px; }
.gl-wine-ph img { max-width: 58px; max-height: 96px; object-fit: contain; }
.gl-bottle { display: block; }
/* Las botellas de plantilla son fotos recortadas: el ancho sale de su proporción,
   y una sombra suave las posa sobre la tarjeta en vez de dejarlas flotando. */
.gl-bottle-tpl { width: auto; filter: drop-shadow(0 6px 10px rgba(0,0,0,.5)); }
.gl-wine-n { font-family: var(--serif); font-size: 17px; line-height: 1.2; margin-bottom: 4px; }
.gl-wine-m { font-size: 12px; color: var(--fg-3); }
.gl-copas { color: var(--gold); font-size: 12px; margin-top: 6px; letter-spacing: .08em; }
.gl-copas .off { color: var(--fg-4); }
.gl-copas .n { font-family: var(--mono); color: var(--fg-3); margin-left: 6px; }

/* ── Reserva de botellas ──────────────────────────────────────────────────── */
.gl-res { display: flex; align-items: center; gap: 10px; margin-top: 10px;
          padding-top: 10px; border-top: 1px dashed var(--line-hair); }
.gl-res.busy { opacity: .5; pointer-events: none; }
.gl-step { width: 30px; height: 30px; border-radius: 50%; cursor: pointer;
           border: 1px solid var(--line-gold); background: rgba(212,163,71,.08);
           color: var(--gold-bright); display: inline-flex; align-items: center;
           justify-content: center; font-weight: 700; user-select: none; }
.gl-step:hover { background: var(--gold); color: #1a0f02; }
.gl-count { font-family: var(--mono); font-weight: 600; min-width: 18px; text-align: center; }
.gl-res-l { font-size: 10px; letter-spacing: .1em; text-transform: uppercase; color: var(--fg-4); }
.gl-res.on .gl-res-l { color: var(--ok); }

/* ── Barra de acción fija ─────────────────────────────────────────────────── */
.gl-cta { position: fixed; left: 0; right: 0; bottom: 0; z-index: 25;
          padding: 14px 20px calc(96px + env(safe-area-inset-bottom));
          background: linear-gradient(180deg, rgba(6,6,10,0), #06060A 45%); }
.gl-cta-in { max-width: 560px; margin: 0 auto; display: flex; gap: 10px; }
/* El reparto va en .gl-cta-in, no en .gl-cta: once pantallas usan la fila de
   botones sin la barra fija, y ahí cada botón se quedaba del ancho de su texto
   —"Back" pequeñito al lado de "Save changes"—. */
.gl-cta-in > * { flex: 1 1 0; min-width: 0; }
.gl-cta .btn-gold, .gl-cta .btn-ghost { font-size: 15px; }
.gl-done { flex: 1; text-align: center; padding: 14px 20px; border-radius: 999px;
           border: 1px solid rgba(74,222,128,.35); background: rgba(74,222,128,.08);
           color: var(--ok); font-weight: 600; }

/* ── Portada del cliente ─────────────────────────────────────────────────── */
.gl-head { display: flex; align-items: center; gap: 12px; margin-bottom: 16px; }
.gl-hola { font-family: var(--serif); font-size: 22px; font-weight: 600; }

/* Chapa de nivel: octógono recortado, como el badge del prototipo. */
.gl-lvl {
  width: 46px; height: 46px; min-width: 46px;
  clip-path: polygon(50% 0%, 93% 25%, 93% 75%, 50% 100%, 7% 75%, 7% 25%);
  background: linear-gradient(160deg, #2a2113, #16161C);
  border: 0; position: relative;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  color: var(--gold-bright);
  box-shadow: 0 0 18px rgba(212,163,71,.28);
}
.gl-lvl i { font-size: 13px; line-height: 1; }
.gl-lvl span { font-size: 12px; line-height: 1.1; }

.gl-xp-top { display: flex; justify-content: space-between; align-items: baseline; margin: 2px 0 5px; gap: 10px; }
.gl-xp { height: 6px; background: rgba(255,255,255,.05); border: 1px solid var(--line-hair);
         border-radius: 999px; overflow: hidden; }
.gl-xp-fill { height: 100%; border-radius: 999px;
              background: linear-gradient(90deg, #8C6A2B, #D4A347 50%, #E8B64C);
              box-shadow: 0 0 8px rgba(232,182,76,.5); }

.gl-stats { display: grid; grid-template-columns: repeat(4, 1fr); gap: 8px; margin-bottom: 6px; }
.gl-stats > div, .gl-stats > a { background: var(--bg-surface); border: 1px solid var(--line-hair);
                border-radius: var(--radius-card); padding: 10px; text-align: center; }
.gl-stats b { display: block; font-family: var(--mono); font-size: 17px; color: var(--gold-bright); }
.gl-stats span { font-size: 10px; letter-spacing: .1em; text-transform: uppercase; color: var(--fg-4); }

/* Carril horizontal de "mis próximas catas", tipo tarjeta de embarque. */
.gl-rail { display: flex; gap: 10px; overflow-x: auto; padding-bottom: 4px;
           scrollbar-width: none; }
.gl-rail::-webkit-scrollbar { display: none; }
.gl-pass { display: flex; gap: 12px; align-items: center; min-width: 240px;
           padding: 12px; text-decoration: none; color: inherit;
           background: var(--bg-surface); border: 1px solid var(--line-gold);
           border-radius: var(--radius-card); }
.gl-pass-d { text-align: center; min-width: 46px; padding-right: 12px;
             border-right: 1px dashed var(--line-hair); }
.gl-pass-d b { display: block; font-family: var(--serif); font-size: 26px; line-height: 1;
               color: var(--gold-bright); }
.gl-pass-d span { font-size: 10px; text-transform: uppercase; letter-spacing: .12em; color: var(--fg-3); }
.gl-pass-d.small b { font-size: 20px; }
.gl-pass-n { font-family: var(--serif); font-size: 17px; line-height: 1.2;
             overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.gl-pass-m { font-size: 12px; color: var(--fg-3); margin-top: 2px; }

/* Cata destacada */
.gl-feat { display: block; position: relative; min-height: 210px; border-radius: var(--radius-card);
           overflow: hidden; text-decoration: none; color: inherit;
           background-size: cover; background-position: center;
           border: 1px solid var(--line-gold); }
.gl-feat::after { content: ''; position: absolute; inset: 0;
  background: linear-gradient(90deg, rgba(6,6,10,.85) 0%, rgba(6,6,10,.5) 45%, rgba(6,6,10,0) 75%); }
.gl-feat-b { position: relative; z-index: 2; padding: 18px; display: flex;
             flex-direction: column; justify-content: flex-end; min-height: 210px; }
.gl-feat-b h3 { font-family: var(--serif); font-size: 26px; font-weight: 600; margin: 8px 0 2px; }

.gl-list { display: flex; flex-direction: column; gap: 8px; }
.gl-row { display: flex; align-items: center; gap: 12px; padding: 12px;
          text-decoration: none; color: inherit; background: var(--bg-surface);
          border: 1px solid var(--line-hair); border-radius: var(--radius-card);
          transition: border-color .18s; }
.gl-row:hover { border-color: var(--line-gold); }

.gl-totals { display: flex; justify-content: center; gap: 28px; padding: 18px 0 4px;
             border-top: 1px solid var(--line-hair); }
.gl-totals div { text-align: center; }
.gl-totals b { display: block; font-size: 18px; color: var(--fg-2); }
.gl-totals span { font-size: 10px; letter-spacing: .1em; text-transform: uppercase; color: var(--fg-4); }

/* ── Ficha de vino ───────────────────────────────────────────────────────── */
.gl-stage { position: relative; height: 330px; overflow: hidden; display: flex;
            align-items: center; justify-content: center; }
.gl-stage-glow { position: absolute; inset: 0;
  background: radial-gradient(80% 60% at 50% 42%, rgba(114,47,55,.7), transparent 70%),
              linear-gradient(180deg, #140508 0%, #06060A 100%); }
.gl-stage::after { content: ''; position: absolute; inset: 0;
  background: linear-gradient(180deg, rgba(6,6,10,.1) 0%, transparent 28%, transparent 62%, #06060A 100%); }
.gl-stage-bottle { position: relative; z-index: 2; transform: translateY(14px);
                   filter: drop-shadow(0 30px 34px rgba(0,0,0,.85)); }
.gl-stage-bottle img { max-height: 260px; max-width: 60vw; object-fit: contain; }

.gl-wine-title { font-family: var(--serif); font-weight: 600; font-size: clamp(26px, 5.4vw, 36px);
                 line-height: 1.1; margin: 10px 0 4px; }

.gl-copas { display: inline-flex; align-items: center; gap: 3px; }

/* Valoración en copas */
.gl-rate { display: flex; justify-content: center; gap: 10px; margin-bottom: 14px; }
.gl-rate i { font-size: 26px; color: var(--fg-4); cursor: pointer;
             transition: color .15s, transform .15s; }
.gl-rate i:hover { transform: translateY(-2px); }
.gl-rate i.on { color: var(--gold-bright); text-shadow: 0 0 14px rgba(232,182,76,.55); }

.gl-ta { width: 100%; background: var(--bg-canvas); color: var(--fg);
         border: 1px solid var(--line-hair); border-radius: 12px; padding: 10px 12px;
         font-family: var(--ui); font-size: 14px; resize: vertical; }
.gl-ta:focus { outline: none; border-color: var(--line-gold); }

/* Aviso de XP ganado */
.gl-toast { margin-top: 10px; height: 20px; font-family: var(--mono); font-weight: 600;
            color: #c9a3ff; text-shadow: 0 0 12px rgba(155,77,255,.8);
            opacity: 0; transform: translateY(6px); transition: opacity .25s, transform .25s; }
.gl-toast.show { opacity: 1; transform: translateY(0); }

/* ── Calendario de catas ─────────────────────────────────────────────────── */
.gl-cal-top { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.gl-cal-mes { font-family: var(--serif); font-size: 26px; font-weight: 600; margin: 0;
              text-transform: capitalize; }
.gl-cal-mes .mono { font-size: 15px; color: var(--fg-3); text-transform: none; }
.gl-cal-nav { width: 38px; height: 38px; border-radius: 50%; display: flex;
              align-items: center; justify-content: center; text-decoration: none;
              color: var(--fg-2); border: 1px solid var(--line-hair); }
.gl-cal-nav:hover { border-color: var(--line-gold); color: var(--gold-bright); }

.gl-filtros { display: flex; gap: 8px; margin: 16px 0 4px; }
.gl-filtro { padding: 8px 14px; border-radius: 999px; cursor: pointer;
             border: 1px solid var(--line-hair); background: transparent;
             color: var(--fg-3); font-family: var(--ui); font-size: 13px; }
.gl-filtro.activo { border-color: var(--line-gold); background: rgba(212,163,71,.08);
                    color: var(--gold-bright); }

.gl-cal { display: grid; grid-template-columns: repeat(7, 1fr); gap: 4px; margin-top: 16px; }
.gl-cal-h { text-align: center; font-size: 10px; letter-spacing: .1em; color: var(--fg-4);
            text-transform: uppercase; padding-bottom: 4px; }
.gl-cal-d { position: relative; aspect-ratio: 1 / 1; display: flex; flex-direction: column;
            align-items: center; justify-content: center; border-radius: 10px;
            font-size: 13px; color: var(--fg-4); border: 1px solid transparent; }
.gl-cal-d.vacio { visibility: hidden; }
.gl-cal-d.con { color: var(--fg); background: rgba(255,255,255,.03);
                border-color: var(--line-hair); cursor: pointer; }
.gl-cal-d.con:hover { border-color: var(--line-gold); }
.gl-cal-d.hoy { color: var(--gold-bright); }
.gl-cal-d.sel { background: rgba(212,163,71,.12); border-color: var(--gold);
                color: var(--gold-bright); }
.gl-cal-p { position: absolute; bottom: 4px; font-size: 9px; line-height: 1;
            color: var(--gold); letter-spacing: 1px; font-weight: 700; }

.gl-cata { display: flex; gap: 12px; align-items: center; padding: 10px;
           text-decoration: none; color: inherit; background: var(--bg-surface);
           border: 1px solid var(--line-hair); border-radius: var(--radius-card);
           transition: border-color .18s; }
.gl-cata:hover { border-color: var(--line-gold); }
.gl-cata.voy { border-color: rgba(74,222,128,.3); }
.gl-cata-img { width: 62px; min-width: 62px; height: 62px; border-radius: 10px;
               background-size: cover; background-position: center;
               background-color: #14090c; display: flex; align-items: center;
               justify-content: center; color: var(--gold-deep); }

/* ── QR de compra ────────────────────────────────────────────────────────── */
/* Más ancha y con menos relleno que antes: cada píxel que gana la tarjeta es
   un píxel más por módulo del código, y eso es justo lo que decide si el móvil
   de la tienda lo lee. */
.gl-qr-card { max-width: 360px; margin: 0 auto; padding: 14px; text-align: center;
              background: var(--bg-surface); border: 1px solid var(--line-gold);
              border-radius: 20px;
              box-shadow: inset 0 0 0 1px rgba(212,163,71,.12),
                          0 0 40px -8px rgba(212,163,71,.35); }
.gl-qr-card.ok { border-color: rgba(74,222,128,.45);
                 box-shadow: 0 0 40px -8px rgba(74,222,128,.35); }
.gl-qr-card.off { border-color: var(--line-hair); box-shadow: none; opacity: .7; }
.gl-qr { display: flex; justify-content: center; }
/* Zona de silencio: el QR necesita un margen claro alrededor. Pegado al borde
   de una tarjeta oscura, el anillo exterior de los patrones de posición se
   fundía con el fondo y ningún decodificador lo encontraba, aunque la cámara
   del móvil, más tolerante, sí lo leía. El redondeo va en el margen, no en los
   módulos.

   El margen ya no lo pone el CSS: viene dentro de la imagen, que es donde no se
   puede perder. Aquí se intentó con padding y salió mal de dos maneras a la vez
   —box-sizing:border-box hacía que el margen se comiera el código, y la regla
   sólo apuntaba a `img` cuando la librería deja un `canvas` en algunos
   navegadores—. Ver gl-qr.js. */
.gl-qr img, .gl-qr canvas {
    display: block; max-width: 100%; height: auto;
    background: #FFFFFF; border-radius: 14px; }
.gl-qr-token { margin-top: 14px; font-size: 15px; letter-spacing: .18em;
               color: var(--gold-bright); }

.gl-esperando { margin-top: 12px; font-size: 12px; color: var(--fg-3);
                display: flex; align-items: center; justify-content: center; gap: 3px; }
.gl-esperando i { width: 4px; height: 4px; border-radius: 50%; background: var(--gold);
                  display: inline-block; animation: pestanea 1.4s infinite; }
.gl-esperando i:nth-child(3) { animation-delay: .2s; }
.gl-esperando i:nth-child(4) { animation-delay: .4s; }
@keyframes pestanea { 0%,80%,100% { opacity: .2; } 40% { opacity: 1; } }

.gl-tick { width: 96px; height: 96px; margin: 6px auto 4px; border-radius: 50%;
           display: flex; align-items: center; justify-content: center;
           font-size: 40px; color: var(--ok);
           background: rgba(74,222,128,.1); border: 1px solid rgba(74,222,128,.35); }
.gl-tick.off { color: var(--fg-4); background: rgba(255,255,255,.03);
               border-color: var(--line-hair); }

.gl-item { display: flex; justify-content: space-between; gap: 12px; padding: 10px 0;
           border-bottom: 1px solid var(--line-hair); }
.gl-item:last-child { border-bottom: 0; }
.gl-item.total { border-top: 1px dashed var(--line-hair); border-bottom: 0; margin-top: 4px; }

/* ── Perfil y camino de niveles ──────────────────────────────────────────── */
.gl-perfil { text-align: center; }
.gl-perfil-n { font-family: var(--serif); font-size: 28px; font-weight: 600; margin: 14px 0 2px; }

/* El aro se rellena según el progreso al siguiente nivel (--pct de 0 a 100). */
.gl-aro { width: 116px; height: 116px; margin: 0 auto; border-radius: 50%;
          display: flex; align-items: center; justify-content: center;
          background: conic-gradient(var(--gold) calc(var(--pct) * 1%),
                                     rgba(255,255,255,.07) 0);
          box-shadow: 0 0 30px rgba(212,163,71,.25); }
.gl-aro-in { width: 100px; height: 100px; border-radius: 50%;
             background: linear-gradient(160deg, #221a10, #0f0f14);
             border: 1px solid var(--line-gold);
             display: flex; flex-direction: column; align-items: center;
             justify-content: center; gap: 2px; color: var(--gold-bright); }
.gl-aro-in i { font-size: 22px; }
.gl-aro-in span { font-size: 20px; }

.gl-falta { margin-top: 12px; font-size: 13px; color: var(--fg-3); }
.gl-falta b { color: var(--fg); font-style: italic; }

.gl-camino { display: flex; flex-direction: column; gap: 8px; }
.gl-nivel { display: flex; align-items: center; gap: 12px; padding: 12px;
            background: var(--bg-surface); border: 1px solid var(--line-hair);
            border-radius: var(--radius-card); }
.gl-nivel-i { width: 40px; min-width: 40px; height: 40px; border-radius: 50%;
              display: flex; align-items: center; justify-content: center;
              background: rgba(255,255,255,.03); color: var(--fg-4); }
.gl-nivel-n { font-family: var(--serif); font-size: 18px; }
.gl-nivel-xp { font-size: 11px; color: var(--fg-4); }

.gl-nivel.completed .gl-nivel-i { color: var(--fg-2); background: rgba(255,255,255,.05); }
.gl-nivel.current { border-color: var(--gold); background: rgba(212,163,71,.07);
                    box-shadow: 0 0 24px -6px rgba(212,163,71,.4); }
.gl-nivel.current .gl-nivel-i { color: var(--gold-bright);
                                background: rgba(212,163,71,.14); }
.gl-nivel.locked { opacity: .55; }

/* Hoja inferior */
/* La hoja vive dentro de .gl-scroll, que tiene z-index propio y por tanto crea
   contexto de apilamiento: por muy alto que sea su z-index, no puede pasar por
   encima de la barra de navegación, que es hermana de .gl-scroll. En vez de
   pelearse con las capas, mientras hay una hoja abierta la barra se retira,
   que además es lo que hace cualquier app al abrir una hoja modal. */
body.con-hoja .gl-nav { display: none; }

.gl-sheet { position: fixed; inset: 0; z-index: 60; display: none;
            background: rgba(6,6,10,.75); backdrop-filter: blur(6px); }
/* Anclada al fondo con position, no con flex-end: con el contenedor flex el
   interior acababa 30px por debajo del borde y el botón de cerrar quedaba fuera
   de la pantalla. Así no hay dudas de dónde queda. */
.gl-sheet.abierta { display: block; }
.gl-sheet-in { position: absolute; left: 0; right: 0; bottom: 0;
               width: 100%; max-width: 460px; margin: 0 auto;
               background: var(--bg-elevated); border: 1px solid var(--line-hair);
               border-radius: var(--radius-sheet) var(--radius-sheet) 0 0;
               padding: 12px 20px calc(24px + env(safe-area-inset-bottom));
               /* Transición y no animación: con @@keyframes, si la animación no
                  llega a avanzar (pestaña en segundo plano, motor con las
                  animaciones frenadas) el elemento se queda clavado en el primer
                  fotograma, 30px más abajo, y el botón de cerrar acaba fuera de
                  la pantalla. Con transición el estado por defecto ya es el
                  bueno y sólo se anima la entrada. */
               transform: translateY(30px); opacity: 0;
               transition: transform .25s ease-out, opacity .25s ease-out;
               /* En pantallas cortas el QR más el botón no caben: que la hoja
                  se pueda desplazar en vez de dejar el botón fuera. */
               max-height: 92vh; overflow-y: auto; }
.gl-sheet.abierta .gl-sheet-in { transform: translateY(0); opacity: 1; }
.gl-sheet-asa { width: 42px; height: 4px; border-radius: 999px;
                background: var(--line-hair); margin: 0 auto 12px; }


/* ── Escáner ─────────────────────────────────────────────────────────────── */
/* El escáner es CUADRADO a propósito, y el recuadro dorado marca exactamente la
   zona que se lee. Antes el visor era una franja alargada puramente decorativa
   mientras la librería leía otra región: el dependiente no sabía dónde apuntar.
   Y sin límite de ancho, el vídeo salía a su tamaño natural y desbordaba la
   página a la derecha en el móvil. */
.gl-scan { position: relative; background: #08080c; overflow: hidden;
           width: 100%; max-width: 100%; margin: 0 auto;
           aspect-ratio: 1 / 1;
           /* Tope de altura: sin esto la cámara se comía la pantalla del móvil y
              la casilla para teclear el código quedaba fuera, había que alejar el
              zoom para verla. */
           max-height: 46vh; }
.gl-scan-cam { width: 100%; height: 100%; max-width: 100%; overflow: hidden; }
/* !important: html5-qrcode escribe medidas en el propio elemento. */
.gl-scan-cam video, .gl-scan-cam canvas {
  width: 100% !important; height: 100% !important;
  object-fit: cover; display: block; }
.gl-scan.sin-camara { aspect-ratio: auto; min-height: 160px; }

/* Ningún elemento del escáner puede empujar la página a lo ancho: en iOS eso
   dispara el "encoger para caber" y toda la pantalla se ve ampliada de golpe. */
.gl-scan, .gl-scan * { max-width: 100%; }

/* Navegadores sin aspect-ratio (Safari viejo): se cae a una altura fija. */
@supports not (aspect-ratio: 1 / 1) {
  .gl-scan { height: 340px; }
}
.gl-scan.destello::after { content: ''; position: absolute; inset: 0;
                           box-shadow: inset 0 0 0 3px var(--gold-bright);
                           pointer-events: none; }

/* Arranque de la cámara: botón centrado sobre el recuadro negro, y el motivo
   cuando falla. Antes un fallo dejaba un cuadro negro sin decir nada. */
.gl-scan-arranque { position: absolute; inset: 0; display: flex; z-index: 2;
                    flex-direction: column; align-items: center; justify-content: center;
                    gap: 12px; padding: 20px; text-align: center; }
.gl-scan-sub { color: var(--fg-3); font-size: 13px; max-width: 26ch; }

/* Esquinas doradas del visor */
/* Cuadrado y centrado, del mismo tamaño que el qrbox del lector (85%). */
.gl-visor { position: absolute; inset: 7.5%; pointer-events: none; }
.gl-visor .e { position: absolute; width: 26px; height: 26px;
               border: 2px solid var(--gold-bright); }
.gl-visor .tl { top: 0; left: 0; border-right: 0; border-bottom: 0; border-radius: 6px 0 0 0; }
.gl-visor .tr { top: 0; right: 0; border-left: 0; border-bottom: 0; border-radius: 0 6px 0 0; }
.gl-visor .bl { bottom: 0; left: 0; border-right: 0; border-top: 0; border-radius: 0 0 0 6px; }
.gl-visor .br { bottom: 0; right: 0; border-left: 0; border-top: 0; border-radius: 0 0 6px 0; }
/* En porcentaje, no en píxeles: el visor ya no tiene una altura fija. */
.gl-visor .scanner-laser { top: 0; left: 0; right: 0;
                           animation: laserCuadro 2.4s ease-in-out infinite; }
@keyframes laserCuadro { 0% { top: 2%; opacity: .25; }
                         50% { top: 96%; opacity: 1; }
                         100% { top: 2%; opacity: .25; } }

.gl-scan-t { position: absolute; left: 0; right: 0; bottom: 14px; text-align: center;
             font-size: 13px; color: var(--fg-2);
             text-shadow: 0 1px 8px rgba(0,0,0,.9); }

.gl-manual { display: flex; gap: 8px; }
.gl-input { flex: 1; background: var(--bg-canvas); color: var(--fg);
            border: 1px solid var(--line-hair); border-radius: 999px;
            padding: 12px 16px; font-family: var(--mono); font-size: 14px; }
.gl-input:focus { outline: none; border-color: var(--line-gold); }

/* Aviso flotante de "añadida" / error */
.gl-aviso { position: fixed; left: 50%; transform: translateX(-50%);
            bottom: calc(180px + env(safe-area-inset-bottom)); z-index: 70;
            padding: 10px 18px; border-radius: 999px; font-size: 13px;
            background: var(--bg-elevated); border: 1px solid var(--line-hair);
            color: var(--fg); box-shadow: 0 10px 30px -10px rgba(0,0,0,.8); }
.gl-aviso.ok { border-color: rgba(74,222,128,.4); color: var(--ok); }
.gl-aviso.mal { border-color: rgba(239,68,68,.4); color: var(--danger); }

/* Un primario deshabilitado no puede verse igual de apetecible que uno activo:
   se apaga y se le quita el brillo que recorre el borde. */
.btn-gold:disabled { opacity: .4; cursor: not-allowed; box-shadow: none; }
.btn-gold:disabled::after { animation: none; opacity: 0; }

/* ── Área de tienda ──────────────────────────────────────────────────────────
   Mismo lenguaje que el cliente pero más apretado: aquí se viene a trabajar,
   no a coleccionar. Menos aire, más cosas a la vista. */
.gl-hero-tienda { min-height: 34vh; }

.gl-select { background: rgba(0,0,0,.4); color: var(--fg); font-family: var(--ui);
             border: 1px solid var(--line-gold); border-radius: 999px;
             padding: 7px 14px; font-size: 13px; max-width: 100%; }

/* Diez accesos: cinco por fila, o dos en el móvil. Así no queda ninguna fila a medias. */
.gl-acciones { display: grid; grid-template-columns: repeat(5, 1fr); gap: 8px;
               margin-top: 18px; }
@media (max-width: 560px) { .gl-acciones { grid-template-columns: repeat(2, 1fr); } }
.gl-accion { position: relative; }
.gl-accion-n { position: absolute; top: 6px; right: 8px; min-width: 18px; height: 18px; padding: 0 5px;
               border-radius: 9px; background: var(--gold-bright); color: #1a1206; font-size: 11px; font-weight: 700;
               line-height: 18px; text-align: center; }
.gl-accion { display: flex; flex-direction: column; align-items: center; gap: 7px;
             padding: 14px 8px; text-decoration: none; text-align: center;
             background: var(--bg-surface); border: 1px solid var(--line-hair);
             border-radius: var(--radius-card); color: var(--fg-2);
             font-size: 12px; transition: border-color .18s, color .18s; }
.gl-accion i { font-size: 19px; color: var(--fg-3); }
.gl-accion:hover { border-color: var(--line-gold); color: var(--fg); }
.gl-accion:hover i { color: var(--gold-bright); }
.gl-accion.destacada { border-color: var(--line-gold); background: rgba(212,163,71,.08); }
.gl-accion.destacada i, .gl-accion.destacada span { color: var(--gold-bright); }

/* ── Comercial (rep) ─────────────────────────────────────────────────────── */
.gl-volver { display: inline-flex; align-items: center; gap: 6px; text-decoration: none;
             color: var(--fg-3); font-size: 13px; }
.gl-volver:hover { color: var(--gold-bright); }

.gl-pend { border-color: var(--line-gold); background: rgba(212,163,71,.05); }

/* Contador de unidades vendidas: pensado para el dedo, no para el ratón. */
.gl-uds { display: flex; align-items: center; gap: 8px; }
.gl-uds .gl-step { width: 34px; height: 34px; font-size: 16px; }
.gl-uds-n { width: 56px; height: 34px; text-align: center; font-size: 16px;
            background: var(--bg-canvas); color: var(--fg);
            border: 1px solid var(--line-hair); border-radius: 8px; }
.gl-uds-n:focus { outline: none; border-color: var(--line-gold); }
/* Fuera las flechitas del campo numérico: ya hay botones grandes al lado. */
.gl-uds-n::-webkit-outer-spin-button, .gl-uds-n::-webkit-inner-spin-button {
    -webkit-appearance: none; margin: 0; }
.gl-uds-n { -moz-appearance: textfield; }

.gl-fotos { display: grid; grid-template-columns: repeat(auto-fill, minmax(96px, 1fr));
            gap: 8px; }
.gl-fotos a { display: block; aspect-ratio: 1 / 1; border-radius: 10px;
              background-size: cover; background-position: center;
              border: 1px solid var(--line-hair); }

.gl-subir { display: flex; align-items: center; justify-content: center; gap: 8px;
            padding: 14px; border-radius: 999px; cursor: pointer;
            border: 1px dashed var(--line-gold); color: var(--gold-bright);
            background: rgba(212,163,71,.05); font-size: 14px; }
.gl-subir:hover { background: rgba(212,163,71,.12); }

/* ── Mapas ───────────────────────────────────────────────────────────────────
   Teselas oscuras del mismo proveedor que la versión clara, servidas por el
   proxy propio (/tiles/dark/...) para no depender de un CDN externo ni perder
   la caché en disco que ya existía. */
.gl-mapa { width: 100%; border-radius: var(--radius-card);
           border: 1px solid var(--line-hair); overflow: hidden;
           background: #0A0709; }
.gl-mapa.alto { height: 240px; }
.gl-mapa.bajo { height: 150px; }

/* Leaflet pinta su propio fondo blanco mientras carga: se apaga. */
.gl-mapa .leaflet-container { background: #0A0709; }

/* Recoloreado de las teselas.
   Llegan en gris; se les quita el color que traigan (grayscale), se estira el
   contraste para separar el fondo de las calles, y luego sepia + saturate +
   hue-rotate lo llevan al marrón de la app. El agua, que ya viene más oscura
   que la tierra, se va a negro al estirar el contraste — que es justo lo que
   se busca.

   El brillo y el contraste van por banda de zoom (el JS marca data-z en el
   contenedor). El fondo de la tesela sube de luminancia 65 en vista de mundo a
   80 en vista de calle, y con un solo ajuste no se puede tener continentes
   marrones Y calles legibles: el contraste que hace falta abajo deja el mundo
   entero negro.

   Todo cuelga de .gl-mapa-oscuro, que pone el propio JS. Antes esto iba por
   `#mapa-catas` y la especificidad del id se comía las reglas por banda: el
   mapa de catas salía en negro porque le tocaba el contraste de calle. */
.gl-mapa-oscuro .leaflet-tile {
    filter: grayscale(1) brightness(1.32) contrast(2.6)
            sepia(1) saturate(2.3) hue-rotate(-16deg);
}
.gl-mapa-oscuro[data-z="mundo"] .leaflet-tile {
    /* Menos saturación que el resto: aquí no hay edificios que teñir, sólo el
       continente entero, y con el marrón de ciudad sale un pegote de barro.
       Con contraste 2,3 la tierra (luminancia 65) quedaba casi negra, y el mapa
       de catas abre en esta banda cuando hay catas en Florida y en Nueva York:
       se veía todo negro. Con 1,5 y 1,55 la tierra queda marrón y el mar negro. */
    filter: grayscale(1) brightness(1.5) contrast(1.55)
            sepia(1) saturate(1.5) hue-rotate(-16deg);
}
.gl-mapa-oscuro[data-z="region"] .leaflet-tile {
    filter: grayscale(1) brightness(1.38) contrast(2.6)
            sepia(1) saturate(2.3) hue-rotate(-16deg);
}
.gl-mapa-oscuro[data-z="ciudad"] .leaflet-tile {
    filter: grayscale(1) brightness(1.32) contrast(2.6)
            sepia(1) saturate(2.3) hue-rotate(-16deg);
}
.gl-mapa-oscuro[data-z="calle"] .leaflet-tile {
    filter: grayscale(1) brightness(1.24) contrast(2.7)
            sepia(1) saturate(2.3) hue-rotate(-16deg);
}
/* Los controles cuelgan de .gl-mapa-oscuro, que el JS pone en el contenedor del
   propio Leaflet: así valen para cualquier mapa oscuro y no sólo para el de
   catas. Colgados de .gl-mapa, el alta de tienda se quedaba con los botones
   blancos de serie encima del mapa marrón. */
/* .leaflet-container en el selector no es adorno: la regla de Leaflet es
   `.leaflet-container .leaflet-control-attribution`, empata en especificidad
   con la nuestra, y su hoja se carga después —la vista la mete en @section
   Styles—, así que ganaba ella y la atribución salía en un recuadro blanco
   encima del mapa oscuro. Con la clase de más ya no depende del orden. */
.gl-mapa .leaflet-control-attribution,
.gl-mapa-oscuro.leaflet-container .leaflet-control-attribution {
    background: rgba(6,6,10,.7); color: var(--fg-4); font-size: 9px; }
.gl-mapa .leaflet-control-attribution a,
.gl-mapa-oscuro.leaflet-container .leaflet-control-attribution a { color: var(--fg-3); }
.gl-mapa .leaflet-control-zoom a,
.gl-mapa-oscuro.leaflet-container .leaflet-control-zoom a {
    background: rgba(22,22,28,.92); color: var(--gold-bright);
    border-color: var(--line-hair); }
.gl-mapa .leaflet-control-zoom a:hover,
.gl-mapa-oscuro.leaflet-container .leaflet-control-zoom a:hover {
    background: var(--gold); color: #1a0f02; }

/* Chincheta dorada con pulso, en vez del icono azul por defecto. */
.gl-pin { position: relative; width: 18px; height: 18px; }
.gl-pin::before { content: ''; position: absolute; inset: 0; border-radius: 50%;
                  background: radial-gradient(circle at 35% 35%, #E8B64C, #8C6A2B);
                  box-shadow: 0 0 0 2px rgba(6,6,10,.8), 0 0 14px rgba(212,163,71,.9); }
.gl-pin::after { content: ''; position: absolute; inset: -6px; border-radius: 50%;
                 border: 2px solid rgba(232,182,76,.5);
                 animation: pinPulso 2.4s ease-out infinite; }
@keyframes pinPulso { 0% { transform: scale(.6); opacity: .9; }
                      100% { transform: scale(1.6); opacity: 0; } }

/* ── Pantallas de entrada (login, registro, contraseña) ──────────────────────
   Sin barra inferior: aquí no hay sesión y no hay a dónde navegar. La tarjeta
   va centrada y con un ancho de lectura cómodo también en escritorio. */
.gl-auth { min-height: 100vh; display: flex; align-items: center; justify-content: center;
           padding: 32px 20px calc(32px + env(safe-area-inset-bottom)); }
.gl-auth-caja { width: 100%; max-width: 420px; }

.gl-auth-marca { text-align: center; margin-bottom: 26px; }
.gl-auth-logo { height: 46px; width: auto; display: block; margin: 0 auto;
                 /* El logo ya viene dorado; el halo lo asienta sobre el fondo. */
                 filter: drop-shadow(0 0 22px rgba(212,163,71,.30)); }
.gl-auth-lema { display: block; margin-top: 6px; font-size: 11px; letter-spacing: .22em;
                text-transform: uppercase; color: var(--fg-4); }

.gl-auth-t { font-family: var(--serif); font-size: 27px; margin: 0 0 6px; }
.gl-auth-sub { color: var(--fg-3); font-size: 14px; margin: 0 0 22px; }

/* Los campos: etiqueta pequeña arriba, caja ancha. En móvil se teclea con el
   pulgar, así que la caja es alta. */
.gl-campo { margin-bottom: 16px; }
.gl-campo > label { display: block; font-size: 11px; letter-spacing: .1em;
                    text-transform: uppercase; color: var(--fg-4); margin-bottom: 6px; }
.gl-campo .gl-input { width: 100%; padding: 13px 14px; font-size: 15px; }
.gl-campo .text-danger { display: block; margin-top: 6px; font-size: 12px; color: #ffb4b4 !important; }

.gl-auth-fila { display: flex; align-items: center; justify-content: space-between;
                gap: 12px; margin: 4px 0 20px; font-size: 13px; }
.gl-auth-fila a { color: var(--gold-bright); text-decoration: none; }
.gl-auth-pie { text-align: center; margin-top: 20px; font-size: 13px; color: var(--fg-3); }
.gl-auth-pie a { color: var(--gold-bright); text-decoration: none; font-weight: 600; }

/* Entrar con Google: blanco a propósito. Es un botón que la gente reconoce por
   su aspecto, y disfrazarlo de dorado sólo consigue que no se vea que es Google. */
.gl-google { width: 100%; display: flex; align-items: center; justify-content: center;
             gap: 10px; background: #fff; color: #1f1f1f; border: none;
             border-radius: 999px; padding: 13px 18px; font-family: var(--ui);
             font-weight: 600; font-size: 15px; cursor: pointer; }
.gl-google:hover { background: #f1f1f1; }

.gl-auth-sep { display: flex; align-items: center; gap: 12px; margin: 20px 0;
               color: var(--fg-4); font-size: 11px; letter-spacing: .1em;
               text-transform: uppercase; }
.gl-auth-sep::before, .gl-auth-sep::after {
    content: ''; flex: 1; height: 1px; background: var(--line-hair); }

/* Casillas y radios del navegador: por defecto salen blancos y cantan mucho
   sobre el fondo oscuro. accent-color los tiñe sin tener que dibujar un control
   propio, que es lo que hacía el diseño claro con custom-control. */
body.gl-dark input[type="checkbox"],
body.gl-dark input[type="radio"] {
    accent-color: var(--gold);
    width: 17px; height: 17px;
    vertical-align: middle;
}

/* La marca dentro de la app: sólo en el perfil, al final del todo. Apagada
   —medio opacidad y sin halo— porque ahí no tiene que llamar la atención, sólo
   estar. */
.gl-marca-pie { text-align: center; margin-top: 34px; opacity: .45; }
.gl-marca-pie img { height: 26px; width: auto; display: block; margin: 0 auto 6px; }
.gl-marca-pie span { display: block; font-size: 9px; letter-spacing: .24em;
                     text-transform: uppercase; color: var(--fg-4); }

/* ============================================================================
   PÁGINAS PÚBLICAS  (alta de tienda, condiciones, privacidad, cookies)
   Sin sesión y sin barra inferior: una cabecera con el logo para poder salir,
   y los legales en el pie, que es donde los busca todo el mundo.
   ========================================================================== */

.gl-pub-cab { padding: 20px 16px 6px; text-align: center; }
.gl-pub-marca { display: inline-block; }
.gl-pub-marca img { height: 34px; width: auto; display: block; }

.gl-pub-pie { margin-top: 46px; padding: 22px 16px calc(26px + env(safe-area-inset-bottom));
              border-top: 1px solid var(--line-hair); text-align: center;
              display: flex; gap: 18px; flex-wrap: wrap; justify-content: center; }
.gl-pub-pie a { color: var(--fg-4); text-decoration: none; font-size: 12px;
                letter-spacing: .04em; }
.gl-pub-pie a:hover { color: var(--gold); }

/* Los textos legales comparten vista con la piel clara a propósito: duplicarlos
   sería tener dos versiones de las condiciones y cambiar sólo una. Así que aquí
   se repinta lo que consumer.css deja claro, sin tocar el contenido. */
.gl-dark .legal-page { max-width: 720px; margin: 0 auto; padding: 30px 18px 0; }
.gl-dark .legal-page h1 { font-family: var(--serif); font-size: 30px; font-weight: 600;
                          color: var(--fg); margin: 0 0 6px; letter-spacing: -.01em; }
.gl-dark .legal-page .legal-updated { font-family: var(--mono); font-size: 11px;
                                      color: var(--fg-4); margin-bottom: 30px;
                                      letter-spacing: .06em; }
.gl-dark .legal-page h2 { font-family: var(--ui); font-size: 14px; font-weight: 600;
                          color: var(--gold); margin: 32px 0 10px;
                          text-transform: uppercase; letter-spacing: .1em; }
.gl-dark .legal-page p,
.gl-dark .legal-page li { color: var(--fg-2); line-height: 1.75; font-size: 14px; }
.gl-dark .legal-page ul { padding-left: 20px; }
.gl-dark .legal-page li { margin-bottom: 5px; }
.gl-dark .legal-page strong { color: var(--fg); }
.gl-dark .legal-page a { color: var(--gold); }

/* ---- Alta de tienda ------------------------------------------------------ */

.gl-alta { max-width: 900px; margin: 0 auto; padding: 12px 16px 0; }
.gl-alta-hero { text-align: center; padding: 14px 0 26px; }
.gl-alta-hero h1 { font-family: var(--serif); font-size: 32px; font-weight: 600;
                   color: var(--fg); margin: 0 0 8px; line-height: 1.15; }
.gl-alta-hero p { color: var(--fg-3); font-size: 15px; margin: 0; }

/* Los pasos numerados. El número en dorado es lo único que grita en la página:
   dice cuánto queda por hacer de un vistazo. */
.gl-paso { display: flex; gap: 14px; align-items: flex-start; margin: 30px 0 16px; }
.gl-paso-n { flex: 0 0 32px; height: 32px; border-radius: 50%;
             border: 1px solid var(--line-gold); color: var(--gold);
             font-family: var(--mono); font-size: 13px;
             display: flex; align-items: center; justify-content: center; }
.gl-paso-c h3 { font-family: var(--ui); font-size: 15px; font-weight: 600;
                color: var(--fg); margin: 5px 0 4px; }
.gl-paso-c p { color: var(--fg-3); font-size: 13px; margin: 0; line-height: 1.6; }

.gl-alta-fila { display: flex; gap: 12px; flex-wrap: wrap; }
.gl-alta-fila > * { flex: 1 1 200px; min-width: 0; }

/* Resultados y mapa, uno al lado del otro en pantalla ancha y apilados en el
   móvil. La altura fija evita que la página pegue saltos al buscar. */
.gl-alta-busca { display: flex; gap: 12px; flex-wrap: wrap; margin-top: 14px; }
.gl-alta-busca > * { flex: 1 1 280px; min-width: 0; }
.gl-alta-res { height: 300px; overflow-y: auto; background: var(--bg-surface);
               border: 1px solid var(--line-hair); border-radius: var(--radius-card); }
.gl-alta-mapa { height: 300px; border-radius: var(--radius-card); overflow: hidden;
                border: 1px solid var(--line-hair); }

.gl-alta-vacio { padding: 40px 20px; text-align: center; color: var(--fg-4); font-size: 13px; }
.gl-alta-vacio i { display: block; font-size: 26px; margin-bottom: 10px; opacity: .5; }

.gl-alta-item { display: flex; align-items: center; justify-content: space-between;
                gap: 10px; padding: 12px 14px; border-bottom: 1px solid var(--line-hair); }
/* El botón no se encoge: con flex por defecto cedía sitio al nombre de la
   tienda y se quedaba en "Claim this stor". Lo que se recorta es el nombre. */
.gl-alta-item > button { flex: 0 0 auto; }
.gl-alta-item > div { min-width: 0; }
.gl-alta-item-n, .gl-alta-item-d { overflow: hidden; text-overflow: ellipsis;
                                   white-space: nowrap; }
.gl-alta-item:last-child { border-bottom: 0; }
.gl-alta-item-n { font-family: var(--serif); font-size: 16px; color: var(--fg); }
.gl-alta-item-d { font-size: 12px; color: var(--fg-3); margin-top: 2px; }

/* El local ya elegido: verde, que es el único sitio de la pantalla donde algo
   está confirmado. */
.gl-alta-elegido { display: flex; align-items: center; justify-content: space-between;
                   gap: 12px; margin-top: 14px; padding: 14px;
                   border: 1px solid var(--ok); border-radius: var(--radius-card);
                   background: rgba(74, 222, 128, .07); }
.gl-alta-elegido i.fa-circle-check { color: var(--ok); margin-right: 8px; }

/* Un adjunto usa la forma de .chip pero NO su tipografía de etiqueta: los
   nombres de fichero se leen tal cual, no en mayúsculas. */
.chip.gl-fichero { text-transform: none; letter-spacing: 0; font-family: var(--ui); }

/* El selector de ficheros de serie sale en el idioma del navegador ("Elegir
   archivos"), y eso no lo cambia el lang de la página. Se esconde y se pinta
   una etiqueta nuestra, que sí pasa por el catálogo. */
.gl-fich { position: relative; }
.gl-fich input[type=file] { position: absolute; inset: 0; width: 100%; height: 100%;
                            opacity: 0; cursor: pointer; }
.gl-fich-btn { display: flex; align-items: center; gap: 10px; pointer-events: none;
               padding: 13px 15px; border: 1px dashed var(--line-hair);
               border-radius: var(--radius-card); background: var(--bg-surface);
               color: var(--fg-3); font-size: 14px; }
.gl-fich input[type=file]:focus + .gl-fich-btn { border-color: var(--gold); }
.gl-fich-btn i { color: var(--gold); }
.gl-fich-btn b { color: var(--fg-2); font-weight: 500; }

/* Antes de buscar no hay nada que enseñar: en el móvil, 300 px de caja vacía más
   300 px de mapa del mundo son dos pantallas de scroll para llegar al paso 2.
   Hasta la primera búsqueda se encoge la caja y se esconde el mapa. En pantalla
   ancha caben los dos de sobra, así que ahí no se toca nada. */
@media (max-width: 720px) {
    .gl-alta-busca.sin-buscar .gl-alta-res { height: auto; }
    .gl-alta-busca.sin-buscar .gl-alta-mapa { display: none; }
    .gl-alta-busca.sin-buscar .gl-alta-vacio { padding: 26px 20px; }
}

/* Banda de aviso EN LÍNEA, para lo que trae el servidor pintado en la página:
   el error del login, el "guardado" de un formulario. No confundir con
   .gl-aviso, que es el emergente flotante que crea el JS y desaparece solo.
   Estuvieron compartiendo clase un tiempo, y el resultado era que un fallo de
   contraseña salía como una pastilla flotando por encima de la barra inferior,
   lejos del campo que lo había provocado. */
.gl-banda { display: flex; align-items: flex-start; gap: 10px;
            padding: 12px 14px; border-radius: var(--radius-card);
            background: var(--bg-surface); border: 1px solid var(--line-hair);
            border-left-width: 3px; color: var(--fg-2); font-size: 14px;
            line-height: 1.5; }
.gl-banda i { margin-top: 2px; }
.gl-banda.ok { border-left-color: var(--ok); color: #bff5d3; }
.gl-banda.mal { border-left-color: var(--danger); color: #ffb4b4; }

/* Validación de ASP.NET. Las plantillas oscuras NO cargan Bootstrap, así que
   .text-danger y .validation-summary-errors llegaban sin ningún estilo: el
   "Invalid email or password." del login salía como una lista con viñeta y del
   mismo color que el resto del texto. Se le da la misma forma que a .gl-banda
   para que un fallo se vea como un fallo. */
.gl-dark .validation-summary-errors,
.gl-dark [data-valmsg-summary="true"]:not(.validation-summary-valid) {
    padding: 12px 14px; border-radius: var(--radius-card);
    background: var(--bg-surface); border: 1px solid var(--line-hair);
    border-left: 3px solid var(--danger); color: #ffb4b4;
    font-size: 14px; line-height: 1.5; }
.gl-dark .validation-summary-errors ul { margin: 0; padding: 0; list-style: none; }
.gl-dark .validation-summary-errors li + li { margin-top: 4px; }
/* El resumen vacío lo pinta ASP.NET siempre, aunque no haya nada que decir. */
.gl-dark .validation-summary-valid { display: none; }

/* El error de cada campo, justo debajo del suyo. */
.gl-dark .text-danger,
.gl-dark .field-validation-error { color: #ffb4b4; font-size: 12px; }
.gl-dark .field-validation-error { display: block; margin-top: 5px; }
.gl-dark .gl-input.input-validation-error { border-color: var(--danger); }

/* ---- Editar la ficha del local: banner y recorte ------------------------- */

.gl-banner-prev { border-radius: var(--radius-card); overflow: hidden;
                  border: 1px solid var(--line-hair); background: var(--bg-surface); }
.gl-banner-prev img { display: block; width: 100%; height: 150px; object-fit: cover; }

/* Cropper.js trae su propia hoja y pinta sobre fondo blanco. El contenedor va a
   negro para que la parte recortada no deslumbre en una pantalla oscura. */
.gl-crop { max-height: 380px; overflow: hidden; border-radius: var(--radius-card);
           background: #000; border: 1px solid var(--line-hair); }
.gl-crop img { max-width: 100%; display: block; }
.gl-dark .cropper-view-box,
.gl-dark .cropper-face { outline-color: var(--gold); }
.gl-dark .cropper-line, .gl-dark .cropper-point { background-color: var(--gold); }

.gl-crop-btns { display: flex; justify-content: space-between; align-items: center;
                gap: 10px; margin-top: 10px; flex-wrap: wrap; }
.gl-crop-btns > span { display: flex; gap: 8px; }

/* Botón pequeño: los de esta pantalla van en fila y a tamaño completo no caben
   en un móvil. */
.gl-mini { padding: 8px 14px; font-size: 13px; width: auto; }

/* ---- Canje de recompensas ------------------------------------------------ */

/* El saldo manda en esta pantalla: es lo que decide si algo se puede pedir o
   no, así que va grande y antes que la lista. */
.gl-saldo { text-align: center; margin: 20px 0 6px; padding: 20px 16px;
            border-radius: var(--radius-card); background: var(--bg-surface);
            border: 1px solid var(--line-gold); }
.gl-saldo-n { font-size: 34px; line-height: 1; color: var(--gold-bright); font-weight: 500; }
.gl-saldo-l { margin-top: 8px; font-size: 10px; letter-spacing: .18em;
              text-transform: uppercase; color: var(--fg-4); }

.gl-premio { gap: 14px; align-items: center; }
.gl-premio-i { flex: 0 0 42px; height: 42px; border-radius: 12px;
               display: flex; align-items: center; justify-content: center;
               background: var(--bg-surface-2); color: var(--gold); font-size: 17px; }
.gl-premio-p { color: var(--gold-bright); font-size: 14px; white-space: nowrap; }
.gl-premio-falta { display: block; margin-top: 8px; font-size: 11px; color: var(--fg-4);
                   white-space: nowrap; }

/* Lo que no alcanza se apaga, pero se sigue leyendo: es lo que da la idea de
   cuánto falta para lo siguiente. Ocultarlo quitaría justamente el incentivo. */
.gl-premio.lejos { opacity: .55; }
.gl-premio.lejos .gl-premio-i { color: var(--fg-4); }
.gl-premio.lejos .gl-premio-p { color: var(--fg-3); }

/* En la lista de recompensas el título SÍ envuelve: .gl-pass-n corta con
   puntos suspensivos, y quedaba "10% off your next purc…" encima de una
   descripción de tres líneas. Lo que importa aquí es qué te llevas. */
.gl-premio .gl-pass-n { white-space: normal; overflow: visible; text-overflow: clip; }

/* ---- Glooopies ----------------------------------------------------------- */

/* Morado, no dorado. El dorado son los puntos de UNA tienda y los Glooopies
   valen en todas: si se pintan igual, no hay forma de distinguir qué se está
   gastando, que es lo único que se puede hacer mal en estas pantallas. */
.gl-saldo-g { border-color: rgba(155,77,255,.35); }
.gl-saldo-g .gl-saldo-n { color: var(--neon-purple); }
.gl-glo .gl-premio-i { color: var(--neon-purple); }
.gl-glo .gl-premio-p { color: var(--neon-purple); }
.gl-glo.puesto { border-color: rgba(155,77,255,.4); }

.gl-quedan { display: block; margin-top: 4px; font-size: 11px; color: var(--warn); }

/* Pestañas de categoría. Píldoras, no subrayado: en el móvil hay que poder
   darles con el pulgar. */
.gl-pestanas { display: flex; gap: 8px; flex-wrap: wrap; margin: 18px 0 4px; }
.gl-pest { padding: 7px 14px; border-radius: 999px; font-size: 13px;
           text-decoration: none; color: var(--fg-3);
           border: 1px solid var(--line-hair); background: var(--bg-surface); }
.gl-pest.on { background: rgba(155,77,255,.14); color: var(--fg);
              border-color: rgba(155,77,255,.5); }

/* ---- Agenda de la tienda ------------------------------------------------- */

.gl-contacto { display: flex; align-items: center; gap: 12px; padding: 12px 0;
               border-top: 1px solid var(--line-hair); }
.gl-contacto-i { flex: 0 0 32px; height: 32px; border-radius: 9px;
                 display: flex; align-items: center; justify-content: center;
                 background: var(--bg-surface-2); color: var(--gold); font-size: 13px; }

/* La equis de quitar: apagada hasta que se le pasa por encima. Es destructiva y
   no tiene que competir con el botón principal de la fila. */
.gl-x { background: none; border: 0; cursor: pointer; padding: 6px 8px;
        color: var(--fg-4); font-size: 14px; line-height: 1; }
.gl-x:hover { color: var(--danger); }

/* Sugerencias del buscador de distribuidores. */
.gl-sugerencias { display: none; position: absolute; top: 100%; left: 0; right: 0;
                  z-index: 20; max-height: 260px; overflow-y: auto;
                  background: var(--bg-elevated); border: 1px solid var(--line-hair);
                  border-radius: var(--radius-card);
                  box-shadow: 0 18px 40px -12px rgba(0,0,0,.85); }
.gl-sug { padding: 11px 14px; cursor: pointer; border-bottom: 1px solid var(--line-hair); }
.gl-sug:last-child { border-bottom: 0; }
.gl-sug:hover { background: var(--bg-surface-2); }
.gl-sug-n { font-family: var(--serif); font-size: 16px; color: var(--fg); }
.gl-sug-m { font-size: 11px; color: var(--fg-3); margin-top: 2px; }
.gl-sug-vacio { padding: 14px; font-size: 13px; color: var(--fg-4); }

/* ---- Planes de suscripción ---------------------------------------------- */

.gl-planes { display: flex; gap: 14px; flex-wrap: wrap; }
.gl-plan { flex: 1 1 280px; min-width: 0; display: flex; flex-direction: column;
           padding: 20px; border-radius: var(--radius-card);
           background: var(--bg-surface); border: 1px solid var(--line-hair); }
.gl-plan.actual { border-color: var(--line-gold); }
.gl-plan-p { font-size: 30px; color: var(--gold-bright); margin-top: 10px; line-height: 1; }
.gl-plan-p span { font-size: 12px; color: var(--fg-4); margin-left: 4px; }
.gl-plan-f { font-size: 13px; color: var(--fg-2); padding: 5px 0; }
.gl-plan-f i { color: var(--ok); margin-right: 8px; font-size: 11px; }

/* ---- El x2 de comprar en la cata ----------------------------------------
   Es el momento más goloso de toda la app: acabas de llevarte el doble. Antes
   era una etiqueta pequeña debajo de los puntos, del tamaño de una nota al
   pie. Aquí se le da el sitio que merece y, sobre todo, se enseña la CUENTA:
   "3 → 6". Un "2×" suelto no dice nada si no ves de qué partías. */
.gl-doble { margin: 20px auto 0; max-width: 320px; padding: 18px 16px;
            border-radius: var(--radius-card);
            background: linear-gradient(160deg, rgba(212,163,71,.16), rgba(114,47,55,.14));
            border: 1px solid var(--line-gold);
            box-shadow: 0 0 34px -8px rgba(212,163,71,.4);
            animation: dobleEntra .5s cubic-bezier(.2,.9,.3,1.3) both .35s; }

.gl-doble-cuenta { display: flex; align-items: center; justify-content: center;
                   gap: 12px; font-size: 26px; line-height: 1; }
/* Lo que habrías tenido: tachado y apagado, para que se vea que te lo saltas. */
.gl-doble-antes { color: var(--fg-4); text-decoration: line-through;
                  text-decoration-thickness: 2px; }
.gl-doble-cuenta i { font-size: 13px; color: var(--gold-deep); }
.gl-doble-despues { color: var(--gold-bright); font-size: 32px;
                    text-shadow: 0 0 22px rgba(212,163,71,.55); }

.gl-doble-t { margin-top: 10px; font-family: var(--serif); font-size: 17px;
              color: var(--fg); line-height: 1.3; }
.gl-doble-m { margin-top: 4px; font-size: 11px; letter-spacing: .14em;
              text-transform: uppercase; color: var(--gold); }

/* Entra un poco después que los puntos, para que se lea en dos tiempos:
   primero "+6", y entonces "ah, y es el doble". */
@keyframes dobleEntra {
    from { opacity: 0; transform: translateY(14px) scale(.94); }
    to   { opacity: 1; transform: none; }
}

/* Los puntos, contando hacia arriba en vez de aparecer ya puestos. */
.gl-premio-n { animation: premioEntra .55s cubic-bezier(.2,.9,.3,1.25) both; }
@keyframes premioEntra {
    from { opacity: 0; transform: scale(.6); }
    60%  { transform: scale(1.08); }
    to   { opacity: 1; transform: none; }
}

@media (prefers-reduced-motion: reduce) {
    .gl-doble, .gl-premio-n { animation: none; }
}

/* ===========================================================================
   Nivel: barra de progreso y celebracion de subida
   ---------------------------------------------------------------------------
   OJO con el prefijo: .gl-nivel YA ESTA COGIDO por el mapa de niveles del
   perfil (linea ~546). Al llamar asi a la barra, y estar mi bloque despues en
   el fichero, le pisaba el display:flex y descuadraba el perfil entero. De ahi
   el prefijo .gl-esc.

   La barra sale en TODAS las compras. La subida, solo cuando toca, y entonces
   tapa la pantalla entera: pasa cada muchas compras y tiene que notarse.
   El color lo pone la vista en --nivel-color, sacado de WineLevelHelper, para
   que cada peldano se celebre distinto y no todos en dorado.
   =========================================================================== */

.gl-esc {
    margin: 26px auto 0;
    max-width: 340px;
    padding: 14px 16px 13px;
    border: 1px solid var(--line-hair);
    border-radius: 14px;
    background: rgba(255, 255, 255, .02);
    text-align: left;
}

.gl-esc-fila {
    display: flex;
    align-items: center;
    gap: 9px;
}

.gl-esc-icono {
    width: 26px;
    height: 26px;
    min-width: 26px;
    border-radius: 8px;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 12px;
    color: var(--nivel-color, var(--gold-bright));
    background: color-mix(in srgb, var(--nivel-color, #D4A347) 16%, transparent);
}

/* color-mix es reciente; sin el, el fondo se queda transparente y el icono
   se sigue leyendo. Nada se rompe en un navegador viejo. */

.gl-esc-nom {
    flex: 1;
    min-width: 0;
    font-size: 13px;
    font-weight: 600;
    color: var(--fg);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.gl-esc-num {
    font-size: 10px;
    letter-spacing: .1em;
    text-transform: uppercase;
    color: var(--fg-4);
    white-space: nowrap;
}

.gl-esc-barra {
    position: relative;
    height: 7px;
    margin-top: 11px;
    border-radius: 99px;
    background: rgba(255, 255, 255, .06);
    overflow: hidden;
}

.gl-esc-relleno {
    position: absolute;
    inset: 0 auto 0 0;
    border-radius: 99px;
    background: linear-gradient(90deg,
                color-mix(in srgb, var(--nivel-color, #D4A347) 55%, transparent),
                var(--nivel-color, #D4A347));
    /* Arranca a cero y crece hasta el ancho que le pone la vista: la barra se
       ve MOVERSE, que es justo lo que hace que la mires. */
    animation: barraCrece .9s cubic-bezier(.22, 1, .36, 1) .25s both;
    transform-origin: left center;
}

@keyframes barraCrece {
    from { transform: scaleX(0); }
    to   { transform: scaleX(1); }
}

.gl-esc-pie {
    display: flex;
    justify-content: space-between;
    gap: 10px;
    margin-top: 8px;
    font-size: 11px;
    color: var(--fg-4);
}

.gl-esc-gano {
    color: var(--nivel-color, var(--gold-bright));
    font-weight: 600;
}

/* --- la subida ---------------------------------------------------------- */

/* La celebracion vive dentro de .gl-scroll, que tiene z-index propio y por
   tanto crea contexto de apilamiento: por muy alto que le ponga el z-index, no
   puede pasar por encima de la barra de navegacion, que es hermana de
   .gl-scroll. Es la misma trampa que ya tenia la hoja modal, y se resuelve
   igual: mientras hay celebracion, la barra se retira. Ademas es lo que hace
   cualquier app —una pantalla de recompensa no comparte sitio con el menu. */
body.con-subida .gl-nav { display: none; }

.gl-subida {
    position: fixed;
    inset: 0;
    z-index: 9000;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 24px;
    cursor: pointer;
    animation: subidaEntra .3s ease both;
}

.gl-subida.fuera {
    animation: subidaSale .26s ease both;
}

@keyframes subidaEntra { from { opacity: 0; } to { opacity: 1; } }
@keyframes subidaSale  { from { opacity: 1; } to { opacity: 0; } }

.gl-subida-fondo {
    position: absolute;
    inset: 0;
    background:
        radial-gradient(circle at 50% 38%,
            color-mix(in srgb, var(--nivel-color, #D4A347) 22%, transparent) 0%,
            transparent 62%),
        rgba(6, 6, 10, .965);
    backdrop-filter: blur(5px);
}

.gl-subida-caja {
    position: relative;
    text-align: center;
    max-width: 320px;
    animation: subidaCaja .5s cubic-bezier(.22, 1, .36, 1) .05s both;
}

@keyframes subidaCaja {
    from { opacity: 0; transform: translateY(18px) scale(.94); }
    to   { opacity: 1; transform: none; }
}

.gl-subida-kicker {
    font-size: 11px;
    letter-spacing: .3em;
    text-transform: uppercase;
    color: var(--nivel-color, var(--gold-bright));
    margin-bottom: 18px;
}

.gl-subida-aro {
    width: 96px;
    height: 96px;
    margin: 0 auto;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 38px;
    color: var(--nivel-color, var(--gold-bright));
    border: 2px solid var(--nivel-color, #D4A347);
    background: color-mix(in srgb, var(--nivel-color, #D4A347) 12%, transparent);
    box-shadow: 0 0 44px color-mix(in srgb, var(--nivel-color, #D4A347) 42%, transparent);
    animation: aroLate 2.4s ease-in-out .6s infinite;
}

@keyframes aroLate {
    0%, 100% { transform: scale(1);    }
    50%      { transform: scale(1.055); }
}

.gl-subida-num {
    margin-top: 20px;
    font-size: 11px;
    letter-spacing: .18em;
    text-transform: uppercase;
    color: var(--fg-4);
}

.gl-subida-nom {
    margin: 5px 0 0;
    font-size: 32px;
    line-height: 1.15;
    color: var(--fg);
}

.gl-subida-premio {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    margin-top: 18px;
    padding: 9px 15px;
    border-radius: 99px;
    font-size: 12.5px;
    color: var(--fg-2);
    border: 1px solid var(--line-hair);
    background: rgba(255, 255, 255, .03);
}

.gl-subida-premio i { color: var(--nivel-color, var(--gold-bright)); }

.gl-subida-ok {
    margin-top: 26px;
    min-width: 150px;
}

/* Chispas: catorce cuadraditos que suben y se apagan. Sin libreria de confeti
   —son 14 spans y dos keyframes— porque cargar un JS entero para esto en un
   movil con datos moviles no compensa. */
.gl-subida-chispas {
    position: absolute;
    inset: 0;
    overflow: hidden;
    pointer-events: none;
}

.gl-subida-chispas span {
    position: absolute;
    top: 46%;
    left: 50%;
    width: 7px;
    height: 7px;
    border-radius: 2px;
    background: var(--nivel-color, #D4A347);
    opacity: 0;
    /* Cada chispa sale con su angulo y su retardo, calculados desde --i, para
       que no vayan las catorce en bloque. */
    transform: rotate(calc(var(--i) * 25.7deg));
    animation: chispa 1.25s ease-out calc(.18s + var(--i) * .035s) both;
}

@keyframes chispa {
    0%   { opacity: 0; transform: rotate(calc(var(--i) * 25.7deg)) translateY(0) scale(.4); }
    18%  { opacity: 1; }
    100% { opacity: 0; transform: rotate(calc(var(--i) * 25.7deg)) translateY(-190px) scale(.85); }
}

/* Quien pide menos movimiento se queda con la informacion y sin el baile: la
   barra aparece llena, la caja sin salto y las chispas no salen. */
@media (prefers-reduced-motion: reduce) {
    .gl-esc-relleno,
    .gl-subida,
    .gl-subida-caja,
    .gl-subida-aro {
        animation: none;
    }
    .gl-subida-chispas { display: none; }
}


/* ── Opciones de una lista (entrega, direcciones) ─────────────────────────────
   Toda la fila es pulsable, que en el móvil es la diferencia entre acertar y
   pelearse con un círculo de 14 píxeles. */
.gl-opcion { display: flex; gap: 12px; align-items: flex-start; cursor: pointer;
             background: var(--bg-card); border: 1px solid var(--line-hair);
             border-radius: var(--radius-card); padding: 14px 16px; margin-bottom: 8px; }
.gl-opcion input { margin-top: 3px; accent-color: var(--gold-bright); flex: none; }
.gl-opcion span { display: block; min-width: 0; }
.gl-opcion b { display: block; font-weight: 600; }
.gl-opcion small { display: block; color: var(--fg-3); font-size: 13px; margin-top: 2px; }
.gl-opcion:focus-within { border-color: var(--gold-bright); }
.gl-input + .gl-input, .gl-input + div, div + .gl-input { margin-top: 8px; }

/* Cómo quiere el cliente su reserva, en la tarjeta de la tienda. */
.po-envio { display: flex; gap: 10px; align-items: flex-start; margin-top: 10px;
            padding: 10px 12px; background: var(--bg-canvas);
            border-radius: var(--radius-card); font-size: 13px; }
.po-envio i { color: var(--gold-bright); margin-top: 2px; flex: none; }
.po-envio b { display: block; font-weight: 600; }
.po-envio small { display: block; color: var(--fg-3); margin-top: 2px; }

/* ── Banderín de descuento sobre la botella ──────────────────────────────────
   Lo pone la tienda por cata (o el habitual suyo) y es lo primero que mira el
   cliente, así que va encima de la foto y no en una línea de texto debajo. */
.gl-wine-ph { position: relative; }
.gl-off { position: absolute; top: 6px; left: 6px; z-index: 2;
          background: var(--gold-bright); color: #1a1206;
          font-family: var(--mono); font-size: 11px; font-weight: 700;
          letter-spacing: .04em; padding: 3px 7px; border-radius: 999px;
          box-shadow: 0 2px 10px rgba(0,0,0,.45); }
.gl-off.grande { font-size: 13px; padding: 4px 10px; }

/* El formulario de descuento en el calendario de la tienda. */
.gl-desc-cata { display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
                margin-top: 14px; padding-top: 12px;
                border-top: 1px solid var(--line-hair); }
.gl-desc-cata label { color: var(--fg-3); font-size: 13px; margin: 0; flex: 1 1 auto; }
.gl-desc-cata .gl-input { max-width: 90px; text-align: right; }


/* ── Ambiente: fondos de cata, banners de tienda y monedas (2026-09-11) ────── */
/* Victor: "darle más color a la app, que ahora mismo está muerta y es muy sosa".
   Las imágenes están en /rsc y las elige Fase2/Ambiente.cs.

   En las celdas de cata la foto va a la derecha y se funde hacia la izquierda en
   el color de la tarjeta, así el texto, que va a la izquierda, se lee siempre. La
   vista pasa la imagen por la variable --fondo. isolation crea el contexto para
   que las capas con z-index negativo queden encima del fondo de la propia tarjeta
   y debajo del texto. */
.gl-ambiente { position: relative; overflow: hidden; isolation: isolate; }
.gl-ambiente::before { content: ''; position: absolute; top: 0; right: 0; bottom: 0; width: 72%;
    background-image: var(--fondo); background-size: cover; background-position: 70% center;
    z-index: -2; }
.gl-ambiente::after { content: ''; position: absolute; top: 0; right: 0; bottom: 0; left: 0; z-index: -1;
    background: linear-gradient(90deg, #16161C 30%, rgba(22,22,28,.88) 46%,
                rgba(22,22,28,.5) 70%, rgba(22,22,28,.16) 100%); }
/* La fecha de las filas lleva su propia tarjetita: sobre la foto necesita fondo. */
.gl-ambiente .gl-pass-d { background: rgba(22,22,28,.72); border-radius: 10px; }

.gl-moneda { display: block; margin: 0 auto 8px; object-fit: contain;
             filter: drop-shadow(0 8px 20px rgba(212,163,71,.35)); }
.gl-moneda-pop { margin-top: 18px; animation: gl-moneda-pop .75s cubic-bezier(.2, 1.5, .4, 1) both; }
@keyframes gl-moneda-pop {
    from { transform: scale(.35) rotate(-14deg); opacity: 0; }
    to   { transform: none; opacity: 1; }
}
@media (prefers-reduced-motion: reduce) { .gl-moneda-pop { animation: none; } }

/* Los tres escáneres (compras, canjes y vales). Antes de encender la cámara la
   caja era un negro vacío; ahora enseña su escena, oscurecida para que el botón y
   el texto se lean. Al arrancar, el vídeo va encima y la tapa sin tocar nada más. */
.gl-scan { background: linear-gradient(180deg, rgba(8,8,12,.30), rgba(8,8,12,.78)),
                       url('/rsc/escaner.jpg') center / cover no-repeat, #08080c; }


/* ── Movimiento (2026-09-11) ─────────────────────────────────────────────── */
/* Victor pidió "ELITE": entradas al hacer scroll, parallax, luz al tocar. Lo
   mueve wwwroot/js/gl-motion.js; aquí sólo hay transform y opacity, que el
   iPhone anima con la tarjeta gráfica. gl-mov la pone un script en <head> y se
   retira sola si el script no llega: nada se queda escondido. */

/* Escondido desde antes de pintar, para que no asome y luego desaparezca. */
.gl-mov :is(.gl-row, .gl-cata, .gl-pass, .gl-feat, .card, .gl-saldo, .gl-sec-t, .gl-qr-card):not(.gl-dentro) {
    opacity: 0; }
.gl-mov .gl-revela:not(.gl-dentro) { transform: translate3d(var(--dx, 0px), 22px, 0) scale(.97); }
.gl-mov .gl-revela.gl-dentro {
    transition: opacity .6s cubic-bezier(.2, .7, .2, 1) var(--retraso, 0ms),
                transform .95s cubic-bezier(.16, 1, .3, 1) var(--retraso, 0ms); }

/* Las catas llegan de un lado, alternando, y se posan con un halo dorado. */
.gl-mov .gl-revela.gl-desde-izq { --dx: -48px; }
.gl-mov .gl-revela.gl-desde-der { --dx: 48px; }
.gl-mov .gl-dentro.gl-es-cata { animation: gl-llega 1.35s ease-out var(--retraso, 0ms) both; }
@keyframes gl-llega {
    0%   { box-shadow: 0 0 0 0 rgba(232,182,76,0); }
    38%  { box-shadow: 0 0 34px -6px rgba(232,182,76,.55), inset 0 0 0 1px rgba(232,182,76,.5); }
    100% { box-shadow: 0 0 0 0 rgba(232,182,76,0), inset 0 0 0 1px rgba(232,182,76,0); }
}
/* El destello: una franja de luz que cruza la celda una vez al entrar. */
.gl-destello { position: absolute; top: -25%; bottom: -25%; left: -45%; width: 38%; z-index: 1;
    pointer-events: none; opacity: 0; transform: skewX(-18deg);
    background: linear-gradient(100deg, rgba(255,226,160,0) 0%, rgba(255,226,160,.30) 50%, rgba(255,226,160,0) 100%); }
.gl-dentro > .gl-destello {
    animation: gl-destello 1.2s cubic-bezier(.3, .1, .2, 1) calc(var(--retraso, 0ms) + 280ms) both; }
@keyframes gl-destello {
    0%   { opacity: 0; transform: skewX(-18deg) translateX(0); }
    15%  { opacity: 1; }
    100% { opacity: 0; transform: skewX(-18deg) translateX(430%); }
}

/* Parallax: la foto de las celdas de cata se mueve un poco con el scroll. Por
   eso sobra por arriba y por abajo. */
.gl-ambiente::before { top: -12px; bottom: -12px; transform: translate3d(0, var(--plx, 0px), 0); }
/* Y la destacada y las cabeceras llevan su fondo en una capa que va más lenta. */
.gl-con-plx { overflow: hidden; }
.gl-plx { position: absolute; left: 0; right: 0; top: -30%; bottom: -30%; z-index: 0;
    background-size: cover; background-position: center; pointer-events: none; will-change: transform; }

/* Luz al tocar: un estallido dorado en el punto exacto del dedo. */
.gl-toque-luz { position: fixed; width: 160px; height: 160px; margin: -80px 0 0 -80px; z-index: 9999;
    border-radius: 50%; pointer-events: none; mix-blend-mode: screen;
    background: radial-gradient(circle, rgba(255,232,176,.6) 0%, rgba(232,182,76,.3) 34%, rgba(232,182,76,0) 70%);
    animation: gl-toque-luz .62s cubic-bezier(.2, .8, .2, 1) forwards; }
@keyframes gl-toque-luz { from { transform: scale(.2); opacity: 1; } to { transform: scale(1.7); opacity: 0; } }

/* Entre pantallas: la nueva entra subiendo y la vieja se apaga. iOS 18.2 y
   Chrome lo hacen solos; el resto cambia de página como siempre. */
@view-transition { navigation: auto; }
::view-transition-old(root) { animation: gl-vt-sale .2s ease-in both; }
::view-transition-new(root) { animation: gl-vt-entra .42s cubic-bezier(.16, 1, .3, 1) both; }
@keyframes gl-vt-sale  { to   { opacity: 0; transform: scale(.985); } }
@keyframes gl-vt-entra { from { opacity: 0; transform: translateY(16px); } }

@media (prefers-reduced-motion: reduce) {
    .gl-dentro.gl-es-cata, .gl-dentro > .gl-destello, .gl-toque-luz { animation: none; }
    .gl-ambiente::before { transform: none; }
    ::view-transition-old(root), ::view-transition-new(root) { animation: none; }
}

/* La barra de abajo se queda quieta al cambiar de pantalla: sólo cambia el resto. */
.gl-nav { view-transition-name: gl-nav; }

/* ── Celdas de cata más altas y la línea de apuntados (2026-09-11) ──────────── */
/* Más aire para que la foto de fondo luzca y quepa la línea de quién va. */
.gl-row.gl-ambiente, .gl-cata.gl-ambiente, .gl-pass.gl-ambiente {
    min-height: 108px; padding-top: 14px; padding-bottom: 14px; }
.gl-cata.gl-ambiente .gl-cata-img { width: 70px; min-width: 70px; height: 70px; }

/* Quién va: circulitos apilados, dorado con un check si vas tú. No se enseñan
   nombres ni caras: sólo cuántos. */
.gl-asisten { display: flex; align-items: center; gap: 8px; margin-top: 8px;
              font-size: 12px; color: var(--fg-3); }
.gl-asisten b { color: var(--fg); font-weight: 600; }
.gl-asisten.voy b { color: var(--gold-bright); }
.gl-caras { display: inline-flex; }
.gl-caras i { width: 18px; height: 18px; border-radius: 50%; margin-left: -6px;
              border: 1.5px solid #16161C; display: inline-flex; align-items: center; justify-content: center;
              background: linear-gradient(140deg, #3a2a2e, #1f1f27); font-size: 8px; color: #16161C; }
.gl-caras i:first-child { margin-left: 0; }
.gl-caras i:nth-child(2) { background: linear-gradient(140deg, #4a3630, #262129); }
.gl-caras i:nth-child(3) { background: linear-gradient(140deg, #2f3440, #1c1c24); }
.gl-caras i.tu { background: linear-gradient(140deg, var(--gold-bright), var(--gold-deep)); }


/* ── Calendario con vida (2026-09-11) ───────────────────────────────────────
   Victor: "muy soso; que los días con catas destaquen mucho y un fondo chulo
   con parallax". Todo va bajo .gl-cal: .gl-cal-d.con también se usa suelto como
   insignia de fecha en las filas de cata, y ahí el oro dejaría el día invisible. */
.gl-cal { gap: 5px; }
.gl-cal .gl-cal-d { border-radius: 11px; background: rgba(255,255,255,.025); text-decoration: none;
    transition: transform .2s cubic-bezier(.2,.9,.3,1.3), box-shadow .2s; }
/* Los días con cata, lingotes de oro. El brillo que cruza y la onda que late son
   decoración: el día se ve igual aunque las animaciones no lleguen a correr. */
.gl-cal .gl-cal-d.con { color: #241703; font-weight: 800; font-size: 15px; cursor: pointer;
    border-color: rgba(255,228,160,.85);
    background-image: linear-gradient(110deg, transparent 38%, rgba(255,255,255,.55) 50%, transparent 62%),
                      linear-gradient(150deg, #F8D985 0%, #E4AC42 48%, #A9731C 100%);
    background-size: 260% 100%, 100% 100%; background-repeat: no-repeat;
    background-position: 160% 0, 0 0;
    box-shadow: 0 6px 18px rgba(228,168,58,.42), 0 0 0 1px rgba(255,215,120,.18), inset 0 1px 0 rgba(255,255,255,.6);
    text-shadow: 0 1px 0 rgba(255,240,200,.45);
    animation: gl-cal-brillo 4.5s ease-in-out infinite; animation-delay: calc(var(--i, 0) * 180ms); }
.gl-cal .gl-cal-d.con::after { content: ''; position: absolute; inset: -2px; border-radius: 13px;
    border: 1.5px solid rgba(248,217,133,.75); opacity: 0; pointer-events: none;
    animation: gl-cal-onda 3s ease-out infinite; animation-delay: calc(var(--i, 0) * 180ms); }
.gl-cal .gl-cal-d.con:active { transform: scale(.94); }
.gl-cal .gl-cal-d.con .gl-cal-p { color: rgba(40,24,2,.75); }
.gl-cal .gl-cal-d.hoy { box-shadow: inset 0 0 0 1px rgba(232,182,76,.6); }
.gl-cal .gl-cal-d.con.hoy { color: #241703;
    box-shadow: 0 6px 18px rgba(228,168,58,.42), 0 0 0 2px rgba(255,244,214,.45), inset 0 1px 0 rgba(255,255,255,.6); }
.gl-cal .gl-cal-d.con.sel { color: #1a1003; transform: scale(1.1); z-index: 2; border-color: #fff4d6;
    background-image: linear-gradient(110deg, transparent 38%, rgba(255,255,255,.6) 50%, transparent 62%),
                      linear-gradient(150deg, #FFE7A6 0%, #F0BC52 48%, #B98224 100%);
    box-shadow: 0 0 0 2px rgba(255,244,214,.9), 0 0 28px rgba(248,210,120,.75), 0 10px 24px rgba(0,0,0,.45); }
@keyframes gl-cal-brillo { 0%, 62% { background-position: 160% 0, 0 0; } 100% { background-position: -60% 0, 0 0; } }
@keyframes gl-cal-onda { 0% { opacity: .85; transform: scale(.94); } 75%, 100% { opacity: 0; transform: scale(1.28); } }

/* La escena: el calendario sobre una foto que va más lenta que la página. La capa
   que se mueve la mete gl-motion.js; el velo va en ::after, por encima de esa capa
   y por debajo del contenido. */
.gl-cal-escena { position: relative; isolation: isolate; overflow: hidden; margin: 0 -6px;
    padding: 16px 12px 14px; border-radius: 22px; border: 1px solid rgba(232,182,76,.22);
    background: #0d0d12 center / cover no-repeat;
    box-shadow: 0 24px 60px rgba(0,0,0,.55), inset 0 1px 0 rgba(255,255,255,.06); }
.gl-cal-escena::after { content: ''; position: absolute; inset: 0; z-index: 0; pointer-events: none;
    background: radial-gradient(130% 55% at 50% 0%, rgba(212,163,71,.22), transparent 62%),
                linear-gradient(180deg, rgba(8,8,12,.45) 0%, rgba(8,8,12,.68) 38%, rgba(8,8,12,.86) 100%); }
.gl-cal-escena > :not(.gl-plx) { position: relative; z-index: 1; }
.gl-cal-escena .gl-cal-mes { text-shadow: 0 2px 16px rgba(0,0,0,.6); }
.gl-cal-escena .gl-cal-mes .mono { color: rgba(255,255,255,.7); }
.gl-cal-escena .gl-cal-nav { background: rgba(10,10,14,.45); border-color: rgba(255,255,255,.16); color: var(--fg); }
.gl-cal-escena .gl-cal-h { color: rgba(255,255,255,.6); }
.gl-cal-escena .gl-filtro { background: rgba(10,10,14,.45); color: var(--fg-2); }
.gl-cal-escena .gl-filtro.activo { background: rgba(212,163,71,.2); color: var(--gold-bright); }
.gl-cal-escena .gl-cal .gl-cal-d:not(.con) { background: rgba(255,255,255,.06); color: rgba(255,255,255,.55); }
.gl-cal-escena .gl-cal .gl-cal-d.hoy:not(.con) { color: var(--gold-bright); }
@media (prefers-reduced-motion: reduce) {
    .gl-cal .gl-cal-d.con, .gl-cal .gl-cal-d.con::after { animation: none; }
}

/* ── Pre-pedidos de la tienda (2026-09-11) ──────────────────────────────────
   Las clases po-* de antes sólo tenían estilos en la vista clara, así que en la
   oscura la página salía casi sin formato. Victor: "muy feo; debe verse quién
   hace el pedido, con su foto, su nombre y luego el pedido". */
.po2-hero { min-height: 190px; }
.po2-aviso { padding: 10px 14px; border-radius: 12px; margin-bottom: 12px; font-size: 14px; }
.po2-aviso.ok { background: rgba(79,209,165,.1); border: 1px solid rgba(79,209,165,.35); color: #9fe9cf; }
.po2-aviso.mal { background: rgba(224,106,106,.1); border: 1px solid rgba(224,106,106,.35); color: #f2a8a8; }

.po2-stats { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; }
.po2-stat { background: var(--bg-surface); border: 1px solid var(--line-hair); border-radius: var(--radius-card);
    padding: 12px 6px; text-align: center; }
.po2-stat b { display: block; font-family: var(--serif); font-size: 30px; line-height: 1; font-weight: 600;
    color: var(--gold-bright); text-shadow: 0 0 18px rgba(232,182,76,.35); }
.po2-stat span { display: block; margin-top: 6px; font-size: 10.5px; letter-spacing: .06em;
    text-transform: uppercase; color: var(--fg-3); }
.po2-stat.alerta { border-color: rgba(232,182,76,.5);
    background: linear-gradient(160deg, rgba(232,182,76,.16), rgba(232,182,76,.03)); }
.po2-filtros { overflow-x: auto; flex-wrap: nowrap; padding-bottom: 2px; }
.po2-filtros .gl-filtro { text-decoration: none; white-space: nowrap; }

.po2-lista { display: flex; flex-direction: column; gap: 12px; margin-top: 14px; }
.po2 { --po-color: var(--fg-4); position: relative; overflow: hidden; padding: 14px 14px 14px 17px;
    border-radius: 18px; border: 1px solid var(--line-hair);
    background: linear-gradient(180deg, var(--bg-elevated), var(--bg-surface)); }
.po2::before { content: ''; position: absolute; left: 0; top: 0; bottom: 0; width: 3px; background: var(--po-color); }
.po2-Pending { --po-color: #E8B64C; border-color: rgba(232,182,76,.38); box-shadow: 0 12px 32px rgba(232,182,76,.08); }
.po2-Confirmed { --po-color: #4FD1A5; }
.po2-Collected { --po-color: #7AA7FF; }
.po2-Cancelled { --po-color: #E06A6A; opacity: .72; }

.po2-cab { display: flex; align-items: center; gap: 12px; }
.po2-ava { width: 50px; height: 50px; min-width: 50px; border-radius: 50%; overflow: hidden;
    display: flex; align-items: center; justify-content: center;
    font-family: var(--serif); font-size: 19px; font-weight: 700; color: #241703;
    background: linear-gradient(150deg, #F8D985, #B8812A);
    box-shadow: 0 0 0 2px var(--bg-elevated), 0 0 0 3.5px var(--po-color); }
.po2-ava img { width: 100%; height: 100%; object-fit: cover; display: block; }
.po2-quien { flex: 1; min-width: 0; }
.po2-nombre { font-family: var(--serif); font-size: 20px; font-weight: 600; color: var(--fg); line-height: 1.15;
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.po2-cuando { font-size: 12px; color: var(--fg-3); margin-top: 3px; }
.po2-cuando i { color: var(--gold); }
.po2-estado { align-self: flex-start; font-size: 11px; font-weight: 700; letter-spacing: .04em; white-space: nowrap;
    padding: 5px 10px; border-radius: 999px; color: var(--po-color); border: 1px solid currentColor; }

.po2-vinos { list-style: none; margin: 12px 0 0; padding: 0; border-top: 1px solid var(--line-hair); }
.po2-vinos li { display: flex; align-items: center; gap: 12px; padding: 9px 0; border-bottom: 1px solid var(--line-hair); }
.po2-bot { width: 40px; min-width: 40px; height: 58px; display: flex; align-items: center; justify-content: center; }
.po2-bot img { max-width: 40px; max-height: 58px; object-fit: contain; }
.po2-vino { flex: 1; min-width: 0; font-size: 14px; color: var(--fg); line-height: 1.3; }
.po2-vino small { display: block; color: var(--fg-4); font-size: 12px; }
.po2-n { font-weight: 800; font-size: 15px; color: var(--gold-bright); white-space: nowrap;
    background: rgba(232,182,76,.1); border: 1px solid rgba(232,182,76,.32); border-radius: 10px; padding: 4px 9px; }

.po2-pie { display: flex; align-items: flex-start; gap: 10px; margin-top: 12px; font-size: 13px; color: var(--fg-2); }
.po2-pie i { color: var(--gold); margin-top: 3px; }
.po2-pie small { display: block; color: var(--fg-3); margin-top: 2px; }
.po2-nota { margin-top: 10px; padding: 8px 10px; border-radius: 10px; background: rgba(255,255,255,.04);
    color: var(--fg-3); font-size: 13px; font-style: italic; }
.po2-acciones { display: flex; align-items: center; gap: 8px; margin-top: 14px; flex-wrap: wrap; }
/* Sin partir: "Marcar recogido" en dos líneas quedaba más alto que "Confirmar". Si no cabe, baja entero. */
.po2-acciones .btn-gold, .po2-acciones .btn-ghost { flex: 1 1 40%; white-space: nowrap;
    padding-left: 12px; padding-right: 12px; }
/* La fecha de la cata y la del pedido parten entre ellas, no a mitad de fecha. */
.po2-cuando span { white-space: nowrap; }
.po2-rechazar { background: none; border: 0; color: #E88B8B; font-size: 13px; font-weight: 600;
    padding: 10px 8px; cursor: pointer; font-family: inherit; }

.po2-candado, .po2-vacio { text-align: center; padding: 30px 20px; color: var(--fg-3); }
.po2-candado-i, .po2-vacio > i { font-size: 28px; color: var(--gold); display: block; margin-bottom: 12px; }
.po2-candado h3 { color: var(--fg); margin: 0 0 8px; font-size: 22px; }
.po2-candado .btn-gold { display: inline-flex; margin-top: 14px; text-decoration: none; }


/* ── Clientes de la tienda (2026-09-11) ─────────────────────────────────────
   Listado y el historial de cada uno en esta tienda. Victor: desde un pre-pedido,
   tocar a la persona lleva a su historial; y un botón de clientes en la portada. */
.po2-cliente { display: flex; align-items: center; gap: 12px; flex: 1; min-width: 0;
    color: inherit; text-decoration: none; }
a.po2-cliente[href] .po2-nombre { text-decoration: underline; text-decoration-color: rgba(232,182,76,.35);
    text-underline-offset: 4px; }

.cli-buscar { position: relative; display: block; margin: 16px 0 0; }
.cli-buscar i { position: absolute; left: 15px; top: 50%; transform: translateY(-50%); color: var(--fg-4); }
.cli-buscar input { width: 100%; padding-left: 42px; }
.cli-lista { display: flex; flex-direction: column; gap: 8px; }
.cli-fila { display: flex; align-items: center; gap: 12px; padding: 12px; border-radius: 16px;
    text-decoration: none; color: inherit; background: var(--bg-surface); border: 1px solid var(--line-hair);
    transition: border-color .18s; }
.cli-fila:hover { border-color: var(--line-gold); }
.cli-ava { width: 46px; height: 46px; min-width: 46px; border-radius: 50%; overflow: hidden;
    display: flex; align-items: center; justify-content: center;
    font-family: var(--serif); font-size: 18px; font-weight: 700; color: #241703;
    background: linear-gradient(150deg, #F8D985, #B8812A);
    box-shadow: 0 0 0 2px var(--bg-surface), 0 0 0 3.5px rgba(232,182,76,.5); }
.cli-ava img { width: 100%; height: 100%; object-fit: cover; display: block; }
.cli-ava.grande { width: 88px; height: 88px; min-width: 88px; font-size: 34px;
    box-shadow: 0 0 0 3px var(--bg-surface), 0 0 0 5px rgba(232,182,76,.75), 0 14px 34px rgba(0,0,0,.5); }
.cli-quien { flex: 1; min-width: 0; }
.cli-nombre { display: block; font-family: var(--serif); font-size: 18px; font-weight: 600; color: var(--fg);
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.cli-datos { display: flex; flex-wrap: wrap; gap: 3px 12px; margin-top: 3px; font-size: 12px; color: var(--fg-3); }
.cli-datos i { color: var(--gold); margin-right: 4px; }
.cli-datos .cli-sigue i, .cli-sigue i { color: #F08FA8; }
.cli-cuando { font-size: 11px; color: var(--fg-4); white-space: nowrap; }

.cli-cab { display: flex; flex-direction: column; align-items: center; text-align: center; gap: 8px;
    margin-top: 12px; padding: 24px 16px 18px; border-radius: 22px; border: 1px solid rgba(232,182,76,.22);
    background: radial-gradient(120% 70% at 50% 0%, rgba(212,163,71,.18), transparent 65%), var(--bg-surface); }
.cli-cab .gl-wine-title { margin: 6px 0 0; }
.cli-chips { display: flex; flex-wrap: wrap; justify-content: center; gap: 6px; margin-top: 2px; }
.cli-item { display: flex; align-items: center; gap: 12px; padding: 12px; border-radius: 14px;
    background: var(--bg-surface); border: 1px solid var(--line-hair); text-decoration: none; color: inherit; }
.cli-item + .cli-item { margin-top: 8px; }
a.cli-item:hover { border-color: var(--line-gold); }
.cli-item-t { flex: 1; min-width: 0; font-size: 14px; color: var(--fg); line-height: 1.35; }
.cli-item-t small { display: block; font-size: 12px; color: var(--fg-3); margin-top: 2px; }
.cli-item-t small i { color: var(--gold); }
.cli-mas { font-family: var(--mono); font-size: 16px; color: var(--gold-bright); white-space: nowrap; }
.cli-menos { font-family: var(--mono); font-size: 16px; color: var(--fg-3); white-space: nowrap; }


/* ── Botellas que apartar y recordatorio de recogida (2026-09-11) ───────────
   Victor: tocar "Botellas que apartar" tiene que ser útil: filtrar para enviar o
   para recoger, verlo por botellas o por pedidos, borrar una reserva y mandar un
   recordatorio al cliente para que confirme si viene. */
a.po2-stat-enlace { text-decoration: none; color: inherit; transition: border-color .18s; }
a.po2-stat-enlace:hover { border-color: var(--line-gold); }
.po2-stat span i { color: var(--gold); }
.apa-barra { display: flex; align-items: center; justify-content: flex-start; gap: 10px; flex-wrap: wrap; margin-top: 14px; }
.apa-modos { display: inline-flex; gap: 2px; padding: 3px; border-radius: 999px;
    background: var(--bg-surface); border: 1px solid var(--line-hair); }
.apa-modos a { padding: 8px 16px; border-radius: 999px; font-size: 13px; color: var(--fg-3); text-decoration: none;
    white-space: nowrap; }
.apa-modos a.activo { background: linear-gradient(150deg, #F8D985, #C8912F); color: #1a1003; font-weight: 700;
    box-shadow: 0 4px 14px rgba(228,168,58,.3); }
.apa-vinos { display: flex; flex-direction: column; gap: 8px; margin-top: 14px; }
.apa-vino { display: flex; align-items: center; gap: 14px; padding: 12px 16px 12px 12px; border-radius: 16px;
    background: linear-gradient(180deg, var(--bg-elevated), var(--bg-surface)); border: 1px solid var(--line-hair); }
.apa-vino .po2-bot { height: 64px; }
.apa-vino-t { flex: 1; min-width: 0; }
.apa-vino-n { display: block; font-size: 15px; color: var(--fg); line-height: 1.3; }
.apa-vino-n small { color: var(--fg-4); font-size: 12px; margin-left: 4px; }
.apa-vino-m { display: flex; flex-wrap: wrap; gap: 4px 12px; margin-top: 5px; font-size: 12px; color: var(--fg-3); }
.apa-vino-m i { color: var(--gold); margin-right: 4px; }
.apa-vino-m .apa-pend, .apa-vino-m .apa-pend i { color: #E8B64C; }
.apa-total { font-family: var(--serif); font-size: 36px; font-weight: 600; line-height: 1; min-width: 52px; text-align: right;
    color: var(--gold-bright); text-shadow: 0 0 18px rgba(232,182,76,.35); }

.po2-seg { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 10px; }
.po2-seg .chip i { margin-right: 3px; }
.po2-seg .po2-no-va { color: #F2A8A8; border-color: rgba(224,106,106,.4); }
.po2-acciones button[disabled] { opacity: .5; cursor: default; box-shadow: none; }

.rec-pregunta { font-family: var(--serif); font-size: 26px; font-weight: 600; line-height: 1.2; color: var(--fg); margin: 4px 0 12px; }
.rec-vinos { border-top: 1px solid var(--line-hair); }
.rec-botones { display: flex; flex-direction: column; gap: 10px; margin-top: 20px; }
.rec-botones .btn-gold { width: 100%; }
.rec-no { width: 100%; background: none; border: 1px solid rgba(224,106,106,.45); color: #F2A8A8; border-radius: 999px;
    padding: 13px; font: inherit; font-weight: 600; cursor: pointer; }
