/* Mathquilibrium: the tile board and operator keys. Everything else is in shared/core.css. */
:root { --brand: var(--pink); --brand-text: var(--pink-text); --on-brand: var(--on-pink); }

/* Equations read left to right in every language: the board (and its scroller), the keys and the operator lists never mirror
   (in right-to-left text a lone < would even show as >) */
.zoom, .board, .p-grid, .palette, .intro-keys, #g-sub, .p-ops b { direction: ltr; unicode-bidi: isolate; }

/* The board pinch-zooms (game.js sets --zoom) inside its own scroller; the page keeps one screen tall so the keys stay put. */
#game { height: calc(100 * var(--dvh)); container-type: inline-size; } /* keys size from cqw, not vw */
.board-wrap { min-height: 0; grid-template: minmax(0, 1fr) / minmax(0, 1fr); container-type: size; }
.zoom {
  place-self: stretch; overflow: auto; overscroll-behavior: contain;
  display: grid; place-items: safe center;
  padding: 6px; margin: -6px; /* room for the selection outline and the tile animations, without scrollbars */
  touch-action: pan-x pan-y; /* pinch is ours, not the page's */
  /* edges with more board past them fade out (game.js sets --l/--r/--t/--b to 0 there) */
  mask: linear-gradient(to right, rgb(0 0 0 / var(--l, 1)), #000 28px, #000 calc(100% - 28px), rgb(0 0 0 / var(--r, 1))),
        linear-gradient(to bottom, rgb(0 0 0 / var(--t, 1)), #000 28px, #000 calc(100% - 28px), rgb(0 0 0 / var(--b, 1)));
  mask-composite: intersect;
}
.zoom * { touch-action: pan-x pan-y; /* beat the global `* { manipulation }`, which would let the tiles pinch the page */
}
/* a typed length, so it's worked out once on .board and the grid gets plain px: under the text & tile size zoom, WebKit
   reads vw and cq units in grid-template-* differently from everywhere else (and from Chromium) */
@property --cell { syntax: '<length>'; inherits: true; initial-value: 0px; }
.board {
  --gap: clamp(3px, calc(1 * var(--vw)), 6px);
  /* fitted to the board area (the .board-wrap container), times the pinch zoom */
  --cell: calc(var(--zoom, 1) * min(62px,
    calc(100cqw * var(--cq, 1) / var(--cols) - var(--gap)),
    calc(100cqh * var(--cq, 1) / var(--rows) - var(--gap))));
  display: grid; gap: var(--gap);
  grid-template-columns: repeat(var(--cols), var(--cell));
  grid-template-rows: repeat(var(--rows), var(--cell));
}
.board.mini { --cell: 40px; --gap: 5px; }
/* in a dialog (help, intro), a long line shrinks to fit its width: min(420px, 100vw - 32px), less 56px of padding (core.css) */
/* (4px more for the tiles' shadows) */
dialog .board.mini { --fit: calc((min(420px, 100 * var(--vw) - 32px) - 60px + 5px) / var(--cols) - 5px); --cell: min(40px, var(--fit)); }

.cell {
  display: grid; place-items: center; padding: 0; border: 0;
  border-radius: calc(var(--cell) * .2);
  font-size: calc(var(--cell) * .44); font-weight: 600; font-variant-numeric: tabular-nums; line-height: 1;
  user-select: none;
  animation: enter .3s var(--d, 0ms) both var(--ease);
  transition: background-color .2s, color .2s, box-shadow .14s var(--ease), transform .14s var(--ease);
}
.cell.long { font-size: calc(var(--cell) * .34); letter-spacing: -0.03em; }
/* numbers: printed on card stock */
.cell.num { background: var(--grain), var(--stock); box-shadow: inset 0 0 0 1px var(--hair), var(--lift); }
.cell.op { font-size: calc(var(--cell) * .54); font-weight: 400; }
/* given operators: printed straight onto the page, no tile */
.cell.op.given { background: none; color: var(--muted); }
/* blanks: a halftone screen waiting for ink */
button.cell.op:not(.filled), .cell.slot {
  background: radial-gradient(circle, var(--dot) .9px, transparent 1.25px) 0 0 / 5px 5px;
  box-shadow: inset 0 0 0 1px var(--line); color: var(--on-brand);
}
button.cell.op:not(.filled):hover { box-shadow: inset 0 0 0 1.5px var(--brand); }
.cell.slot { box-shadow: inset 0 0 0 1.5px var(--brand); }
/* filled: the brand drum, slightly out of register with the key */
.cell.filled { background: var(--speck), var(--brand); color: var(--on-brand); box-shadow: 1.5px 2px 0 var(--reg); }
.cell.hinted { background: var(--speck), var(--sun); color: var(--on-sun); box-shadow: 1.5px 2px 0 var(--reg); }

.cell.hl.num { background: var(--grain), var(--hl); }
button.cell.hl:not(.filled) { box-shadow: inset 0 0 0 1.5px var(--brand); background: radial-gradient(circle, color-mix(in srgb, var(--brand) 55%, transparent) .9px, transparent 1.3px) 0 0 / 5px 5px; }
.cell.ok.num { background: var(--grain), color-mix(in srgb, var(--teal) 16%, var(--stock)); color: var(--teal-text); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--teal) 40%, transparent), var(--lift); }
.cell.ok.op.given { color: var(--teal-text); }
.cell.ok.filled { background: var(--speck), var(--teal); color: var(--on-teal); }
/* false lines are hatched as well as red, so they don't rely on colour alone */
.cell.bad.num { background: repeating-linear-gradient(135deg, color-mix(in srgb, var(--red) 30%, transparent) 0 1.5px, transparent 1.5px 6px), var(--grain), color-mix(in srgb, var(--red) 16%, var(--stock)); color: var(--red-text); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--red) 45%, transparent), var(--lift); }
.cell.bad.filled { background: repeating-linear-gradient(135deg, rgb(255 255 255 / .22) 0 1.5px, transparent 1.5px 6px), var(--speck), var(--red); color: var(--on-red); }
.cell.bad.op.given { color: var(--red-text); text-decoration: line-through; text-decoration-thickness: 1.5px; }
/* selected: a crisp key-ink frame; the tile settles into register */
.cell.sel { outline: 2px solid var(--ink); outline-offset: 2px; z-index: 1; }
button.cell.sel.filled { transform: translate(1.5px, 2px); box-shadow: 0 0 0 var(--reg); }

.cell.pop { animation: pop .22s var(--ease); }
.cell.shake { animation: shake .4s; }
.board.solved .cell { animation: wave .6s calc(var(--d) * 1.6) both var(--ease); }

.palette { display: flex; flex-wrap: wrap; justify-content: center; gap: 6px; }
/* the widest palette is 11 keys (7 ops, 3 relations, erase): size for 6 per row so it never takes more than 2.
   cqw is #game's content box, i.e. the width the palette really gets (100vw drifts under zoom/text scaling);
   the 1px is slack so subpixel rounding can't push the 6th key onto a new row. */
.key {
  --fit: calc((100cqw * var(--cq, 1) - 5 * 6px - 1px) / 6);
  width: min(52px, var(--fit)); height: min(48px, var(--fit));
  border: 0; border-radius: 12px; font-size: 24px; font-weight: 400;
  background: var(--speck), var(--brand); color: var(--on-brand); box-shadow: 2px 3px 0 var(--reg);
  transition: transform .1s var(--ease), box-shadow .1s var(--ease);
}
.key:active, .key.press { transform: translate(2px, 3px); box-shadow: 0 0 0 var(--reg); }
.key.eq { background: var(--speck), var(--ink); color: var(--paper); box-shadow: 2px 3px 0 var(--brand); }
.key.eq:active, .key.eq.press { box-shadow: 0 0 0 var(--brand); }
.key.erase { background: var(--grain), var(--stock); color: var(--ink); box-shadow: inset 0 0 0 1px var(--line), 2px 3px 0 var(--hair); display: grid; place-items: center; }
.key.erase:active { box-shadow: inset 0 0 0 1px var(--line); }

#help-grid { margin: 0 auto 8px; --cell: 34px; }

@media (orientation: landscape) and (max-height: 540px) {
  .key { width: 44px; height: 44px; font-size: 22px; } /* 6 per row in the 300px side column */
  /* the controls column can run past the screen; keep the board in view (90px ≈ top bar + padding) */
  .board-wrap { max-height: calc(100 * var(--dvh) - 90px); align-self: start; }
}

@media (pointer: coarse) and (min-width: 700px) and (min-height: 700px) {
  .board:not(.mini) { --cell: calc(var(--zoom, 1) * min(84px,
    calc(100cqw * var(--cq, 1) / var(--cols) - var(--gap)),
    calc(100cqh * var(--cq, 1) / var(--rows) - var(--gap)))); }
  .palette { gap: 10px; }
  .key { --fit: calc((100cqw * var(--cq, 1) - 5 * 10px - 1px) / 6); width: min(64px, var(--fit)); height: min(60px, var(--fit)); font-size: 28px; border-radius: 14px; }
}
@media (pointer: coarse) and (orientation: landscape) and (min-height: 700px) {
  .palette { gap: 8px; }
  .key { width: 60px; height: 56px; } /* 6 per row in the 400px side column */
}

/* level intro modal */
.intro section + section { margin-top: 18px; padding-top: 18px; border-top: 1px solid var(--hair); }
.intro .board.mini { margin: 0 auto; --cell: min(34px, var(--fit)); justify-content: center; }
.intro p { margin: 12px 0 0; line-height: 1.45; text-wrap: balance; }
.intro p b { font-weight: 600; }
.intro-keys { display: flex; justify-content: center; gap: 8px; margin-bottom: 14px; }
.intro-keys .key { display: grid; place-items: center; width: 52px; height: 48px; animation: pop .4s .15s both var(--ease); }

#logo { --cell: 24px; --gap: 4px; } /* fits the 140px logo slot (core.css) */

/* ---------- print ---------- */
.p-ops { margin: 0; font-size: 12pt; display: flex; align-items: center; gap: 4mm; }
.p-ops b { display: grid; place-items: center; min-width: 9mm; height: 9mm; border: 1pt solid #000; border-radius: 2mm; font-size: 16pt; font-weight: 500; }
.p-grid {
  --cell: min(16mm, calc(180mm / var(--cols) / 1.1), calc(165mm / var(--rows) / 1.1)); /* cell + its .1 gap */
  display: grid; gap: calc(var(--cell) * .1);
  grid-template-columns: repeat(var(--cols), var(--cell)); grid-template-rows: repeat(var(--rows), var(--cell));
}
.p-grid > div { display: grid; place-items: center; border-radius: calc(var(--cell) * .16); font-size: calc(var(--cell) * .44); font-weight: 600; font-variant-numeric: tabular-nums; }
.p-grid .long { font-size: calc(var(--cell) * .34); }
.p-num { border: 1pt solid #000; }
.p-given { font-weight: 400 !important; font-size: calc(var(--cell) * .54) !important; }
.p-blank { border: 1pt dashed #000; }
