/* The Emote Wheel — a carved wooden field-guide dial, not a Fortnite wheel.
 *
 * Design law (research/menu-design-rehaul.md): moss and brass, three flat
 * surface steps doing the work borders used to do, ONE brass hairline on the
 * outer edge (nesting depth of bordered boxes: 1), a hard 11px type floor, one
 * gold CTA per screen (here: the editor's Done), selection is 2px cream and the
 * one glowing element.
 *
 * The dial earns "carved wooden" from three things, none of them a border: a
 * wood rim ring, eight engraved tick marks on the wedge boundaries, and the
 * game's own carved-token recipe on the chips (moss gradient over a hard
 * `0 3px 0` shadow — the same shape #topbtns .btn already uses, which is what
 * makes the wheel read as Worldhopper chrome rather than a generic radial).
 *
 * Tokens come from game-ui.css :root.
 */

#emotewheel[hidden] { display: none !important; }

#emotewheel {
  position: fixed;
  inset: 0;
  /* Above the persistent HUD/chat/tap-menu tier, below the takeovers that must
   * win: #postcard and #fade (40), #cloudflight (45), #bootveil (60). */
  z-index: 39;
  color: var(--ui-ink);
  font-family: var(--font-body);
  -webkit-user-select: none;
  user-select: none;
  touch-action: none;
}

.ew-veil {
  position: absolute;
  inset: 0;
  background: rgba(2, 7, 4, .42);
}

#emotewheel.ew-editing .ew-veil { background: rgba(2, 7, 4, .62); }

/* Screen-reader status. Never given a visual home: the hub already says it. */
.ew-live {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
}

/* ---- the dial ---------------------------------------------------------- */

/* 20px is the dial's own rim allowance and it is load-bearing in two places:
 * this width formula and DIAL_RIM in emote-wheel.js, which is what keeps the
 * clamp from letting the rim hang off a 390pt screen. Change both together. */
.ew-dial {
  --ew-radius: 128px;
  --ew-slot: 56px;
  --ew-dead: 34px;
  position: absolute;
  left: 50%;
  top: 50%;
  width: calc((var(--ew-radius) + var(--ew-slot) / 2 + 20px) * 2);
  height: calc((var(--ew-radius) + var(--ew-slot) / 2 + 20px) * 2);
  transform: translate(-50%, -50%);
  border-radius: 50%;
  /* OPAQUE. A translucent dial let the world's name plates and lamp posts ghost
   * through the middle of the menu, which read as a rendering fault. The veil
   * is what dims the world; the dial is furniture sitting on top of it. */
  background:
    /* the medallion seat: a groove the hub sits down into, ringed just outside
     * the hub's own radius (--ew-dead + 22px) so it reads as a halo, not a lid */
    radial-gradient(circle closest-side at 50% 50%,
      transparent 0 calc(var(--ew-dead) + 26px),
      rgba(4, 10, 6, .6) calc(var(--ew-dead) + 26px) calc(var(--ew-dead) + 27.5px),
      transparent calc(var(--ew-dead) + 27.5px)),
    /* the carved wood rim */
    radial-gradient(circle closest-side at 50% 50%,
      transparent 0 calc(100% - 13px),
      var(--ui-wood) calc(100% - 13px),
      #2b1e13 calc(100% - 4px),
      #1a1109 100%),
    /* the moss face, lit from just above centre */
    radial-gradient(circle at 50% 34%, var(--ui-moss-3), var(--ui-moss-0) 78%);
  border: 1px solid var(--ui-hairline);
  box-shadow: 0 14px 44px rgba(0, 0, 0, .48);
}

/* Eight engraved ticks, one on each wedge boundary, masked to a band just
 * inside the rim. This is the whole reason the surface reads as a DIAL: it
 * shows you the eight wedges without drawing eight boxes. If mask-image is
 * unavailable the ticks simply become full spokes, which still reads. */
.ew-dial::before {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: 50%;
  pointer-events: none;
  background: repeating-conic-gradient(from 22.2deg at 50% 50%,
    rgba(242, 230, 189, .18) 0deg .7deg, transparent .7deg 45deg);
  -webkit-mask-image: radial-gradient(circle closest-side at 50% 50%,
    transparent calc(100% - 32px), #000 calc(100% - 28px),
    #000 calc(100% - 17px), transparent calc(100% - 14px));
  mask-image: radial-gradient(circle closest-side at 50% 50%,
    transparent calc(100% - 32px), #000 calc(100% - 28px),
    #000 calc(100% - 17px), transparent calc(100% - 14px));
}

#emotewheel.ew-editing .ew-dial { display: none; }

.ew-ring {
  position: absolute;
  inset: 0;
  pointer-events: none;
  outline: none;
}

/* ---- the lit wedge ------------------------------------------------------ */

/* On a dial the DIRECTION is the selection, so the whole wedge lights, hub to
 * rim, and swings with the pointer. The chip says WHAT; this says WHICH WAY,
 * which is the half an eyes-free flick actually relies on.
 *
 * A rim needle was tried first and does not fit: a chip's far corner reaches
 * within 2px of the rim on the four diagonals, so any marker outside the ring
 * is occluded exactly half the time. A sector has no such geometry to lose.
 *
 * `from -22.5deg` centres the 45deg sector on straight up, which is slot 0, so
 * --ew-aim can just be the slot's own centre angle. */
.ew-aim {
  position: absolute;
  inset: 0;
  border-radius: 50%;
  opacity: 0;
  pointer-events: none;
  background: conic-gradient(from -22.5deg at 50% 50%,
    transparent 0deg, rgba(242, 230, 189, .14) 9deg 36deg,
    transparent 45deg 360deg);
  -webkit-mask-image: radial-gradient(circle closest-side at 50% 50%,
    transparent calc(var(--ew-dead) + 22px), #000 calc(var(--ew-dead) + 48px),
    #000 calc(100% - 15px), transparent calc(100% - 13px));
  mask-image: radial-gradient(circle closest-side at 50% 50%,
    transparent calc(var(--ew-dead) + 22px), #000 calc(var(--ew-dead) + 48px),
    #000 calc(100% - 15px), transparent calc(100% - 13px));
  transform: rotate(var(--ew-aim, 0deg));
  transition: transform .11s ease-out, opacity .11s linear;
}

#emotewheel.ew-aimed .ew-aim { opacity: 1; }

/* ---- slots ------------------------------------------------------------- */

.ew-slot[hidden] { display: none; }

/* The chip is the game's carved token: moss gradient, one hard shadow beneath,
 * no border. The label lives INSIDE the chip box (it used to hang off a 56px
 * circle, which read as an overflow bug on the two long labels). */
.ew-slot {
  position: absolute;
  left: 50%;
  top: 50%;
  width: calc(var(--ew-slot) + 18px);
  height: var(--ew-slot);
  margin: 0;
  padding: 0;
  box-sizing: border-box;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 1px;
  pointer-events: auto;
  cursor: pointer;
  color: var(--ui-ink);
  background: linear-gradient(160deg, var(--ui-moss-3), var(--ui-moss-1));
  border: 0;
  border-radius: 12px;
  box-shadow: 0 3px 0 rgba(4, 9, 6, .72);
  transform: translate(-50%, -50%) translate(var(--ew-x, 0), var(--ew-y, 0));
  transition: background .12s ease, box-shadow .12s ease, filter .12s ease;
}

.ew-slot-glyph {
  font-size: 26px;
  line-height: 1;
}

.ew-slot-label {
  max-width: calc(var(--ew-slot) + 8px);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  color: var(--ui-muted);
  font: 600 11px/1.2 var(--font-body);
}

/* Selection is 2px cream per the law, and it is the screen's one glow. */
.ew-slot.is-active {
  background: linear-gradient(160deg, #2d533d, var(--ui-moss-3));
  box-shadow: 0 0 0 2px var(--ui-ink), 0 0 16px rgba(242, 230, 189, .32), 0 3px 0 rgba(4, 9, 6, .72);
  filter: brightness(1.06);
}

.ew-slot.is-active .ew-slot-label { color: var(--ui-ink); }

/* ---- hub --------------------------------------------------------------- */

/* A round medallion seated in the dial's groove, not a floating pill. */
.ew-hub {
  position: absolute;
  left: 50%;
  top: 50%;
  width: calc(var(--ew-dead) * 2 + 44px);
  height: calc(var(--ew-dead) * 2 + 44px);
  padding: 4px;
  box-sizing: border-box;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 2px;
  text-align: center;
  background: radial-gradient(circle at 50% 32%, var(--ui-panel), var(--ui-moss-0) 84%);
  border-radius: 50%;
  transform: translate(-50%, -50%);
  box-shadow: 0 4px 12px rgba(0, 0, 0, .5);
}

/* Ligatures OFF on every display-face string in this sheet. The Pixelify Sans
 * subset ships broken "fi"/"fl"/"ff" ligature glyphs, so "High five" — an
 * actual slot label — renders as "High Ave". This is not local to the wheel;
 * any --font-display string in the game with those pairs is affected. */
.ew-hub-title {
  max-width: 82%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font: 700 15px/1.1 var(--font-display, var(--font-body));
  font-variant-ligatures: none;
  color: var(--ui-ink);
}

.ew-hub-target[hidden] { display: none; }

/* "at <Name>" is what turns a performance into an address. The name arrives via
 * textContent only — it is user-controlled text. */
.ew-hub-target {
  max-width: 82%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  color: var(--ui-brass);
  font: 700 11px/1.3 var(--font-body);
}

.ew-hub-edit {
  margin: 1px 0 0;
  padding: 3px 9px;
  color: var(--ui-muted);
  background: transparent;
  border: 0;
  border-radius: 999px;
  cursor: pointer;
  font: 600 11px/1.3 var(--font-body);
}

.ew-hub-edit:hover { color: var(--ui-ink); background: rgba(242, 230, 189, .08); }

/* During a hold gesture the hub is a cancel zone, not a button: releasing over
 * it must cancel, never open the editor. */
#emotewheel.ew-hold .ew-hub-edit { pointer-events: none; opacity: .5; }

/* ---- open animation ---------------------------------------------------- */

#emotewheel.ew-open .ew-dial { animation: ew-dial-in .16s ease-out both; }
#emotewheel.ew-open .ew-slot { animation: ew-slot-in .17s ease-out both; }

@keyframes ew-dial-in {
  from { opacity: 0; transform: translate(-50%, -50%) scale(.9); }
  to { opacity: 1; transform: translate(-50%, -50%) scale(1); }
}

@keyframes ew-slot-in {
  from { opacity: 0; transform: translate(-50%, -50%) translate(calc(var(--ew-x, 0) * .6), calc(var(--ew-y, 0) * .6)); }
  to { opacity: 1; transform: translate(-50%, -50%) translate(var(--ew-x, 0), var(--ew-y, 0)); }
}

/* No spin-in, just a fade. Honours the module's reducedMotion() as well as the
 * media query, because the game exposes its own motion setting. */
#emotewheel.ew-reduced .ew-dial,
#emotewheel.ew-reduced .ew-slot { animation: ew-fade-in .12s linear both; }
#emotewheel.ew-reduced .ew-aim { transition: opacity .11s linear; }

@media (prefers-reduced-motion: reduce) {
  #emotewheel .ew-dial,
  #emotewheel .ew-slot { animation: ew-fade-in .12s linear both; }
  .ew-slot { transition: none; }
  .ew-aim { transition: opacity .11s linear; }
}

@keyframes ew-fade-in {
  from { opacity: 0; }
  to { opacity: 1; }
}

/* ---- loadout editor ---------------------------------------------------- */

.ew-editor[hidden] { display: none; }

.ew-editor {
  position: absolute;
  left: 50%;
  top: 50%;
  width: min(520px, calc(100vw - 28px));
  max-height: min(78dvh, 660px);
  padding: 16px;
  box-sizing: border-box;
  overflow-y: auto;
  overscroll-behavior: contain;
  display: flex;
  flex-direction: column;
  gap: 12px;
  transform: translate(-50%, -50%);
  background: var(--ui-panel);
  border: 1px solid var(--ui-hairline);
  border-radius: 14px;
  box-shadow: 0 14px 44px rgba(0, 0, 0, .48);
}

.ew-editor-title {
  margin: 0;
  font: 700 20px/1.2 var(--font-display, var(--font-body));
  font-variant-ligatures: none;
  color: var(--ui-ink);
}

.ew-editor-note {
  margin: -6px 0 0;
  color: var(--ui-muted);
  font: 500 13px/1.5 var(--font-body);
}

.ew-editor-slots {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 8px;
}

.ew-editor-slot {
  min-height: 62px;
  padding: 6px 4px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 2px;
  cursor: pointer;
  color: var(--ui-ink);
  background: linear-gradient(160deg, var(--ui-moss-3), var(--ui-moss-1));
  border: 0;
  border-radius: 10px;
  box-shadow: 0 3px 0 rgba(4, 9, 6, .72);
  font: inherit;
}

.ew-editor-slot.is-picked {
  box-shadow: 0 0 0 2px var(--ui-ink), 0 3px 0 rgba(4, 9, 6, .72);
}

.ew-editor-slot-num {
  color: var(--ui-brass);
  font: 700 11px/1.2 var(--font-body);
  font-variant-numeric: tabular-nums;
}

.ew-editor-slot-glyph { font-size: 22px; line-height: 1; }

.ew-editor-slot-label {
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  color: var(--ui-muted);
  font: 600 11px/1.2 var(--font-body);
}

/* The second half of "pick a slot, then pick an emote" needs a name, or the
 * list below reads as decoration rather than the other half of the sentence. */
.ew-editor-kicker {
  margin: 2px 0 -6px;
  color: var(--ui-brass);
  font: 700 11px/1.3 var(--font-body);
  letter-spacing: .06em;
  text-transform: uppercase;
}

.ew-editor-library {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(148px, 1fr));
  gap: 4px 6px;
}

.ew-editor-item {
  min-height: 44px;
  padding: 7px 10px;
  display: grid;
  grid-template-columns: 26px minmax(0, 1fr) auto;
  grid-template-rows: auto auto;
  /* Top-aligned, not centre-aligned: a two-line hint used to shove its glyph
   * and label out of line with everything else in the same row. */
  align-items: start;
  align-content: start;
  gap: 0 8px;
  text-align: left;
  cursor: pointer;
  color: var(--ui-ink);
  background: transparent;
  border: 0;
  border-radius: 10px;
  font: inherit;
}

.ew-editor-item:hover { background: var(--ui-raised); }

.ew-editor-item-glyph {
  grid-column: 1;
  grid-row: 1 / span 2;
  align-self: center;
  font-size: 22px;
  line-height: 1;
}

.ew-editor-item-label {
  grid-column: 2;
  grid-row: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font: 600 13px/1.4 var(--font-body);
}

/* Which of the eight this one already holds. Its own column, so the ellipsis
 * can never eat it. */
.ew-editor-item-slot {
  grid-column: 3;
  grid-row: 1;
  align-self: center;
  min-width: 19px;
  padding: 1px 5px;
  box-sizing: border-box;
  color: var(--ui-brass);
  background: var(--ui-moss-0);
  border-radius: 999px;
  text-align: center;
  font: 700 11px/1.5 var(--font-body);
  font-variant-numeric: tabular-nums;
}

/* One line, always. Ragged two-line hints made every row in the grid a
 * different height and the whole library looked like a mis-render. */
.ew-editor-item-hint {
  grid-column: 2 / span 2;
  grid-row: 2;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  color: var(--ui-muted);
  font: 500 12px/1.35 var(--font-body);
}

/* An emote already in the eight reads as spoken-for, without a border. */
.ew-editor-item.is-slotted .ew-editor-item-label { color: var(--ui-brass); }

/* The one gold CTA on this screen — and it is sticky at EVERY width, because
 * the library is taller than the sheet on a desktop too and a CTA you have to
 * scroll to find is a CTA in the wrong place. A solid panel band first so
 * nothing scrolls out from behind it, then a soft fade so the list runs under. */
.ew-editor-done {
  position: sticky;
  bottom: 0;
  align-self: flex-end;
  min-height: 40px;
  padding: 0 20px;
  cursor: pointer;
  color: #22170e;
  background: linear-gradient(180deg, #f1d27d, #c99443);
  border: 0;
  border-radius: 999px;
  font: 700 13px/1 var(--font-body);
  letter-spacing: .02em;
  box-shadow: 0 0 0 16px var(--ui-panel), 0 -18px 18px 16px var(--ui-panel);
}

.ew-editor-done:active { transform: translateY(2px); }

/* ---- coarse pointers ---------------------------------------------------- */

/* On a phone the wedge angle is fixed by the slot count, so a bigger ring is
 * the only way to a 44x44 target. The JS supplies the radius; this keeps the
 * type above the 12px mobile floor to match. */
#emotewheel.ew-coarse .ew-slot-glyph { font-size: 28px; }
#emotewheel.ew-coarse .ew-slot-label { font-size: 12px; }
#emotewheel.ew-coarse .ew-hub-edit { padding: 6px 12px; font-size: 12px; }

@media (max-width: 560px) {
  .ew-editor {
    top: auto;
    bottom: 0;
    width: 100%;
    max-height: 82dvh;
    border-radius: 14px 14px 0 0;
    transform: translate(-50%, 0);
    padding-bottom: calc(16px + env(safe-area-inset-bottom, 0px));
  }

  .ew-editor-note { font-size: 15px; }
  .ew-editor-item-label { font-size: 15px; }
  .ew-editor-item-hint { font-size: 12.5px; }

  .ew-editor-done {
    align-self: stretch;
    min-height: 48px;
  }
}
