/* ==================================================================
   Mahjong Solitaire — interface

   One design system across both screens: a jade-black shell watermarked
   with a gold lattice for the chrome, a lit jade felt table for play.
   Surfaces are glass over a fixed ambient wash, hairlines are 1px,
   numerals are tabular, and the only saturated colour on screen belongs
   to the tiles.

   Layout contract
     .screen      full-bleed, one visible at a time
     .table       hud / time-bar / board-area / dock, board-area flexes
     .menu-scroll the only scrolling region on the menu screen
   ================================================================== */

@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=Outfit:wght@300;400;500;600;700&display=swap');

:root{
  /* shell — the menu is the same material as the table, several stops
     darker, so walking onto a board reads as a light coming on rather than
     as a different app */
  --bg:#06110d;
  --bg-2:#0a1f18;
  --glass:rgba(255,255,255,.045);
  --glass-2:rgba(255,255,255,.075);
  --glass-border:rgba(255,255,255,.09);
  --line:rgba(255,255,255,.07);
  --line-2:rgba(255,255,255,.14);
  --bar:rgba(4,16,12,.82);
  --panel:rgba(9,26,20,.96);
  /* the lattice: gold hairlines on the diagonal, at the opacity of a
     watermark. Anything louder competes with the tiles. */
  --lattice:rgba(251,191,36,.07);
  --lattice-node:rgba(251,191,36,.085);

  /* table */
  --felt-1:#124636;
  --felt-2:#0a2a21;
  --felt-edge:rgba(3,20,15,.55);

  /* text */
  --text:#eaf0f7;
  --text-2:#9aa9bc;
  --text-3:#64748b;

  /* accents */
  --accent:#34d399;
  --accent-2:#10b981;
  --accent-soft:rgba(52,211,153,.12);
  --accent-glow:rgba(52,211,153,.28);
  --gold:#fbbf24;
  --gold-glow:rgba(251,191,36,.28);
  --warn:#f87171;
  --focus:#38bdf8;

  /* tiles */
  --tile-face:#fdf7e8;
  --tile-face-2:#f0e4c6;
  --tile-edge:#cdbb93;
  --tile-edge-2:#a08f6a;

  /* metrics */
  --r-xs:6px;
  --r-sm:10px;
  --r-md:14px;
  --r-lg:20px;
  --hud-h:58px;
  --dock-h:64px;
  --safe-t:env(safe-area-inset-top,0px);
  --safe-b:env(safe-area-inset-bottom,0px);
  --safe-l:env(safe-area-inset-left,0px);
  --safe-r:env(safe-area-inset-right,0px);
  --ease:cubic-bezier(.4,0,.2,1);
  --emoji:"Apple Color Emoji","Segoe UI Emoji","Noto Color Emoji",sans-serif;
}

*{box-sizing:border-box;-webkit-tap-highlight-color:transparent}

html,body{height:100%}
/* A phone's URL bar slides away as you scroll, and `100%` resolves against the
   viewport as if it were already gone — which parks the dock behind it until
   you scroll, on a screen that never scrolls. dvh is the visible height. */
@supports (height:100dvh){
  html,body{height:100dvh}
}
body{
  margin:0;
  font-family:'Inter',system-ui,-apple-system,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif;
  font-size:15px;line-height:1.45;
  color:var(--text);
  background:var(--bg);
  overflow:hidden;
  user-select:none;-webkit-user-select:none;
  touch-action:manipulation;
  -webkit-font-smoothing:antialiased;
}

/* ================= ambient background =================
   Four layers, painted top to bottom: a gold node at each lattice crossing,
   the lattice itself, two soft lights, and the jade ground under all of it.
   All of it is gradients — the game still ships with zero image files. */
.ambient-bg{
  position:fixed;inset:0;z-index:0;pointer-events:none;
  background-image:
    radial-gradient(circle, var(--lattice-node) 0 1.3px, transparent 1.7px),
    radial-gradient(circle, var(--lattice-node) 0 1.3px, transparent 1.7px),
    linear-gradient(45deg,  transparent 49.55%, var(--lattice) 49.55% 50.45%, transparent 50.45%),
    linear-gradient(-45deg, transparent 49.55%, var(--lattice) 49.55% 50.45%, transparent 50.45%),
    radial-gradient(ellipse 900px 620px at 12% 16%, rgba(16,185,129,.16) 0%, transparent 62%),
    radial-gradient(ellipse 780px 540px at 88% 84%, rgba(251,191,36,.07) 0%, transparent 62%),
    linear-gradient(150deg,#050f0c 0%,#0a1f18 40%,#0b241b 68%,#050e0b 100%);
  /* one X per 64px tile, so the two line families cross exactly at each tile's
     centre and corner — which is where the nodes are pinned. Drawing the lines
     with repeating-linear-gradient instead would drift out of register with
     them by a third of a pixel per cell. */
  background-size:64px 64px,64px 64px,64px 64px,64px 64px,auto,auto,auto;
  background-position:32px 32px,0 0,0 0,0 0,0 0,0 0,0 0;
}
.vignette{
  position:fixed;inset:0;z-index:1;pointer-events:none;
  background:radial-gradient(ellipse at center,transparent 44%,rgba(2,8,6,.6) 100%);
}

/* ================= layout ================= */
.app{position:relative;height:100%;width:100%;z-index:2}
.screen{position:absolute;inset:0;display:none;flex-direction:column;min-height:0}
.screen.is-active{display:flex;animation:screenIn .32s var(--ease)}
@keyframes screenIn{from{opacity:0;transform:scale(.985)}to{opacity:1;transform:none}}

.sr-only{
  position:absolute;width:1px;height:1px;
  margin:-1px;padding:0;border:0;
  clip:rect(0 0 0 0);clip-path:inset(50%);
  overflow:hidden;white-space:nowrap;
}
:focus-visible{outline:2px solid var(--focus);outline-offset:2px}

/* ---- the icon family ---- */
.ic{
  display:block;flex:0 0 auto;
  fill:none;stroke:currentColor;
  stroke-width:1.8;stroke-linecap:round;stroke-linejoin:round;
}
.ic .f{fill:currentColor;stroke:none}
.ic.on{color:var(--gold);filter:drop-shadow(0 0 4px var(--gold-glow))}
.ic.off{color:rgba(255,255,255,.16)}
.ic.best{color:var(--gold)}
.ic.trail{opacity:.65;margin-left:-1px}

/* ==================================================================
   BUTTONS
   ================================================================== */
.btn{
  font:600 .875rem/1 'Inter',system-ui,sans-serif;
  color:var(--text);
  background:var(--glass-2);
  border:1px solid var(--glass-border);
  border-radius:var(--r-md);
  padding:11px 18px;cursor:pointer;
  display:inline-flex;align-items:center;justify-content:center;gap:7px;
  transition:background .18s var(--ease),border-color .18s var(--ease),
             transform .18s var(--ease),box-shadow .18s var(--ease);
}
.btn:hover{background:rgba(255,255,255,.11);border-color:var(--line-2);transform:translateY(-1px)}
.btn:active{transform:translateY(0)}
.btn[disabled]{opacity:.35;cursor:not-allowed;transform:none}
.btn i{font-style:normal;opacity:.6;font-size:.85em;font-weight:500}

.btn-primary{
  background:linear-gradient(135deg,#3ee0a4,#059669);
  color:#04241a;border-color:transparent;font-weight:700;
  box-shadow:0 6px 20px rgba(5,150,105,.28);
}
.btn-primary:hover{
  background:linear-gradient(135deg,#4dedb0,#0ea371);
  box-shadow:0 10px 28px rgba(5,150,105,.36);
}
.btn-primary .ic{color:#04241a}
.btn-ghost{background:transparent;border-color:var(--line-2);color:var(--text-2)}
.btn-ghost:hover{background:var(--glass);color:var(--text)}

/* small chrome button with icon + label */
.ghost-btn,.icon-btn{
  font:600 .8rem/1 'Inter',system-ui,sans-serif;
  color:var(--text-2);
  background:transparent;
  border:1px solid transparent;
  border-radius:var(--r-sm);
  padding:8px 12px;cursor:pointer;
  display:inline-flex;align-items:center;gap:8px;white-space:nowrap;
  transition:background .16s var(--ease),color .16s var(--ease),border-color .16s var(--ease);
}
.ghost-btn .gi,.icon-btn .ii{display:flex;color:var(--text-3);transition:color .16s var(--ease)}
.ghost-btn:hover,.icon-btn:hover{background:var(--glass);color:var(--text);border-color:var(--line)}
.ghost-btn:hover .gi,.icon-btn:hover .ii{color:var(--accent)}
.icon-btn.icon-only{padding:9px;border-radius:var(--r-sm)}

/* ==================================================================
   MENU SCREEN
   ================================================================== */
.menu-bar{
  flex:0 0 auto;
  height:calc(54px + var(--safe-t));
  padding:var(--safe-t) calc(18px + var(--safe-r)) 0 calc(18px + var(--safe-l));
  display:flex;align-items:center;justify-content:space-between;gap:12px;
  border-bottom:1px solid var(--line);
  background:linear-gradient(to bottom,rgba(4,16,12,.65),transparent);
  z-index:5;
}
.brand{display:flex;align-items:center;gap:10px}
.brand-mark{font-family:var(--emoji);font-size:1.15rem;line-height:1;filter:saturate(.9)}
.brand-name{
  font-family:'Outfit',system-ui,sans-serif;
  font-size:.82rem;font-weight:600;letter-spacing:.24em;text-transform:uppercase;
  color:var(--text-2);
}
.menu-bar-actions{display:flex;align-items:center;gap:2px}

.menu-scroll{
  flex:1 1 auto;min-height:0;overflow-y:auto;overscroll-behavior:contain;
  scrollbar-width:thin;scrollbar-color:rgba(255,255,255,.14) transparent;
}
.menu-scroll::-webkit-scrollbar{width:10px}
.menu-scroll::-webkit-scrollbar-thumb{
  background:rgba(255,255,255,.12);border-radius:99px;
  border:3px solid transparent;background-clip:content-box;
}
.menu-wrap{
  width:min(1080px,100%);margin:0 auto;
  padding:36px calc(24px + var(--safe-r)) calc(48px + var(--safe-b)) calc(24px + var(--safe-l));
}

/* ---- hero ---- */
.hero{text-align:center;margin-bottom:30px}
.logo{margin:0;line-height:1}
.logo-word{
  display:block;
  font-family:'Outfit',system-ui,sans-serif;
  font-size:clamp(1.9rem,5vw,3rem);font-weight:600;
  letter-spacing:.2em;text-transform:uppercase;
  background:linear-gradient(100deg,#eaf0f7 0%,var(--accent) 38%,var(--gold) 72%,#eaf0f7 100%);
  background-size:220% auto;
  -webkit-background-clip:text;-webkit-text-fill-color:transparent;background-clip:text;
  animation:logoShimmer 8s linear infinite;
}
@keyframes logoShimmer{to{background-position:220% center}}
.logo small{
  display:block;margin-top:12px;
  font-size:.82rem;font-weight:400;color:var(--text-3);letter-spacing:.03em;
}

.progress-strip{
  display:flex;justify-content:center;align-items:stretch;gap:10px;flex-wrap:wrap;
  margin-top:22px;
}
.progress-strip span{
  display:inline-flex;flex-direction:column;align-items:center;gap:2px;
  min-width:104px;padding:9px 18px;
  background:var(--glass);border:1px solid var(--glass-border);
  border-radius:var(--r-md);
  font-size:.66rem;font-weight:600;letter-spacing:.12em;text-transform:uppercase;
  color:var(--text-3);
}
.progress-strip b{
  font-family:'Outfit',system-ui,sans-serif;
  font-size:1.15rem;font-weight:600;color:var(--text);
  letter-spacing:0;text-transform:none;font-variant-numeric:tabular-nums;
  display:inline-flex;align-items:center;gap:5px;
}

/* ---- primary actions ---- */
.play-row{
  display:grid;grid-template-columns:minmax(0,1.6fr) minmax(0,1fr);
  gap:12px;margin-bottom:26px;align-items:stretch;
}
.continue-slot,.quick-match-slot{min-width:0;display:flex}
.continue-slot[hidden]{display:none}

.continue-card{
  flex:1 1 auto;
  display:flex;align-items:center;gap:16px;flex-wrap:wrap;
  padding:18px 20px;
  background:linear-gradient(135deg,rgba(52,211,153,.10),var(--glass) 55%);
  border:1px solid rgba(52,211,153,.22);
  border-radius:var(--r-lg);
  box-shadow:0 10px 34px rgba(0,0,0,.3);
  transition:border-color .22s var(--ease),box-shadow .22s var(--ease);
}
.continue-card:hover{border-color:rgba(52,211,153,.4);box-shadow:0 14px 40px rgba(0,0,0,.36)}
.continue-text{flex:1 1 180px;min-width:0}
.continue-text strong{
  display:block;font-family:'Outfit',system-ui,sans-serif;
  font-size:1.05rem;font-weight:600;color:var(--text);
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
}
.continue-text span{
  display:block;margin-top:3px;font-size:.78rem;color:var(--text-3);
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
}
.continue-go{padding:12px 26px;font-size:.92rem}

.quick-match-btn{
  flex:1 1 auto;
  font:600 .95rem/1.2 'Outfit',system-ui,sans-serif;
  color:var(--text);
  background:var(--glass);
  border:1px solid var(--glass-border);
  border-radius:var(--r-lg);
  padding:16px 20px;cursor:pointer;
  display:flex;align-items:center;gap:12px;text-align:left;
  transition:background .2s var(--ease),border-color .2s var(--ease),transform .2s var(--ease);
}
.quick-match-btn:hover{
  background:var(--glass-2);border-color:rgba(139,92,246,.4);transform:translateY(-2px);
}
.quick-match-btn .qm-icon{
  display:grid;place-items:center;flex:0 0 auto;
  width:38px;height:38px;border-radius:12px;
  background:rgba(139,92,246,.16);color:#c4b5fd;
}
.quick-match-btn .qm-label{display:flex;flex-direction:column;gap:3px;min-width:0}
.quick-match-btn .qm-sub{
  font:400 .72rem/1.2 'Inter',system-ui,sans-serif;color:var(--text-3);
}

/* ---- tile swatch ----
   The picker panel that used to live here is gone, and so is the face preview
   that used to sit on the level cards — a card now shows a miniature of its
   board instead. This is kept because renderSetPicker() still builds with it:
   the artwork is drawn for a cream face, and on a bare dark surface the dark
   inks would vanish. */
.chip-tile{
  width:22px;height:22px;flex:0 0 auto;border-radius:5px;
  background:linear-gradient(155deg,var(--tile-face),var(--tile-face-2));
  border:1px solid rgba(60,45,20,.28);
  display:grid;place-items:center;overflow:hidden;
}
.chip-tile img{width:80%;height:80%;object-fit:contain}
.chip-tile .glyph{font-family:var(--emoji);font-size:12px;line-height:1}

/* ---- section head + chapter filter ---- */
.section-head{
  display:flex;align-items:center;justify-content:space-between;gap:14px;
  flex-wrap:wrap;margin-bottom:14px;
}
.section-title{
  margin:0;font-family:'Outfit',system-ui,sans-serif;
  font-size:1rem;font-weight:600;letter-spacing:.1em;text-transform:uppercase;color:var(--text-2);
}
.chapter-tabs{
  display:flex;gap:4px;flex-wrap:wrap;
  padding:4px;border-radius:999px;
  background:rgba(255,255,255,.03);border:1px solid var(--line);
}
.chapter-tab{
  font:600 .74rem/1 'Inter',system-ui,sans-serif;
  color:var(--text-3);background:transparent;border:0;border-radius:999px;
  padding:7px 14px;cursor:pointer;
  display:inline-flex;align-items:center;gap:6px;
  transition:background .16s var(--ease),color .16s var(--ease);
}
.chapter-tab:hover{color:var(--text)}
.chapter-tab.on{background:var(--glass-2);color:var(--text)}
.chapter-tab em{font-style:normal;font-size:.68rem;color:var(--text-3);font-variant-numeric:tabular-nums}
.chapter-tab.on em{color:var(--accent)}

/* ---- level cards ----
   A level select, not a table of levels: each card is a thumbnail of the board
   it deals with its number stamped on it, and the numbers you only want when
   comparing two levels (clock, best) sit small underneath. */
.level-grid{
  display:grid;
  grid-template-columns:repeat(auto-fill,minmax(184px,1fr));
  gap:12px;
}
.level-card{
  position:relative;
  display:flex;flex-direction:column;
  padding:0;overflow:hidden;
  background:var(--glass);
  border:1px solid var(--glass-border);
  border-radius:var(--r-lg);
  text-align:left;cursor:pointer;
  font:inherit;font-family:'Inter',system-ui,sans-serif;color:var(--text);
  transition:border-color .2s var(--ease),transform .2s var(--ease),
             box-shadow .2s var(--ease),background .2s var(--ease);
  animation:cardEnter .4s var(--ease) backwards;
  animation-delay:calc(var(--i,0) * 22ms);
}
@keyframes cardEnter{
  from{opacity:0;transform:translateY(14px) scale(.97)}
  to{opacity:1;transform:none}
}
.level-card:hover{
  background:var(--glass-2);
  border-color:rgba(52,211,153,.35);
  transform:translateY(-3px);
  box-shadow:0 14px 32px rgba(0,0,0,.4);
}
.level-card.cleared{border-color:rgba(251,191,36,.2)}
/* the one the Play card points at, so the eye finds it in a grid of fifty */
.level-card.is-next{
  border-color:rgba(52,211,153,.55);
  box-shadow:0 0 0 1px rgba(52,211,153,.25),0 10px 30px rgba(0,0,0,.35);
}
.level-card.locked{cursor:not-allowed}
.level-card.locked:hover{transform:none;background:var(--glass);border-color:var(--glass-border);box-shadow:none}
.level-card.is-hidden{display:none}

/* the board miniature */
.lc-map{
  position:relative;
  aspect-ratio:240/108;
  background:
    radial-gradient(ellipse 120% 100% at 50% 40%,rgba(255,255,255,.05),transparent 62%),
    linear-gradient(170deg,var(--felt-1),var(--felt-2));
  border-bottom:1px solid rgba(0,0,0,.35);
  overflow:hidden;
}
.lc-map canvas{display:block;width:100%;height:100%}
/* a scrim along the top edge: the number and the set name sit over whatever
   silhouette the board happens to have, and cream tiles reach the corners */
.lc-map::after{
  content:'';position:absolute;inset:0 0 auto;height:34px;pointer-events:none;
  background:linear-gradient(to bottom,rgba(3,14,10,.55),transparent);
}
.level-card.locked .lc-map canvas{filter:grayscale(.85) brightness(.45)}

.lc-no{
  position:absolute;top:0;left:0;
  min-width:30px;padding:3px 8px 4px;
  font-family:'Outfit',system-ui,sans-serif;
  font-size:.8rem;font-weight:600;line-height:1;
  color:var(--text);font-variant-numeric:tabular-nums;
  background:rgba(3,14,10,.62);
  border-bottom-right-radius:10px;
  text-align:center;
}
.level-card.cleared .lc-no{color:var(--gold)}
.lc-set{
  position:absolute;top:6px;right:8px;
  font-size:.56rem;font-weight:700;letter-spacing:.12em;text-transform:uppercase;
  color:rgba(255,255,255,.55);
  text-shadow:0 1px 3px rgba(0,0,0,.6);
}
.lc-next{
  position:absolute;left:8px;bottom:7px;
  font-size:.56rem;font-weight:700;letter-spacing:.14em;text-transform:uppercase;
  color:#04241a;background:var(--accent);
  padding:3px 8px;border-radius:999px;
  box-shadow:0 2px 10px rgba(52,211,153,.45);
}
/* a play button rises over the board on hover — the card is a button, and this
   is what says so */
.lc-play{
  position:absolute;inset:0;
  display:grid;place-items:center;
  background:rgba(3,14,10,.5);
  opacity:0;transition:opacity .18s var(--ease);
}
.lc-play .ic{
  color:#04241a;background:var(--accent);
  width:40px;height:40px;padding:9px 8px 9px 11px;border-radius:50%;
  box-shadow:0 6px 20px rgba(0,0,0,.45);
}
.level-card:hover .lc-play,.level-card:focus-visible .lc-play{opacity:1}

.lc-foot{
  display:flex;align-items:center;justify-content:space-between;gap:8px;
  padding:10px 12px 0;
}
.level-name{
  font-family:'Outfit',system-ui,sans-serif;
  font-size:.88rem;font-weight:600;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
}
.stars{display:inline-flex;gap:2px;flex:0 0 auto}
.lc-meta{
  display:flex;align-items:center;gap:11px;flex-wrap:wrap;
  padding:6px 12px 11px;
  font-size:.68rem;color:var(--text-3);font-variant-numeric:tabular-nums;
}
.lc-meta span{display:inline-flex;align-items:center;gap:4px}
.lc-meta .ic{opacity:.75}
.lc-best{color:var(--gold);font-weight:600}
.lc-best .ic{opacity:1}

/* The lock covers the board and nothing else. Forty of the fifty cards are
   locked for a new player, and hiding every name behind a padlock turned the
   grid into a grey wall with nothing to look forward to. */
.lock-badge{
  position:absolute;inset:0;z-index:2;
  display:flex;flex-direction:column;align-items:center;justify-content:center;gap:7px;
  background:rgba(5,13,10,.45);
  color:var(--text-3);
}
.lock-badge .ic{color:var(--text-2)}
.lock-badge em{
  font-style:normal;
  font-size:.58rem;font-weight:700;letter-spacing:.12em;text-transform:uppercase;
  padding:3px 9px;border-radius:999px;
  background:rgba(3,14,10,.7);border:1px solid var(--line);
}
.level-card.locked .lc-foot,.level-card.locked .lc-meta{opacity:.45}
.menu-legal{
  margin:28px 0 0;text-align:center;
  font-size:.72rem;color:var(--text-3);
}

/* ==================================================================
   GAME SCREEN
   ================================================================== */
.table{
  position:relative;
  display:flex;flex-direction:column;
  height:100%;width:100%;min-height:0;
  background:
    radial-gradient(ellipse 120% 90% at 50% 42%,rgba(255,255,255,.045) 0%,transparent 60%),
    linear-gradient(170deg,var(--felt-1) 0%,var(--felt-2) 100%);
}
/* woven-felt texture, cheap: two offset dot grids */
.table::before{
  content:'';position:absolute;inset:0;pointer-events:none;opacity:.5;
  background-image:
    radial-gradient(rgba(0,0,0,.16) 1px,transparent 1px),
    radial-gradient(rgba(255,255,255,.035) 1px,transparent 1px);
  background-position:0 0,9px 9px;
  background-size:18px 18px,18px 18px;
}
.table::after{
  content:'';position:absolute;inset:0;pointer-events:none;
  box-shadow:inset 0 0 140px rgba(2,15,11,.75);
}

/* ---- head-up display ----
   A strip, not a dashboard: back, level, clock, readout, menu — one grid cell
   each. The two flexible columns are always the same width whatever they
   hold, so the clock holds the centre of the screen whatever the level is
   called and whatever the score has grown to, while still taking part in the
   layout: on a narrow phone a long level name ellipses against the clock
   rather than running underneath it. */
.hud{
  position:relative;z-index:20;flex:0 0 auto;
  min-height:calc(var(--hud-h) + var(--safe-t));
  padding:calc(6px + var(--safe-t)) calc(12px + var(--safe-r)) 6px calc(12px + var(--safe-l));
  display:grid;
  grid-template-columns:auto minmax(0,1fr) auto minmax(0,1fr) auto;
  align-items:center;gap:10px;
  background:var(--bar);
  backdrop-filter:blur(18px) saturate(1.2);-webkit-backdrop-filter:blur(18px) saturate(1.2);
  border-bottom:1px solid rgba(0,0,0,.35);
}
/* Every cell is placed by hand rather than flowed, because the narrow
   breakpoints hide the level name outright: with auto-placement, dropping it
   would slide the clock into its column and take the strip apart. */
.hud > :first-child{grid-column:1}
.hud-level{grid-column:2}
.hud-clock{grid-column:3}
.hud-stats{grid-column:4}
.hud > :last-child{grid-column:5}

.hud-level{
  min-width:0;justify-self:start;
  font-family:'Outfit',system-ui,sans-serif;
  font-size:.85rem;font-weight:500;color:var(--text-2);
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
}

.hud-clock{
  justify-self:center;
  display:flex;align-items:center;gap:8px;
  padding:0 4px;
  pointer-events:none;
}
.clock-i{display:flex;color:var(--text-3)}
.hud-clock b{
  font-family:'Outfit',system-ui,sans-serif;
  font-size:1.35rem;font-weight:500;line-height:1;
  font-variant-numeric:tabular-nums;letter-spacing:.01em;
}
.hud-clock.warn b{color:var(--warn);animation:warnPulse 1s ease-in-out infinite}
.hud-clock.warn .clock-i{color:var(--warn)}
@keyframes warnPulse{50%{opacity:.45}}

.hud-stats{
  display:flex;align-items:center;gap:16px;
  justify-self:end;min-width:0;
  font-variant-numeric:tabular-nums;
}
.ro{display:flex;flex-direction:column;align-items:flex-end;line-height:1.15}
.ro b{font-family:'Outfit',system-ui,sans-serif;font-size:1rem;font-weight:600;color:var(--text)}
.ro i{
  font-style:normal;font-size:.56rem;font-weight:600;
  letter-spacing:.12em;text-transform:uppercase;color:var(--text-3);
}
.ro-score b{color:var(--gold)}
.hud .icon-btn{color:var(--text-2);flex:0 0 auto}
.hud .icon-btn .ii{color:var(--text-2)}

/* ---- countdown ---- */
.time-bar{
  position:relative;z-index:19;flex:0 0 auto;
  height:3px;background:rgba(0,0,0,.42);overflow:hidden;
}
.time-bar.hidden{display:none}
.time-bar span{
  display:block;height:100%;width:100%;
  background:linear-gradient(90deg,var(--accent-2),var(--accent));
  box-shadow:0 0 10px var(--accent-glow);
  transition:width .25s linear;
}
.time-bar.urgent span{
  background:linear-gradient(90deg,#dc2626,var(--warn));
  box-shadow:0 0 12px rgba(248,113,113,.5);
  animation:barPulse .9s ease-in-out infinite;
}
@keyframes barPulse{50%{opacity:.45}}

/* ---- board ---- */
.board-area{flex:1 1 auto;position:relative;overflow:hidden;z-index:5;min-height:0}
.board{
  position:absolute;left:50%;top:50%;
  transform:translate(-50%,-50%);
  transform-origin:center center;
  will-change:transform;
  transition:opacity .2s var(--ease),filter .2s var(--ease);
}
.board:focus{outline:none}
.board.is-hidden{opacity:.05;filter:blur(12px);pointer-events:none}

/* ---- action dock ----
   Four bare buttons on a strip. Boxing each one in its own bordered card put
   four more rectangles on a screen that already has two hundred tiles. */
.dock{
  position:relative;z-index:20;flex:0 0 auto;
  min-height:calc(var(--dock-h) + var(--safe-b));
  padding:6px calc(12px + var(--safe-r)) calc(6px + var(--safe-b)) calc(12px + var(--safe-l));
  display:flex;align-items:stretch;justify-content:center;gap:4px;
  background:var(--bar);
  backdrop-filter:blur(18px) saturate(1.2);-webkit-backdrop-filter:blur(18px) saturate(1.2);
  border-top:1px solid rgba(255,255,255,.05);
}
.dock-btn{
  flex:0 1 108px;min-width:0;
  font:600 .74rem/1 'Inter',system-ui,sans-serif;
  color:var(--text-2);
  background:transparent;border:0;
  border-radius:var(--r-md);
  padding:7px 10px;cursor:pointer;
  display:flex;flex-direction:column;align-items:center;justify-content:center;gap:6px;
  transition:background .16s var(--ease),color .16s var(--ease);
}
.dock-i{display:flex;color:var(--text-2);transition:color .16s var(--ease)}
.dock-l{display:inline-flex;align-items:baseline;gap:4px;white-space:nowrap}
.dock-l i{font-style:normal;font-size:.76em;opacity:.55;font-variant-numeric:tabular-nums}
.dock-btn:hover{background:var(--glass);color:var(--text)}
.dock-btn:hover .dock-i{color:var(--accent)}
.dock-btn:active{background:var(--glass-2)}
.dock-btn[disabled]{opacity:.28;cursor:not-allowed}
.dock-btn[disabled]:hover{background:transparent;color:var(--text-2)}
.dock-btn[disabled]:hover .dock-i{color:var(--text-2)}

/* ---- game menu sheet ---- */
.sheet{
  position:absolute;z-index:40;
  top:calc(var(--hud-h) + var(--safe-t) + 4px);
  right:calc(14px + var(--safe-r));
  width:250px;max-width:calc(100vw - 28px);
  /* nine rows do not fit above the dock on a phone held sideways, and a menu
     that runs off the bottom of the table has no way back */
  max-height:calc(100% - var(--hud-h) - var(--safe-t) - var(--dock-h) - var(--safe-b) - 12px);
  overflow-y:auto;overscroll-behavior:contain;
  padding:8px;
  background:var(--panel);
  backdrop-filter:blur(20px);-webkit-backdrop-filter:blur(20px);
  border:1px solid var(--glass-border);
  border-radius:var(--r-md);
  box-shadow:0 22px 50px rgba(0,0,0,.55);
  display:flex;flex-direction:column;gap:2px;
  animation:sheetIn .16s var(--ease);
}
.sheet.hidden{display:none}
@keyframes sheetIn{from{opacity:0;transform:translateY(-6px) scale(.98)}to{opacity:1;transform:none}}
.sheet-head{
  margin:2px 0 4px;padding:0 8px;
  font-size:.6rem;font-weight:700;letter-spacing:.16em;
  text-transform:uppercase;color:var(--text-3);
}
.sheet-row{
  font:600 .84rem/1 'Inter',system-ui,sans-serif;
  color:var(--text);
  background:transparent;border:0;border-radius:var(--r-sm);
  padding:10px 10px;cursor:pointer;
  display:flex;align-items:center;gap:11px;text-align:left;width:100%;
  transition:background .14s var(--ease);
}
.sheet-row:hover{background:var(--glass-2)}
.sheet-i{display:flex;color:var(--text-3);flex:0 0 auto}
.sheet-row:hover .sheet-i{color:var(--accent)}
.sheet-l{flex:1 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.sheet-v{
  flex:0 0 auto;font-size:.72rem;font-weight:600;color:var(--text-3);
  max-width:96px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
}
.sheet-sep{height:1px;background:var(--line);margin:5px 4px}

/* ==================================================================
   TILES
   ================================================================== */
.tile{
  position:absolute;
  width:62px;height:82px;
  border-radius:8px;
  background:linear-gradient(155deg,var(--tile-face) 0%,var(--tile-face-2) 100%);
  border:1px solid rgba(0,0,0,.12);
  box-shadow:
    2px 2px 0 var(--tile-edge),
    3px 4px 0 var(--tile-edge-2),
    5px 7px 13px rgba(0,0,0,.45),
    inset 0 1px 0 rgba(255,255,255,.9);
  display:grid;place-items:center;
  cursor:default;
  transition:transform .12s var(--ease),filter .15s var(--ease),box-shadow .12s var(--ease);
}
.tile.layer-1{filter:brightness(1.03)}
.tile.layer-2{filter:brightness(1.06)}
.tile.layer-3{filter:brightness(1.09)}
.tile.layer-4{filter:brightness(1.12)}
.tile img{width:76%;height:76%;object-fit:contain;pointer-events:none}
.tile .glyph{font-family:var(--emoji);font-size:36px;line-height:1;pointer-events:none}

.tile.free{cursor:pointer}
.tile.free:hover{
  transform:translate(-2px,-3px);
  box-shadow:
    5px 6px 0 var(--tile-edge),
    6px 7px 0 var(--tile-edge-2),
    9px 13px 20px rgba(0,0,0,.5),
    0 0 18px rgba(52,211,153,.14),
    inset 0 1px 0 rgba(255,255,255,.9);
}
/* Buried tiles are dimmed, not greyed out: the player still has to read
   their faces to plan, so this is a step back in the light, not a wash. */
.tile.blocked{filter:brightness(.92) saturate(.88)}
.tile.selected{
  background:linear-gradient(155deg,#fff9e4,#f6e3a8);
  border-color:#b8892a;
  transform:translate(-2px,-3px);
  box-shadow:
    0 0 0 2px var(--gold),
    5px 6px 0 var(--tile-edge),
    6px 7px 0 var(--tile-edge-2),
    0 0 26px 6px rgba(251,191,36,.32);
  animation:selectedPulse 2s ease-in-out infinite;
}
@keyframes selectedPulse{
  0%,100%{box-shadow:0 0 0 2px var(--gold),5px 6px 0 var(--tile-edge),6px 7px 0 var(--tile-edge-2),0 0 26px 6px rgba(251,191,36,.3)}
  50%{box-shadow:0 0 0 3px var(--gold),5px 6px 0 var(--tile-edge),6px 7px 0 var(--tile-edge-2),0 0 34px 8px rgba(251,191,36,.42)}
}
.tile.cursor{
  box-shadow:0 0 0 2px var(--focus),3px 3px 0 var(--tile-edge),
             4px 4px 0 var(--tile-edge-2),0 0 18px 4px rgba(56,189,248,.35);
}
.tile:focus{outline:none}
.tile.hinted{animation:hintPulse .8s ease-in-out 3}
@keyframes hintPulse{
  0%,100%{box-shadow:3px 3px 0 var(--tile-edge),4px 4px 0 var(--tile-edge-2),6px 8px 16px rgba(0,0,0,.45)}
  50%{box-shadow:0 0 0 2px var(--focus),3px 3px 0 var(--tile-edge),4px 4px 0 var(--tile-edge-2),0 0 24px 6px rgba(56,189,248,.5)}
}
.tile.shake{animation:shake .3s var(--ease)}
@keyframes shake{
  0%,100%{transform:translateX(0)}
  25%{transform:translateX(-4px)}
  50%{transform:translateX(4px)}
  75%{transform:translateX(-2px)}
}
.tile.vanish{animation:vanish .3s var(--ease) forwards;pointer-events:none}
@keyframes vanish{
  0%{transform:scale(1);opacity:1}
  40%{transform:scale(1.12);opacity:1}
  100%{transform:scale(.3);opacity:0}
}
.tile.deal{animation:deal .28s var(--ease) backwards}
@keyframes deal{
  from{transform:translateY(-20px) scale(.94);opacity:0}
  to{transform:none;opacity:1}
}

/* score popup */
.pop{
  position:absolute;pointer-events:none;
  font-family:'Outfit',system-ui,sans-serif;
  font-weight:700;font-size:.9rem;color:var(--text);
  text-shadow:0 2px 10px rgba(0,0,0,.9);
  animation:pop 1s var(--ease) forwards;
  z-index:99999;font-variant-numeric:tabular-nums;
}
.pop-bonus{color:var(--accent);text-shadow:0 0 12px var(--accent-glow),0 2px 8px rgba(0,0,0,.8)}
.pop-score{color:var(--gold);font-size:1rem;text-shadow:0 0 12px var(--gold-glow),0 2px 8px rgba(0,0,0,.8)}
@keyframes pop{
  from{transform:translate(-50%,0) scale(.85);opacity:0}
  25%{transform:translate(-50%,-14px) scale(1.1);opacity:1}
  to{transform:translate(-50%,-44px) scale(1);opacity:0}
}

/* match particles */
.spark{
  position:absolute;width:7px;height:7px;border-radius:50%;
  margin:-3.5px 0 0 -3.5px;pointer-events:none;z-index:99998;
  animation:spark .55s ease-out forwards;
}
@keyframes spark{
  from{transform:translate(0,0) scale(1);opacity:.9}
  to{transform:translate(var(--dx),var(--dy)) scale(.2);opacity:0}
}

/* combo badge */
.combo{
  position:absolute;top:14px;left:50%;
  transform:translateX(-50%) scale(.85);
  padding:8px 20px;border-radius:999px;
  background:rgba(6,20,16,.88);
  backdrop-filter:blur(10px);-webkit-backdrop-filter:blur(10px);
  border:1px solid rgba(52,211,153,.6);
  color:var(--text);text-align:center;
  pointer-events:none;opacity:0;z-index:30;
  box-shadow:0 0 26px rgba(52,211,153,.2);
}
.combo b{
  display:block;font-family:'Outfit',system-ui,sans-serif;
  font-size:.95rem;font-weight:700;color:var(--accent);
  text-shadow:0 0 8px var(--accent-glow);
}
.combo span{font-size:.65rem;color:var(--text-3)}
.combo.show{animation:comboIn 1.4s var(--ease) forwards}
@keyframes comboIn{
  0%{opacity:0;transform:translateX(-50%) scale(.8)}
  14%{opacity:1;transform:translateX(-50%) scale(1.04)}
  24%{transform:translateX(-50%) scale(1)}
  76%{opacity:1}
  100%{opacity:0;transform:translateX(-50%) scale(1)}
}

.bump{animation:scoreBump .25s var(--ease)}
@keyframes scoreBump{
  0%{transform:scale(1)}
  40%{transform:scale(1.16);color:var(--gold)}
  100%{transform:scale(1)}
}

/* ==================================================================
   COACH — the mimed walkthrough on the first two levels

   The finger, the ripples and the tags are children of .board, so they
   inherit its scale transform and stay pinned to their tiles at every
   board size. The caption is not: it belongs to the board *area*, sits
   at a readable size whatever the board is doing, and is the one part
   of this that takes a click.
   ================================================================== */
.coach-hand{
  position:absolute;left:0;top:0;
  width:34px;height:34px;margin:-4px 0 0 -7px;
  pointer-events:none;z-index:99996;
  opacity:0;transform:translateY(8px);
  filter:drop-shadow(0 6px 12px rgba(0,0,0,.55));
  transition:left .46s var(--ease),top .46s var(--ease),
             opacity .22s var(--ease),transform .22s var(--ease);
}
.coach-hand.is-on{opacity:1;transform:none}
/* white with a dark keyline: the finger crosses cream tiles and dark felt
   in the same move, and has to read on both */
.coach-hand .ic{width:34px;height:34px;color:#fff}
.coach-hand .ic .f{fill:#fff;stroke:rgba(3,18,13,.9);stroke-width:1.5}
.coach-hand.tap{animation:coachTap .42s var(--ease)}
@keyframes coachTap{
  0%,100%{transform:none}
  45%{transform:translate(-3px,-7px) scale(.92)}
}

.coach-ring{
  position:absolute;width:20px;height:20px;margin:-10px 0 0 -10px;
  border-radius:50%;border:2px solid var(--gold);
  pointer-events:none;z-index:99995;
  animation:coachRing .6s var(--ease) forwards;
}
.coach-ring.bad{border-color:var(--warn)}
@keyframes coachRing{
  from{transform:scale(.45);opacity:.95}
  to{transform:scale(4.4);opacity:0}
}

.coach-tag{
  position:absolute;z-index:99997;pointer-events:none;
  padding:3px 8px;border-radius:999px;white-space:nowrap;
  font:600 .68rem/1 'Inter',system-ui,sans-serif;
  background:rgba(6,20,16,.94);border:1px solid var(--line-2);color:var(--text);
  box-shadow:0 4px 14px rgba(0,0,0,.45);
  animation:coachTagIn .24s var(--ease) both;
}
.coach-tag.bad{border-color:rgba(248,113,113,.7);color:#fecaca}
.coach-tag.good{border-color:rgba(52,211,153,.7);color:#bbf7d0}
@keyframes coachTagIn{
  from{opacity:0;transform:translate(-50%,-86%)}
  to{opacity:1;transform:translate(-50%,-100%)}
}

/* the tile the finger is picking up — the selected look, without pretending
   the player selected it */
.tile.coach-pick{
  background:linear-gradient(155deg,#fff9e4,#f6e3a8);
  border-color:#b8892a;
  box-shadow:0 0 0 2px var(--gold),5px 6px 0 var(--tile-edge),
             6px 7px 0 var(--tile-edge-2),0 0 26px 6px rgba(251,191,36,.32);
}
.tile.coach-hit{animation:coachHit .5s var(--ease)}
@keyframes coachHit{
  0%{transform:none}
  40%{transform:translateY(-6px) scale(1.06)}
  100%{transform:none}
}
/* the pair left for the player when the walkthrough bows out: a standing
   invitation, so unlike a hint it does not time out — the next tap ends it */
.tile.coach-open{animation:coachOpen 2s ease-in-out infinite}
@keyframes coachOpen{
  0%,100%{box-shadow:0 0 0 2px var(--gold),3px 3px 0 var(--tile-edge),4px 4px 0 var(--tile-edge-2),0 0 18px 4px rgba(251,191,36,.28)}
  50%{box-shadow:0 0 0 3px var(--gold),3px 3px 0 var(--tile-edge),4px 4px 0 var(--tile-edge-2),0 0 30px 7px rgba(251,191,36,.46)}
}
/* "clear this one first" — the tile the demo is pointing past */
.tile.coach-aim{
  box-shadow:0 0 0 2px var(--accent),3px 3px 0 var(--tile-edge),
             4px 4px 0 var(--tile-edge-2),0 0 22px 5px var(--accent-glow);
}

.coach-note{
  position:absolute;left:50%;bottom:12px;transform:translateX(-50%);
  z-index:40;width:max-content;max-width:min(520px,calc(100% - 24px));
  display:flex;flex-direction:column;gap:9px;
  padding:12px 14px;border-radius:var(--r-md);
  background:rgba(6,20,16,.9);
  backdrop-filter:blur(14px);-webkit-backdrop-filter:blur(14px);
  border:1px solid var(--glass-border);
  box-shadow:0 14px 34px rgba(0,0,0,.5);
  animation:rise .28s var(--ease) both;
}
.coach-text{
  margin:0;text-align:center;
  font:500 .875rem/1.4 'Inter',system-ui,sans-serif;color:var(--text);
}
.coach-foot{display:flex;align-items:center;justify-content:space-between;gap:14px}
.coach-dots{display:flex;align-items:center;gap:5px}
.coach-dot{
  width:6px;height:6px;border-radius:50%;background:var(--line-2);
  transition:background .2s var(--ease),box-shadow .2s var(--ease);
}
.coach-dot.on{background:var(--accent);box-shadow:0 0 8px var(--accent-glow)}
.coach-skip{
  font:600 .72rem/1 'Inter',system-ui,sans-serif;
  color:var(--text-3);background:transparent;
  border:1px solid var(--line);border-radius:999px;
  padding:5px 12px;cursor:pointer;
  transition:color .18s var(--ease),border-color .18s var(--ease);
}
.coach-skip:hover{color:var(--text);border-color:var(--line-2)}

/* ==================================================================
   PAUSE + DIALOGS
   ================================================================== */
.pause-veil{
  position:fixed;inset:0;z-index:99999;
  display:grid;place-items:center;
  background:rgba(3,12,9,.8);
  backdrop-filter:blur(16px);-webkit-backdrop-filter:blur(16px);
  animation:fade .18s var(--ease);
}
.pause-veil.hidden{display:none}
.pause-card{text-align:center;padding:24px}
.pause-card h2{
  margin:0 0 8px;font-family:'Outfit',system-ui,sans-serif;
  font-size:1.5rem;font-weight:600;letter-spacing:.16em;text-transform:uppercase;
}
.pause-card p{margin:0 0 22px;color:var(--text-3);font-size:.83rem}

.overlay{
  position:fixed;inset:0;z-index:100000;
  background:rgba(3,10,8,.74);
  backdrop-filter:blur(10px);-webkit-backdrop-filter:blur(10px);
  display:grid;place-items:center;padding:20px;
  animation:fade .16s var(--ease);
}
.overlay.hidden{display:none}
@keyframes fade{from{opacity:0}to{opacity:1}}
.modal{
  width:min(460px,100%);
  background:var(--panel);
  backdrop-filter:blur(20px);-webkit-backdrop-filter:blur(20px);
  color:var(--text);
  border:1px solid var(--glass-border);
  border-radius:var(--r-lg);
  padding:28px;text-align:center;
  box-shadow:0 28px 70px rgba(0,0,0,.6);
  animation:rise .22s cubic-bezier(.2,1.1,.4,1);
  max-height:88vh;overflow:auto;overscroll-behavior:contain;
}
@supports (max-height:88dvh){
  .modal{max-height:88dvh}
}
@keyframes rise{from{transform:translateY(14px) scale(.97);opacity:0}to{transform:none;opacity:1}}
.modal h2{
  margin:0 0 10px;font-family:'Outfit',system-ui,sans-serif;
  font-size:1.3rem;font-weight:600;
}
.modal p{margin:8px 0;color:var(--text-2);font-size:.85rem;line-height:1.55}
.modal ul{
  text-align:left;margin:12px 0 0;padding-left:18px;
  color:var(--text-2);font-size:.83rem;line-height:1.7;
}
.modal ul b{color:var(--text);font-weight:600}
.modal-actions{margin-top:22px;display:flex;gap:8px;justify-content:center;flex-wrap:wrap}
.big-stars{display:flex;justify-content:center;gap:8px;margin:4px 0 14px}
.big-stars .ic.on{animation:starPop .5s var(--ease) backwards}
.big-stars .ic.on:nth-child(1){animation-delay:.1s}
.big-stars .ic.on:nth-child(2){animation-delay:.25s}
.big-stars .ic.on:nth-child(3){animation-delay:.4s}
@keyframes starPop{
  from{transform:scale(0) rotate(-30deg);opacity:0}
  60%{transform:scale(1.3) rotate(5deg);opacity:1}
  to{transform:scale(1) rotate(0)}
}
.score-line{
  font-family:'Outfit',system-ui,sans-serif;
  font-size:2.6rem;font-weight:300;line-height:1;
  color:var(--text);font-variant-numeric:tabular-nums;letter-spacing:-.02em;
}
.score-line small{
  display:block;margin-top:7px;
  font-family:'Inter',system-ui,sans-serif;
  font-size:.64rem;font-weight:600;letter-spacing:.16em;
  text-transform:uppercase;color:var(--text-3);
}
.result-row{
  display:flex;justify-content:center;gap:0;margin-top:20px;flex-wrap:wrap;
  border-top:1px solid var(--line);padding-top:16px;
}
.result-row div{
  flex:1 1 0;min-width:64px;
  font-size:.62rem;font-weight:600;letter-spacing:.1em;
  text-transform:uppercase;color:var(--text-3);
}
.result-row b{
  display:flex;align-items:center;justify-content:center;gap:4px;
  margin-top:5px;
  font-size:1.05rem;font-weight:600;letter-spacing:0;
  text-transform:none;color:var(--text);font-variant-numeric:tabular-nums;
}
/* .ic is display:block, so an icon sitting inside a run of text (the
   personal-best trophy) would otherwise drop onto a line of its own */
.result-row b .ic{display:inline-block}
.bonus-note{color:var(--accent) !important;font-weight:600;font-size:.8rem !important}
#autoNext{color:var(--accent);font-variant-numeric:tabular-nums}

/* settings dialog */
.settings{display:grid;gap:8px;margin:16px 0 4px;text-align:left}
.setting{
  display:flex;align-items:center;justify-content:space-between;gap:14px;
  background:rgba(255,255,255,.035);
  border:1px solid var(--glass-border);
  border-radius:var(--r-md);padding:12px 15px;
  font-size:.85rem;font-weight:600;cursor:pointer;
  transition:background .16s var(--ease),border-color .16s var(--ease);
}
.setting:hover{background:var(--glass-2);border-color:var(--line-2)}
.setting input[type=checkbox]{width:18px;height:18px;accent-color:var(--accent);cursor:pointer}
/* a setting that needs a row of choices rather than one control */
.setting-block{display:block;cursor:default}
.setting-block:hover{background:rgba(255,255,255,.035);border-color:var(--glass-border)}
.setting-head{
  display:block;margin-bottom:10px;
  font-size:.66rem;font-weight:700;letter-spacing:.14em;
  text-transform:uppercase;color:var(--text-3);
}
.chip-row{display:flex;flex-wrap:wrap;gap:6px}
.chip{
  font:600 .78rem/1 'Inter',system-ui,sans-serif;
  color:var(--text-2);
  background:rgba(255,255,255,.03);
  border:1px solid var(--glass-border);
  border-radius:999px;
  padding:5px 13px 5px 6px;cursor:pointer;
  display:inline-flex;align-items:center;gap:7px;
  transition:background .16s var(--ease),border-color .16s var(--ease),color .16s var(--ease);
}
.chip:hover{background:var(--glass-2);color:var(--text);border-color:var(--line-2)}
.chip.on{background:var(--accent-soft);border-color:rgba(52,211,153,.6);color:var(--accent)}
.chip-icon{display:flex;color:var(--text-3)}
.setting input[type=range]{flex:0 1 170px;accent-color:var(--accent);cursor:pointer}
.settings-note{font-size:.75rem;color:var(--text-3) !important}

/* ==================================================================
   RESPONSIVE

   The board takes care of itself — it is laid out at full size and scaled to
   whatever the board area turns out to be — so these rules are about the
   chrome around it. The order things are given up in, as the screen narrows:
   button labels, then the level name, then the tile counter. The clock and
   the score are the last two standing, because they are the only two that
   are not already visible on the board itself.
   ================================================================== */

/* a fifty-card grid has room to breathe on a desktop monitor */
@media (min-width:1440px){
  .menu-wrap{width:min(1240px,100%)}
}

/* ---- big screens ----
   Every size below the default is a px constant tuned for a phone, and they
   were never scaled back UP: on a 1920-wide monitor — which is what fullscreen
   play is — a 58px strip, an 11px dock label and a 9px "SCORE" caption sit in
   the far corners of a screen six times wider than the one they were drawn
   for, and read as a toolbar someone forgot to finish. The board has the same
   problem and is dealt with in fitBoard(); the two have to move together, or a
   bigger strip just frames a smaller island.

   Guarded on HEIGHT as well as width, and placed ahead of the short-landscape
   block below so that a wide-but-short window (1920x500) still gets the
   tightened chrome — there, height is the scarce thing and the board needs all
   of it. */
@media (min-width:1200px) and (min-height:600px){
  :root{--hud-h:70px;--dock-h:78px}
  .hud{gap:14px;padding:calc(9px + var(--safe-t)) calc(20px + var(--safe-r)) 9px calc(20px + var(--safe-l))}
  .hud-level{font-size:.95rem}
  .hud-clock{gap:10px}
  .hud-clock b{font-size:1.6rem}
  .clock-i .ic{width:17px;height:17px}
  .hud-stats{gap:22px}
  .ro b{font-size:1.2rem}
  .ro i{font-size:.64rem}
  .hud .icon-btn .ic{width:22px;height:22px}
  .time-bar{height:4px}

  .dock{gap:8px;padding:9px calc(20px + var(--safe-r)) calc(9px + var(--safe-b)) calc(20px + var(--safe-l))}
  .dock-btn{flex:0 1 132px;font-size:.86rem;padding:9px 14px;gap:8px}
  .dock-i .ic{width:24px;height:24px}
  /* the counts ("Hint (5)") were the least legible thing on the strip — a
     0.76em label at 55% opacity over a dark bar */
  .dock-l i{font-size:.8em;opacity:.72}
}
@media (min-width:1600px) and (min-height:720px){
  :root{--hud-h:80px;--dock-h:90px}
  .hud{gap:16px;padding:calc(11px + var(--safe-t)) calc(26px + var(--safe-r)) 11px calc(26px + var(--safe-l))}
  .hud-level{font-size:1.05rem}
  .hud-clock b{font-size:1.9rem}
  .clock-i .ic{width:19px;height:19px}
  .hud-stats{gap:26px}
  .ro b{font-size:1.38rem}
  .ro i{font-size:.7rem}
  .hud .icon-btn .ic{width:24px;height:24px}
  .time-bar{height:5px}

  .dock-btn{flex:0 1 152px;font-size:.95rem;padding:11px 16px;gap:9px}
  .dock-i .ic{width:27px;height:27px}
}
@media (max-width:880px){
  .play-row{grid-template-columns:1fr}
  .hud-stats{gap:13px}
}
@media (max-width:720px){
  :root{--hud-h:52px;--dock-h:60px}
  .menu-wrap{padding-top:26px}
  .ghost-btn .gl{display:none}
  .ghost-btn{padding:9px}
  .icon-btn{padding:9px}
  .hud{gap:8px}
  .hud-clock b{font-size:1.2rem}
  .ro b{font-size:.92rem}
  .level-grid{grid-template-columns:repeat(auto-fill,minmax(156px,1fr))}
  .section-head{gap:10px}
  .chapter-tab{padding:6px 11px;font-size:.7rem}
  .dock-btn{flex:1 1 0}
}
@media (max-width:560px){
  /* the clock owns the middle of the strip, so the level name gives way
     before the readout does — you know which board you are on, and the
     score and the tiles left are what change while you play */
  .hud-level{display:none}
  .hud-stats{gap:13px}
  .progress-strip span{min-width:88px;padding:8px 12px}
  .lc-meta{gap:9px}
  .dock-l{font-size:.7rem}
  /* a dialog on a phone is a sheet of paper, not a card on a desk */
  .overlay{padding:14px}
  .modal{padding:22px 18px}
  .pause-card{padding:18px}
}
@media (max-width:460px){
  /* Down to one readout rather than a row of bare digits: tiles left is
     already on the board in front of you, score is not. What survives keeps
     its label — an unlabelled number is not a readout. */
  .hud-stats .ro:nth-child(2){display:none}
}
@media (max-width:420px){
  .level-grid{grid-template-columns:repeat(2,minmax(0,1fr));gap:9px}
  .lc-foot{padding:8px 10px 0}
  .lc-meta{padding:5px 10px 9px;gap:8px;font-size:.64rem}
  .level-name{font-size:.8rem}
  .menu-wrap{padding-left:calc(14px + var(--safe-l));padding-right:calc(14px + var(--safe-r))}
  /* the bar and the grid under it share one left edge */
  .menu-bar{padding-left:calc(14px + var(--safe-l));padding-right:calc(14px + var(--safe-r))}
}
/* the narrow end of the phone range: a 320px screen still has to seat four
   buttons in the dock, and they cannot each keep 100px of label */
@media (max-width:380px){
  .hud{gap:6px;padding-left:calc(8px + var(--safe-l));padding-right:calc(8px + var(--safe-r))}
  .hud-clock{gap:6px}
  .hud-clock b{font-size:1.08rem}
  .ro b{font-size:.88rem}
  .dock{gap:2px;padding-left:calc(6px + var(--safe-l));padding-right:calc(6px + var(--safe-r))}
  .dock-btn{padding:7px 4px;font-size:.68rem;gap:5px}
  /* the counts are still on each button's title, and in the win summary */
  .dock-l i{display:none}
  .progress-strip{gap:7px}
  .progress-strip span{min-width:0;flex:1 1 84px;padding:8px 10px}
}
/* phone in landscape: every pixel of height belongs to the board, and on the
   menu the hero has to stop eating the whole first screenful */
@media (max-height:520px) and (orientation:landscape){
  :root{--hud-h:46px;--dock-h:52px}
  .hud-clock b{font-size:1.15rem}
  .dock-btn{flex-direction:row;gap:7px;padding:6px 12px}
  .dock{padding-top:6px}
  /* nine rows against 360px of screen: the menu still scrolls, but tightening
     the rows is the difference between "New deal" being under the fold and
     being on it */
  .sheet-row{padding:7px 10px}
  .sheet-head{margin:0 0 2px}
  .sheet-sep{margin:3px 4px}
  .menu-bar{height:calc(46px + var(--safe-t))}
  .menu-wrap{padding-top:20px}
  .hero{margin-bottom:20px}
  .logo small{margin-top:8px}
  .progress-strip{margin-top:14px}
  .modal{padding:20px;max-height:94vh}
  .modal-actions{margin-top:16px}
  .big-stars{margin:2px 0 10px}
}
@supports (max-height:94dvh){
  @media (max-height:520px) and (orientation:landscape){
    .modal{max-height:94dvh}
  }
}

/* ==================================================================
   TOUCH
   A tap leaves :hover stuck on whatever you tapped until you tap something
   else, so the lifts and glows that read as "this is live" under a pointer
   read as "this is selected" under a finger. Static feedback only here;
   :active still fires, and so does every animation that means something.
   ================================================================== */
@media (hover:none){
  .btn:hover,.quick-match-btn:hover,.dock-btn:hover,.continue-card:hover{
    transform:none;
  }
  .level-card:hover{
    transform:none;box-shadow:none;
    background:var(--glass);border-color:var(--glass-border);
  }
  .level-card.cleared:hover{border-color:rgba(251,191,36,.2)}
  .level-card.is-next:hover{
    border-color:rgba(52,211,153,.55);
    box-shadow:0 0 0 1px rgba(52,211,153,.25),0 10px 30px rgba(0,0,0,.35);
  }
  /* a free tile that keeps a lifted shadow after a tap reads as selected,
     which is the one state on this screen that has to be unambiguous */
  .tile.free:not(.selected):hover{
    transform:none;
    box-shadow:
      2px 2px 0 var(--tile-edge),
      3px 4px 0 var(--tile-edge-2),
      5px 7px 13px rgba(0,0,0,.45),
      inset 0 1px 0 rgba(255,255,255,.9);
  }
  .dock-btn:hover .dock-i{color:var(--text-2)}
  .ghost-btn:hover .gi,.icon-btn:hover .ii{color:var(--text-3)}
}

/* ==================================================================
   REDUCED MOTION
   Movement is decoration here, never information: the same states are
   also carried by colour, shape and the live region.
   ================================================================== */
@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{
    animation-duration:.001ms !important;
    animation-iteration-count:1 !important;
    transition-duration:.001ms !important;
  }
  .tile.free:hover,.tile.selected{transform:none}
  .logo-word{animation:none !important}
}
