/* Rubik, shipped with the game so it works offline */
@font-face{font-family:'Rubik';font-style:normal;font-weight:500;font-display:swap;src:url(../fonts/rubik-latin-ext-500-normal.woff2) format('woff2');unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}
@font-face{font-family:'Rubik';font-style:normal;font-weight:500;font-display:swap;src:url(../fonts/rubik-latin-500-normal.woff2) format('woff2');unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}
@font-face{font-family:'Rubik';font-style:normal;font-weight:700;font-display:swap;src:url(../fonts/rubik-latin-ext-700-normal.woff2) format('woff2');unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}
@font-face{font-family:'Rubik';font-style:normal;font-weight:700;font-display:swap;src:url(../fonts/rubik-latin-700-normal.woff2) format('woff2');unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}
/* Pixelify Sans (open font licence), the pixel look; shipped with the game so it works offline */
@font-face{font-family:'Pixelify Sans';font-style:normal;font-weight:500;font-display:swap;src:url(../fonts/pixelify-sans-latin-ext-500-normal.woff2) format('woff2');unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}
@font-face{font-family:'Pixelify Sans';font-style:normal;font-weight:500;font-display:swap;src:url(../fonts/pixelify-sans-latin-500-normal.woff2) format('woff2');unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}
@font-face{font-family:'Pixelify Sans';font-style:normal;font-weight:700;font-display:swap;src:url(../fonts/pixelify-sans-latin-ext-700-normal.woff2) format('woff2');unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}
@font-face{font-family:'Pixelify Sans';font-style:normal;font-weight:700;font-display:swap;src:url(../fonts/pixelify-sans-latin-700-normal.woff2) format('woff2');unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}
/* the digits only, in a clearer pixel font (Pixelify's 2 and 8 look alike at score size); scaled to sit with Pixelify's letters */
@font-face{font-family:'Digits';font-style:normal;font-weight:400 800;font-display:swap;src:url(../fonts/press-start-2p-latin-400-normal.woff2) format('woff2');unicode-range:U+0030-0039;size-adjust:72%}
/* Layout: one column - sound button, stats, storage unit (--cols x --rows cells of --c), tray */
:root{
  --bg:#081230;--bg2:#14286b;--well:rgba(12,24,70,.7);--line:rgba(140,170,255,.16);--frame:#4766c9;
  /* the game's look (same as the welcome screen): a thick blue frame, lighter on top and darker below, on a dark 3D edge;
     drawn with shadows so it never changes an element's size */
  --rim:0 -6px 0 #6a88e6,0 6px 0 #2f4aa0,0 0 0 6px var(--frame),0 14px 0 6px #0a1440;
  --tile:inset 0 0 0 2px var(--frame),inset 0 2px 0 2px #6a88e6,0 4px 0 #0a1440;
  --fg:#e8eeff;--dim:#8d9ed6;--font:"Digits","Pixelify Sans","Rubik",system-ui,-apple-system,"Segoe UI",sans-serif;
  /* small text reads better in the clean font; the pixel font is for big text */
  --read:"Rubik",system-ui,-apple-system,"Segoe UI",sans-serif;
  color-scheme:dark;
  /* cell size from the screen size alone, so it is right from the first paint and the same on every load: as wide as fits
     (the unit at most 640px), and short enough that the whole game fits the screen height with the browser bars shown (svh).
     190px plus the top and bottom padding (safe areas included) is everything that does not scale (paddings, logo row, stats, gaps); each px of cell adds rows + 1 px to the unit
     with its padding and 1px to the tray (one cell). Must match W and H in game.js */
  --cols:6;--rows:7;
  --c:max(24px,min((100vw - 28px) / var(--cols),634px / var(--cols),(100svh - 110px - max(20px,env(safe-area-inset-top,0px)) - max(20px,env(safe-area-inset-bottom,0px))) / (var(--rows) + 1.5)));
}
[hidden]{display:none!important}
/* app feel: no pinch or double-tap zoom, no pull-to-refresh or bounce, no grey tap flash, no long-press image menu */
html,body{height:100%;overscroll-behavior:none}
/* the level's colour glows behind the game and breathes very slowly: a little brighter and wider, then back */
body::before{content:"";position:fixed;inset:0;z-index:-1;pointer-events:none;
  background:radial-gradient(circle at 50% 55%,var(--bg2),transparent min(80vmin,620px));animation:breathe 12s ease-in-out infinite alternate}
@keyframes breathe{from{opacity:.88;scale:1}to{opacity:1;scale:1.02}}
body{margin:0;background:var(--bg);color:var(--fg);font-family:var(--font);
  display:flex;flex-direction:column;align-items:center;gap:16px;padding-top:max(20px,env(safe-area-inset-top,0px));padding-bottom:max(20px,env(safe-area-inset-bottom,0px));
  padding-left:max(8px,env(safe-area-inset-left,0px));padding-right:max(8px,env(safe-area-inset-right,0px));
  box-sizing:border-box;user-select:none;-webkit-user-select:none;overflow-x:hidden;touch-action:pan-x pan-y;-webkit-tap-highlight-color:transparent;-webkit-touch-callout:none}
.top{margin-top:auto;width:calc(var(--c) * var(--cols));display:flex;justify-content:space-between;align-items:center;gap:12px}
.lvl{display:flex;align-items:center;gap:8px;font-size:1.6rem;font-weight:800;font-variant-numeric:tabular-nums}
/* the logo: every 15s in the game it pulses once with a gloss sweeping across it as it grows (cut to the letters by the logo
   itself as a mask) */
.brand{position:relative;display:block;animation:beat 10s ease-in-out 3s infinite}
.brand img{display:block;height:56px;width:auto;filter:drop-shadow(0 1.75px 2.6px rgba(0,0,0,.45))}
.brand::after{content:'';position:absolute;inset:0;pointer-events:none;
  -webkit-mask:url(../img/logo.svg?v=9) center/100% 100% no-repeat;mask:url(../img/logo.svg?v=9) center/100% 100% no-repeat;
  background:linear-gradient(105deg,transparent 40%,rgba(255,255,255,.7) 50%,transparent 60%) no-repeat;background-size:250% 100%;
  background-position:100% 0;animation:shine 10s ease-in-out 3s infinite}
@keyframes beat{0%,6%,100%{scale:1}3%{scale:1.08}}
@keyframes shine{0%,1.5%{background-position:100% 0}10.5%,100%{background-position:0 0}}
/* the unit slides off-screen between levels and confetti flies out: clip sideways so the page never gets wider than the screen */
.wrap{align-self:stretch;display:grid;justify-content:center;overflow-x:clip;padding:calc(var(--c) * .3) 0 calc(var(--c) * .2)}
.van{position:relative;width:calc(var(--c) * var(--cols));height:calc(var(--c) * var(--rows));border-radius:0;
  background-color:var(--well);background-image:linear-gradient(var(--line) 1px,transparent 1px),linear-gradient(90deg,var(--line) 1px,transparent 1px);
  background-size:var(--c) var(--c);box-shadow:var(--rim);
  isolation:isolate}
/* pixel corner caps on the unit's frame: four squares centred on its corners, light on top like the frame */
.van::after,.frame::after,.card::after{content:"";position:absolute;inset:-11px;z-index:2;pointer-events:none;--g:linear-gradient(#8fb0ff 0 4px,#4f7af0 4px);
  background:var(--g) 0 0/16px 16px no-repeat,var(--g) 100% 0/16px 16px no-repeat,var(--g) 0 100%/16px 16px no-repeat,var(--g) 100% 100%/16px 16px no-repeat}
/* a full unit is the victory: the frame turns into the game's colours (pink, gold, green, blue, purple) running round it,
   glowing out twice, then fades back to blue. The ring is the frame's width, cut out of a spinning colour wheel */
@property --spin{syntax:'<angle>';inherits:false;initial-value:0deg}
.van.win{animation:win 1.6s ease-out}
/* one packed row: a quick white glow under the frame */
.van.packed{animation:packed .35s ease-out}
@keyframes packed{50%{box-shadow:var(--rim),0 10px 16px 2px rgba(255,255,255,.55)}}
.van.win::before{content:'';position:absolute;inset:-6px;z-index:1;padding:6px;border-radius:6px;pointer-events:none;
  background:conic-gradient(from var(--spin),#ff7ab8,#ffd166,#7ee8a2,#7cc6ff,#c9a2ff,#ff7ab8);
  -webkit-mask:linear-gradient(#000 0 0) content-box,linear-gradient(#000 0 0);-webkit-mask-composite:xor;
  mask:linear-gradient(#000 0 0) content-box exclude,linear-gradient(#000 0 0);animation:rainbow 1.6s linear forwards}
@keyframes rainbow{0%{--spin:0deg;opacity:1}75%{opacity:1}100%{--spin:540deg;opacity:0}}
@keyframes win{0%,31%{box-shadow:var(--rim),0 0 0 6px rgba(255,255,255,.6)}
  30%,62%{box-shadow:var(--rim),0 0 0 calc(var(--c) * .5) rgba(255,255,255,0)}
  100%{box-shadow:var(--rim),0 0 0 6px rgba(255,255,255,0)}}
.blk{--s:20px;position:relative;box-sizing:border-box;border-radius:calc(var(--s) * .16);overflow:hidden;
  display:flex;flex-direction:column;align-items:center;justify-content:center;gap:.15em;text-align:center;line-height:1.1;
  font-size:max(8px,calc(var(--s) * .3));color:#fff;text-shadow:0 1px 2px rgba(0,0,0,.55);
  background:linear-gradient(150deg,hsl(var(--h) 95% 78% / .92),hsl(var(--h) 90% 55% / .8) 45%,hsl(var(--h) 95% 34% / .92));
  box-shadow:inset 0 0 0 1.5px hsl(var(--h) 100% 85% / .7),inset 0 -3px 6px hsl(var(--h) 90% 18% / .7),0 0 12px hsl(var(--h) 100% 60% / .35)}
.blk::after{content:"";position:absolute;left:8%;right:8%;top:5%;height:30%;max-height:calc(var(--s) * .45);border-radius:calc(var(--s) * .1);
  background:linear-gradient(rgba(255,255,255,.45),rgba(255,255,255,0));pointer-events:none}
.blk b{font-weight:700}
.placed{position:absolute;margin:1px}
/* a matched item pops: it flashes bright, swells and fades, and sends out a white ring (see burst) */
.blk.pop{animation:pop .3s ease-in forwards}
@keyframes pop{30%{filter:brightness(2.2)}to{transform:scale(1.25);opacity:0;filter:brightness(2.2)}}
/* the shockwave: a white square ring growing out of a cleared item */
.ring{position:absolute;z-index:7;width:var(--c);height:var(--c);box-sizing:border-box;border:calc(var(--c) * .08) solid #fff;pointer-events:none}
/* the placed items: clipped at the unit's bottom edge, so the stack that has sunk below the frame stays out of sight */
.stack{position:absolute;inset:0;overflow:hidden}
.preview{position:absolute;pointer-events:none;opacity:.4}
.preview .blk{margin:1px}
.drag{position:fixed;left:0;top:0;z-index:5;pointer-events:none;will-change:transform}
/* the unit sits alone in its grid cell */
.wrap>*{grid-area:1/1}
/* room for one item, so the page height never changes */
.tray{margin-bottom:auto;width:min(100%,640px);display:flex;flex-wrap:wrap;gap:12px;justify-content:center;align-items:flex-end;min-height:var(--c);padding-bottom:10px}
.piece{touch-action:none;cursor:grab}
.piece.dim{opacity:.3;cursor:default}
.piece.lifted{opacity:.15}
/* pixel buttons: square, flat blue with a hard light top and dark bottom edge, a solid drop edge and four corner studs */
.btn{position:relative;font:inherit;font-size:1.3rem;font-weight:700;color:#fff;border:0;border-radius:0;padding:16px 28px;width:min(100%,320px);cursor:pointer;
  --hi:#7fa8ff;--lo:#1d45b0;--edge:#0a1a60;background:#2f6cf0;text-shadow:0 2px 0 var(--lo);
  box-shadow:inset 0 4px 0 var(--hi),inset 0 -4px 0 var(--lo),0 6px 0 var(--edge),0 12px 22px rgba(0,0,0,.5)}
.btn::before{content:"";position:absolute;inset:8px;pointer-events:none;--d:linear-gradient(rgba(255,255,255,.4) 0 0);
  background:var(--d) 0 0/6px 6px no-repeat,var(--d) 100% 0/6px 6px no-repeat,var(--d) 0 100%/6px 6px no-repeat,var(--d) 100% 100%/6px 6px no-repeat}
.btn:active{transform:translateY(4px);box-shadow:inset 0 4px 0 var(--hi),inset 0 -4px 0 var(--lo),0 2px 0 var(--edge),0 6px 14px rgba(0,0,0,.5)}
.btn.alt{--hi:#8ff0ad;--lo:#16753a;--edge:#0b3d1f;background:#2fb85c}
.btn:disabled{opacity:.5;cursor:default}
.btn:focus-visible,.ico:focus-visible{outline:2px solid var(--fg);outline-offset:3px}
/* Play and Try Again: they pulse, and a gloss sweeps across them every 3 seconds, to draw the eye */
#again,#play{position:relative;overflow:hidden;animation:pulse 4s ease-in-out 1.2s infinite}
#again::after,#play::after{content:"";position:absolute;inset:0;pointer-events:none;
  background:linear-gradient(110deg,transparent 40%,rgba(255,255,255,.5) 50%,transparent 60%) 100% 0/250% 100% no-repeat;animation:gloss 3s ease-in-out 1s infinite}
@keyframes gloss{0%{background-position:100% 0}35%,100%{background-position:0 0}}
.ico{display:grid;place-items:center;width:40px;height:40px;padding:0;border:0;border-radius:0;background:var(--well);color:var(--dim);cursor:pointer;box-shadow:var(--tile)}
/* welcome screen, in the game's own look: its background, the preview in the unit's frame and the game's Play button,
   which pulses gently (scale, so it can still press down) */
.welcome{position:fixed;inset:0;z-index:10;display:grid;place-content:center;justify-items:center;gap:16px;
  padding:24px max(8px,env(safe-area-inset-right,0px)) 24px max(8px,env(safe-area-inset-left,0px));text-align:center;
  --w:min(100vw - 28px,400px,(100svh - 18svh - 270px - var(--x,0px)) * 6 / 7);background:radial-gradient(circle at 50% 55%,#182f7c,transparent min(70vmin,520px)),var(--bg)}
.welcome .brand{margin-bottom:-4px}
/* the theme picker on a small pixel plaque fixed to the bottom of the preview's frame: arrows either side of the name; gold pixel letters on dark blue, the
   tiles' light-edged border and four corner studs */
.welcome .theme{position:relative;z-index:3;display:flex;align-items:center;gap:12px;margin:-10px 0 0;padding:8px 10px 7px;font-size:1.5rem;font-weight:700;line-height:1;
  color:#ffd166;letter-spacing:.03em;text-shadow:0 2px 0 #6b4500;background:#0d1a48;box-shadow:var(--tile)}
.welcome .theme::before{content:"";position:absolute;inset:4px;pointer-events:none;--d:linear-gradient(rgba(255,255,255,.35) 0 0);
  background:var(--d) 0 0/3px 3px no-repeat,var(--d) 100% 0/3px 3px no-repeat,var(--d) 0 100%/3px 3px no-repeat,var(--d) 100% 100%/3px 3px no-repeat}
.welcome .brand img{height:auto;width:min(63vw,315px,18svh * 2.567);filter:drop-shadow(0 5px 7px rgba(0,0,0,.45))}
/* on the welcome screen the logo's pulse and gloss play once, on load */
.welcome .brand{animation:beat1 .6s ease-in-out .1s}
.welcome .brand::after{animation:shine1 .9s ease-in-out .2s}
@keyframes beat1{50%{scale:1.08}}
@keyframes shine1{from{background-position:100% 0}to{background-position:0 0}}
/* a still preview of a packed unit, drawn with the game's own items (see welcomePeek) */
/* in the game's frame (--rim); clipped, so the items drop in from the top of the box */
.peek{position:relative;width:var(--w);aspect-ratio:6/7;border-radius:0;background-color:var(--well);
  background-image:linear-gradient(var(--line) 1px,transparent 1px),linear-gradient(90deg,var(--line) 1px,transparent 1px);
  background-size:calc(100% / 6) calc(100% / 7);overflow:hidden}
/* the preview's frame: the same rim and corner caps as the game unit, outside the clipped preview */
.frame{position:relative;box-shadow:var(--rim)}
/* Play comes alive once the preview items have dropped in (16 items, 50ms apart, 380ms each: about 1.1s), then every 4s:
   two quick pulses and a rest */
.welcome .btn{width:calc(var(--w) + 12px);font-size:1.8rem;padding-block:14px;margin-top:6px;
  animation:pulse 4s ease-in-out 1.2s infinite}
@keyframes pulse{0%,24%{scale:1}6%,18%{scale:1.05}12%{scale:1}}
.peek .blk{position:absolute;margin:1px}
.over{position:fixed;inset:0;display:grid;place-items:center;background:rgba(4,8,28,.75);backdrop-filter:blur(6px);z-index:9;
  padding-left:max(16px,env(safe-area-inset-left,0px));padding-right:max(16px,env(safe-area-inset-right,0px))}
.card{position:relative;display:grid;gap:14px;justify-items:center;text-align:center;padding:24px;border-radius:0;background:#0d1a48;box-shadow:var(--rim);max-width:100%;box-sizing:border-box}
.card h2{margin:0;font-size:1.4rem}
/* a settings switch: a pill that slides its knob right and turns green when on */
.opt{display:flex;align-items:center;justify-content:space-between;gap:24px;width:220px;font-weight:700;cursor:pointer}
.opt input{appearance:none;-webkit-appearance:none;position:relative;width:48px;height:28px;margin:0;border-radius:0;background:var(--well);box-shadow:var(--tile);cursor:pointer}
.opt input::after{content:"";position:absolute;top:5px;left:5px;width:18px;height:18px;border-radius:0;background:var(--dim);transition:transform .15s}
.opt input:checked{background:#5be38a}
.opt input:checked::after{transform:translateX(20px);background:#fff}
/* one size for every headline: the longest (No room left!) fits on one line */
#over .card{width:340px}
#head{font-size:1.85rem;line-height:1.15}
/* the score line on the game over card, the new best in gold */
.card .score{margin:0;font-size:1.2rem;color:var(--dim)}
.card .score b{color:#ffd166}
/* the game over card: the big crown and the score counting up in gold */
#overCrown{display:block}
.card .count{margin:0;font-size:3rem;font-weight:800;line-height:1;color:#ffd166;font-variant-numeric:tabular-nums}
/* messages fade in, hold and fade out instead of floating up, for phones set to reduce motion */
@keyframes done{0%{opacity:0}15%{opacity:1}80%{opacity:1}100%{opacity:0}}
.blk.art{justify-content:flex-end;padding:0;background:none;box-shadow:none;overflow:visible}
.blk.art::after{display:none}
.blk .pic{position:absolute;inset:0;width:100%;height:100%;overflow:visible}
/* every message sits in the middle of the storage unit as big bold colour text with a thick dark outline:
   green for plain messages, amber hints, gold records, and pink Perfect, purple Great, blue Nice */
.praise{position:absolute;left:50%;top:50%;z-index:6;transform:translate(-50%,-50%);pointer-events:none;width:max-content;max-width:calc(var(--c) * 5.5);
  text-align:center;line-height:1.1;font-size:calc(var(--c) * .6);--r1:#7ee8a2;--r3:#0d5a2c;animation:praise 1s ease-out forwards;
  font-weight:800;text-transform:uppercase;letter-spacing:.03em;color:var(--r1);-webkit-text-stroke:.14em var(--r3);paint-order:stroke fill;text-shadow:0 .12em 0 var(--r3),0 .2em .5em rgba(0,0,0,.5)}
.praise.hint{--r1:#ffc46b;--r3:#6b3a00}
.praise.gold{--r1:#ffd166;--r3:#6b4500}
.praise.t50{--r1:#ff7ab8;--r3:#6e0b3c}
.praise.t30{--r1:#c9a2ff;--r3:#3a1580}
.praise.t15{--r1:#7cc6ff;--r3:#0f347a}
@keyframes praise{0%{opacity:0;translate:0 0}15%{opacity:1}100%{opacity:0;translate:0 calc(var(--c) * -.8)}}
/* a new item swooshes into the tray */
.piece.arrive{animation:arrive .4s cubic-bezier(.2,.8,.3,1.3)}
@keyframes arrive{from{opacity:0;transform:translateX(-48px) scale(.85)}}
@media (prefers-reduced-motion:reduce){body::before,.brand,.brand::after,.welcome .btn,#again,#again::after,#play::after{animation:none}.praise{animation:done 1s ease-out forwards}
  .van.win::before{display:none}}
.welcome .how{margin:4px 0 0;max-width:32ch;font-size:1rem;line-height:1.5;color:var(--dim)}

/* small text in the clean font, easier to read than pixel letters */
.welcome .how,.opt,.card .score{font-family:var(--read)}
.welcome .theme .arrow{font:inherit;font-size:.8em;line-height:1;color:#ffd166;background:none;border:0;padding:4px 6px;cursor:pointer}
.welcome .theme .arrow:active{transform:translateY(2px)}
/* the store badges under Play, on the website only (a 40px row and a gap the preview makes room for); Google's badge image has
   a margin of its own, cut off so both are 40px tall */
.welcome:has(.stores:not([hidden])){--x:56px}
.welcome .stores{display:flex;gap:12px;justify-content:center;margin:0}
.welcome .stores img{display:block;height:40px}
.welcome .stores .android img{height:60px;margin:-10px}
