/* local: rotate / reflect the board. The frame carries the pose; every cell button and cage badge
   carries the inverse, so tiles, pencil marks, shadows and numbers always read upright. */
#board-root, #tut-board-root { perspective: 1800px; }
.board-frame { transform: var(--turn, none); }
.board { perspective: 1400px; } /* per-cell flips (ripple) get depth */
.board .cellbtn, .board .badge { transform: var(--unturn, none); }
.board .badge.spot { transform: var(--unturn, none) scale(1.22); }
.turning .board-frame { will-change: transform; }
.turning .cellbtn { pointer-events: none; }
.board > svg { transform-origin: 50% 50%; }

/* controls */
.orient-strip { display: flex; gap: 8px; }
.orient-btn {
  width: 40px; height: 40px; border: 0; border-radius: 50%; padding: 0; cursor: pointer;
  font-family: inherit; font-size: 19px; font-weight: 800; line-height: 1;
  color: var(--ink); background: var(--srf); box-shadow: 0 3px 0 var(--press);
  display: inline-flex; align-items: center; justify-content: center;
}
.orient-btn:hover { filter: brightness(1.04); }
.orient-btn:active { transform: translateY(2px); box-shadow: 0 1px 0 var(--press); }
.orient-btn:focus-visible { outline: 3px solid var(--gold); outline-offset: 2px; }
.orient-btn:disabled { opacity: .35; cursor: default; transform: none; }
.orient-read { color: var(--d1); }

/* beside the board: hangs off the root's right edge (the root is exactly the board's width), centred
   on the board's height; lives outside the posed frame so it never turns */
#board-root, #tut-board-root { position: relative; }
.orient-strip.orient-side { position: absolute; right: -54px; transform: translateY(-50%); flex-direction: column; }

/* top bar */
.orient-top:empty { display: none; }
.orient-strip.orient-topbar { gap: 7px; margin-right: 4px; }
.orient-strip.orient-topbar .orient-btn { width: 36px; height: 36px; font-size: 17px; }

/* settings row */
.orient-strip.orient-inline .orient-btn { width: 34px; height: 34px; font-size: 16px; box-shadow: 0 2px 0 var(--press); }

@media (max-width: 560px) {
  .orient-strip.orient-topbar { gap: 5px; margin-right: 0; }
  .orient-strip.orient-topbar .orient-btn { width: 32px; height: 32px; font-size: 15px; }
}

/* corner: a single toggle outside the board's top-right corner; open, the moves hang below it over
   the board's edge on a translucent card, so nothing in the layout moves */
.orient-corner { position: absolute; top: -8px; right: -22px; z-index: 7; display: flex; flex-direction: column; align-items: flex-end; gap: 6px; }
.orient-toggle {
  width: 28px; height: 28px; border: 0; border-radius: 50%; padding: 0; cursor: pointer;
  font-family: inherit; font-size: 15px; font-weight: 800; line-height: 1;
  color: var(--ink); background: var(--srf); box-shadow: 0 3px 0 var(--press), 0 0 0 3px var(--card);
  display: inline-flex; align-items: center; justify-content: center; transition: transform .25s cubic-bezier(.2,.9,.25,1.3);
}
.orient-toggle:active { transform: translateY(2px); box-shadow: 0 1px 0 var(--press), 0 0 0 3px var(--card); }
.orient-corner.open .orient-toggle { transform: rotate(180deg); background: var(--ink); color: var(--bg); box-shadow: 0 3px 0 var(--inkSh), 0 0 0 3px var(--card); }
.orient-corner .orient-strip.orient-corner { flex-direction: column; gap: 6px; padding: 7px; border-radius: 999px;
  background: color-mix(in srgb, var(--card) 90%, transparent); box-shadow: 0 10px 24px var(--spotSh); }
.orient-corner:not(.open) .orient-strip { display: none; }
.orient-corner.open .orient-strip { animation: orient-fan .22s cubic-bezier(.2,.9,.25,1.2) both; }
.orient-strip.orient-corner .orient-btn { width: 36px; height: 36px; font-size: 17px; }
@keyframes orient-fan { from { opacity: 0; transform: translateY(-8px) scale(.9); } to { opacity: 1; transform: none; } }

/* keys: a quiet row below erase + pencil. A small board glyph says what the row is for; the four
   moves are ghost buttons in the caption colour that lift into a key only on hover/press. */
.key-row.orient-keys-row { gap: 6px; align-items: center; margin-top: 2px; }
/* above the board: the same quiet row, right-aligned over the grid's top edge, with air below */
.key-row.orient-keys-row.orient-above { justify-content: flex-end; margin: 0 0 12px; width: 100%; }
/* in the check bar (always a 2-column grid: "check totals" over "meter totals"): with the moves on,
   the meter row spans the full width and holds the lights and the four keys on one line, while
   Check and the totals both top-align on the first row. The phone bar is set by an #checkbar-root
   rule (meter | summary, 20px row), so the same layout is restated with an id to outrank it, and
   Summary drops to a third full-width row. */
#checkbar-root .checkbar-inner.has-orient, .game-shell .checkbar-inner.has-orient {
  grid-template-areas: "check totals" "meter meter"; grid-template-rows: auto auto; align-items: start; row-gap: 4px;
}
#checkbar-root .checkbar-inner.has-orient .check-trigger, .game-shell .checkbar-inner.has-orient .check-trigger { align-self: start; }
#checkbar-root .checkbar-inner.has-orient .check-totals, .game-shell .checkbar-inner.has-orient .check-totals { align-self: start; }
#checkbar-root .checkbar-inner.has-orient .check-mid, .game-shell .checkbar-inner.has-orient .check-mid {
  align-self: start; flex-direction: row; align-items: center; justify-content: flex-start; gap: 12px; flex-wrap: nowrap; min-width: 0;
}
.game-shell .checkbar-inner.has-orient .check-meter { width: auto; flex: 0 0 auto; }
.game-shell .checkbar-inner.has-orient .orient-keys-row { width: auto; margin: 0; gap: 2px; flex: 0 1 auto; justify-content: flex-start; }
#checkbar-root .checkbar-inner.has-orient > .check-summary { grid-area: auto; grid-column: 1 / -1; height: auto; min-height: 0; width: 100%; }
.orient-keys-row.orient-meter .orient-key { width: 36px; height: 30px; font-size: 17px; border-radius: 9px; }
@media (max-width: 560px) {
  #checkbar-root .checkbar-inner.has-orient .check-mid { justify-content: space-between; gap: 8px; }
  .orient-keys-row.orient-meter .orient-key { width: 34px; }
}
.orient-key {
  width: 40px; height: 34px; border: 0; border-radius: 11px; padding: 0; cursor: pointer;
  font-family: inherit; font-size: 19px; font-weight: 800; line-height: 1; color: var(--ink3); background: transparent;
  display: inline-flex; align-items: center; justify-content: center;
  transition: background .15s, color .15s, box-shadow .15s, transform .1s;
}
.orient-key:hover:not(:disabled) { background: var(--srf); color: var(--ink); box-shadow: 0 3px 0 var(--press); transform: translateY(-1px); }
.orient-key:active:not(:disabled) { transform: translateY(2px); box-shadow: 0 1px 0 var(--press); }
.orient-key:focus-visible { outline: 3px solid var(--gold); outline-offset: 1px; }
.orient-key:disabled { opacity: .4; cursor: default; }
.key.read-key .L { color: var(--d1); }
.key.read-key:disabled .L { color: var(--ink3); }
@media (max-width: 960px) {
  .keys .key-row.orient-keys-row { width: auto; }
}
@media (max-width: 560px) {
  .orient-key { width: 38px; height: 32px; font-size: 17px; }
  .keys .key.tool-key { min-width: 0; flex: 1 1 0; padding-inline: 8px; }
}
html[data-theme="letterpress"] .orient-key { border-radius: 4px; }
html[data-theme="inked"] .orient-key { border-radius: 4px; }

/* settings › advanced */
.adv-block { margin-top: 6px; border-top: 1px solid var(--line); padding-top: 8px; }
.adv-head { cursor: pointer; list-style: none; font-size: 11px; font-weight: 800; letter-spacing: .1em; text-transform: uppercase; color: var(--ink3); display: flex; align-items: center; gap: 6px; padding: 4px 0; user-select: none; }
.adv-head::-webkit-details-marker { display: none; }
.adv-head::before { content: ''; width: 6px; height: 6px; border-right: 2px solid currentColor; border-bottom: 2px solid currentColor; transform: rotate(-45deg); transition: transform .15s; margin-right: 2px; }
.adv-block[open] .adv-head::before { transform: rotate(45deg); }
.adv-block .fx-row { margin-top: 6px; }
.adv-note { font-size: 11px; line-height: 1.4; color: var(--ink3); margin-top: 4px; text-wrap: pretty; }
