/* Loomoku web game. Mirrors the iOS app's Theme.swift and screens. */
*, *::before, *::after { box-sizing: border-box; }
html, body { margin: 0; height: 100%; }
body {
  font-family: var(--sans); color: var(--ink); background: var(--paper);
  -webkit-font-smoothing: antialiased; -webkit-tap-highlight-color: transparent;
  overscroll-behavior: none; touch-action: manipulation;
}
button { font: inherit; color: inherit; background: none; border: 0; padding: 0; cursor: pointer; }
button:disabled { cursor: default; }
a { color: var(--clay-text); }
.sr-only { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
.ic { width: 1em; height: 1em; display: inline-block; vertical-align: -0.125em; flex: none; }
.num { font-variant-numeric: tabular-nums; }
:focus-visible { outline: 2.5px solid var(--indigo); outline-offset: 2px; border-radius: 6px; }

/* Layers: shell 0, covers 30, first launch 40, splash 50, sheets 60, toast 70 */
#app { position: fixed; inset: 0; overflow: hidden; }
.paper {
  background-color: var(--linen-tint); background-image: var(--linen);
  background-size: cover; background-position: center; background-blend-mode: multiply;
}
.screen { position: absolute; inset: 0; display: flex; flex-direction: column; isolation: isolate; }
.cover { z-index: 30; }
.corners::after, .corners::before { /* quilt fans in the lower corners */
  content: ""; position: absolute; bottom: 0; pointer-events: none; z-index: -1;
  background: url("/assets/img/felt/quilt_corner.webp") no-repeat center / contain; opacity: .9;
}
.corners::after { right: 0; width: min(220px, 42vmin); height: min(220px, 42vmin); }
.corners::before { left: 0; width: min(158px, 30vmin); height: min(158px, 30vmin); transform: scaleX(-1); }
@media (prefers-color-scheme: dark) { .corners::after, .corners::before { opacity: .7; filter: brightness(.38); } }
[hidden] { display: none !important; }

/* Type */
.t-title { font-family: var(--serif); font-weight: 700; letter-spacing: -0.01em; }
.t-heading { font-family: var(--serif); font-weight: 600; }
.soft { color: var(--ink-soft); }

/* Stitched card */
.card {
  position: relative; background: var(--card); border: 1px solid var(--line); border-radius: 18px; padding: 16px;
  box-shadow: 0 3px 6px rgb(var(--shadow) / .08);
}
.card::after {
  content: ""; position: absolute; inset: 4px; border-radius: 14px; pointer-events: none;
  border: 1px dashed color-mix(in srgb, var(--gold) 45%, transparent);
}
.card.gold { background: var(--gold-tint); }

/* Clay pill button: a raised felt pill that presses onto its darker lip */
.btn {
  --lip: 4px; position: relative; display: flex; align-items: center; justify-content: center; gap: 8px;
  width: 100%; min-height: 54px; padding: 0 16px; margin-bottom: var(--lip);
  border-radius: 20px; font-weight: 600; font-size: 19px; line-height: 1.15; text-align: center; text-decoration: none;
  color: #fff; background: var(--clay); border: 1px solid color-mix(in srgb, var(--clay-deep) 60%, transparent);
  box-shadow: 0 var(--lip) 0 var(--clay-deep);
  transition: transform .18s cubic-bezier(.3, 1.4, .5, 1), box-shadow .18s cubic-bezier(.3, 1.4, .5, 1);
  white-space: nowrap; user-select: none; -webkit-user-select: none;
}
.btn::after {
  content: ""; position: absolute; inset: 3.5px; border-radius: 16px; pointer-events: none;
  border: 1.2px dashed rgb(255 255 255 / .45);
}
.btn:active:not(:disabled) { transform: translateY(var(--lip)); box-shadow: 0 0 0 var(--clay-deep); }
.btn.paperbtn { color: var(--clay-text); background: var(--card); border: 1.5px solid var(--clay); box-shadow: 0 var(--lip) 0 var(--clay-tint); }
.btn.paperbtn::after { border-color: color-mix(in srgb, var(--clay) 55%, transparent); }
.btn.paperbtn:active:not(:disabled) { box-shadow: 0 0 0 var(--clay-tint); }
.btn.compact { --lip: 3px; min-height: 44px; border-radius: 15px; font-size: 16px; }
.btn.compact::after { border-radius: 11.5px; }
.btn:disabled { filter: saturate(.6); opacity: .5; }
.btn .sub { display: block; font-size: 12px; font-weight: 400; opacity: .85; }
.btn.stack { flex-direction: column; gap: 2px; padding: 8px 16px; }
.textbtn { font-weight: 600; font-size: 17px; color: var(--clay-text); padding: 10px 14px; border-radius: 12px; display: inline-flex; align-items: center; gap: 8px; text-decoration: none; }

/* Small raised key: tools, digit pad, round header buttons */
.key {
  position: relative; display: flex; align-items: center; justify-content: center;
  background: var(--card); border: 1px solid var(--line); border-radius: 16px; box-shadow: 0 3px 0 var(--line);
  transition: transform .16s cubic-bezier(.3, 1.4, .5, 1), box-shadow .16s; user-select: none; -webkit-user-select: none;
  -webkit-touch-callout: none;
}
.key:active:not(:disabled) { transform: translateY(2.5px); box-shadow: 0 .5px 0 var(--line); }
.key.active { background: var(--clay-tint); border-color: var(--clay); box-shadow: 0 3px 0 color-mix(in srgb, var(--clay) 70%, transparent); color: var(--clay-text); }
.key:disabled { opacity: .45; }
.key.round { width: 44px; height: 44px; font-size: 18px; flex: none; }

/* Chips */
.chip {
  display: inline-flex; align-items: center; gap: 6px; height: 36px; padding: 0 11px; border-radius: 999px;
  background: var(--card); border: 1px solid var(--line); box-shadow: 0 2px 3px rgb(var(--shadow) / .08);
  font-weight: 600; font-size: 15px; font-variant-numeric: tabular-nums; white-space: nowrap;
}
.chip img { width: 20px; height: 20px; }
.chip .ic { color: var(--gold); font-size: 17px; }
@media (max-width: 389px) { .topbar { gap: 8px; } .topbar .chip { padding: 0 9px; gap: 5px; } }

/* ---------- Splash ---------- */
#splash { z-index: 50; align-items: center; justify-content: center; cursor: pointer; }
.splash-in { display: flex; flex-direction: column; align-items: center; gap: 26px; padding: 0 24px; }
.loom { --side: min(46vmin, 230px); position: relative; width: calc(var(--side) + 60px); height: calc(var(--side) + 60px); }
.loom .patches {
  position: absolute; inset: 30px; display: grid; grid-template-columns: repeat(3, 1fr); gap: calc(var(--side) * .045);
}
.patch {
  position: relative; border-radius: 20%; display: grid; place-items: center; box-shadow: 0 2px 3px rgb(0 0 0 / .14);
  font-family: var(--serif); font-weight: 700; color: #F6F1E7; font-size: calc(var(--side) * .14);
  opacity: 0; transform: scale(.3) rotate(var(--rot, -14deg));
  animation: patch-in .45s cubic-bezier(.3, 1.35, .5, 1) forwards; animation-delay: var(--d);
}
.patch::after { content: ""; position: absolute; inset: 9%; border-radius: 14%; border: 1px dashed var(--st, var(--gold)); opacity: .9; }
@keyframes patch-in { to { opacity: 1; transform: none; } }
.loom .thread { position: absolute; background: color-mix(in srgb, var(--gold) 75%, transparent); border-radius: 1px; }
.loom .warp { top: 12px; bottom: 12px; width: 1.5px; transform-origin: top; transform: scaleY(0); animation: grow .45s ease-out .15s forwards; }
.loom .weft { left: 12px; right: 12px; height: 1.5px; background: color-mix(in srgb, var(--clay) 70%, transparent); transform: scaleX(0); animation: grow .3s ease-in-out forwards; animation-delay: var(--d); }
@keyframes grow { to { transform: none; } }
.loom .frame { position: absolute; inset: 17px; }
.loom .frame rect { fill: none; stroke: var(--gold); stroke-width: 2; stroke-linecap: round; stroke-dasharray: 7 6; }
.loom .frame-mask rect { stroke-dasharray: 1; stroke-dashoffset: 1; animation: draw .6s ease-in-out 1.23s forwards; }
@keyframes draw { to { stroke-dashoffset: 0; } }
.loom .star {
  /* Centred at (side / 2 + 8, -side / 2 - 8) from the loom's centre, as in SplashView. */
  position: absolute; width: calc(var(--side) * .26); left: calc(50% + var(--side) / 2 + 8px); top: calc(50% - var(--side) / 2 - 8px);
  margin: calc(var(--side) * -.13) 0 0 calc(var(--side) * -.13); opacity: 0;
  transform: scale(.2) rotate(-30deg); animation: star-in .5s cubic-bezier(.3, 1.5, .5, 1) 2.015s forwards;
}
@keyframes star-in { to { opacity: 1; transform: rotate(12deg); } }
.wordmark { font-size: 40px; line-height: 1; display: flex; margin: 0; }
.wordmark span { opacity: 0; transform: translateY(16px) rotate(-8deg); transform-origin: bottom; animation: letter .4s cubic-bezier(.3, 1.4, .5, 1) forwards; animation-delay: calc(1.43s + var(--i) * .055s); }
@keyframes letter { to { opacity: 1; transform: none; } }
.splash-words { display: flex; flex-direction: column; align-items: center; gap: 10px; }
.underline { width: 150px; height: 8px; }
.underline path { fill: none; stroke: var(--clay); stroke-width: 2; stroke-linecap: round; stroke-dasharray: 8 6; }
.underline .m path { stroke: #fff; stroke-dasharray: 1; stroke-dashoffset: 1; animation: draw .45s ease-out 1.815s forwards; }
.tagline { font-size: 17px; color: var(--clay-text); margin: 0; text-align: center; opacity: 0; transform: translateY(6px); animation: letter .4s ease-out 2.015s forwards; }
#splash.out { opacity: 0; transition: opacity .35s ease; pointer-events: none; }

/* ---------- First launch ---------- */
#first { z-index: 40; overflow-y: auto; }
.first-in { margin: auto; width: 100%; max-width: 468px; padding: 24px; display: flex; flex-direction: column; align-items: center; gap: 24px; }
.first-hero { display: flex; flex-direction: column; align-items: center; gap: 10px; text-align: center; }
.first-hero canvas { width: 120px; height: 120px; animation: tile-settle .7s cubic-bezier(.3, 1.3, .5, 1) both; }
@keyframes tile-settle { from { transform: rotate(-6deg) scale(.85); } }
.first-hero h1 { font-size: 40px; margin: 0; line-height: 1.05; }
.first-hero .tag { font-size: 17px; color: var(--clay-text); margin: 0; }
.first-hero p { margin: 0; font-size: 16px; }
.choices { width: 100%; display: flex; flex-direction: column; gap: 10px; }
.choices h2 { font-size: 18px; margin: 0 0 2px; text-align: center; }
.choice {
  display: flex; align-items: center; gap: 12px; text-align: left; padding: 14px; width: 100%;
  background: var(--card); border: 1px dashed var(--line); border-radius: 14px;
}
.choice b { display: block; font-size: 17px; font-weight: 600; }
.choice small { display: block; font-size: 13px; color: var(--ink-soft); margin-top: 3px; line-height: 1.35; }
.choice .radio { margin-left: auto; width: 22px; height: 22px; border-radius: 50%; border: 2px solid var(--ink-soft); flex: none; display: grid; place-items: center; }
.choice[aria-checked="true"] { border: 2px solid var(--clay); padding: 13px; }
.choice[aria-checked="true"] .radio { border-color: var(--clay); }
.choice[aria-checked="true"] .radio::after { content: ""; width: 12px; height: 12px; border-radius: 50%; background: var(--clay); }
.fine { font-size: 12px; color: var(--ink-soft); text-align: center; margin: 0; line-height: 1.4; }

/* ---------- Shell, tabs ---------- */
#shell { z-index: 0; }
.tabpane { flex: 1; min-height: 0; display: flex; flex-direction: column; position: relative; }
.tabbar {
  flex: none; display: flex; justify-content: center; gap: 4px; padding: 6px 8px calc(6px + env(safe-area-inset-bottom));
  background: color-mix(in srgb, var(--card) 94%, transparent); border-top: 1px solid var(--line);
}
.tab { flex: 1; max-width: 140px; display: flex; flex-direction: column; align-items: center; gap: 2px; padding: 5px 4px; font-size: 11px; font-weight: 600; color: var(--ink-soft); border-radius: 12px; }
.tab .ic { font-size: 25px; }
.tab[aria-selected="true"] { color: var(--clay-text); }
.topbar { flex: none; display: flex; align-items: center; gap: 10px; padding: calc(8px + env(safe-area-inset-top)) 16px 8px; }
.topbar .who { font-weight: 600; font-size: min(16px, 4.1vw); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-width: 0; }
.topbar .grow { flex: 1; }
.topbar .navtitle { flex: 1; text-align: center; font-size: 17px; }
.topbar .navspace { width: 44px; flex: none; }
.scroll { flex: 1; min-height: 0; overflow-y: auto; scrollbar-width: none; -webkit-overflow-scrolling: touch; }
.scroll::-webkit-scrollbar { display: none; }

/* Journey */
.journey { display: flex; flex: 1; min-height: 0; }
.mappage { flex: 1; min-width: 0; display: flex; flex-direction: column; position: relative; }
.mapcol { display: flex; flex-direction: column; gap: 10px; align-items: center; padding-bottom: 96px; }
.chapterhead { width: 100%; max-width: 592px; padding: 0 16px; display: flex; flex-direction: column; gap: 6px; }
.chapterhead .row { display: flex; align-items: baseline; gap: 8px; }
.chapterhead h1 { font-size: clamp(18px, 5.5vw, 28px); margin: 0; flex: 1; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; line-height: 1.2; }
.pager { display: flex; background: var(--card); border: 1px solid var(--line); border-radius: 999px; flex: none; align-self: center; }
.pager button { width: 34px; height: 34px; display: grid; place-items: center; font-size: 14px; border-radius: 999px; }
.pager button:disabled { opacity: .3; }
.starsline { display: flex; align-items: center; gap: 5px; font-weight: 600; font-size: 15px; }
.starsline img { width: 18px; height: 18px; }
.starsline .next { margin-left: auto; font-weight: 400; font-size: 13px; color: var(--ink-soft); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.stops { position: relative; height: 44px; }
.stops .track { position: absolute; left: 0; right: 0; top: 15px; height: 10px; border-radius: 5px; background: var(--gold-tint); overflow: hidden; }
.stops .fill { height: 100%; border-radius: 5px; background: var(--gold); transition: width .8s ease-out; }
.stops .stop { position: absolute; top: 8px; transform: translateX(-50%); display: flex; flex-direction: column; align-items: center; gap: 3px; font-size: 12px; font-weight: 500; color: var(--ink-soft); }
.stops .stop:last-child { transform: translateX(-100%); }
.stops .stop i { width: 24px; height: 24px; border-radius: 50%; background: var(--card); border: 1.5px solid var(--line); display: grid; place-items: center; color: color-mix(in srgb, var(--gold) 40%, transparent); font-size: 12px; }
.stops .stop.on i { border-color: var(--gold); color: var(--gold); }

.mapwrap { width: 100%; max-width: 560px; padding: 0 12px; }
.map {
  --s: 1; position: relative; aspect-ratio: 1 / 1.25; border-radius: 26px; overflow: hidden; isolation: isolate;
  border: 1px solid var(--line); box-shadow: 0 5px 10px rgb(var(--shadow) / .10); background: var(--paper-deep);
}
.map::after { content: ""; position: absolute; inset: 5px; border-radius: 21px; pointer-events: none; border: 1.2px dashed color-mix(in srgb, var(--gold) 60%, transparent); z-index: 5; }
.map .cloth { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; z-index: -1; }
.map .cloth.mirrored { transform: scaleX(-1); }
@media (prefers-color-scheme: dark) { .map .cloth, .dim-dark { filter: brightness(.36) saturate(.9); } }
.map svg.rope { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; pointer-events: none; }
.node {
  --size: calc(58px * var(--s)); position: absolute; width: calc(var(--size) + 14px * var(--s)); height: calc(var(--size) + 14px * var(--s));
  transform: translate(-50%, -50%); display: grid; place-items: center; border-radius: 50%;
  transition: scale .2s cubic-bezier(.3, 1.6, .5, 1);
}
.node:active:not(:disabled) { scale: .92; }
.node.reveal { animation: node-in .5s cubic-bezier(.3, 1.45, .5, 1) both; animation-delay: calc(.15s + var(--i) * .04s); }
@keyframes node-in { from { opacity: 0; scale: .3; } }
.node .bob { position: absolute; inset: 0; display: grid; place-items: center; }
.node .lip, .node .face, .node .halo, .node svg.sparks { position: absolute; left: 50%; top: 50%; }
.node .lip, .node .face { width: var(--size); height: var(--size); border-radius: 50%; margin: calc(var(--size) / -2) 0 0 calc(var(--size) / -2); }
.node .lip { background: #CDBF9F; translate: 0 calc(4px * var(--s)); box-shadow: 0 3px 4px rgb(31 36 48 / .10); }
.node .face { background: #FBF8F1; }
.node .face::after { content: ""; position: absolute; inset: calc(3.5px * var(--s)); border-radius: 50%; border: 1.6px dashed color-mix(in srgb, var(--clay) 70%, transparent); }
.node .in { position: relative; display: flex; flex-direction: column; align-items: center; color: #1F2430; line-height: 1; translate: 0 -1px; }
.node .n { font-weight: 700; font-size: calc(21px * var(--s)); font-variant-numeric: tabular-nums; }
.node .st { display: flex; margin-top: 1px; }
.node .st img { width: calc(13px * var(--s)); height: calc(13px * var(--s)); }
.node.locked .in { color: #8A8576; translate: 0 0; }
.node.locked .face::after { border-color: #CDBF9F; }
.node.solved .lip { background: #1C2A4C; box-shadow: 0 3px 4px rgb(31 36 48 / .22); }
.node.solved .face { background: #2B3F6E; }
.node.solved .face::after { border-color: var(--gold); }
.node.solved .in, .node.current .in { color: #fff; }
.node.current { --size: calc(66px * var(--s)); z-index: 2; }
.node.current .lip { background: var(--clay-deep); box-shadow: 0 3px 4px rgb(31 36 48 / .22); }
.node.current .face { background: var(--clay); }
.node.current .face::after { border-color: #F3C7B0; }
.node.bonus { --size: calc(68px * var(--s)); }
.node.boss { --size: calc(84px * var(--s)); }
.node.bonus .face::after, .node.boss .face::after { border-color: var(--gold); border-width: 2.5px; }
.node.boss .n { font-size: calc(24px * var(--s)); }
.node.bonus:not(.solved) .n { font-size: calc(17px * var(--s)); }
.node .crown { width: calc(26px * var(--s)); height: calc(22px * var(--s)); object-fit: contain; }
.node .spool { width: calc(20px * var(--s)); height: calc(20px * var(--s)); }
.node .bosslabel { font-size: calc(10px * var(--s)); font-weight: 600; }
.node .halo { width: calc(var(--size) + 22px * var(--s)); height: calc(var(--size) + 22px * var(--s)); margin: calc((var(--size) + 22px * var(--s)) / -2) 0 0 calc((var(--size) + 22px * var(--s)) / -2); border-radius: 50%; background: color-mix(in srgb, var(--clay) 25%, transparent); animation: halo 1.3s ease-in-out infinite alternate; }
@keyframes halo { from { scale: .94; } to { scale: 1.12; } }
.node.current .bob { animation: bob 1.3s ease-in-out infinite alternate; }
@keyframes bob { to { translate: 0 -3px; } }
.node svg.sparks { width: calc(var(--size) + 32px * var(--s)); height: calc(var(--size) + 32px * var(--s)); margin: calc((var(--size) + 32px * var(--s)) / -2) 0 0 calc((var(--size) + 32px * var(--s)) / -2); stroke: var(--clay); stroke-width: 2.5; stroke-linecap: round; fill: none; animation: sparks 1.3s ease-in-out infinite alternate; }
@keyframes sparks { from { opacity: .35; } }
.node.selected:not(.current)::after { content: ""; position: absolute; width: calc(var(--size) + 8px * var(--s)); height: calc(var(--size) + 8px * var(--s)); border-radius: 50%; border: 2.5px solid var(--clay); }
.seal {
  position: absolute; left: 50%; top: 50%; translate: -50% -50%; width: min(280px, 78%); z-index: 3;
  display: flex; flex-direction: column; align-items: center; gap: 8px; text-align: center; padding: 20px 22px;
  background: var(--card); border-radius: 20px; box-shadow: 0 5px 10px rgb(var(--shadow) / .12);
}
.seal::after { content: ""; position: absolute; inset: 5px; border-radius: 15px; border: 1.2px dashed var(--gold); pointer-events: none; }
.seal img { width: 64px; height: 54px; object-fit: contain; }
.seal h2 { font-size: 26px; margin: 0; line-height: 1.1; }
.seal p { margin: 0; font-size: 15px; color: var(--ink-soft); line-height: 1.35; }
.seal .btn { margin-top: 6px; position: relative; z-index: 1; }
.veil { position: absolute; inset: 0; background: color-mix(in srgb, var(--paper) 38%, transparent); }
.playbar { position: absolute; left: 0; right: 0; bottom: 12px; padding: 0 20px; display: flex; justify-content: center; pointer-events: none; }
.playbar .btn { max-width: 520px; pointer-events: auto; box-shadow: 0 var(--lip) 0 var(--clay-deep), 0 9px 12px rgb(var(--shadow) / .18); }
.detailpage { display: none; }

/* Notebook spread on roomy screens (the app's regular size class) */
@media (min-width: 768px) and (min-height: 560px) {
  .journey { max-width: 1240px; margin: 0 auto; width: 100%; }
  .mappage { flex: 0 0 55%; }
  .mappage .playbar { display: none; }
  .mapcol { padding-bottom: 24px; }
  .detailpage { display: block; flex: 1; min-width: 0; overflow-y: auto; padding: 20px 28px 20px 8px; border-left: 1px dashed var(--line); margin: 16px 0; }
  .detail { display: flex; flex-direction: column; gap: 16px; max-width: 460px; margin: 0 auto; padding-left: 20px; }
  .detail h2 { font-size: 32px; margin: 0; line-height: 1.1; }
  .detail p { margin: 0; }
  .detail .stars3 img { width: 28px; height: 28px; margin-right: 8px; }
  .detail .tilerow { display: flex; gap: 14px; align-items: center; }
  .detail .tilerow canvas { width: 96px; height: 96px; flex: none; }
  .detail .links { display: flex; justify-content: flex-end; gap: 6px; }
  .detail .links a { font-size: 14px; font-weight: 500; padding: 6px 8px; }
}

/* Teaser tabs and settings */
.page { max-width: 600px; width: 100%; margin: 0 auto; padding: 4px 16px 28px; display: flex; flex-direction: column; gap: 14px; }
.page > h1 { font-size: 30px; margin: 4px 0 0; }
.page p { margin: 0; line-height: 1.45; }
.page .lead { color: var(--ink-soft); font-size: 15px; }
.inapp { display: inline-flex; align-self: flex-start; align-items: center; gap: 6px; font-size: 13px; font-weight: 600; color: var(--indigo); background: var(--indigo-tint); padding: 5px 10px; border-radius: 999px; }
.quiltgrid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 5px; }
.quiltgrid canvas, .quiltgrid i { width: 100%; aspect-ratio: 1; border-radius: 6px; display: block; }
.quiltgrid i { border: 1px dashed var(--line); background: color-mix(in srgb, var(--card) 60%, transparent); }
.swatches { display: grid; grid-template-columns: repeat(auto-fill, minmax(132px, 1fr)); gap: 10px; }
.swatch { display: flex; align-items: center; gap: 10px; font-size: 14px; font-weight: 500; }
.swatch canvas, .swatch i { width: 40px; height: 40px; border-radius: 9px; flex: none; }
.weekrow { display: flex; gap: 6px; }
.weekrow span { flex: 1; text-align: center; padding: 9px 0 7px; border-radius: 12px; background: var(--card); border: 1px dashed var(--line); font-size: 12px; color: var(--ink-soft); }
.weekrow b { display: block; font-size: 16px; color: var(--ink); font-variant-numeric: tabular-nums; }
.settings h2 { font-size: 13px; font-weight: 600; text-transform: uppercase; letter-spacing: .04em; color: var(--ink-soft); margin: 10px 4px -6px; font-family: var(--sans); }
.group { background: var(--card); border: 1px solid var(--line); border-radius: 18px; overflow: hidden; }
.setrow { display: flex; align-items: center; gap: 12px; min-height: 52px; padding: 8px 16px; font-size: 16px; text-decoration: none; color: var(--ink); width: 100%; text-align: left; }
.setrow + .setrow { border-top: 1px solid var(--line); }
.setrow .grow { flex: 1; }
.setrow .ic { font-size: 20px; color: var(--ink-soft); }
.setrow.danger { color: var(--clay-text); }
.switch { appearance: none; -webkit-appearance: none; width: 51px; height: 31px; border-radius: 999px; background: var(--line); position: relative; flex: none; margin: 0; cursor: pointer; transition: background .2s; }
.switch::after { content: ""; position: absolute; top: 2px; left: 2px; width: 27px; height: 27px; border-radius: 50%; background: #fff; box-shadow: 0 1px 3px rgb(0 0 0 / .25); transition: transform .2s cubic-bezier(.3, 1.3, .5, 1); }
.switch:checked { background: var(--clay); }
.switch:checked::after { transform: translateX(20px); }
input[type=range] { accent-color: var(--clay); width: 130px; }
.foot { font-size: 13px; color: var(--ink-soft); margin: -6px 6px 0; line-height: 1.4; }

.starsline .sl { display: inline-flex; align-items: center; gap: 5px; }
.patch-earned { display: inline-flex; align-items: center; gap: 4px; color: var(--gold); }
.switch.sage:checked { background: var(--sage); }
.volrow input[type=range] { width: min(180px, 45%); }

/* ---------- Solve ---------- */
#solve .solvewrap {
  --gap: 14px; flex: 1; min-height: 0; width: 100%; max-width: 600px; margin: 0 auto;
  display: flex; flex-direction: column; gap: var(--gap);
  padding: calc(8px + env(safe-area-inset-top)) 16px calc(8px + env(safe-area-inset-bottom));
}
#solve .solvewrap.short { --gap: 8px; }
.controls { display: contents; }
.solvehead { order: 1; display: flex; align-items: center; gap: 8px; position: relative; }
.boardarea { order: 2; display: flex; justify-content: center; flex: none; }
.hintslot { order: 3; min-height: 0; flex: 0 1 auto; overflow-y: auto; }
.hintslot:empty, .noticeslot:empty { display: none; }
.spacer { order: 4; flex: 1; min-height: 0; }
.noticeslot { order: 5; }
.toolrow { order: 6; }
.pad { order: 7; }
.solvehead .titles { min-width: 0; flex: 0 1 auto; }
.solvehead h1 { font-size: 22px; margin: 0; line-height: 1.15; white-space: nowrap; }
.short .solvehead h1 { font-size: 18px; }
.solvehead .sub { font-size: 13px; color: var(--ink-soft); white-space: nowrap; }
.solvehead .grow { flex: 1; min-width: 2px; }
.hearts { display: flex; align-items: center; gap: 2px; flex: none; }
.hearts .livecount { font-size: 17px; font-weight: 700; margin-left: 1px; }
.heart { position: relative; width: 26px; height: 26px; }
.short .heart { width: 22px; height: 22px; }
.heart img { position: absolute; inset: 0; width: 100%; height: 100%; transition: transform .4s cubic-bezier(.3, 1.6, .5, 1), opacity .25s; }
.heart.lost .full { transform: scale(.2); opacity: 0; }
.heart:not(.lost) .empty { opacity: 0; }
.gentlepill { display: inline-flex; align-items: center; gap: 5px; height: 30px; padding: 0 9px; border-radius: 999px; background: var(--card); border: 1px dashed color-mix(in srgb, var(--sage) 60%, transparent); color: var(--sage); font-size: 13px; font-weight: 600; flex: none; }
.timer { height: 36px; padding: 0 8px; display: grid; place-items: center; border-radius: 12px; background: var(--card); border: 1px solid var(--line); font-weight: 600; font-size: 17px; font-variant-numeric: tabular-nums; flex: none; }
.short .timer { font-size: 15px; }
.boardbox { position: relative; width: min(100%, 56dvh); max-width: 100%; aspect-ratio: 1; box-shadow: 0 4px 8px rgb(var(--shadow) / .10); }
.boardbox canvas { position: absolute; inset: 0; width: 100%; height: 100%; display: block; }
.cells { position: absolute; inset: 0; display: grid; grid-template-columns: repeat(9, 1fr); grid-template-rows: repeat(9, 1fr); }
.cells button { border-radius: 0; outline-offset: -3px; }
.toolrow { display: flex; gap: 10px; }
.tool { flex: 1; min-height: 60px; flex-direction: column; gap: 4px; font-size: 13px; font-weight: 500; }
.tool .ic { font-size: 21px; }
.tool .badge { position: absolute; top: 4px; right: 4px; background: var(--gold); color: #fff; font-size: 12px; font-weight: 700; padding: 2px 7px; border-radius: 999px; font-variant-numeric: tabular-nums; line-height: 1.2; }
.pad { display: flex; gap: 6px; }
.digit { flex: 1; min-width: 0; height: 72px; flex-direction: column; color: var(--player); font-variant-numeric: tabular-nums; }
.digit b { font-size: 30px; font-weight: 500; line-height: 1.1; }
.digit small { font-size: 12px; font-weight: 500; color: var(--ink-soft); line-height: 1.2; }
.digit.done { color: color-mix(in srgb, var(--ink-soft) 40%, transparent); opacity: 1; }
.digit.done small { color: inherit; }
.digit.active b { color: var(--clay-text); }

.notice {
  position: relative; display: flex; align-items: center; gap: 10px; padding: 10px 14px; border-radius: 16px; width: 100%; text-align: left;
  background: var(--clay-tint); box-shadow: 0 3px 6px rgb(var(--shadow) / .10); font-size: 14px; font-weight: 500; line-height: 1.35;
  animation: pop .35s cubic-bezier(.3, 1.4, .5, 1) both; transform-origin: bottom;
}
.notice::after { content: ""; position: absolute; inset: 3px; border-radius: 13px; border: 1px dashed color-mix(in srgb, var(--clay) 55%, transparent); pointer-events: none; }
.notice > .ic { color: var(--clay-text); font-size: 17px; }
.notice span { flex: 1; }
.notice .btn { width: auto; z-index: 1; }
@keyframes pop { from { opacity: 0; transform: scale(.9); } }
.hintcard { padding: 14px; display: flex; flex-direction: column; gap: 10px; animation: rise .3s cubic-bezier(.3, 1.2, .5, 1) both; }
@keyframes rise { from { opacity: 0; transform: translateY(14px); } }
.hintcard .top { display: flex; align-items: center; gap: 8px; }
.hintcard .top b { font-size: 15px; font-weight: 600; display: inline-flex; align-items: center; gap: 6px; }
.hintcard .top .cost { margin-left: auto; font-size: 12px; color: var(--ink-soft); white-space: nowrap; }
.hintcard .top .x { margin-left: auto; width: 32px; height: 32px; display: grid; place-items: center; color: var(--ink-soft); font-size: 14px; position: relative; z-index: 1; }
.hintcard .top .cost + .x { margin-left: 0; }
.hintcard p { margin: 0; font-size: 15px; line-height: 1.4; }
.hintcard .acts { display: flex; align-items: center; gap: 10px; position: relative; z-index: 1; }
.hintcard .acts .btn { max-width: 260px; }
.hintcard .acts .textbtn { font-size: 14px; font-weight: 500; padding: 6px; }

/* Wide: board beside the pad (landscape) */
#solve .solvewrap.wide { max-width: none; flex-direction: row; gap: 16px; align-items: stretch; }
.wide .boardarea { order: 0; flex: 1 1 0; min-width: 0; align-items: center; container-type: size; }
.wide .boardbox { width: min(100cqw, 100cqh, 760px); }
.wide .controls { order: 1; display: flex; flex-direction: column; align-items: center; gap: var(--gap); flex: 1 1 0; min-width: 250px; min-height: 0; }
.wide .controls > * { width: 100%; max-width: 380px; }
.wide.lefty .controls { order: -1; }
.wide .pad { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; }
.wide .digit { height: var(--keyh, 88px); }
.wide .digit b { font-size: min(44px, calc(var(--keyh, 88px) * .5)); }
.wide.short .tool { min-height: 44px; gap: 1px; font-size: 11px; }
.wide.short .tool .ic { font-size: 16px; }
.wide.tiny .digit small { display: none; }
.wide .controls { position: relative; }
.wide .noticeslot { position: absolute; left: 50%; translate: -50% 0; top: 0; z-index: 4; }
.wide .solvehead { order: 0; }
.wide .hintslot { overflow-y: auto; min-height: 0; }
.wide.short.hinting .toolrow, .wide.short.hinting .pad, .wide.short.hinting .spacer { display: none; }

/* Coach marks */
.coach { position: absolute; top: calc(4px + env(safe-area-inset-top)); left: 0; right: 0; z-index: 8; display: flex; justify-content: center; padding: 0 16px; pointer-events: none; }
.coach .card { pointer-events: auto; max-width: 408px; width: 100%; box-shadow: 0 4px 10px rgb(var(--shadow) / .18); display: flex; flex-direction: column; gap: 8px; animation: drop .4s cubic-bezier(.3, 1.2, .5, 1) both; }
@keyframes drop { from { opacity: 0; transform: translateY(-20px); } }
.coach h2 { font-size: 18px; margin: 0; flex: 1; }
.coach p { margin: 0; font-size: 15px; color: var(--ink-soft); line-height: 1.4; }
.coach .look { font-size: 13px; font-weight: 600; color: var(--clay-text); display: flex; align-items: center; gap: 6px; }
.coach .rowx { display: flex; align-items: center; position: relative; z-index: 1; }
.coach .rowx .btn { width: 110px; margin-left: auto; }
.coach .skip { font-size: 15px; color: var(--ink-soft); padding: 8px 4px; }

/* ---------- Solved ---------- */
#solved { position: absolute; inset: 0; overflow-y: auto; display: flex; z-index: 6; animation: fade .35s ease both; }
@keyframes fade { from { opacity: 0; } }
#solved .closex { position: fixed; top: calc(16px + env(safe-area-inset-top)); left: 16px; z-index: 3; }
.solvedcols { margin: auto; width: 100%; padding: 20px; display: flex; flex-direction: column; align-items: center; gap: 18px; }
.tilecol { width: 100%; max-width: 440px; display: flex; flex-direction: column; align-items: center; gap: 10px; padding-top: 40px; }
.tilecol h1 { font-size: 38px; margin: 0; line-height: 1.1; position: relative; z-index: 2; white-space: nowrap; }
.tilecol h1.done { font-size: clamp(30px, 9vw, 42px); animation: cheer .5s cubic-bezier(.3, 1.7, .5, 1); }
@keyframes cheer { from { transform: scale(.8); } }
.tilecol .meta { font-size: 15px; color: var(--ink-soft); margin: 0; position: relative; z-index: 2; padding: 3px 12px; border-radius: 999px; background: color-mix(in srgb, var(--paper) 88%, transparent); }
.tilestage { position: relative; width: min(100%, 40dvh, 400px); aspect-ratio: 1; margin: 30px 0 18px; }
.tilestage canvas { position: absolute; inset: 8px; width: calc(100% - 16px); height: calc(100% - 16px); z-index: 1; filter: drop-shadow(0 4px 10px rgb(var(--shadow) / .12)); }
.tilestage.jump canvas { animation: jump .8s cubic-bezier(.3, 1.8, .5, 1); }
@keyframes jump { 25% { transform: scale(1.08); } }
.sun { position: absolute; left: 50%; top: 50%; width: 136%; height: 136%; margin: -68% 0 0 -68%; opacity: 0; transform: scale(.5); transition: transform .8s cubic-bezier(.3, 1.5, .5, 1), opacity .5s; pointer-events: none; }
.sun img { width: 100%; height: 100%; animation: turn 51.4s linear infinite, breathe 4.83s ease-in-out infinite alternate; }
@keyframes breathe { from { scale: .975; } to { scale: 1.025; } }
.sun.on { opacity: 1; transform: none; }
@keyframes turn { to { transform: rotate(360deg); } }
.burst { position: absolute; inset: 0; z-index: 2; pointer-events: none; }
.burst img {
  position: absolute; left: 50%; top: 50%; width: var(--sz); height: var(--sz); margin: calc(var(--sz) / -2) 0 0 calc(var(--sz) / -2);
  opacity: 0; transform: translate(calc(var(--dx) * .25), calc(var(--dy) * .25)) rotate(calc(var(--spin) - 120deg)) scale(.2);
}
.burst.out img { animation: burst-out .75s cubic-bezier(.3, 1.3, .5, 1) forwards, burst-gone .9s ease-in 1.5s forwards; animation-delay: var(--d), 1.5s; }
@keyframes burst-out { to { opacity: 1; transform: translate(var(--dx), var(--dy)) rotate(var(--spin)) scale(1); } }
@keyframes burst-gone { from { opacity: 1; transform: translate(var(--dx), var(--dy)) rotate(var(--spin)); } to { opacity: 0; transform: translate(var(--dx), var(--dy2)) rotate(var(--spin)); } }
.rewards { width: 100%; max-width: 520px; display: flex; flex-direction: column; align-items: center; gap: 16px; opacity: 0; transition: opacity .4s ease-out; }
.rewards.on { opacity: 1; }
.stars3big { display: flex; align-items: flex-end; gap: 10px; }
.stars3big .s { width: 56px; height: 56px; position: relative; transform: scale(.7) rotate(calc(var(--r) - 35deg)); transition: transform .5s cubic-bezier(.3, 1.7, .5, 1); }
.stars3big .s:nth-child(2) { width: 68px; height: 68px; translate: 0 -8px; }
.stars3big .s img { position: absolute; inset: 0; width: 100%; height: 100%; }
.stars3big .s .f { opacity: 0; transition: opacity .15s; }
.stars3big .s.on { transform: rotate(var(--r)); }
.stars3big .s.on .f { opacity: 1; }
.rewards .starcount { font-size: 20px; margin: 0; }
.rewards .starnote { font-size: 14px; color: var(--ink-soft); margin: -10px 0 0; }
.spoolcard { width: 100%; display: flex; align-items: center; gap: 14px; padding: 10px 14px; }
.spoolcard img { width: 52px; height: 52px; transform: rotate(-8deg); transition: transform .3s cubic-bezier(.3, 1.8, .5, 1); }
.spoolcard img.w { transform: rotate(8deg); }
.spoolcard b { display: block; font-size: 24px; font-family: var(--serif); font-weight: 600; font-variant-numeric: tabular-nums; line-height: 1.2; }
.spoolcard small { font-size: 14px; color: var(--ink-soft); }
.rrow { width: 100%; display: flex; align-items: center; gap: 10px; padding: 0 8px; font-size: 15px; font-weight: 500; }
.rrow .ic { font-size: 18px; }
.nextreward { width: 100%; display: flex; flex-direction: column; align-items: center; gap: 6px; padding-top: 4px; }
.nextreward .bar { position: relative; width: 100%; height: 28px; }
.nextreward .bar .track { position: absolute; left: 0; right: 13px; top: 7px; height: 14px; border-radius: 7px; background: var(--gold-tint); }
.nextreward .bar .fill { position: absolute; left: 0; top: 7px; height: 14px; min-width: 14px; border-radius: 7px; background: var(--gold); width: 14px; transition: width .9s ease-out .3s; }
.nextreward .bar img { position: absolute; right: 0; top: 0; width: 28px; height: 28px; }
.nextreward small { font-size: 13px; color: var(--ink-soft); }
.rewards .btn { margin-top: 6px; }
@media (max-aspect-ratio: 115/100) { .rewards > .btn { position: sticky; bottom: calc(10px + env(safe-area-inset-bottom)); z-index: 3; box-shadow: 0 var(--lip) 0 var(--clay-deep), 0 9px 14px rgb(var(--shadow) / .2); } }
.rewards .quiet { font-size: 14px; color: var(--ink-soft); text-align: center; margin: 0; line-height: 1.45; }
@media (min-aspect-ratio: 115/100) and (min-width: 760px) {
  .solvedcols { flex-direction: row; gap: 24px; max-width: 1040px; }
  .tilecol { flex: 1; max-width: none; padding-top: 0; }
  .tilestage { width: min(100%, calc(100dvh - 210px), 420px); min-width: 150px; }
  .tilecol { align-self: flex-start; position: sticky; top: 0; padding-top: 4px; }
  .rewards { flex: 0 1 420px; }
}

/* ---------- Sheets ---------- */
.scrim { position: absolute; inset: 0; z-index: 60; background: rgb(20 22 28 / .32); display: flex; align-items: flex-end; justify-content: center; animation: fade .2s ease both; }
.sheet {
  position: relative; width: 100%; max-width: 520px; max-height: 92dvh; overflow-y: auto; isolation: isolate;
  border-radius: 26px 26px 0 0; padding: 26px 24px calc(22px + env(safe-area-inset-bottom));
  display: flex; flex-direction: column; align-items: center; gap: 16px; text-align: center;
  box-shadow: 0 -6px 24px rgb(var(--shadow) / .18); animation: sheet-up .38s cubic-bezier(.3, 1.15, .5, 1) both;
}
@keyframes sheet-up { from { transform: translateY(60%); opacity: 0; } }
@media (min-width: 620px) { .scrim { align-items: center; } .sheet { border-radius: 26px; } }
.sheet h2 { font-size: 30px; margin: 0; line-height: 1.1; }
.sheet p { margin: 0; font-size: 15px; color: var(--ink-soft); line-height: 1.45; max-width: 400px; }
.sheet .btns { width: 100%; max-width: 372px; display: flex; flex-direction: column; gap: 12px; }
.sheet .hearts3 img { width: 34px; height: 34px; margin: 0 3px; }
.sheet .bigic { font-size: 44px; color: var(--gold); }
.sheet .appicon { width: 92px; height: 92px; border-radius: 22%; box-shadow: 0 5px 12px rgb(var(--shadow) / .18); }
.sheet .qr { display: none; }
@media (hover: hover) and (pointer: fine) and (min-width: 760px) {
  .sheet .qr { display: flex; align-items: center; gap: 14px; text-align: left; font-size: 14px; color: var(--ink-soft); background: var(--card); border: 1px dashed var(--line); border-radius: 16px; padding: 10px 14px 10px 10px; max-width: 372px; }
  .sheet .qr img { width: 96px; height: 96px; border-radius: 8px; background: #fff; flex: none; }
}
.sheet .closex { position: absolute; top: 14px; right: 14px; width: 36px; height: 36px; display: grid; place-items: center; color: var(--ink-soft); border-radius: 50%; }
.sheet.left { text-align: left; align-items: stretch; }

.toast { position: absolute; z-index: 70; top: calc(8px + env(safe-area-inset-top)); left: 50%; translate: -50% 0; background: var(--ink); color: var(--paper); font-size: 15px; font-weight: 500; padding: 10px 16px; border-radius: 999px; animation: drop .35s cubic-bezier(.3, 1.3, .5, 1) both; max-width: calc(100% - 32px); text-align: center; }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: .01ms !important; animation-delay: 0s !important; animation-iteration-count: 1 !important; transition-duration: .01ms !important; }
  .sun img, .node .halo, .node.current .bob, .node svg.sparks { animation: none !important; }
}
