/* the game's name, the seals and the 削除 mark, with only their characters (fonts/OFL.txt) */
@font-face { font-family: "Yuji Syuku"; src: url("fonts/yuji-syuku.woff2") format("woff2"); font-display: block; }
:root {
  --felt: #1d2026;
  --raised: #2a2e36;
  --edge: #434852;
  --text: #ece7dc;
  --muted: #a39d92;
  --shu: #c13a24;
  --paper-color: #f4f0e5;
  --ink: #151311;
  --grid: rgba(64, 74, 96, 0.24);
  /* the marks of the services an ID is on */
  --logo-x: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='%23ece7dc' d='M18.901 1.153h3.68l-8.04 9.19L24 22.846h-7.406l-5.8-7.584-6.638 7.584H.474l8.6-9.83L0 1.154h7.594l5.243 6.932ZM17.61 20.644h2.039L6.486 3.24H4.298Z'/%3E%3C/svg%3E");
  --logo-threads: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='%23ece7dc' d='M12.186 24h-.007c-3.581-.024-6.334-1.205-8.184-3.509C2.35 18.44 1.5 15.586 1.472 12.01v-.017c.03-3.579.879-6.43 2.525-8.482C5.845 1.205 8.6.024 12.18 0h.014c2.746.02 5.043.725 6.826 2.098 1.677 1.29 2.858 3.13 3.509 5.467l-2.04.569c-1.104-3.96-3.898-5.984-8.304-6.015-2.91.022-5.11.936-6.54 2.717C4.307 6.504 3.616 8.914 3.589 12c.027 3.086.718 5.496 2.057 7.164 1.43 1.783 3.631 2.698 6.54 2.717 2.623-.02 4.358-.631 5.8-2.045 1.647-1.613 1.618-3.593 1.09-4.798-.31-.71-.873-1.3-1.634-1.75-.192 1.352-.622 2.446-1.284 3.272-.886 1.102-2.14 1.704-3.73 1.79-1.202.065-2.361-.218-3.259-.801-1.063-.689-1.685-1.74-1.752-2.964-.065-1.19.408-2.285 1.33-3.082.88-.76 2.119-1.207 3.583-1.291a13.853 13.853 0 0 1 3.02.142c-.126-.742-.375-1.332-.75-1.757-.513-.586-1.308-.883-2.359-.89h-.029c-.844 0-1.992.232-2.721 1.32L7.734 7.847c.98-1.454 2.568-2.256 4.478-2.256h.044c3.194.02 5.097 1.975 5.287 5.388.108.046.216.094.321.142 1.49.7 2.58 1.761 3.154 3.07.797 1.82.871 4.79-1.548 7.158-1.85 1.81-4.094 2.628-7.277 2.65Zm1.003-11.69c-.242 0-.487.007-.739.021-1.836.103-2.98.946-2.916 2.143.067 1.256 1.452 1.839 2.784 1.767 1.224-.065 2.818-.543 3.086-3.71a10.5 10.5 0 0 0-2.215-.221z'/%3E%3C/svg%3E");
  color-scheme: dark;
}
[hidden] { display: none !important; }
* { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
/* the header and the screen under it sit together in the middle of the window; taller than the window, they start at the top */
body {
  margin: 0;
  min-height: 100dvh;
  display: flex; flex-direction: column;
  color: var(--text);
  background: var(--felt) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0.06 0'/%3E%3C/filter%3E%3Crect width='180' height='180' filter='url(%23n)'/%3E%3C/svg%3E");
  font-family: system-ui, -apple-system, "Hiragino Sans", "Noto Sans JP", "Noto Sans SC", "Noto Sans TC", "Noto Sans KR", sans-serif;
  -webkit-tap-highlight-color: transparent;
}

/* the game's name in the middle and the mute button at the right; on the desk, laid out as the sheet and the strip below it, the
   name stands in the middle of the sheet */
.top {
  display: grid; grid-template-columns: 44px 1fr 44px; align-items: center;
  width: 100%; max-width: 600px; margin: auto auto 0; padding: 8px 12px 4px;
}
.top .logo { grid-column: 2; justify-self: center; }
body:has(#desk:not([hidden])) .top { grid-template-columns: var(--S) var(--W); column-gap: var(--gap-b); justify-content: center; padding-inline: 16px; }
body:has(#desk:not([hidden])) .top .logo { grid-column: 1; }
.top #mute { grid-column: 3; justify-self: end; }
body:has(#desk:not([hidden])) .top #mute { grid-column: 2; }
.logo { font-family: "Yuji Syuku", serif; font-size: 25px; color: var(--paper-color); text-decoration: none; letter-spacing: 0.06em; }
.icon {
  display: inline-grid; place-items: center; width: 44px; height: 44px; padding: 0;
  border: 0; border-radius: 50%; background: none; color: var(--text); font: inherit; font-size: 22px; cursor: pointer;
}
.icon:disabled { opacity: 0.3; cursor: default; }
.icon svg { width: 24px; height: 24px; }
#mute .off, #mute[aria-pressed="true"] .on { display: none; }
#mute[aria-pressed="true"] .off { display: inline; }

main {
  width: 100%; max-width: 600px; margin: 0 auto auto;
  padding: 4px 16px calc(20px + env(safe-area-inset-bottom));
  display: flex; flex-direction: column; gap: 14px;
}

.btn {
  display: inline-flex; align-items: center; justify-content: center; min-height: 46px; padding: 0 14px;
  border: 1px solid var(--edge); border-radius: 10px; background: var(--raised); color: var(--text);
  font: inherit; font-size: 15px; font-weight: 600; text-align: center; text-decoration: none; word-break: auto-phrase; cursor: pointer;
}
.btn:disabled { opacity: 0.4; cursor: default; }
.btn.primary { background: var(--shu); border-color: var(--shu); color: #fff; }
.btn.big { min-height: 54px; font-size: 17px; }
.btn.ghost { background: none; }

/* a new start, then the links; on a phone the new start takes a row of its own above them */
.links { display: flex; flex-wrap: wrap; align-items: center; justify-content: center; gap: 4px 18px; min-height: 46px; }
@media (max-width: 599px) { .links #again { flex-basis: 100%; } }
.author { color: var(--muted); font-size: 14px; text-decoration: none; white-space: nowrap; }
.author:hover { color: var(--text); }

/* entry: three steps, each a scene as it shows on X beside a line saying what happens */
.entry { display: flex; flex-direction: column; gap: 10px; padding-top: 4px; }
.explainer {
  list-style: none; margin: 0 auto; padding: 2px 14px; width: 100%; max-width: 520px; counter-reset: step;
  background: #000; border: 1px solid #2f3336; border-radius: 16px; color: #e7e9ea;
}
.explainer li { display: grid; grid-template-columns: min(62%, 270px) 1fr; gap: 0 12px; align-items: center; padding: 6px 0; }
.explainer p { margin: 0; }
.explainer .step { font-size: 14px; font-weight: 700; line-height: 1.5; word-break: auto-phrase; }
:lang(ko) .explainer .step { word-break: keep-all; }
.explainer .step::before {
  counter-increment: step; content: counter(step); display: inline-grid; place-items: center; vertical-align: 1px;
  width: 20px; height: 20px; margin-right: 6px; border-radius: 50%; background: var(--shu); color: #fff; font-size: 12px;
}
/* the post in a rounded frame as X shows one, at the entry and for the branch just written: the avatar and handle, the words of
   the post with its tag and mentions in blue, then the OGP image as wide as the frame. At the entry it is narrower where three
   rows of them would not fit the window, and lower by --fit where the text is larger than they were reckoned for (main.js) */
.posted { min-width: 0; margin: 0; padding: 8px; border: 1px solid #5b626c; border-radius: 14px; background: #16191e; color: #e7e9ea; }
.posted .words { margin: 0 0 4px; font-size: 13px; line-height: 1.4; overflow-wrap: anywhere; }
.posted .tag { color: #1d9bf0; }
.posted :is(canvas, img) { display: block; width: 100%; height: auto; border: 1px solid #2f3336; border-radius: 10px; }
.posted canvas { max-width: calc(((100dvh - 230px) / 3 - 73px - var(--fit, 0px)) / 0.525); }
.posted img { background: var(--paper-color); }
.chip { display: flex; align-items: center; gap: 5px; width: fit-content; margin-bottom: 4px; color: #71767b; font-size: 12px; line-height: 18px; }
.chip i { display: grid; place-items: center; width: 18px; height: 18px; border-radius: 50%; color: #fff; font-size: 10px; font-style: normal; font-weight: 700; }
.go { display: flex; gap: 8px; }
.go .primary { flex: 1; }
/* on a large screen the steps are larger. On any screen the OGP images are as large as three rows of them can be and still fit
   the window */
@media (min-width: 880px) and (min-height: 860px) {
  body:has(#entry:not([hidden])) :is(.top, main) { max-width: 840px; }
  .logo { font-size: 30px; }
  .explainer { max-width: none; padding: 4px 28px; }
  .explainer li { grid-template-columns: clamp(380px, calc(((100dvh - 300px) / 3 - 87px - var(--fit, 0px)) / 0.525 + 26px), min(420px, 52%)) 1fr; gap: 0 28px; padding: 10px 0; }
  .posted { padding: 12px; border-radius: 18px; }
  .posted canvas { max-width: calc(((100dvh - 300px) / 3 - 87px - var(--fit, 0px)) / 0.525); }
  .explainer .step { font-size: 20px; }
  .explainer .step::before { width: 28px; height: 28px; margin-right: 8px; font-size: 15px; vertical-align: 2px; }
  .chip { gap: 8px; margin-bottom: 8px; font-size: 16px; line-height: 26px; }
  .chip i { width: 26px; height: 26px; font-size: 13px; }
  .posted .words { margin-bottom: 8px; font-size: 17px; }
  .posted :is(canvas, img) { border-radius: 14px; }
  .go { width: min(100%, 520px); margin: 6px auto 0; }
  .go .btn { min-height: 62px; font-size: 20px; }
  :is(.actions, .finish) .btn { font-size: 16px; }
  .count output { font-size: 17px; }
  .links .author { font-size: 16px; }
}

/* the desk. The sheet is as large as the window allows. Beside it hangs the branch's cells as a scroll, one column whatever the
   length, so it stays in place while the length is chosen: a quarter of the sheet's side wide (--W) with its mounting, as long
   as the sheet's side with 5 cells, its cells that size up to 5 characters and smaller from 6. The length, while it can be
   chosen, sits above them on the scroll's side. The tools and buttons below line up with them: on a phone the inkstone under the
   scroll and the brush's size under the sheet, on a larger screen both under the sheet. Last come the writer's ID and the
   button that finishes the character and publishes it, apart from the others as it cannot be taken back, with a line below on
   what the ID is for. --chrome is the height of everything but the sheet and the scroll, with the inkstone at its smallest
   (118px wide, 70/120 as tall); one as wide as the scroll beyond that takes 0.1458 of the sheet's side more */
body {
  --gap-b: 10px; --room-w: min(100vw - 32px, 920px); --chrome: 396px;
  --S: max(220px, min((var(--room-w) - var(--gap-b)) * 4 / 5, 100dvh - var(--chrome), (100dvh - var(--chrome) + 68.8px) / 1.1458, 680px));
  --W: calc(var(--S) / 4); --board-w: calc(var(--S) + var(--gap-b) + var(--W));
}
body:has(#countBox:not([hidden])) { --chrome: 426px; }
body:has(#desk:not([hidden])) :is(.top, main) { max-width: calc(max(var(--board-w), min(100vw - 32px, 360px)) + 32px); }
.desk { display: flex; flex-direction: column; gap: 12px; -webkit-user-select: none; user-select: none; -webkit-touch-callout: none; }
/* where the brush follows the mouse it is the pointer, from the sheet down to the inkstone (the length's buttons keep theirs) */
.surface { display: flex; flex-direction: column; gap: 12px; cursor: none; }
.surface .count { cursor: default; }
.surface input, .surface button:not(.icon) { cursor: none; }
.board { display: grid; grid-template-columns: var(--S) var(--W); gap: var(--gap-b); justify-content: center; align-items: start; }
.count {
  grid-column: 1 / -1; grid-row: 1; justify-self: end; display: flex; align-items: center; height: 44px; padding: 0 2px;
  border: 1px solid var(--edge); border-radius: 99px; background: var(--raised);
}
.count .icon { width: 40px; height: 40px; }
.count output { min-width: 5.5em; text-align: center; font-size: 16px; font-weight: 700; }
.sheet {
  position: relative; width: var(--S); aspect-ratio: 1;
  background: var(--paper-color) var(--paper); background-size: 384px;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.45);
  touch-action: none; cursor: none;
}
.sheet canvas, .sheet .guide { position: absolute; inset: 0; width: 100%; height: 100%; }
/* just above the sheet at its left, 4px from it, beside the length while it can be chosen: that leaving the page loses
   nothing (draft.js). Beside the length it takes as many lines as leaves it room, rising above the row rather than making it
   taller */
.board .keep {
  grid-column: 1; grid-row: 1; align-self: end; justify-self: start; max-width: 100%; margin: 0 0 calc(4px - var(--gap-b));
  color: var(--muted); font-size: 14px; line-height: 1.3; word-break: auto-phrase;
}
.board:has(#countBox:not([hidden])) .keep { max-width: calc(var(--board-w) - 182px); margin-top: -24px; }
.board > :is(.sheet, .hanging) { grid-row: 2; }
.guide rect, .guide path { fill: none; stroke: var(--grid); stroke-width: 1; vector-effect: non-scaling-stroke; }
.guide path { stroke-dasharray: 6 5; }
.sheet.fresh { animation: fresh 0.35s ease-out; }
@keyframes fresh { from { transform: translateY(16px) rotate(-1.2deg); opacity: 0.3; } }

.tools { display: grid; grid-template-columns: 1fr max(118px, var(--W)); gap: var(--gap-b); align-items: center; }
.size { display: flex; align-items: center; gap: 10px; min-height: 44px; }
.size input { flex: 1; min-width: 0; accent-color: var(--shu); }
.size i { flex: none; border-radius: 50%; background: var(--text); }
.size .thin { width: 4px; height: 4px; }
.size .thick { width: 16px; height: 16px; }
/* the inkstone: its left end, the sea, gives the brush ink; the rest, the land, takes some off */
.inkstone { position: relative; width: 100%; aspect-ratio: 120 / 70; transition: transform 0.1s; }
.inkstone svg { display: block; width: 100%; height: 100%; filter: drop-shadow(0 5px 8px rgba(0, 0, 0, 0.6)); }
.inkstone:hover svg { filter: drop-shadow(0 5px 8px rgba(0, 0, 0, 0.6)) brightness(1.12); }
.inkstone:active { transform: scale(0.97); }
.inkstone button { position: absolute; top: 0; height: 100%; padding: 0; border: 0; border-radius: 8px; background: none; }
.inkstone .sea { left: 0; width: 28%; }
.inkstone .land { left: 28%; width: 72%; }
.inkstone button:focus-visible { outline: 2px solid var(--shu); outline-offset: -2px; }
.actions { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; }
.actions .btn { gap: 3px; }
:is(.actions, .finish) .btn { padding: 0 8px; font-size: 14px; }
.finish { display: grid; grid-template-columns: 1fr auto; gap: 8px; }
.finish .btn { min-width: 7.5em; }
/* on a screen larger than a phone's, the tools and the buttons and the ID below them are as wide as the sheet, in the middle of
   the screen: the brush's size shorter, so that the inkstone fits beside it */
@media (min-width: 600px) {
  .surface > .tools, .desk > :is(.actions, .finish, .note, .error) { width: var(--S); margin-inline: auto; }
}

/* a branch's cells top to bottom on paper (.piece): on the desk a strip with the cell being written, and a branch on its own in
   columns */
.cells { display: grid; grid-template-columns: var(--cell); grid-auto-rows: var(--cell); justify-content: center; }
.cell { position: relative; width: var(--cell); height: var(--cell); background: var(--paper-color) var(--paper); background-size: 384px; }
.cell > img, .cell > canvas { position: absolute; inset: 0; width: 100%; height: 100%; }
/* a character's image may be ink on white rather than ink alone, so it is multiplied onto the paper */
.cell > img { mix-blend-mode: multiply; }
.cell.empty::before {
  content: ""; position: absolute; inset: 8%; border: 1px solid var(--grid);
  background: linear-gradient(var(--grid), var(--grid)) center / 1px 100% no-repeat, linear-gradient(var(--grid), var(--grid)) center / 100% 1px no-repeat;
}
.cell.now { outline: 2px solid var(--shu); outline-offset: -2px; z-index: 1; }
.piece { position: relative; background: var(--paper-color) var(--paper); background-size: 384px; }
.piece .cell { background: none; }
/* the scroll's mounting takes 14.5 --u along the sheet's side and 7.6 across with the roller's knobs, which with --u at 1/94 of
   the sheet's side makes it a quarter of that wide with 5 cells. It shows 6 cells at most, as long as the sheet's side, and
   scrolls through the rest: where some are out of view that end of the paper fades, with an arrow that turns 6 cells over */
.board .hanging { --u: calc(var(--S) / 94); justify-self: start; margin-left: calc(var(--u) * 1.4); }
.board .mount { position: relative; }
#strip {
  --cell: calc((var(--S) - var(--u) * 14.5) / clamp(5, var(--n), 6)); padding: var(--u);
  max-height: calc(var(--cell) * 6 + var(--u) * 2); overflow-y: auto; overscroll-behavior: contain; scrollbar-width: none;
}
#strip::-webkit-scrollbar { display: none; }
.more {
  position: absolute; left: calc(var(--u) * 1.4); right: calc(var(--u) * 1.4); z-index: 2; height: calc(var(--cell) * 0.5);
  display: grid; justify-items: center; padding: 3px 0; border: 0; color: #3d3631;
  --fade: rgba(244, 240, 229, 0.94), rgba(244, 240, 229, 0);
}
.more.up { top: calc(var(--u) * 2.4); align-items: start; background: linear-gradient(to bottom, var(--fade)); }
.more.down { bottom: calc(var(--u) * 1.2); align-items: end; background: linear-gradient(to top, var(--fade)); }
.more svg { width: 50%; max-width: 20px; fill: none; stroke: currentColor; stroke-width: 2.6; stroke-linecap: round; stroke-linejoin: round; }

/* a branch on its own. Just written, it shows its post as X will (.posted), with the very OGP image X shows. Complete and opened
   from a link, it is drawn as that image is, in a frame of the same look (--frame wide) as tall as the image's at least: its
   scroll on the wall, the columns of --per cells read from the right, each with a line below for its writer's ID where any has
   one (--line), and the seal in the bottom right corner, outside the scroll on its right. The scroll hangs in the middle, or
   further left where it would reach the seal there: the room either side of it is shared evenly, but on the right never less
   than the seal takes. Its cells are as large as the window's height allows with the buttons below in view (--around is the
   height of everything around the cells), 52px at least, and no larger than its room left of the seal allows (--room), a column
   taking 1.42 cells with the IDs; wider still, the frame scrolls and starts at the right */
.work {
  --u: clamp(5px, min(1.9vw, 1.1dvh), 11px); --around: calc(260px + var(--u) * 13); --frame: calc(min(100vw, 600px) - 32px);
  display: flex; flex-direction: column; gap: 12px;
}
.taiwan .work { --around: calc(322px + var(--u) * 13); }
#post, .wall { margin-top: 8px; }
.wall {
  --room: calc(var(--frame) * 0.8433 - 16px);
  position: relative; display: flex; align-items: center; width: 100%; min-height: calc(var(--frame) * 0.525); padding: 8px;
  border: 1px solid #2f3336; border-radius: 16px; overflow-x: auto; direction: rtl;
}
.wall::before, .wall::after { content: ""; flex: 1 1 0; }
.wall::before { min-width: calc(var(--frame) * 0.1567 + var(--u) * 1.4 - 2px); }
.wall::after { min-width: calc(var(--u) * 1.4); }
.wall .seal {
  position: absolute; right: calc(var(--frame) * 0.03); bottom: calc(var(--frame) * 0.03);
  width: calc(var(--frame) * 0.1267); height: calc(var(--frame) * 0.1267);
}
.columns {
  --line: 0px;
  --cell: max(32px, min(calc((var(--room) - 28px - var(--u) * 5.6) / (var(--cols) * 1.42)),
    max(52px, min(128px, calc((100dvh - var(--around) - var(--per) * var(--line)) / var(--per))))));
  flex: none; display: flex; direction: ltr;
}
.columns.named { --line: 24px; }
.columns .piece {
  grid-template-rows: repeat(var(--per), calc(var(--cell) + var(--line))); grid-template-columns: none; grid-auto-flow: column;
  grid-auto-columns: var(--cell); column-gap: var(--apart, calc(var(--cell) * 0.25)); padding: 14px var(--side, 14px); direction: rtl;
}
.columns .cell { direction: ltr; }
/* each ID written across just below its character, in the line kept for it, nearer to it than to the next */
.piece a {
  position: absolute; top: 100%; left: 50%; transform: translateX(-50%);
  color: #4f473e; opacity: 0.6; font-size: var(--id, 13px); font-weight: 600; line-height: 16px; text-decoration: none; white-space: nowrap;
}
/* below it, right after publishing, posting it on X with the share sheet for other apps beside (in Taiwan Threads too, on a row
   of its own); then, below a new start, the other branches from the same first character, each shelf a row of their OGP images
   scrolled sideways */
.send { display: flex; flex-wrap: wrap; gap: 8px; }
.send #next { flex: 1 0 100%; }
.send #xPost { flex: 1; }
.btn.share { flex: none; gap: 6px; min-height: 54px; }
.btn.share svg { width: 22px; height: 22px; }
.send .threads { flex: 1 0 100%; }
/* a shelf (those of a branch on its own and the entry's) is a row of OGP images scrolled sideways, each marked at its corner
   with where it stands where that is wanted: how far it has come, or complete */
.shelf h2 { margin: 4px 0 8px; color: var(--muted); font-size: 14px; font-weight: 600; }
.shelf .row { display: flex; gap: 8px; overflow-x: auto; margin: 0 -16px 10px; padding: 0 16px 6px; scrollbar-width: thin; }
.shelf .row :is(a, button) { position: relative; flex: none; width: 160px; padding: 0; border: 0; border-radius: 6px; overflow: hidden; background: none; cursor: pointer; }
.shelf .row img { display: block; width: 100%; height: auto; border: 1px solid #2f3336; border-radius: 6px; background: var(--paper-color); }
.badge {
  position: absolute; left: 6px; top: 6px; padding: 1px 8px; border-radius: 99px;
  background: rgba(21, 19, 17, 0.8); color: #fff; font-size: 12px; font-weight: 700; line-height: 18px;
}
/* a completed work from the entry's shelf, as large as the window allows over the page dimmed, put away again by a touch */
.zoom { width: min(100vw - 16px, 1200px); max-width: none; max-height: none; padding: 0; border: 0; background: none; }
.zoom::backdrop { background: rgba(0, 0, 0, 0.85); }
.zoom img { display: block; width: 100%; height: auto; border-radius: 10px; }
/* while a branch loads, a drop of ink spreading into a scrap of the paper and fading, again and again; only after 0.3s, so that
   a quick load does not flash it */
.loading { display: grid; place-items: center; min-height: 45dvh; animation: later 0s 0.3s backwards; }
@keyframes later { from { visibility: hidden; } }
.loading i {
  position: relative; width: 72px; height: 72px; background: var(--paper-color) var(--paper); background-size: 384px;
  box-shadow: 0 6px 18px rgba(0, 0, 0, 0.45);
}
.loading i::after {
  content: ""; position: absolute; inset: 0; width: 38px; height: 38px; margin: auto; border-radius: 50%;
  background: radial-gradient(circle, rgba(21, 19, 17, 0.92) 0 28%, rgba(21, 19, 17, 0.5) 50%, rgba(21, 19, 17, 0) 70%);
  animation: bleed 1.8s ease-out infinite;
}
@keyframes bleed { 0% { transform: scale(0.2); opacity: 0; } 20% { opacity: 1; } 70% { transform: scale(1); opacity: 0.9; } 100% { transform: scale(1.12); opacity: 0; } }
@media (prefers-reduced-motion: reduce) { .loading i::after { animation: none; transform: scale(0.8); } }
/* what the game asks of its players and keeps */
.about h2 { margin: 4px 0 10px; font-size: 20px; }
.about p { margin: 0 0 12px; font-size: 15px; line-height: 1.7; word-break: auto-phrase; }
:lang(ko) .about p { word-break: keep-all; }
/* the question before the sheet is reset, over the desk dimmed behind it */
.confirm {
  width: min(100vw - 32px, 340px); padding: 20px 16px 16px;
  border: 1px solid var(--edge); border-radius: 14px; background: var(--raised); color: var(--text);
}
.confirm::backdrop { background: rgba(0, 0, 0, 0.6); }
.confirm p { margin: 0 0 18px; font-size: 15px; line-height: 1.6; white-space: pre-line; }
.confirm form { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
/* the ranking: its three periods side by side as tabs, then a row for each account with its place, the mark of the service its ID
   is on, the ID and how many */
.rank h2 { margin: 4px 0 2px; font-size: 20px; }
.rank .lead { margin: 0 0 12px; color: var(--muted); font-size: 13px; }
.tabs { display: grid; grid-template-columns: repeat(3, 1fr); gap: 4px; padding: 4px; border: 1px solid var(--edge); border-radius: 12px; background: var(--raised); }
.tabs button {
  min-height: 40px; border: 0; border-radius: 8px; background: none; color: var(--muted);
  font: inherit; font-size: 15px; font-weight: 600; cursor: pointer;
}
.tabs [aria-selected="true"] { background: var(--text); color: var(--felt); }
.ranks { margin: 8px 0 0; padding: 0; list-style: none; }
.ranks li { display: grid; grid-template-columns: 2.4em 18px 1fr auto; align-items: center; gap: 10px; min-height: 50px; border-bottom: 1px solid #2f3336; }
.ranks .place { color: var(--muted); font-weight: 700; text-align: right; font-variant-numeric: tabular-nums; }
.ranks .mark { width: 18px; height: 18px; background: var(--logo) center / contain no-repeat; }
.ranks a { min-width: 0; color: var(--text); font-weight: 600; text-decoration: none; overflow-wrap: anywhere; }
.ranks .n { padding-right: 4px; color: var(--muted); font-size: 13px; white-space: nowrap; }
.ranks .n b { color: var(--text); font-size: 17px; font-variant-numeric: tabular-nums; }
.rank .none { margin: 28px 0; color: var(--muted); text-align: center; }
.toast {
  position: fixed; left: 50%; bottom: calc(24px + env(safe-area-inset-bottom)); z-index: 30; transform: translateX(-50%);
  margin: 0; padding: 8px 16px; border-radius: 99px; background: var(--text); color: var(--felt);
  font-size: 14px; font-weight: 600; white-space: nowrap; box-shadow: 0 6px 18px rgba(0, 0, 0, 0.4);
}

/* a completed branch on its own, and the strip on the desk, hang as a scroll: the paper between gold bands (ichimonji) in a
   brocade surround (nakamawashi), plain cloth above and below (ten, chi) with two gold strips hanging from the top (futai), the
   rod along the top edge (hasso) with its cord, and the roller at the foot (jiku) with its knobs. --u scales the mounting */
.hanging {
  position: relative; flex: none;
  margin-block: calc(var(--u) * 2.6) calc(var(--u) * 0.8); padding: calc(var(--u) * 2.5) 0 calc(var(--u) * 3);
  background:
    linear-gradient(#6c7163, #6c7163) 0 0 / 100% calc(var(--u) * 0.5) no-repeat,
    linear-gradient(90deg, #a8873f, #e0c47c 45%, #a8873f) 26% calc(var(--u) * 0.5) / calc(var(--u) * 1.1) calc(var(--u) * 1.5) no-repeat,
    linear-gradient(90deg, #a8873f, #e0c47c 45%, #a8873f) 74% calc(var(--u) * 0.5) / calc(var(--u) * 1.1) calc(var(--u) * 1.5) no-repeat,
    repeating-linear-gradient(90deg, rgba(255, 255, 255, 0.05) 0 1px, transparent 1px 3px),
    repeating-linear-gradient(0deg, rgba(0, 0, 0, 0.04) 0 1px, transparent 1px 3px),
    #a7aa9b;
  box-shadow: 0 calc(var(--u) * 1.2) calc(var(--u) * 2.6) rgba(0, 0, 0, 0.5);
}
.hanging .mount {
  padding: calc(var(--u) * 2.4) calc(var(--u) * 1.4) calc(var(--u) * 1.2);
  background:
    repeating-linear-gradient(45deg, rgba(255, 230, 170, 0.07) 0 1px, transparent 1px 6px),
    repeating-linear-gradient(-45deg, rgba(255, 230, 170, 0.07) 0 1px, transparent 1px 6px),
    #5a4632;
}
.hanging .piece { box-shadow: 0 calc(var(--u) * -0.8) 0 #c4a256, 0 calc(var(--u) * 0.45) 0 #c4a256; }
.hanging::before {
  content: ""; position: absolute; left: max(30%, 50% - var(--u) * 9); right: max(30%, 50% - var(--u) * 9);
  bottom: 100%; height: calc(var(--u) * 2.4);
  --cord: transparent calc(50% - 0.9px), #8c6d43 calc(50% - 0.9px) calc(50% + 0.9px), transparent calc(50% + 0.9px);
  background: linear-gradient(to bottom right, var(--cord)) left / 50% 100% no-repeat, linear-gradient(to bottom left, var(--cord)) right / 50% 100% no-repeat;
}
.hanging::after {
  content: ""; position: absolute; left: calc(var(--u) * -1.4); right: calc(var(--u) * -1.4); bottom: calc(var(--u) * -0.8);
  height: calc(var(--u) * 1.7); border-radius: calc(var(--u) * 0.4);
  --knob: #5f5650, #221c18 30%, #0d0a08 65%, #3d342e;
  background:
    linear-gradient(var(--knob)) left / calc(var(--u) * 1.9) 100% no-repeat,
    linear-gradient(var(--knob)) right / calc(var(--u) * 1.9) 100% no-repeat,
    linear-gradient(#c9ccbd, #a7aa9b 35%, #7c7f71 75%, #646759) center / calc(100% - var(--u) * 3.6) 82% no-repeat;
}
/* the writer's ID, given beside the button that finishes the character (its font no smaller than 16px, so a phone does not zoom
   in), in Taiwan after the service it is on */
.xid {
  display: flex; align-items: center; gap: 8px; min-width: 0; min-height: 46px; padding: 0 12px;
  border: 1px solid var(--edge); border-radius: 10px; background: #1b1e24;
}
.xid:focus-within { border-color: #8b909a; }
.xid label { flex: 1; align-self: stretch; display: flex; align-items: center; gap: 6px; min-width: 0; }
.xid label span { flex: none; width: 18px; height: 18px; background: var(--logo-x) center / contain no-repeat; }
.xid select {
  flex: none; width: 40px; height: 32px; margin-left: -6px; border: 0; border-radius: 6px; appearance: none; color: transparent; font-size: 16px;
  background: var(--logo) 6px center / 18px no-repeat, url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 10 6'%3E%3Cpath d='M1 1l4 4 4-4' fill='none' stroke='%23a39d92' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") right 2px center / 8px no-repeat;
}
.xid select:focus-visible { outline: 2px solid #8b909a; }
.xid select[data-on="threads"], .ranks .mark[data-on="threads"] { --logo: var(--logo-threads); }
.xid select[data-on="x"], .ranks .mark[data-on="x"] { --logo: var(--logo-x); }
.xid select:not([hidden]) + label span { display: none; }
.xid option { color: var(--text); background: #1b1e24; }
.xid input { flex: 1; min-width: 0; border: 0; outline: none; background: none; color: var(--text); font: inherit; font-size: 16px; }
/* what the ID is for, on a line just below it */
.note { margin: -6px 0 0; color: var(--muted); font-size: 12px; }
.error { margin: 0; color: #ff9b87; font-size: 14px; word-break: auto-phrase; }
/* why a link's branch could not be opened, above the entry's picture */
.notice { margin: 0; padding: 8px 12px; border-radius: 10px; background: #3a2422; color: #ffb4a6; font-size: 14px; }

.brush-layer { position: fixed; left: 0; top: 0; z-index: 5; pointer-events: none; }
/* the confetti when a branch is complete (celebrate.js), over everything */
.celebration { position: fixed; inset: 0; width: 100%; height: 100%; z-index: 40; pointer-events: none; }

/* the debug menu (?debug): a tab at the foot of the window, over everything, that opens upward */
.debug {
  position: fixed; left: 8px; bottom: calc(8px + env(safe-area-inset-bottom)); z-index: 20; max-width: calc(100vw - 16px);
  max-height: 70dvh; overflow-y: auto; padding: 6px 10px; border: 1px solid #d9a441; border-radius: 8px;
  background: rgba(20, 22, 27, 0.95); font-size: 13px; line-height: 1.5;
}
.debug summary { color: #d9a441; font-weight: 700; cursor: pointer; }
.debug[open] summary { margin-bottom: 8px; }
.debug div { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 8px; }
.debug button, .debug select {
  min-height: 36px; padding: 0 10px; border: 1px solid var(--edge); border-radius: 6px; background: var(--raised); color: var(--text);
  font: inherit;
}
.debug button:disabled { opacity: 0.5; }
.debug p { margin: 8px 0 0; color: var(--muted); overflow-wrap: anywhere; }
.debug p:empty { display: none; }
