/* Shared chrome for the arcade games.

   Bubble Pop and Stack Up are different games, but the frame around them is
   the same frame: two rows of controls, a readout, a stage, and three
   dialogs. That frame was copied out of Loose Ends for the first of them and
   would have been copied again for the second, which is how one game ends up
   with 2.6rem buttons and the other with 2.4rem ones.

   So it lives here once, under .ar-, and each game's own stylesheet adds only
   what is actually its own.

   Sized for who plays it, exactly as looseEnds.css is: mostly people over
   seventy, often on a laptop trackpad. Nothing here is smaller than 1rem or
   shorter than 2.6rem. */

.arcade-page {
  margin: 0;

  /* ----------------------------------------------------------------------
     The seven colours.

     Read by JavaScript through getComputedStyle, which is why each one is a
     flat value with a separate dark twin rather than a light-dark() pair: a
     custom property computes to its token stream, so light-dark(a, b) reaches
     canvas as the literal string and is silently ignored. See the long
     version at the top of js/games/arcade/palette.js.

     Fixed rather than derived from the theme, and for the reason Loose Ends
     gives: derived colours collide the moment a theme's accent lands near its
     info colour, and in THESE games two colours that look alike is not a
     cosmetic problem, it is a broken rule. The site's eight themes still own
     everything around the board.

     Spread as far apart as seven hues can be. Every one of them also carries
     a shape drawn on the ball, so a player who cannot separate the red from
     the green is never actually relying on this list. ------------------- */

  --ar-hue-1: #2E6FA8;   /* blue   */
  --ar-hue-2: #3E8B4A;   /* green  */
  --ar-hue-3: #C9971B;   /* gold   */
  --ar-hue-4: #7A4E9E;   /* purple */
  --ar-hue-5: #B3417A;   /* pink   */
  --ar-hue-6: #C0392B;   /* red    */
  --ar-hue-7: #17A2B8;   /* cyan   */

  --ar-hue-1-dark: #6FA3D4;
  --ar-hue-2-dark: #6FBE72;
  --ar-hue-3-dark: #D9B44A;
  --ar-hue-4-dark: #A98BC8;
  --ar-hue-5-dark: #D97CAA;
  --ar-hue-6-dark: #E0705F;
  --ar-hue-7-dark: #5AD1E3;

  /* The seventh was a teal, #2A8C97, and it was wrong.
     -------------------------------------------------
     css/games/looseEnds.css already says this in as many words: "An earlier
     set had a teal in it, wedged between the blue and the green, and on a
     packed board the three of them were genuinely hard to tell apart." That
     palette dropped to six colours to be rid of it. This one needed seven,
     put the teal back, and got the same result -- reported from play as
     balls that ought to match refusing to.

     Measured rather than argued about, on the weighted-RGB distance that
     approximates what the eye does. Every pair in the palette, worst first:

         teal set:  Blue/Teal 65 light, 55 dark   <- the clash
         cyan set:  Purple/Pink 110 light, 96 dark

     The six colours WITHOUT a seventh are also limited by Purple/Pink at
     110/96, so this cyan costs the palette nothing at all -- it is as far
     from its neighbours as the palette's own floor. Nine other candidates
     were measured; charcoal and cream tie with it, and both look like a
     mistake beside six rainbow colours.

     Two things still carry the load if a player cannot separate two of
     these anyway: every ball also wears a shape, and the shapes are on by
     default. See the top of js/games/arcade/palette.js. */

  /* The playing surface. Follows the theme, because unlike jigsaw there is no
     photograph to protect. Read fresh every frame, so dragging a colour in
     the theme editor repaints the board live. */
  --ar-well: var(--surface-alt);
  --ar-grid: var(--rule);
}

/* Full-height chain, as the card games, jigsaw and Loose Ends all do it: the
   stage takes whatever is left after the header, nav, bars and footer.
   min-height:0 on the flex children is what lets them shrink instead of
   shoving the footer off the bottom. */
.arcade-page .Master {
  min-height: 100vh;
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
}

.arcade-page .Master > section.ar-shell {
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 8px 10px 10px;
}

.arcade-page footer {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0 8px;
  padding: 2px 10px;
  margin: 0;
}

.arcade-page .build-tag,
.arcade-page .page-hits {
  font-family: 'Trebuchet MS', 'Segoe UI', sans-serif;
  font-size: var(--footer-size);
  letter-spacing: 0.04em;
  opacity: 0.45;
  margin: 0;
}

.arcade-page .page-hits::before { content: '· '; }


/* --------------------------------------------------------------- the bars */

.ar-bar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  padding: 7px 9px;
  border: 1px solid var(--rule);
  border-radius: 10px;
  background: var(--surface);
}

.ar-bar button,
.ar-bar select,
.ar-bar input {
  font-family: inherit;
  font-size: 1rem;
  min-height: 2.6rem;
  padding: 0 0.85rem;
  border: 1px solid var(--rule-strong);
  border-radius: 8px;
  background: var(--button-bg, var(--surface));
  color: var(--button-ink, var(--ink));
  cursor: pointer;
}

.ar-bar input { cursor: text; }

/* Every play-bar button carries an icon and its words: which one shows is
   css/games/phone.css, shared with Mahjong. */

.ar-bar button:hover:not(:disabled),
.ar-bar select:hover {
  background: var(--button-hover-bg, var(--accent-soft));
  border-color: var(--accent);
}

.ar-bar button:disabled {
  color: var(--button-disabled-ink, var(--ink-faint));
  cursor: default;
  opacity: 0.55;
}

/* A pressed toggle reads as pressed. Without this the Shapes and Sound
   buttons only say what they are by their own words, which is fine until
   somebody is skimming. */
.ar-bar button[aria-pressed="false"] {
  color: var(--ink-faint);
  border-style: dashed;
}

.ar-primary {
  background: var(--accent) !important;
  border-color: var(--accent) !important;
  color: var(--on-accent) !important;
  font-weight: 700;
}

.ar-primary:hover:not(:disabled) { filter: brightness(1.12); }

.ar-danger {
  border-color: var(--danger) !important;
  color: var(--danger) !important;
}

.ar-danger:hover { background: var(--danger-soft) !important; }

.ar-field {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 0.82rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-muted);
}

.ar-seed { width: 7.5rem; font-variant-numeric: tabular-nums; }

.ar-group {
  display: flex;
  gap: 4px;
  padding-left: 8px;
  border-left: 1px solid var(--rule);
}

.ar-group button { min-width: 3.2rem; padding: 0 0.7rem; }

/* Pushed to the far end so the way out of full screen is always in the same
   corner, whichever row wrapped. */
.ar-fs { margin-left: auto; }

.ar-fs.fs-on {
  background: var(--accent) !important;
  border-color: var(--accent) !important;
  color: var(--on-accent) !important;
}

.ar-menu {
  padding: 6px;
  border: 1px solid var(--rule-strong);
  border-radius: 10px;
  background: var(--raised, var(--surface));
  color: var(--ink);
  box-shadow: 0 6px 20px var(--shadow, rgba(0, 0, 0, 0.25));
}

.ar-menu button,
.ar-menu__link {
  display: block;
  width: 100%;
  min-height: 2.6rem;
  padding: 0 0.9rem;
  border: 0;
  border-radius: 7px;
  background: none;
  color: var(--ink);
  font: inherit;
  text-align: left;
  text-decoration: none;
  line-height: 2.6rem;
  cursor: pointer;
}

.ar-menu button:hover,
.ar-menu__link:hover { background: var(--accent-soft); }

.ar-menu__rule { border: 0; border-top: 1px solid var(--rule); margin: 5px 2px; }


/* ---------------------------------------------------------- the readout */

.ar-readout {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 4px 18px;
  margin: 0;
  padding: 0 4px;
  font-size: 0.95rem;
  color: var(--ink-muted);
}

.ar-readout__item {
  display: inline-flex;
  align-items: baseline;
  gap: 5px;
}

.ar-readout b {
  font-size: 1.15rem;
  color: var(--ink);
  font-variant-numeric: tabular-nums;
}

/* The score is the number people actually watch, so it is the one allowed to
   shout. */
.ar-readout__lead b {
  font-size: 1.45rem;
  color: var(--accent);
}

.ar-readout__note {
  font-size: 0.82rem;
  letter-spacing: 0.04em;
  color: var(--ink-faint);
}


/* ------------------------------------------------------------- the stage */

.ar-stage {
  position: relative;
  flex: 1;
  /* A floor rather than min-height:0. The board is the only thing that
     flexes, so on a short window it was handed whatever the bars and the
     readout left over, which on a 460px-tall window is a board nobody can
     play. Below this the page scrolls instead, which is a far better outcome:
     the bars go off the top, the board stays usable, and full screen is right
     there for anybody who wants the whole window back. */
  min-height: 19rem;
  border: 1px solid var(--rule-strong);
  border-radius: 12px;
  background: var(--ground);
  overflow: hidden;
}

.ar-stage canvas {
  /* Absolute, not height:100%. The stage is a flex item sized by flex-grow
     and min-height, so its own `height` stays auto — and a percentage height
     resolves against the parent's height PROPERTY, not against the box flex
     actually gave it. So height:100% quietly does nothing and the canvas
     falls back to its attribute height, which the game then measures and
     writes straight back. inset:0 has no such dependency. */
  position: absolute;
  inset: 0;
  display: block;
  width: 100%;
  height: 100%;
  /* Every gesture on the board is ours. A browser that decides a drag was a
     scroll makes the game unplayable on a phone. */
  touch-action: none;
}

.ar-stage canvas:focus-visible {
  outline: 3px solid var(--accent);
  outline-offset: -3px;
}


/* ------------------------------------------------------------- dialogs */

.ar-dialog {
  width: min(34rem, calc(100vw - 32px));
  padding: 0 18px 18px;
  border: 1px solid var(--rule-strong);
  border-radius: 12px;
  background: var(--raised, var(--surface));
  color: var(--ink);
}

.ar-dialog::backdrop { background: var(--backdrop, rgba(0, 0, 0, 0.45)); }

.ar-dialog__head {
  position: sticky;
  top: 0;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin: 0 -18px 4px;
  padding: 12px 18px;
  background: var(--raised, var(--surface));
  border-bottom: 1px solid var(--rule);
}

.ar-dialog__head h2,
.ar-dialog__title {
  margin: 0;
  font-size: 1.25rem;
}

.ar-dialog__title { padding: 16px 0 0; }

.ar-dialog__head button {
  min-width: 2.4rem;
  min-height: 2.4rem;
  border: 1px solid var(--rule-strong);
  border-radius: 8px;
  background: var(--surface);
  color: var(--ink);
  font-size: 1.2rem;
  cursor: pointer;
}

.ar-dialog__body p { margin: 10px 0; line-height: 1.5; }

.ar-dialog__body h3,
.stats-body h3 {
  margin: 20px 0 0;
  font-size: 1rem;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--ink-faint);
}

.ar-dialog__note {
  margin: 14px 0 0;
  font-size: 0.85rem;
  color: var(--ink-faint);
}

.ar-dialog__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 18px;
}

.ar-dialog__actions button {
  font-family: inherit;
  font-size: 1rem;
  min-height: 2.6rem;
  padding: 0 1rem;
  border: 1px solid var(--rule-strong);
  border-radius: 8px;
  background: var(--surface);
  color: var(--ink);
  cursor: pointer;
}

.ar-dialog__actions button:hover { background: var(--accent-soft); }

/* Same markup as looseEnds.css produces, so the two read identically. */
.stats-list,
.ar-done__detail {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 0;
  margin: 12px 0 0;
}

.stats-list dt,
.ar-done__detail dt {
  padding: 7px 0;
  border-bottom: 1px solid var(--rule);
  color: var(--ink-muted);
}

.stats-list dd,
.ar-done__detail dd {
  margin: 0;
  padding: 7px 0;
  border-bottom: 1px solid var(--rule);
  text-align: right;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}


/* The gear's Settings dialog is styled by settings.css, loaded alongside this
   file: Mahjong has one too, and does not load this file. */


/* ---------------------------------------------------------- full screen

   Only .ar-shell is handed to requestFullscreen, so the bars — and with them
   the way back out — go full screen along with the board. */

.ar-shell:fullscreen,
.ar-shell.is-focus {
  padding: 10px 12px 12px;
  background: var(--ground);
}


/* ---------------------------------------------------------- short windows

   Below this the controls are worth more than the scenery, so the bars stop
   being boxes and the gaps close up. */

@media (max-height: 560px) {
  .arcade-page .Master > section.ar-shell { gap: 5px; padding: 5px 7px 7px; }
  .ar-bar { border: 0; padding: 0; background: none; }
  .ar-readout { font-size: 0.85rem; }
}


/* ---------------------------------------------------------------- phones

   The page round the game on a phone -- the thin header, no nav bar, only the
   front door until PLAY, and icons rather than words -- is
   css/games/phone.css, which Mahjong shares. What is left here is this bar's
   own shape on a phone. Same query as that file. */

@media (pointer: coarse) and (max-width: 720px),
       (pointer: coarse) and (max-height: 500px) {
  /* Once a game is on, the play bar is ONE row of icons. Words wrapped it
     onto three rows, which is 115px of an iPhone before the scores. The
     buttons share the row equally, so every one is as big a target as the
     row allows, and the words stay for a screen reader: hidden from sight,
     not from the page. The groups (the arrows, Knock Down's tools) give up
     their own box so their buttons share the row like the rest. */
  .ar-shell .ar-bar--play {
    flex-wrap: nowrap;
    gap: 4px;
    padding: 0;
    border: 0;
    background: none;
  }

  .ar-bar--play .ar-group,
  .ar-bar--play .kd-tools { display: contents; }

  .ar-shell .ar-bar--play button {
    flex: 1 1 0;
    min-width: 0;
    min-height: 2.6rem;
    padding: 0;
    font-size: 1.05rem;
  }

  .ar-shell .ar-fs { margin-left: 0; }

  /* The scores, smaller, so they sit on one line where they can. */
  .ar-shell .ar-readout {
    gap: 0 12px;
    font-size: 0.8rem;
  }

  .ar-shell .ar-readout b { font-size: 0.95rem; }
  .ar-shell .ar-readout__lead b { font-size: 1.1rem; }
}
