/* ============================================================
   WHEEL

   Ported from the approved mockup. Only what is specific to the wheel lives
   here: the buttons are juq.css's .btn, the segmented controls are system.css's
   .u-seg, the scrollbar is the site's, and the panel a title opens into is
   requests.css's - loaded alongside this file, not copied into it.

   THE LAYOUT IS THE REDESIGN. v1 put both modes under one header, so you were
   always looking at controls for the mode you were not in, and the library sat
   as a strip that pushed the wheel down the page. Here the mode is the first
   and biggest choice, the control row underneath belongs only to that mode, and
   choosing a saved wheel is a MOMENT rather than a permanent panel, so the
   library opens over the page and closes once you have picked.
   ============================================================ */

/* ---------- mode, the first choice ----------
   Movies, Games and Custom change what every other control means. */
.wh-modes { display: flex; margin: var(--s-7) 0 var(--s-5); border: var(--bw) solid var(--ink); border-radius: var(--radius); overflow: hidden; }
.wh-modes button {
  flex: 1; display: flex; align-items: center; justify-content: center; gap: var(--s-3);
  font-size: var(--t-h3); font-weight: 700; padding: var(--s-5) var(--s-6); cursor: pointer;
  background: var(--surface); color: var(--muted); border: 0; border-right: var(--bw) solid var(--ink);
}
.wh-modes button:last-child { border-right: 0; }
.wh-modes button[aria-selected="true"] { background: var(--accent); color: var(--accent-ink); }

/* One row, and its mode-specific half only ever holds controls for the mode you
   are in. It lives INSIDE the wheel column rather than across the page, because
   a full-width row that only fills half its width leaves a hole beside it: the
   list starts level with these controls and ends level with the button.

   THE [hidden] RULES ARE LOAD-BEARING. `display: flex` on a class beats the
   browser's own `[hidden] { display: none }`, so every row that swaps by mode
   has to turn itself off explicitly - otherwise the attribute is set, the
   element stays on screen, and you get both modes' controls at once. */
.wh-ctl { display: flex; align-items: center; gap: var(--s-5); flex-wrap: wrap; width: 100%; }
.wh-ctl-mode { display: flex; align-items: center; gap: var(--s-5); flex-wrap: wrap; }
.wh-ctl-mode[hidden], .wh-loaded[hidden], .wh-empty[hidden] { display: none; }

/* A lone toggle. One button wide, so it is a .u-seg of one rather than a
   component of its own. */
.wh-tog {
  font-family: var(--f-mono); font-size: var(--t-label); letter-spacing: 0.1em; text-transform: uppercase;
  padding: var(--s-3) var(--s-5); cursor: pointer;
  border: var(--bw) solid var(--line-strong); border-radius: var(--radius);
  background: var(--surface); color: var(--muted);
}
.wh-tog:hover { border-color: var(--accent); color: var(--ink); }
.wh-tog.on { background: var(--accent); border-color: var(--accent); color: var(--accent-ink); }

/* ---------- the loaded wheel ---------- */
.wh-loaded {
  display: flex; align-items: center; gap: var(--s-4); flex-wrap: wrap; width: 100%;
  padding: var(--s-4) var(--s-5);
  border: var(--bw) solid var(--line-strong); border-radius: var(--radius); background: var(--surface);
}
.wh-loaded b { font-size: var(--t-md); }
.wh-loaded .by { font-family: var(--f-mono); font-size: var(--t-micro); color: var(--muted); }
.wh-loaded .spacer { flex: 1; }

/* ---------- the stage ----------
   Wheel and slice list side by side, both always visible: the wheel is what the
   page is for, and the list is how you read the slivers it cannot label. */
.wh-stage { display: grid; grid-template-columns: minmax(320px, 1fr) 340px; gap: var(--s-8); align-items: stretch; padding-bottom: var(--s-11); }
.wh-left { display: flex; flex-direction: column; align-items: center; gap: var(--s-6); }
.wh-wrap { position: relative; width: 100%; max-width: 460px; aspect-ratio: 1; }
.wh-wrap canvas { width: 100%; height: 100%; display: block; }
.wh-point {
  position: absolute; top: -2px; left: 50%; transform: translateX(-50%);
  width: 0; height: 0; z-index: 2;
  border-left: 13px solid transparent; border-right: 13px solid transparent;
  border-top: 22px solid var(--accent);
  filter: drop-shadow(0 2px 0 var(--ink));
}

/* The label a slice is too thin to carry. Follows the cursor, never takes a
   pointer event, and is why a sliver does not need text painted on it. */
.wh-tip {
  position: absolute; z-index: 3; pointer-events: none; transform: translate(-50%, -150%);
  padding: var(--s-2) var(--s-4);
  border: var(--bw) solid var(--ink); border-radius: var(--radius);
  background: var(--surface); color: var(--ink);
  font-size: var(--t-sm); white-space: nowrap; max-width: 280px; overflow: hidden; text-overflow: ellipsis;
  box-shadow: 0 4px 14px rgba(0, 0, 0, 0.35);
}
.wh-tip span { font-family: var(--f-mono); font-size: var(--t-micro); color: var(--muted); margin-left: var(--s-3); }

/* Custom mode with nothing loaded. Sits ON the empty wheel rather than beside
   it, because the empty wheel is the thing being explained. */
.wh-empty {
  position: absolute; inset: 0; z-index: 2;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: var(--s-4);
  text-align: center; padding: var(--s-7);
}
.wh-empty p { margin: 0; color: var(--muted); font-size: var(--t-md); max-width: 30ch; }

/* Size only. Everything else is .btn, so the biggest button on the site is the
   same button as every other one. */
.wh-spin { width: 100%; max-width: 240px; justify-content: center; padding: var(--s-4) var(--s-6); font-size: var(--t-h3); }
/* .btn is inline-flex, which beats the browser's own [hidden] rule. Nothing to
   spin means no Spin button at all. */
.wh-spin[hidden] { display: none; }
/* The disabled treatment that used to live here is now .btn:disabled in
   patch.css, unchanged, because three pages had each written their own. */

/* The panel is absolutely positioned inside its grid cell, which is the whole
   trick: an absolute child contributes NOTHING to the row's height, so the row
   is measured from the wheel column alone and the panel is then stretched to
   exactly that. Top edge level with the controls, bottom edge level with the
   button, whatever the list happens to contain. */
.wh-side { position: relative; }
.wh-side-in {
  position: absolute; inset: 0; display: flex; flex-direction: column; overflow: hidden;
  border: var(--bw) solid var(--line-strong); border-radius: var(--radius); background: var(--surface);
}
.wh-side-h { display: flex; align-items: baseline; gap: var(--s-3); flex-wrap: wrap; padding: var(--s-5); border-bottom: var(--bw) solid var(--line); }
.wh-side-h b { font-size: var(--t-md); }
.wh-list { flex: 1; min-height: 0; overflow-y: auto; overscroll-behavior: contain; }

.wh-row {
  display: flex; align-items: center; gap: var(--s-4); width: 100%; text-align: left;
  font: inherit; color: inherit; background: transparent;
  padding: var(--s-4) var(--s-5); border: 0; border-bottom: 1px solid var(--line); font-size: var(--t-sm);
}
.wh-row:last-child { border-bottom: 0; }
.wh-row:nth-child(even) { background: var(--surface-2); }
.wh-row .sw { width: 10px; height: 10px; flex: none; border-radius: 2px; }
.wh-row .sw[data-special] { background: var(--accent); }
.wh-row .nm { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.wh-row .pc { font-family: var(--f-mono); font-size: var(--t-micro); color: var(--muted); font-variant-numeric: tabular-nums; }
/* Hovering either the row or its slice lights up both, so the list and the
   wheel are always talking about the same thing. */
.wh-row.hot { background: var(--accent-soft); }
button.wh-row { cursor: pointer; }
button.wh-row .nm { text-decoration: underline; text-decoration-color: transparent; text-underline-offset: 3px; }
button.wh-row.hot .nm { text-decoration-color: var(--accent); }
.wh-row.win, .wh-row.win.hot { background: var(--accent); color: var(--accent-ink); }
.wh-row.win .pc { color: var(--accent-ink); }

/* ---------- the library, as an overlay ----------
   Picking a wheel is a moment, not a panel you live with. 85 is the site's
   modal layer, above .fx. */
.wh-lib { position: fixed; inset: 0; z-index: 85; background: rgba(0, 0, 0, 0.72); display: grid; justify-items: center; align-items: start; padding: 7vh var(--s-7) var(--s-7); overflow-y: auto; }
.wh-lib[hidden] { display: none; }
.wh-lib-box { width: min(920px, 100%); border: var(--bw) solid var(--ink); border-radius: var(--radius); background: var(--surface); }
.wh-lib-h { display: flex; align-items: center; gap: var(--s-4); flex-wrap: wrap; padding: var(--s-6); border-bottom: var(--bw) solid var(--line); }
.wh-lib-h .spacer { flex: 1; }
.wh-lib-x { background: transparent; border: 0; color: var(--muted); font-size: var(--t-h2); line-height: 1; cursor: pointer; padding: 0 var(--s-2); }
.wh-lib-x:hover { color: var(--accent); }
.wh-lib-grid { display: grid; gap: var(--s-5); grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); padding: var(--s-6); }
.wh-card {
  display: flex; flex-direction: column; gap: var(--s-3); text-align: left;
  padding: var(--s-5); cursor: pointer; font: inherit; color: inherit;
  border: var(--bw) solid var(--line-strong); border-radius: var(--radius); background: var(--surface-2);
}
.wh-card:hover { border-color: var(--accent); }
.wh-card b { font-size: var(--t-body); }
.wh-card .meta { display: flex; gap: var(--s-3); flex-wrap: wrap; font-family: var(--f-mono); font-size: var(--t-micro); color: var(--muted); }
.wh-card .prev { display: flex; gap: var(--s-2); flex-wrap: wrap; }
.wh-card .prev span { font-family: var(--f-mono); font-size: var(--t-micro); padding: 1px var(--s-2); border: 1px solid var(--line-strong); border-radius: var(--radius); color: var(--muted); }
.wh-card .prev span.more { border-style: dashed; }

/* ============================================================ BUILDER
   A sheet over the page, not a second page: saving drops you straight onto the
   wheel you just built, which is the whole reason to build one. */
.wh-build { position: fixed; inset: 0; z-index: 85; background: rgba(0, 0, 0, 0.72); display: grid; justify-items: center; align-items: start; padding: 5vh var(--s-7) var(--s-7); overflow-y: auto; }
.wh-build[hidden] { display: none; }
.wh-build-box { width: min(980px, 100%); border: var(--bw) solid var(--ink); border-radius: var(--radius); background: var(--surface); }
.wh-build-h { display: flex; align-items: center; gap: var(--s-4); padding: var(--s-6) var(--s-7); border-bottom: var(--bw) solid var(--line); }
.wh-build-h b { font-size: var(--t-h3); }
.wh-build-h .spacer { flex: 1; }
/* The preview stays put while the slice list scrolls past it: you are shaping
   the thing on the right, so it should not scroll away from you. */
.wh-build-body { display: grid; grid-template-columns: 1fr 280px; gap: var(--s-7); padding: var(--s-7); align-items: start; }
.wh-build-main { display: flex; flex-direction: column; gap: var(--s-7); min-width: 0; }
.wh-build-side { position: sticky; top: var(--s-5); display: flex; flex-direction: column; gap: var(--s-4); }
.wh-build-actions { display: flex; gap: var(--s-5); flex-wrap: wrap; }
.wh-preview { width: 100%; aspect-ratio: 1; }
.wh-preview canvas { width: 100%; height: 100%; display: block; }
.wh-danger { color: var(--accent); }

.wh-field { display: flex; flex-direction: column; gap: var(--s-3); align-items: flex-start; }
.wh-field .u-note { margin: 0; }
.wh-input {
  width: 100%; font: inherit; font-size: var(--t-md);
  padding: var(--s-4) var(--s-5);
  border: var(--bw) solid var(--line-strong); border-radius: var(--radius);
  background: var(--surface-2); color: var(--ink);
}
.wh-input:focus-visible { outline: var(--bw) solid var(--accent); outline-offset: 2px; }

.wh-slices-h { display: flex; align-items: center; gap: var(--s-4); width: 100%; }
.wh-slices-h .spacer { flex: 1; }
.wh-slices { display: flex; flex-direction: column; gap: var(--s-3); width: 100%; }
.wh-adds { display: flex; gap: var(--s-3); flex-wrap: wrap; }

/* One slice. The colour chip is the same hue the wheel will paint it, so the
   row and the slice are findable from each other. */
.wh-slice { position: relative; display: flex; align-items: center; gap: var(--s-3); }
.wh-slice .sw { width: 10px; height: 10px; flex: none; border-radius: 2px; }
.wh-slice .lbl { flex: 1; min-width: 0; }
.wh-slice .wt { width: 58px; flex: none; text-align: center; font-family: var(--f-mono); }
.wh-slice .cover { width: 26px; height: 36px; flex: none; object-fit: cover; border-radius: var(--radius); }
.wh-slice-btn {
  flex: none; cursor: pointer; font-family: var(--f-mono); font-size: var(--t-label);
  padding: var(--s-4) var(--s-4); line-height: 1;
  border: var(--bw) solid var(--line-strong); border-radius: var(--radius);
  background: var(--surface-2); color: var(--muted);
}
.wh-slice-btn:hover { border-color: var(--accent); color: var(--accent); }
.wh-slice-btn:disabled { opacity: 0.4; cursor: default; }
.wh-slice .special-tag {
  flex: 1; min-width: 0; font-family: var(--f-mono); font-size: var(--t-sm);
  padding: var(--s-4) var(--s-5);
  border: var(--bw) dashed var(--line-strong); border-radius: var(--radius); color: var(--muted);
}

/* The per-slice title lookup. Anchored to the row it belongs to, and only one
   is ever open. */
.wh-sug {
  position: absolute; top: calc(100% + var(--s-2)); left: 0; right: 0; z-index: 20;
  max-height: 260px; overflow-y: auto;
  border: var(--bw) solid var(--ink); border-radius: var(--radius); background: var(--surface);
}
.wh-sug[hidden] { display: none; }
.wh-sug-row { display: flex; align-items: center; gap: var(--s-4); width: 100%; text-align: left; cursor: pointer; font: inherit; color: inherit; padding: var(--s-3) var(--s-4); border: 0; border-bottom: 1px solid var(--line); background: transparent; }
.wh-sug-row:last-child { border-bottom: 0; }
.wh-sug-row:hover { background: var(--accent-soft); }
.wh-sug-row img { width: 34px; height: 46px; object-fit: cover; flex: none; border-radius: var(--radius); }
.wh-sug-row .t { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: var(--t-sm); }
.wh-sug-row .s { font-family: var(--f-mono); font-size: var(--t-micro); color: var(--muted); }
.wh-sug-msg { padding: var(--s-4) var(--s-5); color: var(--muted); font-family: var(--f-mono); font-size: var(--t-mono); }

/* ---------- the panel ----------
   ONE overlay. The result and the entry details were two, stacked, and the
   details one sat UNDERNEATH. They were never two things: both are a poster, a
   title and a status, so this is the panel and the result is just the panel
   with its lower half folded away.

   Top-anchored rather than centred, and that is about the unfold rather than
   taste: a centred box grows in BOTH directions, so opening the details would
   slide the poster you are looking at upward. Anchored, the head is at a fixed
   offset from the first frame and only the bottom edge moves. */
.wh-panel { position: fixed; inset: 0; z-index: 85; background: rgba(0, 0, 0, 0.76); display: grid; justify-items: center; align-items: start; padding: 8vh var(--s-7) var(--s-7); overflow-y: auto; }
.wh-panel[hidden] { display: none; }
.wh-panel-box {
  width: min(560px, 100%);
  /* Widening as it unfolds is what sells it as one panel becoming another
     rather than a box that grew a tail. */
  transition: width 0.42s cubic-bezier(0.22, 1, 0.36, 1);
}
.wh-panel-box.wide { width: min(760px, 100%); }
.wh-panel-box .u-lbl { display: block; margin-bottom: var(--s-2); }
.wh-panel-box .rq-lb-h h2 { font-size: clamp(24px, 4vw, 34px); }
.wh-panel-btns { display: flex; gap: var(--s-5); flex-wrap: wrap; }


/* grid-template-rows 0fr -> 1fr, because `display:none` cannot animate and a
   fixed max-height would either clip a long entry or leave a gap under a short
   one. The inner div carries the overflow; the row carries the animation. */
.wh-fold { display: grid; grid-template-rows: 0fr; transition: grid-template-rows 0.42s cubic-bezier(0.22, 1, 0.36, 1); }
.wh-fold > div { overflow: hidden; min-height: 0; }
.wh-fold.open { grid-template-rows: 1fr; }

@media (prefers-reduced-motion: reduce) {
  .wh-panel-box, .wh-fold { transition: none; }
}

/* Stacked, there is no second column to match, so the panel goes back to
   flowing normally and caps itself instead. */
@media (max-width: 860px) {
  .wh-stage { grid-template-columns: 1fr; }
  .wh-side-in { position: static; }
  .wh-list { max-height: 60vh; }
  .wh-modes button { font-size: var(--t-md); padding: var(--s-4); }
  /* The preview goes above the slices rather than beside them, and stops being
     sticky: there is no room to keep it in view without eating the list. */
  .wh-build-body { grid-template-columns: 1fr; }
  .wh-build-side { position: static; order: -1; }
  .wh-preview { max-width: 240px; }
}
