/*
 * Inference Bee. Wide screens show the puzzle with the score and the finds
 * beside it. Phones (480px and under) stack it: a slim top bar with the
 * score, the rules, then the entry, hive and buttons, with the finds in a
 * list that drops from a button. In the app on a phone the page itself
 * never scrolls: the top bar and the bottom area stay put, and only the
 * rules scroll between them.
 */

#game {
  max-width: 980px;
  margin: 0 auto;
  padding: calc(var(--gk-inset-top, 0px) + 8px) 16px calc(var(--gk-inset-bottom, 0px) + 32px);
}

p {
  margin: 0;
}

button {
  font: inherit;
  color: inherit;
}

/* ---------- top line ---------- */

.ib-top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 16px;
}

.ib-date {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 4px 10px;
}

.ib-day {
  font-family: var(--font-serif);
  font-weight: 600;
  font-size: 20px;
}

.ib-day-short,
.ib-top-score {
  display: none;
}

.ib-level {
  font-size: 14px;
  color: var(--color-content-secondary);
}

/* ---------- layout ---------- */

.ib-layout {
  display: grid;
  grid-template-areas: "score" "play" "found";
  gap: 20px;
}

.ib-play {
  grid-area: play;
  min-width: 0;
}

.ib-side-score {
  grid-area: score;
}

.ib-found {
  grid-area: found;
}

@media (min-width: 820px) {
  .ib-layout {
    grid-template-columns: minmax(0, 1fr) 320px;
    grid-template-rows: auto 1fr;
    grid-template-areas: "play score" "play found";
    column-gap: 48px;
    row-gap: 16px;
    align-items: start;
  }
}

/* ---------- rules ---------- */

.ib-theme-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 8px;
}

.ib-theme {
  min-width: 0;
  overflow: hidden;
  font-size: 14px;
  color: var(--color-content-secondary);
  text-overflow: ellipsis;
  white-space: nowrap;
}

.ib-rules {
  --number: 24px;
  --number-gap: 10px;
}

.ib-rules ol {
  display: grid;
  gap: 8px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.ib-rules li {
  display: grid;
  grid-template-columns: var(--number) minmax(0, 1fr);
  gap: var(--number-gap);
  align-items: start;
  font-size: 16px;
  line-height: 1.45;
}

.ib-rule-number {
  position: relative;
  display: flex;
  flex: none;
  align-items: center;
  justify-content: center;
  width: var(--number);
  height: var(--number);
  border-radius: 50%;
  background: var(--color-surface-contrast);
  font-size: 12px;
  font-weight: 600;
}

/* With Rule hints on: finds left that use the rule, like an app icon's count. */
.ib-rule-left {
  position: absolute;
  top: -6px;
  right: -7px;
  min-width: 15px;
  height: 15px;
  padding: 0 3px;
  border-radius: 999px;
  background: var(--color-highlight-dark);
  color: var(--color-content-base-fixed);
  font-size: 10px;
  font-weight: 700;
  line-height: 15px;
  text-align: center;
}

.ib-rule-number.ib-rule-done {
  opacity: 0.4;
}

.ib-fold-hint {
  margin-top: 8px;
  font-size: 13px;
  color: var(--color-content-secondary);
}

/* A rule typed in: one line of lawgic, a quiet Contrapositive link that
   alone switches it to the other form, and a chevron that opens the
   English. Lines sit 44px apart so each control is a full tap target. */
.ib-rules li.ib-folded-li {
  display: block;
}

.ib-fold-line {
  display: grid;
  grid-template-columns: var(--number) minmax(0, 1fr) auto 44px;
  align-items: center;
  min-height: 38px;
}

.ib-fold-fresh .ib-fold-line {
  animation: ib-fold-in 0.25s ease-out;
  animation-delay: calc(var(--age, 0ms) * -1);
}

.ib-fold-lawgic {
  min-width: 0;
  margin-left: var(--number-gap);
  font-size: 15px;
  font-weight: 600;
}

.ib-fold-contra,
.ib-fold-more {
  position: relative;
  height: 38px;
  margin: 0;
  border: 0;
  border-radius: 8px;
  background: none;
  cursor: pointer;
}

.ib-fold-contra::after,
.ib-fold-more::after {
  position: absolute;
  top: -3px;
  right: 0;
  bottom: -3px;
  left: 0;
  content: "";
}

.ib-fold-contra {
  padding: 0 6px;
  color: var(--color-content-secondary);
  font-size: 12px;
  font-weight: 500;
  text-decoration: underline;
  text-decoration-color: var(--color-border-default);
  text-underline-offset: 3px;
}

.ib-fold-more {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  color: var(--color-content-secondary);
}

.ib-fold-more svg {
  width: 18px;
  height: 18px;
  transition: transform 0.15s;
}

.ib-folded-li.ib-open {
  padding-bottom: 8px;
  border-radius: 8px;
  background: var(--color-surface-contrast);
}

.ib-folded-li.ib-open .ib-fold-more svg {
  transform: rotate(180deg);
}

.ib-fold-english {
  padding: 0 12px 0 calc(var(--number) + var(--number-gap));
  font-size: 15px;
  line-height: 1.38;
}

.ib-fold-contra.ib-pressed,
.ib-fold-more.ib-pressed {
  background: var(--color-surface-contrast);
  color: var(--color-content-base);
}

/* The found button lives on the theme line, on a phone only. */
.ib-found-bar {
  display: none;
}

/* ---------- entry ---------- */

.ib-entry {
  position: relative;
  margin-top: 44px;
  text-align: center;
}

.ib-builder {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 12px;
  min-height: 48px;
  font-size: 28px;
  font-weight: 600;
  line-height: 1.2;
}

.ib-slot {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 84px;
  min-height: 40px;
  padding: 0 4px;
  border: 0;
  border-bottom: 2px solid var(--color-border-default);
  background: none;
  font-weight: 600;
}

.ib-slot-active {
  border-bottom-color: var(--color-highlight-dark);
}

/* A placed term: tapping it takes it back. */
.ib-slot-filled {
  border-bottom-color: transparent;
  cursor: pointer;
}

.ib-slot-filled.ib-pressed {
  opacity: 0.6;
}

.ib-slash {
  color: var(--color-content-secondary);
}

.ib-caret {
  display: inline-block;
  width: 2px;
  height: 1em;
  margin-left: 2px;
  background: var(--color-highlight-dark);
  animation: ib-blink 1s steps(1) infinite;
}

.ib-arrow {
  color: var(--color-content-secondary);
  font-weight: 400;
}

.ib-english {
  min-height: 22px;
  margin-top: 6px;
  font-size: 14px;
  color: var(--color-content-secondary);
}

.ib-shake {
  animation: ib-shake 0.4s;
}

/* Above the builder on a wide screen; over the English line on a phone. */
.ib-toast {
  position: absolute;
  bottom: calc(100% + 4px);
  left: 50%;
  z-index: 2;
  width: max-content;
  max-width: 100%;
  padding: 3px 12px;
  border-radius: 6px;
  font-size: 14px;
  font-weight: 600;
  line-height: 18px;
  transform: translateX(-50%);
  animation: ib-toast-in 0.15s ease-out;
  animation-delay: calc(var(--age, 0ms) * -1);
}

.ib-toast-good {
  background: var(--color-highlight-base);
  color: var(--color-content-base-fixed);
}

.ib-toast-miss {
  background: var(--color-content-base);
  color: var(--color-content-invert);
}

/* True but already counted: a rule or a find typed back. */
.ib-toast-info {
  background: var(--color-surface-contrast);
  color: var(--color-content-base);
}

/* ---------- hive ----------
   Flat-topped hexagons: six around one, each sized by --hex. */

.ib-hive {
  --hex: 104px;
  --hex-h: calc(var(--hex) * 0.866);
  --gap: 6px;
  --step-x: calc(var(--hex) * 0.75 + var(--gap));
  --step-y: calc(var(--hex-h) + var(--gap));
  position: relative;
  width: calc(var(--hex) * 2.5 + var(--gap) * 2);
  height: calc(var(--hex-h) * 3 + var(--gap) * 2);
  margin: 24px auto;
}

.ib-cell {
  position: absolute;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  width: var(--hex);
  height: var(--hex-h);
  padding: 0 14px;
  border: 0;
  background: var(--color-surface-contrast);
  clip-path: polygon(25% 0, 75% 0, 100% 50%, 75% 100%, 25% 100%, 0 50%);
  font-size: 16px;
  font-weight: 600;
  line-height: 1.1;
  cursor: pointer;
  transition: transform 0.08s;
  -webkit-tap-highlight-color: transparent;
}

/* Pressed shows the moment a finger lands. */
.ib-cell:active,
.ib-cell.ib-pressed {
  transform: scale(0.92);
}

.ib-cell:disabled {
  opacity: 0.35;
  cursor: default;
}

.ib-long {
  font-size: 13px;
}

.ib-cell-center {
  top: var(--step-y);
  left: var(--step-x);
  background: var(--color-highlight-base);
  color: var(--color-content-base-fixed);
}

.ib-cell-center.ib-not-on {
  background: var(--color-highlight-dark);
}

.ib-not-mark {
  font-size: 30px;
  line-height: 1;
}

.ib-not-word {
  font-size: 12px;
  font-weight: 500;
}

.ib-cell-top {
  top: 0;
  left: var(--step-x);
}

.ib-cell-bottom {
  top: calc(var(--step-y) * 2);
  left: var(--step-x);
}

.ib-cell-upper-right {
  top: calc(var(--step-y) / 2);
  left: calc(var(--step-x) * 2);
}

.ib-cell-lower-right {
  top: calc(var(--step-y) * 1.5);
  left: calc(var(--step-x) * 2);
}

.ib-cell-upper-left {
  top: calc(var(--step-y) / 2);
  left: 0;
}

.ib-cell-lower-left {
  top: calc(var(--step-y) * 1.5);
  left: 0;
}

.ib-key {
  display: none;
  margin-top: 4px;
  font-size: 11px;
  font-weight: 400;
  color: var(--color-content-secondary);
}

@media (hover: hover) and (pointer: fine) {
  .ib-key {
    display: block;
  }
}

/* ---------- controls ---------- */

.ib-controls {
  display: flex;
  justify-content: center;
  gap: 12px;
}

.ib-control {
  position: relative;
  min-width: 96px;
  padding: 12px 20px;
  border: 1px solid var(--color-border-default);
  border-radius: 999px;
  background: var(--color-surface-base);
  font-weight: 600;
  cursor: pointer;
}

.ib-control:active,
.ib-control.ib-pressed {
  background: var(--color-surface-contrast);
}

/* ---------- score ----------
   One marker carries the score along ticks at 120, 130, ... 180. */

.ib-rank {
  display: flex;
  align-items: center;
  width: 100%;
  padding: 0;
  border: 0;
  background: none;
  text-align: left;
  cursor: pointer;
}

.ib-track {
  --dot: 9px;
  --marker: 30px;
  position: relative;
  display: flex;
  flex: 1;
  align-items: center;
  justify-content: space-between;
  height: 30px;
  margin: 0 16px;
}

.ib-track::before {
  position: absolute;
  top: 50%;
  right: 0;
  left: 0;
  height: 1px;
  background: var(--color-border-default);
  content: "";
}

.ib-dot {
  position: relative;
  width: var(--dot);
  height: var(--dot);
  border-radius: 50%;
  background: var(--color-neutral-light);
}

.ib-dot.ib-last {
  border-radius: 2px;
}

.ib-dot.ib-reached {
  background: var(--color-highlight-base);
}

.ib-marker {
  position: absolute;
  top: 50%;
  left: calc(var(--to) * (100% - var(--dot)) + var(--dot) / 2);
  z-index: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  min-width: 36px;
  height: var(--marker);
  padding: 0 6px;
  border-radius: 999px;
  background: var(--color-highlight-base);
  color: var(--color-content-base-fixed);
  font-size: 12px;
  font-weight: 600;
  transform: translate(-50%, -50%);
}

/* A find slides the marker, then ticks it, or pulses it when the score
   passes a tick. Timed from the find, so redraws carry it on. */
.ib-marker-move.ib-marker-tick {
  animation:
    ib-marker-slide 0.45s ease-out,
    ib-marker-tick 0.3s ease-out 0.4s;
  animation-delay: calc(var(--age, 0ms) * -1), calc(0.4s - var(--age, 0ms));
}

.ib-marker-move.ib-rank-up {
  animation:
    ib-marker-slide 0.45s ease-out,
    ib-marker-pulse 0.5s ease-out 0.4s;
  animation-delay: calc(var(--age, 0ms) * -1), calc(0.4s - var(--age, 0ms));
}

/* ---------- found ---------- */

.ib-found {
  padding: 14px 16px;
  border: 1px solid var(--color-border-default);
  border-radius: 10px;
}

.ib-found-head {
  margin: 0;
  font-family: inherit;
  font-size: 16px;
  font-weight: 600;
}

/* Left to find, by chain length: a row of small stats, not chips. */
.ib-left {
  margin-top: 10px;
}

.ib-left-title {
  display: block;
  margin-bottom: 4px;
  font-size: 12px;
  color: var(--color-content-secondary);
}

.ib-left-stats {
  display: grid;
  grid-auto-columns: minmax(0, 1fr);
  grid-auto-flow: column;
  gap: 8px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.ib-left-stats li {
  display: flex;
  flex-direction: column;
  align-items: center;
  min-width: 0;
}

.ib-left-count {
  font-family: var(--font-serif);
  font-size: 22px;
  font-weight: 600;
  line-height: 1.1;
}

.ib-left-label {
  font-size: 11px;
  color: var(--color-content-secondary);
  white-space: nowrap;
}

.ib-left-done .ib-left-count {
  color: var(--color-content-secondary);
  font-family: inherit;
  font-size: 18px;
  line-height: 24px;
}

/* One find per row under its starting term, which is printed once; the
   arrows line up down the whole list. */
.ib-groups {
  margin: 12px 0 0;
  padding: 0;
  list-style: none;
}

.ib-group {
  display: grid;
  grid-template-columns: var(--if-column, max-content) 18px minmax(0, 1fr);
  column-gap: 6px;
  align-items: baseline;
  padding: 6px 0;
  border-bottom: 1px solid var(--color-border-default);
  font-size: 14px;
  line-height: 22px;
}

.ib-group:last-child {
  border-bottom: 0;
}

.ib-group-if {
  grid-row: 1 / span var(--rows);
  align-self: start;
  font-weight: 700;
  white-space: nowrap;
}

.ib-group-arrow {
  grid-column: 2;
  color: var(--color-content-secondary);
}

.ib-then-text {
  grid-column: 3;
  justify-self: start;
  font-weight: 500;
  white-space: nowrap;
}

.ib-then-full {
  font-weight: 700;
  text-decoration: underline;
  text-decoration-color: var(--color-highlight-base);
  text-decoration-thickness: 3px;
  text-underline-offset: 3px;
}

.ib-then-fresh {
  border-radius: 3px;
  background: var(--color-highlight-base);
  color: var(--color-content-base-fixed);
}

/* Rule hints, off by default. */
.ib-hint-switch {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  margin-top: 14px;
  font-size: 13px;
}

.ib-hint-switch small {
  display: block;
  margin-top: 2px;
  font-size: 12px;
  color: var(--color-content-secondary);
}

.ib-switch {
  position: relative;
  flex: none;
  width: 40px;
  height: 24px;
  padding: 0;
  border: 0;
  border-radius: 999px;
  background: var(--color-neutral-light);
  cursor: pointer;
  transition: background 0.15s;
}

.ib-switch::after {
  position: absolute;
  top: -10px;
  right: -4px;
  bottom: -10px;
  left: -4px;
  content: "";
}

.ib-switch-on {
  background: var(--color-highlight-dark);
}

.ib-switch-knob {
  position: absolute;
  top: 3px;
  left: 3px;
  width: 18px;
  height: 18px;
  border-radius: 50%;
  background: var(--color-surface-base);
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.25);
  transition: transform 0.15s;
}

.ib-switch-on .ib-switch-knob {
  transform: translateX(16px);
}

.ib-found-links {
  display: flex;
  gap: 16px;
  margin-top: 14px;
}

.ib-link {
  padding: 0;
  border: 0;
  background: none;
  font-size: 14px;
  font-weight: 600;
  text-decoration: underline;
  text-underline-offset: 2px;
  cursor: pointer;
}

/* The found list on a phone; never opened on a wide screen. */
.ib-dropdown-backdrop,
.ib-dropdown {
  display: none;
}

/* ---------- sheets ---------- */

.ib-sheet-scroll {
  max-height: 420px;
  overflow: auto;
}

/* In the app the kit centers a sheet in the whole window, header and
   all, so the scrolling part is capped to keep the sheet clear of the
   app's header. */
.gk-window .ib-sheet-scroll {
  max-height: calc(100dvh - 2 * var(--gk-inset-top, 0px) - 200px);
}

.ib-ranks {
  margin: 0;
  padding: 0;
  list-style: none;
}

.ib-ranks li {
  display: flex;
  justify-content: space-between;
  padding: 6px 10px;
  border-radius: 6px;
}

.ib-ranks li span:last-child {
  color: var(--color-content-secondary);
}

.ib-rank-current {
  background: var(--color-highlight-base);
  color: var(--color-content-base-fixed);
  font-weight: 600;
}

.ib-rank-current span:last-child {
  color: inherit;
}

.ib-sheet-note {
  margin-top: 12px;
  font-size: 14px;
  color: var(--color-content-secondary);
}

/* Yesterday's answers: the rules with their lawgic, the full chain, and
   every inference with the terms and rules its chain runs through. */
/* The kit spaces every paragraph in a sheet; this one sets its own. */
.gk-sheet .ib-y-meta,
.gk-sheet .ib-y-rules p,
.gk-sheet .ib-y-chain,
.gk-sheet .ib-y-via {
  margin: 0;
}

.gk-sheet .ib-y-rules p {
  font-size: 14px;
}

.gk-sheet .ib-y-meta {
  margin: 2px 0 12px;
  font-size: 13px;
  color: var(--color-content-secondary);
}

.ib-y-head {
  margin: 18px 0 8px;
  font-family: inherit;
  font-size: 13px;
  font-weight: 600;
  color: var(--color-content-secondary);
}

.ib-y-head:first-child {
  margin-top: 0;
}

.ib-y-rules {
  --number: 22px;
  display: grid;
  gap: 10px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.ib-y-rules li {
  display: grid;
  grid-template-columns: var(--number) minmax(0, 1fr);
  gap: 8px;
  font-size: 14px;
  line-height: 1.4;
}

.gk-sheet .ib-y-lawgic {
  margin-top: 2px;
  font-weight: 600;
}

.ib-y-full + .ib-y-full {
  margin-top: 8px;
}

.gk-sheet .ib-y-chain {
  font-size: 15px;
  font-weight: 600;
  line-height: 1.5;
}

.gk-sheet .ib-y-via {
  font-size: 12px;
  line-height: 16px;
  color: var(--color-content-secondary);
}

.ib-y-groups {
  margin-top: 0;
}

.ib-y-row {
  display: flex;
  flex-direction: column;
  grid-column: 3;
  min-width: 0;
  padding-bottom: 4px;
}

.ib-y-row .ib-then-text {
  justify-self: auto;
}

.ib-share-text {
  width: 100%;
  padding: 10px 12px;
  border: 1px solid var(--color-border-default);
  border-radius: 8px;
  background: var(--color-surface-contrast-50);
  font: inherit;
  font-size: 14px;
  resize: none;
}

/* The 175 and 180 cards: the score in a hex like a hive cell. */
.ib-celebrate .gk-sheet-title {
  margin-top: 14px;
}

.ib-celebrate-hex {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 92px;
  height: 80px;
  background: var(--color-highlight-base);
  clip-path: polygon(25% 0, 75% 0, 100% 50%, 75% 100%, 25% 100%, 0 50%);
  color: var(--color-content-base-fixed);
  font-family: var(--font-serif);
  font-size: 30px;
  font-weight: 600;
  animation: ib-hex-in 0.45s cubic-bezier(0.2, 0.9, 0.3, 1.3);
  animation-delay: calc(var(--age, 0ms) * -1);
}

.ib-celebrate-text {
  margin: 6px 0 16px;
  color: var(--color-content-secondary);
}

/* ======================================================================
   Phones
   ====================================================================== */

@media (max-width: 480px) {
  #game {
    padding: calc(var(--gk-inset-top, 0px) + 6px) 16px calc(var(--gk-inset-bottom, 0px) + 16px);
  }

  /* The top bar: the short date and level, and the score, on one line. */
  .ib-top {
    gap: 14px;
    margin-bottom: 10px;
  }

  .ib-date {
    flex: none;
    flex-direction: column;
    gap: 0;
    line-height: 1.25;
  }

  .ib-day {
    display: none;
  }

  .ib-day-short {
    display: block;
    font-size: 14px;
    font-weight: 600;
  }

  .ib-level {
    font-size: 12px;
  }

  .ib-top-score {
    display: block;
    flex: 1;
    min-width: 0;
  }

  .ib-top-score .ib-track {
    --dot: 7px;
    --marker: 22px;
    height: 24px;
  }

  .ib-top-score .ib-marker {
    min-width: 32px;
  }

  .ib-side-score,
  .ib-layout > .ib-found {
    display: none;
  }

  .ib-layout {
    gap: 12px;
  }

  /* Rules */
  .ib-rules {
    --number: 20px;
    --number-gap: 8px;
  }

  .ib-theme-row {
    margin-bottom: 6px;
  }

  .ib-theme {
    font-size: 13px;
  }

  .ib-rules ol {
    gap: 6px;
  }

  .ib-rules li {
    font-size: 15px;
    line-height: 1.38;
  }

  .ib-rule-number {
    margin-top: 1px;
    font-size: 11px;
  }

  /* A folded line has room for long rules: 14px lawgic, a small link,
     and a chevron drawn 36px wide whose tap area runs into the margin. */
  .ib-fold-line {
    grid-template-columns: var(--number) minmax(0, 1fr) auto 36px;
  }

  .ib-fold-lawgic {
    font-size: 14px;
  }

  .ib-fold-contra {
    padding: 0 4px;
    font-size: 11px;
  }

  .ib-fold-more {
    width: 36px;
  }

  .ib-fold-more::after {
    right: -8px;
  }

  /* The found button: the count, or the newest find for a moment. */
  .ib-found-bar {
    position: relative;
    display: inline-flex;
    flex: none;
    align-items: center;
    gap: 2px;
    height: 28px;
    padding: 0 6px 0 10px;
    border: 1px solid var(--color-border-default);
    border-radius: 999px;
    background: var(--color-surface-base);
    font-size: 13px;
    font-weight: 600;
    cursor: pointer;
  }

  .ib-found-bar::after {
    position: absolute;
    top: -9px;
    right: 0;
    bottom: -9px;
    left: 0;
    content: "";
  }

  .ib-found-bar svg {
    width: 16px;
    height: 16px;
    transition: transform 0.15s;
  }

  .ib-found-bar-open svg {
    transform: rotate(180deg);
  }

  .ib-found-bar-fresh {
    border-color: var(--color-highlight-dark);
    background: var(--color-highlight-base);
    color: var(--color-content-base-fixed);
  }

  .ib-found-bar-full {
    border-color: var(--color-content-base-fixed);
  }

  .ib-found-bar-bump {
    animation: ib-bump 0.35s ease-out;
    animation-delay: calc(var(--age, 0ms) * -1);
  }

  /* Entry: the toast sits over the English line, so no gap is held open. */
  .ib-entry {
    margin-top: 12px;
  }

  .ib-builder {
    min-height: 40px;
    font-size: 24px;
  }

  .ib-slot {
    min-width: 76px;
    min-height: 36px;
  }

  .ib-slot::after {
    position: absolute;
    top: -4px;
    right: 0;
    bottom: -6px;
    left: 0;
    content: "";
  }

  .ib-english {
    margin-top: 4px;
    font-size: 13px;
  }

  .ib-toast {
    top: 44px;
    bottom: auto;
    font-size: 13px;
  }

  /* Hive and buttons. Delete and Enter draw 36px tall; their tap areas
     reach 44px. */
  .ib-hive {
    --hex: 84px;
    margin: 14px auto;
  }

  .ib-cell {
    padding: 0 8px;
    font-size: 15px;
  }

  .ib-cell.ib-long {
    font-size: 12px;
  }

  .ib-controls {
    gap: 16px;
  }

  .ib-control {
    min-width: 80px;
    height: 36px;
    padding: 0 16px;
    font-size: 14px;
  }

  .ib-control::after {
    position: absolute;
    top: -5px;
    right: -4px;
    bottom: -5px;
    left: -4px;
    content: "";
  }

  /* The found list drops from its button and may run over the hive. */
  .ib-dropdown-backdrop {
    position: fixed;
    inset: 0;
    z-index: 20;
    display: block;
  }

  .ib-dropdown {
    position: fixed;
    z-index: 21;
    display: block;
    width: min(340px, calc(100vw - 16px));
    overflow: auto;
    padding: 14px 16px 16px;
    border: 1px solid var(--color-border-default);
    border-radius: 12px;
    background: var(--color-surface-base);
    box-shadow: 0 10px 28px rgba(0, 0, 0, 0.18);
    transform-origin: top right;
    animation: ib-drop 0.18s ease-out;
    animation-delay: calc(var(--age, 0ms) * -1);
  }

  .ib-dropdown .ib-found {
    padding: 0;
    border: 0;
  }
}

@media (max-width: 360px) {
  .ib-hive {
    --hex: 80px;
  }
}

/* ======================================================================
   The app on a phone: only the rules scroll
   ====================================================================== */

@media (max-width: 480px) {
  .gk-window,
  .gk-window body {
    height: 100%;
    overflow: hidden;
  }

  .gk-window #game {
    display: flex;
    flex-direction: column;
    height: 100dvh;
    padding-bottom: 0;
  }

  .gk-window .ib-top,
  .gk-window .ib-layout > * {
    flex: none;
  }

  .gk-window .ib-layout,
  .gk-window .ib-layout > .ib-play {
    display: flex;
    flex: 1;
    flex-direction: column;
    gap: 0;
    min-height: 0;
  }

  /* The one scrolling area, edge to edge so a thumb can scroll it from
     anywhere across the screen. */
  .gk-window .ib-rules {
    flex: 1;
    min-height: 0;
    margin: 0 -16px;
    padding: 0 16px 12px;
    overflow-y: auto;
    overscroll-behavior: contain;
  }

  /* The theme line and the found button stay at the top of the rules. The
     button sits at the scroll area's clipped edge, so it is drawn taller
     and its row gives it the rest of its 44px. */
  .gk-window .ib-theme-row {
    position: sticky;
    top: 0;
    z-index: 1;
    margin-bottom: 0;
    padding: 4px 0 6px;
    background: var(--color-surface-base);
  }

  /* A hint bubble sits 6px above its rule number, so with hints on the
     list starts 6px lower and the first bubble clears the theme row. */
  .gk-window .ib-rules ol:has(.ib-rule-left) {
    padding-top: 6px;
  }

  .gk-window .ib-found-bar {
    height: 34px;
  }

  .gk-window .ib-found-bar::after {
    top: -5px;
    bottom: -7px;
  }

  /* The bottom area: entry, hive and buttons, pinned and tight. */
  .gk-window .ib-dock {
    flex: none;
    margin: 0 -16px;
    padding: 8px 16px calc(var(--gk-inset-bottom, 0px) + 6px);
    border-top: 1px solid var(--color-border-default);
    background: var(--color-surface-base);
    box-shadow: 0 -8px 12px -10px rgba(0, 0, 0, 0.25);
  }

  .gk-window .ib-entry {
    margin-top: 0;
  }

  .gk-window .ib-builder {
    min-height: 36px;
  }

  .gk-window .ib-english {
    min-height: 18px;
    margin-top: 2px;
    line-height: 18px;
  }

  .gk-window .ib-hive {
    margin: 4px auto 6px;
  }

  .gk-window .ib-toast {
    top: 35px;
  }
}

/* ---------- motion ---------- */

@keyframes ib-blink {
  50% {
    opacity: 0;
  }
}

@keyframes ib-shake {
  20%,
  60% {
    transform: translateX(-8px);
  }
  40%,
  80% {
    transform: translateX(8px);
  }
}

@keyframes ib-toast-in {
  from {
    opacity: 0;
    transform: translate(-50%, 4px);
  }
}

@keyframes ib-fold-in {
  from {
    transform: scale(0.9);
    opacity: 0;
  }
}

@keyframes ib-bump {
  40% {
    transform: scale(1.08);
  }
}

@keyframes ib-marker-slide {
  from {
    left: calc(var(--from) * (100% - var(--dot)) + var(--dot) / 2);
  }
}

@keyframes ib-marker-tick {
  40% {
    transform: translate(-50%, -50%) scale(1.15);
  }
}

@keyframes ib-marker-pulse {
  40% {
    transform: translate(-50%, -50%) scale(1.3);
    box-shadow: 0 0 0 6px color-mix(in srgb, var(--color-highlight-base) 45%, transparent);
  }
}

@keyframes ib-drop {
  from {
    opacity: 0;
    transform: translateY(-8px) scale(0.97);
  }
}

@keyframes ib-hex-in {
  from {
    transform: scale(0.5) rotate(-30deg);
    opacity: 0;
  }
}
