/* ⛔ TWO GREYS WERE TOO FAINT TO READ, EVERYWHERE THEY APPEARED (2026-09-05).
   #8494A6 measured 3.10:1 on white and #6B7A8D 4.38:1, against a 4.5 bar for
   small text. Raised to #5B6B7E (5.46:1) and #4A5D75 (6.74:1) — both already in
   use in this file, so nothing new was invented. Measured on the live page.
   ⚠️ Nothing caught these: the estate's contrast check only walks hub-next and
   has never looked at the customer app or the website. See W-f7eecb. */
/* THE SCRATCH TICKET — ONE STYLESHEET, READ BY BOTH SURFACES.

   ⛔ THIS WAS INLINE IN app.html AND THEREFORE INVISIBLE ON THE WEBSITE (2026-09-04,
   Admin PIN). Admin: "we would have to do it on the website too". The website's own
   /account page is described in app.py as "the website mirror of the app's Account +
   Rewards tabs" — but the game's markup lived in one template and its 170 lines of CSS
   in the other's <style> block, so putting the slot on the website would have rendered
   an unstyled pile of divs.

   ⛔ IT IS LINKED, NOT COPIED (#32). Change a colour here and BOTH surfaces move with
   nobody editing a second file. Two copies of this would drift, and the one that drifts
   is always the one fewer people open. */

/* ── THE SCRATCH TICKET (2026-09-03, Admin PIN) ─────────────────────────────
   Admin sent a retro "LUCKY SCRATCH" ticket as the shape he wanted: a framed
   card, a sunburst behind a stacked title, then a grid of panels. This is that
   in OUR colours — pink #E41764 leading, navy #1C3554 framing, cream ground —
   rather than the reference's red and gold.
   Everything is CSS and canvas. No image to fetch, nothing to arrive half-loaded
   on a phone with one bar. */
.tk-intro { border:2px solid #FFD3E4; border-radius:18px; padding:16px; margin-bottom:16px;
  background:linear-gradient(160deg,#FFF3F8,#FFF8F3); box-shadow:0 6px 20px rgba(228,23,100,.10); }
.tk-intro-head { display:flex; gap:12px; align-items:flex-start; }
.tk-intro-i { font-size:28px; line-height:1; }
.tk-intro-head b { display:block; font-family:'Bebas Neue',sans-serif; font-size:24px;
  letter-spacing:1px; color:#1C3554; line-height:1.05; }
.tk-intro-brand { display:block; width:112px; height:auto; margin-bottom:4px; }
.tk-intro-head i { display:block; font-style:normal; font-size:13px; color:#4A5D75; margin-top:2px; }
.tk-intro-prizes { display:flex; flex-wrap:wrap; gap:6px; margin:12px 0 10px; }
.tk-intro-prizes span { font-size:12px; background:#fff; border:1px solid #FFD3E4;
  border-radius:99px; padding:5px 10px; color:#1C3554; }
.tk-intro-foot { font-size:12.5px; color:#5B6B7E; }
.tk-intro-foot b { color:#E41764; }
.tk-intro-have { margin-top:12px; font-size:15px; color:#1C3554; }
.tk-intro-have b { font-family:'Bebas Neue',sans-serif; font-size:28px; color:#E41764;
  vertical-align:-2px; margin-right:3px; }
.tk-intro-go { display:block; width:100%; min-height:48px; margin-top:10px; border:0;
  border-radius:14px; background:#E41764; color:#fff; font-size:16px; font-weight:700;
  cursor:pointer; }
.tk-intro-go:active { background:#C21254; }
.tk-intro-none { margin-top:10px; font-size:13px; color:#5B6B7E; }
/* The compact state — one tappable line, 44px+ target, brand pink. */
.tk-bar { display:flex; align-items:center; gap:12px; width:100%; text-align:left;
  min-height:64px; padding:12px 14px; margin-bottom:16px; cursor:pointer;
  border:2px solid #FFD3E4; border-radius:16px;
  background:linear-gradient(135deg,#FFF3F8,#FFF8F3); }
.tk-bar:active { background:#FFE9F2; }
.tk-bar-i { font-size:26px; line-height:1; }
.tk-bar-t { flex:1; min-width:0; }
.tk-bar-t b { display:block; font-size:15px; color:#1C3554; }
.tk-bar-t i { display:block; font-style:normal; font-size:12px; color:#5B6B7E; margin-top:2px; }
.tk-bar-go { flex:0 0 auto; background:#E41764; color:#fff; font-weight:700; font-size:13px;
  padding:9px 14px; border-radius:99px; }
.tk-close { display:block; width:100%; min-height:44px; margin-top:12px;
  border:2px solid #C9D6E2; border-radius:12px; background:#fff; color:#4A5D75;
  font-size:14px; font-weight:600; cursor:pointer; }
.tk { position:relative; border-radius:18px; overflow:hidden; margin-bottom:16px;
  background:#FFF8F3; border:3px solid #1C3554;
  box-shadow:0 8px 26px rgba(28,53,84,.18); }
.tk-rays { position:absolute; inset:0; pointer-events:none;
  background:repeating-conic-gradient(from 0deg at 50% 22%,
    rgba(228,23,100,.16) 0deg 9deg, rgba(228,23,100,0) 9deg 18deg); }
.tk-inner { position:relative; padding:18px 16px 14px; text-align:center; }
.tk-title { line-height:.82; margin-bottom:4px; }
.tk-lucky, .tk-scratch { display:block; font-family:'Bebas Neue',sans-serif; letter-spacing:2px; }
.tk-lucky { font-size:46px; color:#E41764;
  text-shadow:3px 3px 0 #1C3554, -1px -1px 0 #fff, 1px -1px 0 #fff, -1px 1px 0 #fff; }
.tk-scratch { font-size:30px; color:#1C3554;
  text-shadow:2px 2px 0 #A8C0D8, -1px -1px 0 #fff, 1px -1px 0 #fff; }
/* Just "Leslie's" — the shop's own name at the top of its own ticket, not the full
   trading name. Admin's call, and it reads like a banner rather than a form. */
/* The real script wordmark, "Leslie's" only — not the DESSERTS lockup, not type
   pretending to be it. Cropped from the brand artwork Admin sent. */
.tk-brand { display:block; width:148px; max-width:52%; height:auto; margin:0 auto 2px; }
.tk-count { font-size:16px; color:#1C3554; margin:8px 0 14px; font-weight:600; }
.tk-count b { font-family:'Bebas Neue',sans-serif; font-size:30px; color:#E41764;
  letter-spacing:1px; vertical-align:-2px; margin-right:2px; }
.tk-count i { font-style:normal; font-size:12.5px; color:#B45309; font-weight:500; }
.tk-sub { font-size:12.5px; color:#4A5D75; margin:6px 0 14px; font-weight:500; }
.tk-foot { font-size:11.5px; color:#5B6B7E; margin-top:12px; }
.tk-none { font-size:46px; margin:10px 0 6px; }

/* A topping they have already won, on the ordering screen. */
.opt-free { color:#E41764; font-weight:800; letter-spacing:.04em; }
.opt-won { display:inline-block; font-size:10.5px; font-weight:700; letter-spacing:.06em;
  text-transform:uppercase; color:#E41764; background:#FFE9F2; border:1px solid #FFD3E4;
  border-radius:99px; padding:2px 8px; margin-left:6px; vertical-align:1px; }
/* ── THE WIN MOMENT ───────────────────────────────────────────────────────── */
.win-ov { position:fixed; inset:0; z-index:900; display:flex; align-items:center;
  justify-content:center; padding:24px; background:rgba(28,53,84,.55);
  opacity:0; transition:opacity .26s; -webkit-backdrop-filter:blur(3px); backdrop-filter:blur(3px); }
.win-ov.win-in { opacity:1; }
.win-box { position:relative; z-index:2; width:100%; max-width:340px; text-align:center;
  background:linear-gradient(160deg,#FFF8F3,#FFF0F6); border:3px solid #E41764;
  border-radius:22px; padding:26px 20px 20px; box-shadow:0 20px 50px rgba(0,0,0,.35);
  transform:scale(.86); transition:transform .32s cubic-bezier(.2,.9,.3,1.4); }
.win-ov.win-in .win-box { transform:scale(1); }
.win-kicker { font-size:11px; letter-spacing:.14em; text-transform:uppercase;
  color:#E41764; font-weight:700; }
.win-big { font-family:'Bebas Neue',sans-serif; font-size:46px; line-height:1;
  color:#E41764; letter-spacing:1px; margin:4px 0 2px;
  text-shadow:3px 3px 0 #1C3554, -1px -1px 0 #fff, 1px -1px 0 #fff; }
.win-icon { font-size:58px; line-height:1.1; margin:6px 0 2px; animation:winpop .5s cubic-bezier(.2,.9,.3,1.5) both .12s; }
.win-what { font-family:'Bebas Neue',sans-serif; font-size:28px; line-height:1.05;
  color:#1C3554; letter-spacing:.5px; }
.win-sub { font-size:13.5px; color:#4A5D75; margin-top:4px; }
.win-saved { font-size:12px; color:#5B6B7E; margin-top:12px; }
.win-go { width:100%; min-height:50px; margin-top:14px; border:0; border-radius:14px;
  background:#E41764; color:#fff; font-size:16px; font-weight:700; cursor:pointer; }
.win-go:active { background:#C21254; }
@keyframes winpop { 0%{transform:scale(.3) rotate(-14deg);opacity:0} 100%{transform:scale(1) rotate(0);opacity:1} }
.win-confetti { position:absolute; inset:0; overflow:hidden; pointer-events:none; z-index:1; }
.win-confetti span { position:absolute; top:-12px; width:9px; height:14px; border-radius:2px;
  animation:winfall 2.1s linear forwards; }
@keyframes winfall { to { transform:translateY(105vh) rotate(540deg); opacity:.2; } }
@media (prefers-reduced-motion: reduce) {
  .win-confetti { display:none; }
  .win-icon, .win-box { animation:none !important; transition:none !important; transform:none !important; }
}
/* Match 3 to win — the rule, said once, right above the grid. */
.tk-rule { display:inline-block; font-size:11.5px; font-weight:700; letter-spacing:.1em;
  text-transform:uppercase; color:#fff; background:#1C3554; padding:5px 12px;
  border-radius:99px; margin-bottom:12px; }
.tk-icon { font-size:30px; line-height:1; }
.tk-hit { background:linear-gradient(160deg,#FFF3D9,#FFE9F2) !important;
  box-shadow:inset 0 0 0 3px #E41764; }
.tk-result { margin-top:14px; }
.tk-res-win { background:linear-gradient(135deg,#FFE9F2,#FFF3D9); border:2px solid #E41764;
  border-radius:14px; padding:14px; }
.tk-res-win span { display:block; font-size:40px; line-height:1; }
.tk-res-win b { display:block; font-family:'Bebas Neue',sans-serif; font-size:26px;
  color:#1C3554; margin-top:4px; letter-spacing:.5px; }
.tk-res-win i { display:block; font-style:normal; font-size:12.5px; color:#4A5D75; margin-top:2px; }
.tk-res-lose { background:#F6EFE9; border:2px solid #E7DCD3; border-radius:14px; padding:14px; }
.tk-res-lose b { display:block; font-family:'Bebas Neue',sans-serif; font-size:22px; color:#5B6B7E; }
.tk-res-lose i { display:block; font-style:normal; font-size:12.5px; color:#5B6B7E; margin-top:2px; }
.tk-grid { display:grid; grid-template-columns:repeat(3,1fr); gap:9px; }
.tk-cell { position:relative; aspect-ratio:1/1; border-radius:12px; overflow:hidden;
  background:#fff; border:2px solid #1C3554; }
.tk-canvas { position:absolute; inset:0; width:100%; height:100%; display:block;
  z-index:2; touch-action:none; cursor:crosshair; }
.tk-canvas:focus-visible { outline:3px solid #E41764; outline-offset:2px; }
.tk-under { position:absolute; inset:0; z-index:1; display:flex; flex-direction:column;
  align-items:center; justify-content:center; gap:2px; padding:4px; text-align:center;
  background:linear-gradient(160deg,#FFFDF9,#FFF0F6); }
.tk-under b { font-size:9.5px; line-height:1.15; color:#1C3554; font-weight:700; }
.tk-face { font-size:26px; line-height:1; }
.tk-dim { color:#5B6B7E !important; opacity:.75; }
@keyframes tkpop { 0%{transform:scale(.5);opacity:0} 65%{transform:scale(1.15)} 100%{transform:scale(1);opacity:1} }
.tk-win { background:linear-gradient(160deg,#FFE9F2,#FFF3D9); }
.tk-win .tk-face, .tk-win b { animation:tkpop .5s cubic-bezier(.2,.9,.3,1.4) both; }
@media (prefers-reduced-motion: reduce) { .tk-win .tk-face, .tk-win b { animation:none; } }

.sc-prizes { background:#fff; border:2px solid #FFD3E4; border-radius:14px;
  padding:16px; margin-bottom:16px; }
.sc-pt { font-size:11px; letter-spacing:.12em; text-transform:uppercase; color:#E41764;
  font-weight:700; margin-bottom:10px; }
.sc-prize { padding:10px 0; border-bottom:1px solid #F2EAE2; }
.sc-prize:last-child { border-bottom:0; }
.sc-prize b { display:block; font-size:15px; }
.sc-prize span { display:block; font-size:13px; color:#4A5D75; }
.sc-pick { margin:8px 0 4px; display:flex; flex-wrap:wrap; gap:6px; }
.sc-pickl { flex:1 1 100%; font-size:11.5px; color:#E41764; font-weight:700;
  text-transform:uppercase; letter-spacing:.08em; }
.sc-pick button { display:flex; align-items:center; gap:6px; min-height:44px;
  padding:0 12px; border:2px solid #FFD3E4; border-radius:11px; background:#fff;
  font-size:13px; font-weight:600; color:#1C3554; cursor:pointer; }
.sc-pick button:active { background:#FFF0F6; }
.sc-pick button:disabled { opacity:.5; }
.sc-pick button span { font-size:17px; }
.sc-pickmsg { flex:1 1 100%; font-size:12px; color:#B3261E; }
/* #5B6B7E measured 3.10:1 on this card — under the 4.5 bar for 12px text, on the line
   telling somebody when their prize dies. #5B6B7E measures 5.46:1 and is the same grey,
   just dark enough to read. */
.sc-prize i { display:block; font-style:normal; font-size:12px; color:#5B6B7E; margin-top:3px; }
/* THE TWO RULES ON A PRIZE (2026-09-11). 12px, and #5B6B7E is the SAME grey the expiry
   line two rules up was deliberately darkened to — it measures 5.46:1, over the 4.5 bar
   for small text. ⛔ Do not lighten this to make it recede: the note two lines above
   records that the previous grey failed at 3.10:1 on exactly this card, and this is the
   line that stops somebody thinking the app is broken. */
.sc-terms { display:block; font-size:12px; color:#5B6B7E; margin-top:4px; line-height:1.4; }
/* RUNNING OUT: 5.84:1, and a heavier weight. The words already say how many days are
   left, so this still reads correctly with no colour at all. */
.sc-prize i.sc-soon { color:#C4145A; font-weight:600; }
/* ACTIVE / REDEEMED (2026-09-04, Admin PIN) — Admin asked for green and red. The pair
   is carried by a WORD as well as a colour, because roughly one man in twelve cannot
   tell these two hues apart and a status you have to see in colour is not a status. */
.sc-tag { float:right; font-size:10px; font-weight:700; letter-spacing:.08em;
          text-transform:uppercase; padding:3px 8px; border-radius:999px; margin-left:8px; }
.sc-on   { background:#E6F6EC; color:#137A3C; }   /* 5.4:1 on its own ground */
.sc-off  { background:#FDE7EC; color:#B3123A; }   /* 6.1:1 */
.sc-gone { background:#F0F0F2; color:#5A5A66; }
/* HOW TO USE IT, in the row itself. Navy on the card's cream, not muted grey — it is
   an instruction, and a customer who cannot see it asks staff instead. */
.sc-prize u { display:block; text-decoration:none; font-size:12px; line-height:1.45;
              color:#1C3554; background:#FFF8F3; border-radius:8px;
              padding:6px 8px; margin-top:6px; }
/* A spent prize is still legible — dimmed, never greyed out. It is history you are
   meant to be able to read, not a disabled control. */
.sc-done b { color:#4A5D75; }
.sc-pt2 { margin-top:12px; padding-top:10px; border-top:1px solid #F2EAE2; color:#5B6B7E; }
