/* FestaBar — palette taken from the festival poster: teal, orange, mint, cream.
   Mobile-first: meant to be used one-handed, outdoors, in a crowd. */

:root{
  /* Poster palette: sky at the top, sunset at the bottom, yellow spiral sun. */
  --sky:#7FC9E8;
  --sea:#4FBBD4;
  --lagoon:#5FC3C9;
  --meadow:#9ACBA0;
  --sun:#F7D14E;
  --sunset:#F5A03B;
  --flame:#F0651F;      /* the poster's headline red-orange */
  --flame-deep:#DC4A17;

  --cream:#FFF6EA;
  --ink:#0E3A42;
  --ink-soft:#4B7C85;
  --red:#D7263D;
  --green:#1E9E6A;

  /* aliases so the rest of the sheet keeps working */
  --aqua:var(--sea);
  --aqua-light:var(--sky);
  --orange:var(--flame);
  --orange-deep:var(--flame-deep);
  --mint:#A8DCC8;

  --shadow:0 6px 18px -8px rgba(14,58,66,.35);
  --radius:14px;
}

*{box-sizing:border-box;-webkit-tap-highlight-color:transparent;}
html,body{margin:0;padding:0;}

body{
  background:var(--sea);
  color:var(--ink);
  font-family:system-ui,-apple-system,"Segoe UI",Roboto,sans-serif;
  font-size:17px;line-height:1.55;
  -webkit-font-smoothing:antialiased;
}
/* The sky-to-sunset gradient from the poster. Fixed, so it does not scroll away. */
body::before{
  content:"";position:fixed;inset:0;z-index:-1;
  background:linear-gradient(180deg,
    var(--sky)     0%,
    var(--sea)    26%,
    var(--lagoon) 44%,
    var(--meadow) 60%,
    var(--sun)    80%,
    var(--sunset)100%);
}

/* Bottom padding must clear the FIXED bars: the customer's "Totale / Paga" bar
   (~80px) and the staff quick bar (~76px). Without it they sit on top of the
   social links at the end of the page. */
.app{max-width:560px;margin:0 auto;padding:6px 16px 128px;}
.app.with-nav{padding-bottom:112px;}

/* ---------- hero header: sun + wordmark ---------- */
.hero{
  position:relative;
  background:linear-gradient(180deg, rgba(14,58,66,.16), rgba(14,58,66,0));
  overflow:hidden;
}
/* Faint ray burst behind the header, echoing the poster.
   It MOVES: a conic-gradient cannot be animated directly (gradient angles do not interpolate),
   but the element carrying it can be.
   CALIBRATION MATTERS MORE THAN THE IDEA. A first pass turned 5° over 40s and breathed opacity
   between .75 and 1 — but each ray is itself 5° wide, so the turn moved a ray by exactly its own
   width, and the "breathing" was 2% of a fill already sitting at 9% alpha. It was, in practice,
   a still image. These numbers are big enough to read out of the corner of an eye and still slow
   enough to feel like weather rather than an animation. */
.hero::before{
  content:"";position:absolute;inset:-60% -20% auto -20%;height:220%;
  /* .16, not .09. The rays were pitched so faint that any animation of them was animating
     almost-nothing — and the opacity keyframes below swing them down to .45 of this, so the
     dim end still has to be visible. Even at .16 they read as light on the sky, not as stripes. */
  background:repeating-conic-gradient(from 0deg at 50% 0%,
      rgba(255,246,234,.16) 0deg 5deg, transparent 5deg 15deg);
  pointer-events:none;

  /* Rotate around the point the rays fan out FROM, not the middle of the box: turning about
     the centre would make the whole fan orbit, which looks like a spinning wheel. */
  transform-origin:50% 0%;
  animation:
    rayturn    18s ease-in-out infinite,
    raystretch 11s ease-in-out infinite,
    raybreathe  7s ease-in-out infinite;
  will-change:transform, opacity;
}

/* A slow sweep, ±14°: nearly three ray-widths, so a ray visibly travels rather than jittering
   in place. Uneven keyframes so it drifts one way and drifts back differently. */
@keyframes rayturn{
  0%   { rotate:-7deg; }
  40%  { rotate: 7deg; }
  100% { rotate:-7deg; }
}
/* Reaching down the page and pulling back. Y only, from the top, so they lengthen without the
   fan splaying wider. */
@keyframes raystretch{
  0%, 100% { scale:1 1;    }
  50%      { scale:1 1.35; }
}
/* And they brighten and dim — the part that actually sells it as light rather than as geometry.
   The fill is only 9% alpha to begin with, so this has to swing hard to register at all. */
@keyframes raybreathe{
  0%, 100% { opacity:.45; }
  50%      { opacity:1;   }
}
.hero-in{
  position:relative;
  max-width:560px;margin:0 auto;padding:16px;
  display:flex;align-items:center;justify-content:space-between;gap:12px;
}

/* The logo IS a link, but nothing said so: no hover on a phone, no cursor, no press state, so
   it read as decoration. It cannot be labelled without cluttering the header, but it can at
   least respond to a finger — a tap that visibly does something teaches the rest by itself. */
.brand{
  display:flex;align-items:center;gap:11px;text-decoration:none;
  border-radius:14px;padding:4px 8px 4px 4px;margin-left:-4px;
  transition:background .12s ease, transform .12s ease;
  -webkit-tap-highlight-color:transparent;
}
.brand:active{background:rgba(255,255,255,.18);transform:scale(.98);}

/* Hover tells a desktop user the logo is a link BEFORE they click — the press state only tells
   them after. Gated behind `hover: hover` because on a touch screen hover sticks after a tap:
   the logo would stay lit up long after the finger left, which reads as a stuck button. */
@media (hover: hover) and (pointer: fine){
  .brand:hover{background:rgba(255,255,255,.14);}
  .brand:hover .wordmark b{text-shadow:0 2px 10px rgba(255,255,255,.45);}
}

.sun{
  display:grid;place-items:center;
  width:46px;height:46px;
  flex-shrink:0;
}
/* The sun spins slowly and breathes between the poster's orange and yellow.
   A flat yellow disc barely reads as "turning"; the colour shift makes the motion obvious. */
.sunmark{
  display:block;width:42px;height:42px;
  color:var(--flame);
  animation:spin 24s linear infinite, sunbreathe 5s ease-in-out infinite;
}
.sunmark .rays{
  fill:currentColor;
  /* The rays reach out and pull back. Deliberately 7s against the 5s colour breathe and the 24s
     spin: three periods that share no common multiple, so the sun never repeats the same
     combination of length, colour and angle. It reads as alive rather than as a loop.
     transform-origin is the centre of the 100x100 viewBox, so they grow from the middle out. */
  transform-origin:50px 50px;
  animation:sunrays 7s ease-in-out infinite;
}
.sunmark .spiral{
  fill:none;stroke:currentColor;stroke-width:9.5;stroke-linecap:round;
}
@keyframes spin{to{transform:rotate(360deg);}}
@keyframes sunbreathe{
  0%, 100% { color:var(--flame); }   /* orange */
  50%      { color:var(--sun);   }   /* poster yellow */
}
@keyframes sunrays{
  /* Small numbers on purpose: 8% is enough to notice out of the corner of an eye, and not enough
     to look like the logo is throbbing. The uneven stops make the reach out slower than the pull
     back, which is what a flame does. */
  0%   { transform:scale(1);    opacity:.92; }
  35%  { transform:scale(1.08); opacity:1;   }
  55%  { transform:scale(1.03); opacity:.96; }
  75%  { transform:scale(1.06); opacity:1;   }
  100% { transform:scale(1);    opacity:.92; }
}

.wordmark{display:flex;flex-direction:column;line-height:1.05;}
.wordmark b{
  font-size:21px;font-weight:800;letter-spacing:-.02em;color:#fff;
  text-shadow:0 2px 5px rgba(14,58,66,.4);
}
.wordmark small{
  font-size:10.5px;font-weight:700;letter-spacing:.16em;text-transform:uppercase;
  color:rgba(255,255,255,.85);margin-top:2px;
}

.who{
  display:flex;align-items:center;gap:7px;
  font-size:13px;font-weight:700;color:var(--cream);
  background:rgba(14,58,66,.28);
  padding:8px 13px;border-radius:999px;text-decoration:none;
  backdrop-filter:blur(6px);
  white-space:nowrap;
}
.who.ghost-chip{background:var(--cream);color:var(--ink);}
.dot-on{width:7px;height:7px;border-radius:50%;background:#7BE0A8;flex-shrink:0;}

h1{font-size:30px;font-weight:800;letter-spacing:-.02em;color:#fff;margin:6px 0 4px;text-shadow:0 2px 6px rgba(14,58,66,.35);}
.sub{color:#fff;opacity:.92;font-size:15px;margin:0 0 20px;text-shadow:0 1px 4px rgba(14,58,66,.3);}
h2.card-title{font-size:14px;font-weight:700;text-transform:uppercase;letter-spacing:.06em;color:var(--ink-soft);margin:0 0 12px;}

.card,.list .row,.result,.menu-row,.code-box{background:var(--cream);border-radius:var(--radius);box-shadow:var(--shadow);}
.card{padding:18px;margin-bottom:18px;}

.list{display:flex;flex-direction:column;gap:10px;}
.list .row{padding:14px 16px;display:flex;align-items:center;justify-content:space-between;gap:12px;flex-wrap:wrap;}
.list .row.disabled{opacity:.55;}
.detail{font-size:13.5px;color:var(--ink-soft);width:100%;}
.price{font-weight:700;color:var(--orange-deep);margin-left:8px;}
.empty{color:#fff;opacity:.95;text-shadow:0 1px 4px rgba(14,58,66,.3);}

input,select{
  width:100%;padding:14px;font-size:16px;font-family:inherit;
  border:2px solid #DCD3C4;border-radius:12px;background:#fff;color:var(--ink);
}
input:focus,select:focus{outline:none;border-color:var(--aqua);box-shadow:0 0 0 3px rgba(31,169,188,.2);}

/* Buttons and links had no focus style at all: `outline:none` on inputs is fine because they get
   a ring instead, but a button reached by Tab showed nothing, so anyone on a keyboard — or on a
   tablet with a bluetooth keyboard at the counter — had no idea where they were. WCAG 2.4.7.
   :focus-visible, not :focus, so a mouse click does not leave a ring behind. */
button:focus-visible,
a:focus-visible,
label.burger:focus-visible,
[role="button"]:focus-visible{
  outline:3px solid var(--ink);
  outline-offset:2px;
  border-radius:8px;
}
/* On the dark nav bar and the sky header, an ink-coloured ring disappears. */
.nav a:focus-visible,
.brand:focus-visible,
.pending-order:focus-visible,
.my-orders-link:focus-visible{
  outline-color:#fff;
}
label{display:block;font-size:13px;font-weight:700;color:var(--ink-soft);margin:12px 0 6px;text-transform:uppercase;letter-spacing:.05em;}
.form-grid{display:flex;flex-direction:column;gap:10px;}
.form-grid.edit{width:100%;}

button{
  font-family:inherit;font-size:16px;font-weight:700;
  padding:14px 18px;border:0;border-radius:12px;cursor:pointer;min-height:50px;
  transition:transform .06s ease, filter .15s ease;
}
button:active{transform:translateY(1px);}
button:disabled{opacity:.5;cursor:not-allowed;}
button.primary{background:var(--orange);color:#fff;}
button.big{width:100%;background:var(--orange);color:#fff;margin-top:18px;font-size:17px;}
button.ghost{background:transparent;color:var(--ink);border:2px solid #DCD3C4;}
button.danger{background:transparent;color:var(--red);border:2px solid #EFC9CE;}
button.deliver{width:100%;margin-top:14px;background:var(--green);color:#fff;font-size:17px;min-height:56px;}
.actions{display:flex;gap:8px;}
.actions button{padding:10px 14px;min-height:44px;font-size:14px;}

.scan-bar{display:flex;gap:10px;margin-bottom:10px;}
.scan-bar input{flex:1;font-size:24px;font-weight:700;letter-spacing:.16em;text-align:center;text-transform:uppercase;}
.scan-bar button{flex-shrink:0;}
.cam-btn{width:100%;background:var(--ink);color:var(--cream);margin-bottom:14px;}
video#cam{width:100%;border-radius:var(--radius);background:#000;margin-bottom:14px;box-shadow:var(--shadow);}
video#cam.hidden{display:none;}

.result{padding:18px;margin-top:6px;}
.result-top{display:flex;align-items:center;justify-content:space-between;gap:10px;}
.badge-ok,.badge-ko{display:inline-block;font-size:12px;font-weight:800;letter-spacing:.08em;text-transform:uppercase;padding:6px 12px;border-radius:999px;color:#fff;}
.badge-ok{background:var(--green);}
.badge-ko{background:var(--red);}
.amount{font-size:24px;font-weight:800;}
.customer{font-weight:700;margin:10px 0 4px;font-size:18px;}
.items{list-style:none;padding:0;margin:8px 0 0;}
.items li{padding:9px 0;border-bottom:1px solid #E8DFD0;font-size:17px;}
.items li:last-child{border-bottom:0;}
.items b{color:var(--orange-deep);}
.delivered{margin-top:14px;padding:14px;text-align:center;background:#E4F5EE;color:#14684A;border-radius:12px;font-weight:700;}
.result.ko p{margin:10px 0 0;font-size:17px;}

/* "Not paid" is its own thing, not a variant of "wrong code". A thick amber bar and an
   explicit instruction, because at the counter the operator has a person in front of them
   who is convinced they already paid. */
.result.ko.unpaid{border-left:6px solid var(--sunset);}
.result.ko.unpaid .badge-ko{background:var(--sunset);color:#3A2408;}
.unpaid-what{
  margin-top:12px;padding:12px 14px;
  background:rgba(247,209,78,.22);
  border-radius:10px;
  font-size:16px;line-height:1.45;color:var(--ink);
}
.unpaid-what b{color:#9A2709;}   /* darker than --flame-deep: this is the word that must be read at a glance */

/* The take-the-money button. Amber, NOT the green "Consegna" — the two must never be reached for
   by muscle memory. Green means "already paid, hand it over"; amber means "money first". */
/* Cash and POS side by side. Cash is the default — it is what most people hand over at a village
   bar — so it gets the solid amber; POS is the same size but outlined, because a smaller or
   greyer button would get mis-tapped in the dark with a queue waiting. */
.pay-how{display:flex;gap:10px;margin-top:12px;}
.pay-how button{flex:1;margin-top:0;}
button.deliver.pay-pos{
  background:transparent;
  color:#8C2308;
  border:2px solid var(--sunset);
}

/* Step 1 done: the money is in and recorded. Green, because this part is settled — even if the
   page is closed right now, the payment is safe and the order can be delivered later. */
.paid-ok{
  margin-top:12px;padding:11px 13px;border-radius:10px;
  background:rgba(30,158,106,.14);
  color:#12603D;
  font-size:15.5px;font-weight:600;
}
.paid-ok b{color:#0E4A2F;}

button.deliver.pay-first{
  background:var(--sunset);
  color:#2A1A06;
}

/* Customer side: the unpaid pickup code. It carries the order to the counter, but it is not a
   receipt, and it must not look like one — someone holding this up at the bar has to already know
   they still owe money, or the operator is the one who has to say it, with a queue watching. */
.code-box.unpaid-box{
  border:3px solid var(--sunset);
  position:relative;
}
.unpaid-flag{
  display:inline-block;
  margin-bottom:10px;padding:6px 14px;
  border-radius:999px;
  background:var(--sunset);color:#2A1A06;
  font-size:13px;font-weight:800;letter-spacing:.1em;
}
.code-box.unpaid-box .code{color:#8C2308;}
.code-box.unpaid-box .amount{color:#8C2308;}

.menu-row{padding:14px 16px;margin-bottom:10px;display:flex;align-items:center;gap:12px;}
.menu-row .name{flex:1;font-weight:700;font-size:17px;}
.menu-row .p{color:var(--ink-soft);font-weight:600;}
.qty{display:flex;align-items:center;gap:6px;}
.qty button{width:44px;height:44px;min-height:44px;padding:0;border-radius:50%;font-size:22px;line-height:1;background:var(--aqua);color:#fff;}
.qty button.minus{background:#DCD3C4;color:var(--ink);}
.qty .n{width:28px;text-align:center;font-weight:800;font-size:18px;}

.bottombar{position:fixed;left:0;right:0;bottom:0;background:var(--cream);box-shadow:0 -6px 20px -8px rgba(14,58,66,.4);padding:12px 16px calc(12px + env(safe-area-inset-bottom));z-index:20;}
.bottombar-in{max-width:560px;margin:0 auto;display:flex;align-items:center;gap:12px;}
.bottombar .total{flex:1;}
.bottombar .total small{display:block;font-size:12px;color:var(--ink-soft);}
.bottombar .total b{font-size:22px;}
.bottombar button{flex:1;background:var(--orange);color:#fff;}

.code-box{padding:24px;text-align:center;margin-top:10px;}
.qrbox{width:210px;margin:14px auto;}
.qrbox svg{width:100%;height:auto;}
.code{font-family:ui-monospace,"SF Mono",Menlo,monospace;font-size:38px;font-weight:800;letter-spacing:.18em;margin:8px 0;}
.code-box .note{font-size:14px;color:var(--ink-soft);margin:6px 0 0;}

.kpi{display:grid;grid-template-columns:1fr 1fr;gap:10px;margin-bottom:18px;}
.k{background:var(--cream);border-radius:var(--radius);padding:14px;box-shadow:var(--shadow);}
.k.highlight{background:var(--orange);color:#fff;}
.k-n{display:block;font-size:26px;font-weight:800;line-height:1.2;}
.k-l{display:block;font-size:12px;text-transform:uppercase;letter-spacing:.05em;opacity:.75;}

.pill{display:inline-block;font-size:11px;font-weight:800;text-transform:uppercase;letter-spacing:.06em;padding:4px 9px;border-radius:999px;margin-left:8px;background:#E3EEF0;color:var(--ink-soft);}
.pill-admin{background:var(--orange);color:#fff;}
.pill-ok{background:#D8F0E6;color:#14684A;}
.pill-wait{background:#FDE8CF;color:#8A4A05;}
.pill-off{background:#E6E2DA;color:#7A7268;}
.you{font-size:13px;color:var(--ink-soft);font-weight:600;}

.row.log{display:grid;grid-template-columns:auto auto 1fr;gap:10px;align-items:baseline;font-size:14.5px;}
.row.log .time{font-family:ui-monospace,monospace;font-size:12.5px;color:var(--ink-soft);white-space:nowrap;}
.row.log .log-user{font-weight:700;white-space:nowrap;}
.row.log .what em{color:var(--ink-soft);font-style:normal;}

.error{margin-top:12px;padding:12px 14px;border-radius:12px;background:#FBE3E6;color:#8E1B2C;font-size:15px;font-weight:600;}
.success{margin-top:12px;padding:12px 14px;border-radius:12px;background:#DFF3EA;color:#14684A;font-size:15px;font-weight:600;}
.notice{padding:12px 14px;border-radius:12px;margin-bottom:16px;background:var(--mint);color:#0C4A44;font-size:14.5px;font-weight:600;}
pre.pre{background:var(--cream);padding:14px;border-radius:12px;overflow:auto;font-size:12.5px;margin-top:14px;}

.auth{max-width:420px;margin:0 auto;padding:36px 0;}
.auth h1{margin-bottom:4px;}
.auth form{background:var(--cream);padding:22px;border-radius:var(--radius);box-shadow:var(--shadow);margin-top:18px;}

/* ---------- floating staff nav ---------- */
.nav{
  position:fixed;left:0;right:0;bottom:0;z-index:30;
  padding:0 12px calc(12px + env(safe-area-inset-bottom));
  pointer-events:none;
}
.nav-in{
  pointer-events:auto;
  max-width:560px;margin:0 auto;
  display:flex;justify-content:space-around;gap:2px;
  background:rgba(14,58,66,.94);
  backdrop-filter:blur(10px);
  border-radius:18px;
  padding:7px 6px;
  box-shadow:0 12px 30px -10px rgba(14,58,66,.7);
}
.nav a{
  flex:1;
  display:flex;flex-direction:column;align-items:center;gap:4px;
  color:rgba(255,246,234,.62);
  text-decoration:none;
  font-size:11px;font-weight:800;letter-spacing:.04em;text-transform:uppercase;
  padding:9px 4px;border-radius:13px;
  background:transparent;border:0;cursor:pointer;
  min-height:auto;
  transition:color .15s ease, background .15s ease;
}
.nav a span{white-space:nowrap;}
.nav .ic{
  width:21px;height:21px;
  fill:none;stroke:currentColor;stroke-width:1.9;
  stroke-linecap:round;stroke-linejoin:round;
}
.nav a:hover{color:var(--cream);}
.nav a.active{
  color:#fff;
  background:var(--flame);
  box-shadow:0 4px 12px -4px rgba(240,101,31,.8);
}

@media (min-width:600px){
  .kpi{grid-template-columns:repeat(4,1fr);}
  h1{font-size:34px;}
}

/* DESKTOP — staff pages only.
   The 560px column is right for a customer: they are always on a phone, and a narrow measure is
   what makes text readable anyway. It is wrong for the counter. An operator scanning a laptop
   list of forty orders, or reading the end-of-night report, has 1400px and was being given 560 —
   two thirds of the screen left empty while the content scrolled.
   Keyed off .app.with-nav, which is exactly "a staff page" (the quick bar only shows there). */
@media (min-width:900px){
  .app.with-nav{max-width:1000px;}

  /* NO grid here. An earlier version turned `.list` into a multi-column grid, but `.list` is what
     Products, Users, the Activity log AND the Report all use for their rows — so instead of a
     tidy grid of orders, four unrelated pages got their content chopped into ragged columns of
     mismatched heights. A wider column is the whole win on a laptop; the rows stay rows. */

  /* The scanner stays narrow and centred on purpose: it is one job, one camera, one result, and
     stretching it across a laptop would only put the answer further from the eye. */
  .app.with-nav .scan-bar,
  .app.with-nav .result{max-width:560px;margin-left:auto;margin-right:auto;}
}

/* Wider still: the report tables get room, but text never runs past a readable measure. */
@media (min-width:1200px){
  .app.with-nav{max-width:1120px;}
}
@media (prefers-reduced-motion:reduce){
  *{transition:none !important;}
  /* Both animations, not just the spin: the rays pulse on their own timeline, so stopping the
     parent alone would leave them breathing for anyone who asked for stillness. */
  .sunmark{animation:none;color:var(--flame);}
  .sunmark .rays{animation:none;transform:none;opacity:1;}
  /* The header ray burst too — it is the largest moving thing on the page. */
  .hero::before{animation:none;rotate:0deg;scale:1;opacity:1;}
}

/* ---------- report: filters, charts ---------- */
.chips{display:flex;flex-wrap:wrap;gap:8px;margin-bottom:16px;}
.chip{
  padding:9px 14px;min-height:auto;font-size:14px;font-weight:700;
  border-radius:999px;background:#E8E1D4;color:var(--ink);
}
.chip.on{background:var(--ink);color:var(--cream);}
.csv{
  display:inline-block;margin-top:12px;font-size:14px;font-weight:700;
  color:var(--orange-deep);text-decoration:none;
}
.csv:hover{text-decoration:underline;}

.warn-card{border-left:5px solid var(--orange-deep);}

.donut-wrap{display:flex;align-items:center;gap:18px;flex-wrap:wrap;}
.donut{width:160px;height:160px;flex-shrink:0;}
.donut-n{font-size:26px;font-weight:800;fill:var(--ink);}
.donut-l{font-size:9px;font-weight:700;fill:var(--ink-soft);text-transform:uppercase;letter-spacing:.1em;}

.legend{flex:1;min-width:200px;max-width:420px;display:flex;flex-direction:column;gap:2px;}
.leg{display:grid;grid-template-columns:14px 1fr auto;align-items:baseline;column-gap:10px;
     font-size:14.5px;padding:7px 0;border-bottom:1px solid rgba(0,0,0,.05);}
.leg:last-child{border-bottom:none;}
.dot{width:12px;height:12px;border-radius:3px;flex-shrink:0;align-self:center;}
.leg-name{font-weight:700;}
.leg-val{font-weight:800;white-space:nowrap;text-align:right;}
.leg-sub{grid-column:2 / 4;font-weight:500;font-size:12px;color:var(--ink-soft);text-align:right;margin-top:-2px;}

/* horizontal status/money breakdown bar */
.statusbar{display:flex;width:100%;height:22px;border-radius:7px;overflow:hidden;background:#EDE7DC;margin:4px 0 14px;}
.statusbar .seg{height:100%;display:block;transition:width .3s ease;}
.seg-collected{background:#2E9E6B;}   /* ritirati — green */
.seg-ready{background:#1FA9BC;}        /* da ritirare (paid, waiting) — teal */
.seg-unpaid{background:#F0A030;}       /* da pagare — amber */
.seg-cancelled{background:#B7AFA2;}    /* annullati — grey */
.seg-online{background:#1FA9BC;}
.seg-cash{background:#2E9E6B;}
.seg-pos{background:#6B8FD6;}
.status-legend{display:grid;grid-template-columns:repeat(auto-fit,minmax(150px,1fr));gap:8px 18px;}
.status-legend .sl{display:flex;align-items:center;gap:8px;font-size:14.5px;}
.status-legend .sl .dot{width:12px;height:12px;border-radius:3px;flex-shrink:0;}
.status-legend .sl-name{flex:1;font-weight:600;}
.status-legend .sl b{font-weight:800;white-space:nowrap;}

.bar-row{display:flex;align-items:center;gap:10px;margin-bottom:10px;}
.bar-label{width:74px;font-weight:700;font-size:14px;flex-shrink:0;}
.bar-track{flex:1;height:22px;background:#E8E1D4;border-radius:6px;overflow:hidden;}
.bar-fill{display:block;height:100%;background:var(--orange);border-radius:6px;}
.bar-fill.day{background:var(--aqua);}
.bar-val{width:92px;text-align:right;font-weight:700;font-size:14px;flex-shrink:0;}
.bar-val em{font-style:normal;font-weight:500;color:var(--ink-soft);font-size:12px;}

.hours{width:100%;height:120px;display:block;}
.hour-labels{display:flex;margin-top:4px;}
.hour-labels span{flex:1;text-align:center;font-size:11px;color:var(--ink-soft);font-weight:600;}
.hour-labels span.peak{color:var(--orange-deep);font-weight:800;}
.pill-super{background:var(--ink);color:var(--cream);}


/* ---------- follow us (customer pages) ---------- */
.social{
  text-align:center;
  padding:28px 0 8px;
}
.social p{
  margin:0 0 12px;
  font-size:11px;font-weight:800;letter-spacing:.18em;text-transform:uppercase;
  color:#fff;opacity:.9;text-shadow:0 1px 4px rgba(14,58,66,.3);
}
.social a{
  display:inline-grid;place-items:center;
  width:48px;height:48px;margin:0 7px;
  border-radius:15px;
  color:#fff;                       /* brand colours below, white glyph on top */
  box-shadow:0 8px 18px -8px rgba(14,58,66,.55);
  transition:transform .12s ease, filter .12s ease;
}
.social a:hover{transform:translateY(-2px);filter:brightness(1.07);}

/* The paths do not fill their own viewBox: both glyphs stop around x=2..22 of a 0..24 box, so
   an svg sized 24px only draws ~20px of ink. Inside a 48px tile that is 42% — a small mark
   adrift in a big square, which is exactly how it looked. 34px of svg puts ~28px of ink down,
   ≈60% of the tile, matching the real Facebook and Instagram buttons. */
.social svg{width:34px;height:34px;fill:currentColor;}

/* the real brand colours */
.social a.fb{background:#1877F2;}
.social a.ig{
  background:radial-gradient(circle at 30% 107%,
      #FDF497 0%, #FDF497 5%, #FD5949 45%, #D6249F 60%, #285AEB 90%);
}
button.danger-solid{background:var(--red);color:#fff;}
.editing{font-size:14px;color:var(--ink-soft);}
.editing b{color:var(--ink);}

/* ---------- "you have an order waiting" ---------- */
.pending-order{
  display:flex;align-items:center;justify-content:space-between;gap:12px;
  background:var(--sun);color:var(--ink);
  padding:14px 16px;border-radius:var(--radius);
  margin-bottom:16px;text-decoration:none;
  box-shadow:var(--shadow);
}
.pending-order small{
  display:block;font-size:11px;font-weight:800;text-transform:uppercase;
  letter-spacing:.08em;opacity:.75;
}
.pending-order b{
  font-family:ui-monospace,"SF Mono",Menlo,monospace;
  font-size:24px;letter-spacing:.14em;
}
.pending-order .show{font-weight:800;font-size:14px;white-space:nowrap;}
.lost-btn{
  width:100%;background:transparent;color:#fff;
  border:2px dashed rgba(255,255,255,.5);
  font-size:14px;margin-bottom:14px;min-height:44px;
}
.scan-bar input.plain{
  font-size:16px;font-weight:600;letter-spacing:normal;
  text-align:left;text-transform:none;
}
input.filter{margin-bottom:0;}
.pending-row{
  border-top:1px solid #E8DFD0;
  padding:12px 0 14px;
}
.pending-row:first-of-type{border-top:0;}
.pending-head{display:flex;align-items:baseline;justify-content:space-between;gap:10px;}
.pending-head b{font-size:17px;}
.pending-row .deliver{margin-top:10px;min-height:46px;font-size:15px;}

/* ---------- customer: my orders ---------- */
.my-orders-link{
  display:block;text-align:center;margin-bottom:16px;
  color:#fff;font-weight:700;text-decoration:none;
  text-shadow:0 1px 4px rgba(14,58,66,.35);
}
.row.myorder{flex-direction:column;align-items:stretch;gap:8px;}
.row.myorder.done{opacity:.72;}
.myorder-top{display:flex;align-items:center;justify-content:space-between;}
.code-sm{
  font-family:ui-monospace,"SF Mono",Menlo,monospace;
  font-size:22px;font-weight:800;letter-spacing:.14em;
}
.show-code{
  display:block;text-align:center;margin-top:4px;
  background:var(--flame);color:#fff;
  padding:11px;border-radius:12px;
  font-weight:800;text-decoration:none;
}
.back{
  display:block;text-align:center;margin-top:18px;
  color:#fff;font-weight:700;text-decoration:none;
  text-shadow:0 1px 4px rgba(14,58,66,.35);
}

/* The old back link was white text on a background that fades from sky to sunset — halfway down
   the page it lands on pale yellow and vanishes. A solid pill does not care what is behind it,
   and reads as a button rather than as a stray word. */
.back-btn{
  display:inline-flex;align-items:center;gap:6px;
  margin:0 0 16px;padding:11px 18px;
  border-radius:999px;
  background:var(--cream);
  color:var(--ink);
  font-size:15px;font-weight:700;
  text-decoration:none;
  box-shadow:0 8px 20px -10px rgba(14,58,66,.55);
  transition:transform .12s ease;
}
.back-btn:active{transform:scale(.97);}

/* Two ways out, side by side. The orders link is the primary one — someone holding a code wants
   their other codes, not the drinks list. */
.back-row{display:flex;gap:10px;flex-wrap:wrap;margin:0 0 16px;}
.back-btn.ghost-btn{
  background:rgba(255,255,255,.9);
  color:var(--ink-soft);
  box-shadow:0 4px 12px -8px rgba(14,58,66,.4);
}

/* An order that carries a code but has NOT been paid. Amber all the way through — it must not be
   confused with a green "da ritirare" at a glance, because the two mean opposite things at the
   counter: one gets served, the other has to pay first. */
.myorder.topay{
  border-left:5px solid var(--sunset);
}
.pill-topay{
  background:var(--sunset) !important;
  color:#2A1A06 !important;
}
.topay-note{
  margin-top:10px;padding:10px 12px;border-radius:10px;
  background:#FDE8CF;
  color:#5A3208;
  font-size:14px;line-height:1.45;
}
.topay-note b{color:#8C2308;}

/* The end-of-night reconciliation. Amber, because it is the card that explains a discrepancy —
   not a warning, but not routine either. */
.recon-card{border-left:5px solid var(--sunset);}
.recon-sum{
  margin-top:12px;padding:12px 14px;border-radius:10px;
  background:#FDE8CF;color:#5A3208;
}
.recon-row{
  display:flex;justify-content:space-between;gap:14px;
  padding:7px 0;font-size:14.5px;
  border-bottom:1px dotted rgba(90,50,8,.25);
}
.recon-row:last-child{border-bottom:0;}
.recon-row b{white-space:nowrap;color:#8C2308;}
.recon-total{
  margin-top:4px;padding-top:10px;
  border-top:2px solid rgba(90,50,8,.4);
  border-bottom:0;
  font-weight:800;
}
.badge-n{
  display:inline-block;margin-left:5px;padding:1px 6px;border-radius:999px;
  background:var(--flame);color:#fff;font-size:11px;font-weight:800;
}
.chip.on .badge-n{background:var(--sun);color:var(--ink);}

/* The count of codes still to collect on that evening. Different colour from the "stasera"
   badge, because it means something else: there is money already paid sitting unclaimed. */
.badge-wait{background:var(--sun) !important;color:#3A2408 !important;}
.chip.on .badge-wait{background:#fff !important;color:var(--ink) !important;}
.chips-nights{margin-bottom:14px;}
.pending-row.done{opacity:.62;}
.code-tag{
  font-family:ui-monospace,monospace;font-weight:700;
  color:var(--ink);letter-spacing:.06em;
}
a.lost-btn{
  display:block;text-align:center;line-height:40px;text-decoration:none;
}


/* ---------- "Altro" sheet (admin entries) ----------
   Pure CSS toggle: the layout is not interactive in Blazor, so a C# click handler
   here would do nothing. A hidden checkbox drives the panel instead. */
.more-toggle{position:absolute;width:0;height:0;opacity:0;pointer-events:none;}

.sheet-backdrop{
  display:none;
  position:fixed;inset:0;z-index:35;
  background:rgba(14,58,66,.5);
  backdrop-filter:blur(2px);
}
.more-toggle:checked ~ .sheet-backdrop{display:block;}
.more-toggle:checked ~ .sheet{display:flex;}

.sheet{
  display:none;
  position:fixed;left:12px;right:12px;z-index:36;
  bottom:calc(88px + env(safe-area-inset-bottom));
  max-width:536px;margin:0 auto;
  background:var(--cream);
  border-radius:18px;
  padding:8px;
  box-shadow:0 20px 44px -12px rgba(14,58,66,.6);
  flex-direction:column;
}
.sheet a{
  padding:14px 16px;border-radius:12px;
  color:var(--ink);text-decoration:none;
  font-weight:700;font-size:16px;
}
.sheet a:hover{background:rgba(14,58,66,.06);}
.sheet a + a{border-top:1px solid #EDE4D6;}
.sheet a.sheet-out{color:var(--red);}



/* ---------- staff drawer (slides in from the right) ----------
   Driven by a hidden checkbox: the Blazor layout is not interactive, so a C# click handler
   there would do nothing. festa.js only takes care of closing it. */
.drawer-toggle{position:absolute;width:0;height:0;opacity:0;pointer-events:none;}

.burger{
  display:grid;place-items:center;
  width:44px;height:44px;border-radius:13px;
  background:rgba(14,58,66,.28);
  backdrop-filter:blur(6px);
  cursor:pointer;flex-shrink:0;
}
.burger svg{
  width:22px;height:22px;
  fill:none;stroke:var(--cream);stroke-width:2;stroke-linecap:round;
}

.drawer-backdrop{
  position:fixed;inset:0;z-index:40;
  background:rgba(14,58,66,.55);
  backdrop-filter:blur(2px);
  opacity:0;pointer-events:none;
  transition:opacity .22s ease;
}

.drawer{
  position:fixed;top:0;right:0;bottom:0;z-index:41;
  width:min(78vw, 300px);
  background:var(--cream);
  box-shadow:-14px 0 40px -12px rgba(14,58,66,.55);
  transform:translateX(100%);
  transition:transform .24s cubic-bezier(.2,.8,.2,1);
  display:flex;flex-direction:column;
  padding:14px 12px calc(14px + env(safe-area-inset-bottom));
  overflow-y:auto;
}

.drawer-toggle:checked ~ .drawer-backdrop{opacity:1;pointer-events:auto;}
.drawer-toggle:checked ~ .drawer{transform:translateX(0);}

.drawer-head{
  display:flex;align-items:center;justify-content:space-between;
  padding:6px 8px 14px;border-bottom:1px solid #EDE4D6;margin-bottom:8px;
}
.drawer-who{
  font-weight:800;font-size:14px;color:var(--ink-soft);
  text-transform:uppercase;letter-spacing:.08em;
}
.drawer-x{
  font-size:30px;line-height:1;color:var(--ink-soft);
  cursor:pointer;padding:0 6px;
}

.drawer-nav{display:flex;flex-direction:column;}
.drawer-nav a{
  display:flex;align-items:center;gap:13px;
  padding:14px 12px;border-radius:12px;
  color:var(--ink);text-decoration:none;
  font-size:16.5px;font-weight:700;
  white-space:nowrap;               /* full labels: never truncated */
}
.drawer-nav a:hover{background:rgba(14,58,66,.06);}
.drawer-nav .ic{
  width:21px;height:21px;flex-shrink:0;
  fill:none;stroke:currentColor;stroke-width:1.9;
  stroke-linecap:round;stroke-linejoin:round;
}
.drawer-sep{
  font-size:11px;font-weight:800;letter-spacing:.12em;text-transform:uppercase;
  color:var(--ink-soft);opacity:.7;
  padding:16px 12px 6px;
  border-top:1px solid #EDE4D6;margin-top:8px;
}
.drawer-sep:empty{padding:0;margin-top:10px;}
.drawer-nav a.drawer-out{color:var(--red);}

@media (prefers-reduced-motion:reduce){
  .drawer,.drawer-backdrop{transition:none;}
}
.dup-warn{
  margin-top:8px;padding:9px 11px;border-radius:10px;
  background:#FDE8CF;color:#8A4A05;
  font-size:13.5px;font-weight:700;line-height:1.4;
}

/* "There are N orders you are not seeing." Not a warning — just the fact, said out loud,
   because a filtered list that does not say it is filtered is indistinguishable from a bug. */
.hidden-note{
  margin-top:6px;padding:8px 11px;border-radius:8px;
  background:rgba(79,187,212,.12);
  color:var(--ink);font-size:13.5px;line-height:1.45;
}
.hidden-note b{color:#9A2709;}   /* the count must be legible at a glance */

/* Two evenings with the same name split the takings and cannot be told apart later.
   Catch it at the moment of opening, not in the report a week afterwards. */
.dup-session{
  margin-top:14px;padding:14px 16px;border-radius:12px;
  background:#FDE8CF;border-left:4px solid var(--sunset);
  color:#5A3208;
}
.dup-session p{margin:0 0 8px;font-size:14.5px;line-height:1.5;}
.dup-session p:last-of-type{margin-bottom:12px;}
.dup-session b{color:#8C2308;}
.dup-session .detail{color:#7A5423;}
.dup-session-btns{display:flex;gap:10px;flex-wrap:wrap;}
.dup-session-btns button{flex:1;min-width:150px;}
/* An order from a previous evening is a different kind of warning from a duplicate name:
   it is not a mix-up risk, it is a takings risk. Redder, and it says so. */
.dup-warn.old-night{
  background:#FBD9CE;color:#8C2308;
  border-left:4px solid #9A2709;
}
.dup-warn.old-night b{display:block;margin-bottom:2px;}

/* Customer side: which evening the order is from. Quiet when it is tonight, loud when it is not
   — someone turning up with yesterday's code should know it is yesterday's before they queue. */
.myorder-night{
  margin-top:8px;font-size:13.5px;color:var(--ink-soft);
}
.myorder-night.old{
  padding:9px 11px;border-radius:10px;
  background:#FDE8CF;color:#8A4A05;font-weight:600;line-height:1.4;
}
.myorder-night.old b{display:block;color:#8C2308;}
/* The "previous evenings" switch sits under the filter box, with room to breathe:
   squeezed against the input it read like part of the placeholder. */
.allnights{
  display:flex !important;
  align-items:center;
  gap:11px;
  margin:18px 0 4px;
  padding-top:16px;
  border-top:1px solid #EDE4D6;
  font-size:14.5px;
  font-weight:600;
  color:var(--ink-soft);
  text-transform:none !important;
  letter-spacing:normal !important;
  cursor:pointer;
}
.allnights input[type=checkbox]{
  width:22px;height:22px;
  min-width:22px;
  margin:0;
  padding:0;
  accent-color:var(--flame);
  cursor:pointer;
  flex-shrink:0;
}
.allnights span{line-height:1.35;}

/* ---------- till closed (customer) ---------- */
.closed-card{
  background:var(--cream);
  border-radius:var(--radius);
  box-shadow:var(--shadow);
  padding:30px 22px;
  text-align:center;
  margin-bottom:18px;
}
.closed-sun{width:64px;margin:0 auto 14px;}
.closed-sun .sunmark{width:64px;height:64px;}
.closed-card h2{
  margin:0 0 8px;font-size:22px;font-weight:800;color:var(--ink);
}
.closed-card p{
  margin:0;color:var(--ink-soft);font-size:16px;line-height:1.5;
}
.pw-row{display:flex;gap:8px;}
.pw-row input{flex:1;}
.pw-row button{flex-shrink:0;min-height:auto;padding:0 16px;}
.icon-btn{
  flex-shrink:0;
  width:46px;min-height:46px;padding:0;
  display:grid;place-items:center;
  background:transparent;border:2px solid #DCD3C4;border-radius:12px;
  color:var(--ink-soft);
}
.icon-btn:hover{color:var(--ink);border-color:var(--ink-soft);}
.icon-btn svg{
  width:19px;height:19px;
  fill:none;stroke:currentColor;stroke-width:1.9;
  stroke-linecap:round;stroke-linejoin:round;
}
.pw-row{flex-wrap:wrap;}
.pw-row input{min-width:150px;}
button.ghost.warn{border-color:#E7C08A;color:#8A5A05;}

/* ---------- /verifica : the reconciliation cockpit ----------------------------------------
   A dense table on a phone is a lost cause, so it scrolls sideways rather than crushing the
   columns into unreadable slivers. The first column stays put: without a code to anchor to,
   a scrolled row is just numbers. */
.tbl{width:100%;border-collapse:collapse;font-size:.86rem;display:block;overflow-x:auto;white-space:nowrap;}
.tbl th,.tbl td{padding:8px 10px;text-align:left;border-bottom:1px solid var(--line,#e6ddd0);vertical-align:top;}
.tbl thead th{font-weight:700;font-size:.74rem;letter-spacing:.04em;text-transform:uppercase;opacity:.65;}
.tbl tfoot td{border-top:2px solid var(--ink,#0E3A42);border-bottom:none;padding-top:10px;}
.tbl .num{text-align:right;font-variant-numeric:tabular-nums;}
.tbl tr.muted{opacity:.4;}
.tbl small{opacity:.7;white-space:normal;}

/* Green ONLY when it adds up. The whole point of this page is that a wrong sum cannot look
   like a right one. */
.ok-note{color:#2E7D32;font-weight:700;}
.bad-note{color:#C62828;font-weight:800;}
.recon-row.bad,.recon-row.bad *{color:#C62828;}

/* The data-integrity warning light. Deliberately loud: it appears only when something is actually
   wrong with the money, and a warning nobody notices is not a warning. */
.alert-dot{
  display:flex;align-items:center;gap:6px;
  background:#C62828;color:#fff;border:0;border-radius:999px;
  padding:6px 12px 6px 9px;margin-right:8px;cursor:pointer;
  font:inherit;font-weight:800;font-size:.85rem;line-height:1;
  box-shadow:0 2px 10px rgba(198,40,40,.45);
  animation:alertpulse 2.4s ease-in-out infinite;
}
.alert-dot .ic{width:17px;height:17px;stroke:#fff;stroke-width:2;fill:none;}
.alert-dot:active{transform:scale(.94);}
.alert-n{font-variant-numeric:tabular-nums;}
@keyframes alertpulse{
  0%,100%{box-shadow:0 2px 10px rgba(198,40,40,.45);}
  50%    {box-shadow:0 2px 18px rgba(198,40,40,.85);}
}
@media (prefers-reduced-motion:reduce){ .alert-dot{animation:none;} }

/* ---------- paging on the counter's order list -------------------------------------------
   Pressed with one thumb, in the dark, by somebody holding a drink in the other hand. Big
   targets, and the page number between them so nobody has to guess where they are. */
.pager{
  display:flex;align-items:center;justify-content:space-between;gap:10px;
  margin-top:16px;padding-top:14px;border-top:1px solid var(--line,#e6ddd0);
}
.pager .ghost-btn{flex:1;min-height:46px;font-weight:700;}
.pager .ghost-btn:disabled{opacity:.35;}
.pager-n{
  font-variant-numeric:tabular-nums;font-weight:800;opacity:.7;
  min-width:64px;text-align:center;font-size:.9rem;
}

/* The money the counter is about to take. Amber, not red: nothing is wrong, but somebody is
   going to have to open the drawer. */
.topay-note{
  background:#FDF0DC;border-left:4px solid var(--orange-deep,#B5651D);
  padding:10px 12px;border-radius:8px;margin:10px 0 4px;
}

/* ONE-SHOT for unpaid orders at the counter. Flame on purpose, and loud: this order has NOT been
   paid, and anything here that reads like the paid flow means drinks handed out for free. The
   whole card gets a full flame border (not just the left edge) for the same reason. */
.result.ko.unpaid{border:3px solid var(--flame);border-left:8px solid var(--flame);background:#FFF3EA;}
button.deliver.pay-deliver{
  background:var(--flame);
  color:#fff;
  font-weight:800;
  border:2px solid var(--flame-deep);
}
button.deliver.pay-deliver:active{background:var(--flame-deep);}

/* ---- "Report serata" on /cassa ----------------------------------------------------------------
   It used to be a default browser link sitting inside .detail — the soft grey line meant for
   timestamps — which made the one actionable thing on each row the least visible thing on it.
   Now it borrows the chip shape already used by the report filters, so it reads as pressable
   without inventing a new control. The evening still OPEN gets the flame fill: on a night with
   nine closed evenings listed, tonight is the one you are reaching for. */
.night-report{
  display:inline-flex;align-items:center;gap:7px;
  padding:8px 15px;border-radius:999px;
  font-size:13.5px;font-weight:800;line-height:1;
  background:#E8E1D4;color:var(--ink);
  text-decoration:none;white-space:nowrap;
  transition:background .15s ease,color .15s ease,transform .12s ease;
}
.night-report:hover{background:var(--ink);color:var(--cream);}
.night-report:active{transform:translateY(1px);}
.night-report.on{background:var(--flame);color:#fff;}
.night-report.on:hover{background:var(--flame-deep);}
/* The arrow leans into the hover — the same nudge the delivery button uses. */
.night-report .arw{transition:transform .15s ease;}
.night-report:hover .arw{transform:translateX(3px);}

/* ---- home page: "I miei ordini" ---------------------------------------------------------------
   It was bare white text with a shadow, floating on the gradient: on the pale sky at the top of
   the page it read as a caption rather than a link, and on a phone in daylight it half vanished.
   The page's own vocabulary for "tappable" is the cream pill, so it becomes one — same shape as
   the report chips, same shadow as the pending-order banner it sits under. Its target is the
   only other page a customer ever needs, so it should look reachable, not decorative. */
.my-orders-link{
  display:flex;align-items:center;justify-content:center;gap:8px;
  width:fit-content;margin:0 auto 16px;
  padding:11px 20px;border-radius:999px;
  background:var(--cream);color:var(--ink);
  font-size:14.5px;font-weight:800;line-height:1;
  text-decoration:none;text-shadow:none;
  box-shadow:var(--shadow);
  transition:background .15s ease,color .15s ease,transform .12s ease;
}
.my-orders-link:hover{background:var(--ink);color:var(--cream);}
.my-orders-link:active{transform:translateY(1px);}
/* The white outline set higher up is invisible against a cream pill. */
.my-orders-link:focus-visible{outline-color:var(--ink);}
.my-orders-link .arw{transition:transform .15s ease;}
.my-orders-link:hover .arw{transform:translateX(3px);}

/* ---- evening chips on "I miei ordini": badges stay ORANGE when selected --------------------------
   The generic rule turns any badge on a selected chip yellow (readable on dark ink, and it suits
   the counter's filter row). On this row the selected chip is the evening the customer is standing
   in, and yellow-on-ink read as a warning rather than a count. Orange keeps the badge the same
   colour whether or not its chip is selected, so the eye tracks the NUMBER, not the selection.
   Scoped to .chips-nights on purpose: /banco and /report keep the yellow they were tuned with. */
.chips-nights .chip.on .badge-n{background:var(--flame);color:#fff;}
.chips-nights .chip.on .badge-wait{background:var(--flame) !important;color:#fff !important;}

/* ---- counter: what to hand over ----------------------------------------------------------------
   The scan result is read standing up, at arm's length, in the dark, with someone waiting. The
   drink lines were 17px and unlabelled while the price sat at 24px — so the largest thing on the
   card was the number the operator does not need (a paid order's amount) and the smallest was the
   one they act on. Reversed: the list is named and set big, and the quantity becomes a solid chip
   because "2×" misread as "1×" is a wrong handover, not a typo. */
.items-label{
  margin:14px 0 2px;font-size:12px;font-weight:800;letter-spacing:.1em;
  text-transform:uppercase;color:#6C7F76;
}
.items.big li{
  font-size:23px;font-weight:700;padding:13px 0;
  display:flex;align-items:center;gap:12px;
}
.items.big b{
  flex-shrink:0;min-width:52px;padding:4px 10px;border-radius:10px;
  background:var(--flame);color:#fff;
  font-size:21px;font-weight:800;text-align:center;
}
/* A single-line order needs no chip hierarchy, but two lines do — keep the rule uniform so the
   operator never has to work out which layout they are looking at. */
.items.big li:last-child{border-bottom:0;}

/* ---- customer: the drinks on the code screen ---------------------------------------------------
   Centred, because the whole code-box is centred, and quiet: this is confirmation, not the thing
   they act on. The code stays the largest element on the card. */
.order-lines{
  list-style:none;padding:0;margin:10px auto 0;max-width:230px;
  text-align:left;
}
.order-lines li{
  padding:7px 0;border-bottom:1px solid #EDE4D6;
  font-size:16px;font-weight:600;color:var(--ink);
}
.order-lines li:last-child{border-bottom:0;}
.order-lines b{
  display:inline-block;min-width:34px;
  color:var(--flame);font-weight:800;
}

/* ---- customer: why "Paga" is not available -----------------------------------------------------
   Sits in the fixed bottom bar, under the button, because that is where the finger and the eye
   already are. Amber rather than red: nothing has gone wrong, something is simply missing. */
.pay-hint{
  margin:8px 0 0;text-align:center;
  font-size:13.5px;font-weight:700;color:#7A4A10;
}
/* The name card, once it is the only thing standing between them and paying. */
.card.needs{
  border-left:5px solid var(--sunset);
}

/* ---- lists: the drinks are the job, the price is reference -------------------------------------
   In both staff lists the amount was the largest thing on the row (24px, weight 800) and the
   drinks were inside .detail, the small grey line built for timestamps. For a PAID order that is
   backwards: nobody collects money for it, they fetch bottles. So the drinks get their own line at
   19px in full ink, and the amount drops to reference size — still there, because the "da pagare"
   filter and the Orders page both need it, just no longer shouting. */
.row-items{
  margin-top:4px;
  font-size:19px;font-weight:700;line-height:1.35;color:var(--ink);
}
.row .amount{font-size:15px;font-weight:700;color:var(--ink-soft);margin-left:8px;}
/* Settled scan result: the figure is reference, not an instruction. */
.amount.quiet{font-size:16px;font-weight:700;color:var(--ink-soft);}

/* ---- lists: one chip per drink -----------------------------------------------------------------
   A comma-joined line ("2× Birra, 1× Acqua, 3× Coca") is read as prose, and prose is where a line
   gets skipped when there is a queue. Separate chips are counted instead of read, and the quantity
   badge inside each one carries the only number that changes what leaves the counter. */
.row-items{display:flex;flex-wrap:wrap;gap:6px;align-items:center;}
.item-chip{
  display:inline-flex;align-items:center;gap:7px;
  padding:5px 12px 5px 6px;border-radius:999px;
  background:#F1E9DC;color:var(--ink);
  font-size:16px;font-weight:700;line-height:1.2;
}
.item-chip b{
  padding:2px 8px;border-radius:8px;
  background:var(--flame);color:#fff;
  font-size:14px;font-weight:800;
}

/* ---- customer code screen: the drinks, as centred chips ------------------------------------------
   Was a left-aligned list inside a centred box: with a single drink the line sat off to one side of
   a symmetrical card, which read as a mistake rather than a layout. Chips centred with flex-wrap
   stay centred for one drink or for five, and they match what the operator sees on the scan — the
   two screens are held up next to each other at the counter, so they should look like the same
   thing. Overrides the earlier list rules (later wins at equal specificity). */
.order-lines{
  display:flex;flex-wrap:wrap;justify-content:center;align-items:center;
  gap:7px;margin:12px 0 0;padding:0;max-width:none;
  list-style:none;text-align:center;
}

/* ---- /ordini: which evening am I looking at --------------------------------------------------
   With "serate precedenti" ticked, orders from many nights stack up and every row shows only a
   time — so without a strong divider you lose track of which night a block belongs to. The
   heading was unstyled text, invisible between rows. Now it is a filled bar that STICKS to the top
   while you scroll its block: at any scroll position the evening you are looking at is named at the
   top of the screen. It carries the weekday, the date, and how many orders are in that night. */
.night-heading{
  position:sticky;top:0;z-index:5;
  display:flex;align-items:center;justify-content:space-between;gap:10px;
  margin:18px 0 8px;padding:9px 14px;border-radius:10px;
  background:var(--ink);color:var(--cream);
  font-size:15px;font-weight:800;line-height:1.2;
  box-shadow:var(--shadow);
}
.night-heading:first-of-type{margin-top:6px;}
.night-count{
  flex-shrink:0;padding:2px 10px;border-radius:999px;
  background:rgba(255,255,255,.16);color:#fff;
  font-size:12.5px;font-weight:700;white-space:nowrap;
}

/* ---- /ordini: close out an old, never-collected order -------------------------------------------
   A quiet ghost button next to "Consegna" on a paid order from a past evening. It is not the
   default action — most old orders still get delivered — so it must not compete with the green
   button. Slightly warm border to say "this ends something", not a plain neutral ghost. */
.ghost-btn.mark-obsolete{
  margin-top:8px;width:100%;
  border-color:var(--sunset);color:#8A4B12;
  font-size:14px;font-weight:700;
}
.ghost-btn.mark-obsolete:hover{background:#FBEFE0;}

/* ---- report: legend for the order states -------------------------------------------------------
   Six filter tabs is past the point where the names speak for themselves, and the report is the one
   page an admin opens cold at the end of the night. A quiet block under the tabs, one line each. */
.legend{
  margin:0 0 14px;padding:11px 14px;border-radius:10px;
  background:#F4ECDD;color:var(--ink);
  font-size:13px;line-height:1.55;
}
.legend div + div{margin-top:2px;}
.legend b{font-weight:700;}

/* ---- fix contrasto: testo vuoto dentro le card ------------------------------------------------
   .empty è bianco, giusto sullo sfondo azzurro della pagina ma illeggibile dentro una card crema
   (report, tab Archiviati vuoto). Dentro card/list lo rendo scuro e tolgo l'ombra da fondo scuro. */
.card .empty, .list .empty{
  color:var(--ink-soft);
  text-shadow:none;
  opacity:1;
}

/* ---- report: legenda stati in alto, con pallini colore che rispecchiano i grafici ------------- */
.legend-top{margin-top:0;margin-bottom:16px;}
.legend-top div{display:flex;align-items:baseline;gap:8px;}
.legend-top .dot{width:11px;height:11px;border-radius:3px;flex-shrink:0;align-self:center;}
.seg-obsolete{background:#B7AFA2;}     /* archiviati — grigio, come annullati ma distinto in lista */
.seg-recovered{background:#2E9E6B;}    /* recuperati — verde, sono stati consegnati */

/* ---- StatusLegend: componente legenda stati (report sempre aperto, ordini/cassa a scomparsa) ---- */
.statuslegend{margin:0 0 16px;}
.statuslegend-toggle{
  display:flex;align-items:center;gap:9px;width:100%;
  padding:10px 14px;border-radius:10px;border:none;cursor:pointer;
  background:#F1E9DC;color:var(--ink);
  font-size:14px;font-weight:700;text-align:left;
}
.statuslegend-toggle:hover{background:#EAE0CF;}
.statuslegend .sl-q{
  display:inline-flex;align-items:center;justify-content:center;
  width:20px;height:20px;border-radius:50%;flex-shrink:0;
  background:var(--ink);color:var(--cream);
  font-size:13px;font-weight:800;
}
.statuslegend .sl-caret{margin-left:auto;font-size:11px;opacity:.6;}
.statuslegend-body{
  padding:12px 14px;border-radius:10px;
  background:#F4ECDD;color:var(--ink);
  font-size:13px;line-height:1.5;
}
/* quando è a scomparsa e aperto, il corpo si stacca dal bottone */
.statuslegend-toggle + .statuslegend-body{margin-top:6px;}
.sl-item{display:flex;align-items:flex-start;gap:9px;}
.sl-item + .sl-item{margin-top:5px;}
.statuslegend .sl-item .dot{
  width:11px;height:11px;border-radius:3px;flex-shrink:0;margin-top:4px;
}

/* Promemoria alla chiusura cassa (ordini pagati non ritirati). NON un errore: è un avviso, quindi
   ambra come gli altri notice, non il rosso "rischio incasso". Solo il titolo va a capo da solo. */
.dup-warn.close-note{
  background:#FDECD2;color:#7A4A08;
  border-left:4px solid var(--sunset);
  font-weight:500;
}
.dup-warn.close-note b{display:block;margin-bottom:3px;color:#6A3D06;font-weight:800;}

/* Informativa privacy: elenco puntato leggibile e link legale nel footer clienti. */
.privacy-list{margin:8px 0 0;padding-left:20px;color:#3A4A52;font-size:14px;line-height:1.55;}
.privacy-list li{margin-bottom:6px;}
/* Testo legale nel footer clienti. IMPORTANTE: sta dentro .social, quindi va isolato dalle regole
   .social p (maiuscolo/spaziato di "SEGUICI SU") e .social a (riquadro icona 48px con ombra),
   che altrimenti trasformano il link privacy in un riquadro-ombra e il testo in maiuscolo. */
.social-legal{
  margin-top:14px;font-size:13px;
  text-transform:none;letter-spacing:normal;font-weight:400;
  color:#4a5a62;opacity:1;text-shadow:none;
}
.social-legal a{
  display:inline;width:auto;height:auto;margin:0;padding:0;
  border-radius:0;box-shadow:none;background:none;
  color:#41677a;text-decoration:underline;font-weight:400;
}
.social-legal a:hover{transform:none;filter:none;}
.social-copy{
  display:block;margin-top:6px;font-size:12px;font-weight:400;
  color:#6f8188;text-transform:none;letter-spacing:normal;text-shadow:none;
}

/* Nome per il ritiro, mostrato al cliente accanto al codice e in "I miei ordini". */
.pickup-name{margin:6px 0 0;font-size:14px;color:#3A4A52;}
.pickup-name b{color:#1E272C;}
.myorder-name{margin-top:2px;font-size:13.5px;color:#4A5A62;}
.myorder-name b{color:#1E272C;}

/* Riquadro "Installa l'app" nella pagina di login — stile scuro elegante (solo lo staff arriva qui). */
.pwa-box{margin:20px auto 0;max-width:340px;text-align:center;}
.pwa-btn{display:inline-flex;align-items:center;justify-content:center;gap:10px;
  border:none;border-radius:14px;background:#0E3A42;color:#fff;
  font-size:15px;font-weight:700;padding:14px 30px;cursor:pointer;
  box-shadow:0 10px 24px -10px rgba(14,58,66,.8);transition:transform .06s ease,background .15s ease;}
.pwa-btn:hover{background:#123;} .pwa-btn:active{transform:translateY(1px);}
.pwa-btn svg{flex:0 0 auto;}
.pwa-ios{margin:4px 6px 0;font-size:13.5px;color:#12303F;line-height:1.5;}
.pwa-note{margin:11px 0 0;font-size:12.5px;color:#4a6b74;}

/* Wordmark ufficiale del grafico (immagine al posto del testo). Il sole resta il componente <Sun/> che gira. */
.wordmark-img{display:block;height:40px;width:auto;max-width:62vw;}
@media (max-width:480px){ .wordmark-img{height:34px;} }

/* Sunni Pay in alto (header), al posto della scritta; scritta Ferragosto spostata nel footer, dritta. */
.sunni-img{display:block;height:58px;width:auto;}
.footer-wordmark{display:block;width:min(240px,72%);height:auto;margin:0 auto 14px;}

/* ===== Header "Sunni Pay" con raggi azzurri rotanti dietro (no sole) ===== */
.sunni-badge{
  position:relative; display:grid; place-items:center;
  width:118px; height:118px; flex-shrink:0;
}
/* raggi azzurro chiaro che si irradiano dal centro e GIRANO lentamente */
.sunni-badge::before{
  content:""; position:absolute; inset:-55%;
  background:repeating-conic-gradient(from 0deg at 50% 50%,
      rgba(224,244,252,.60) 0deg 4.5deg, transparent 4.5deg 12deg);
  border-radius:50%;
  -webkit-mask:radial-gradient(closest-side,#000 60%, transparent 100%);
          mask:radial-gradient(closest-side,#000 60%, transparent 100%);
  animation:spin 30s linear infinite;
  pointer-events:none; z-index:0; will-change:transform;
}
.sunni-hero{
  position:relative; z-index:1;
  height:104px; width:auto;
  filter:drop-shadow(0 3px 6px rgba(14,58,66,.35));
}
@media (max-width:480px){
  .sunni-badge{width:104px;height:104px;}
  .sunni-hero{height:92px;}
}

/* ============================================================
   HERO "SUNNI PAY" — mascotte centrata e grande + raggi azzurri ROTANTI (versione finale)
   Sostituisce brand piccolo/sole. Il menu staff va in alto a destra (assoluto).
   ============================================================ */
.hero{ min-height:300px; }
.hero-in{
  max-width:660px; margin:0 auto; padding:18px 16px 8px;
  display:block; text-align:center;          /* Sunni centrata */
  position:relative; z-index:1;
}
.brand{ display:inline-flex; justify-content:center; padding:0; margin:0; }
.sunni-badge{ width:auto; height:auto; }
.sunni-hero{
  height:244px; width:auto; max-width:88vw;
  filter:drop-shadow(0 4px 10px rgba(14,58,66,.35));
}
@media (max-width:480px){ .hero{min-height:250px;} .sunni-hero{ height:196px; } }

/* raggi azzurro chiaro dietro la Sunni, che GIRANO lentamente (sfumati ai bordi) */
.hero::before{
  content:""; position:absolute; inset:auto;
  left:50%; top:42%; width:200%; height:200%;
  transform:translate(-50%,-50%); transform-origin:50% 50%;
  background:repeating-conic-gradient(from 0deg at 50% 50%,
      rgba(224,244,252,.55) 0deg 4.5deg, transparent 4.5deg 12deg);
  -webkit-mask:radial-gradient(closest-side,#000 30%, transparent 80%);
          mask:radial-gradient(closest-side,#000 30%, transparent 80%);
  animation:spin 34s linear infinite;
  pointer-events:none; z-index:0;
}

/* menu staff (hamburger) in alto a destra: non disturba la Sunni centrata */
.hero .burger{ position:absolute; top:14px; right:14px; z-index:3; }
