/* Guff Tumble
   Wash day: a white tumble dryer whose display is the clock, the day's nine letters on
   socks, tees, jumpers and polka boxers pegged out on a washing line, a wicker basket
   for the word you're making, and GuffBot with a sock stuck on his head. */
:root {
  --paper: #EEF5F8; --card: #FFFFFF; --ink: #23303A; --muted: #5F6F7A; --line: #D3E1E8;
  --blue: #3D8EB9; --blue-deep: #23628A; --sun: #F2C14E; --sun-deep: #C9971F; --pink: #E15A97;
  --good: #2E8B57; --bad: #C0392B; --wicker: #D9B27C; --wicker-deep: #A97C43; --string: #8C7A63;
  --note: #FFFDF3; --chrome: #C9D3DA;
  --display: "Fraunces", "Iowan Old Style", Georgia, serif;
  --body: "Nunito", -apple-system, system-ui, "Segoe UI", sans-serif;
  --t: min(9vw, 48px);     /* laundry in the basket */
  --g: min(17.5vw, 74px);  /* laundry on the line (Carl, 11 Nov: bigger, the letters were too hard to read) */
}
@media (prefers-color-scheme: dark) {
  :root { --paper: #17222A; --card: #22313B; --ink: #EAF2F6; --muted: #A9BBC6; --line: #34495A;
    --blue: #5AA9D6; --blue-deep: #A9D8F2; --note: #26343E; --string: #B7A58C; --chrome: #6B7C88; }
}
* { box-sizing: border-box; }
[hidden] { display: none !important; }
html { -webkit-text-size-adjust: 100%; }
body { margin: 0; min-height: 100dvh; color: var(--ink); font: 500 17px/1.45 var(--body);
  background: var(--paper) radial-gradient(circle at 80% -10%, rgba(255,255,255,.95), transparent 55%);
  padding-bottom: env(safe-area-inset-bottom); }
@media (prefers-color-scheme: dark) { body { background: var(--paper); } }
button { font: inherit; color: inherit; cursor: pointer; touch-action: manipulation; -webkit-tap-highlight-color: transparent; }
.board, .basket, .peg { -webkit-user-select: none; user-select: none; touch-action: manipulation; }
h3 { font: 800 1rem/1.2 var(--display); color: var(--blue-deep); margin: 20px 0 6px; }
.muted { color: var(--muted); } .centre { text-align: center; }

/* header: GUFF in a soap-powder pill, TUMBLE in letters that won't sit still */
.top { display: flex; align-items: center; justify-content: space-between; max-width: 480px; margin: 0 auto;
  padding: calc(12px + env(safe-area-inset-top, 0px)) 16px 2px; }
.brand { display: inline-flex; align-items: center; gap: 6px; }
.guff { font: 900 .78rem/1 var(--body); letter-spacing: .14em; text-transform: uppercase; color: #fff; background: var(--pink);
  padding: 6px 8px 5px; border-radius: 999px; transform: rotate(-6deg); box-shadow: 0 2px 0 #B23C74; }
.tumble { display: inline-flex; gap: 1px; }
.tumble i { font: 800 1.55rem/1 var(--display); font-style: normal; color: var(--blue-deep); display: inline-block; animation: tumble 3.4s ease-in-out infinite; }
.tumble i:nth-child(1) { transform: rotate(-9deg) translateY(2px); animation-delay: -.2s; }
.tumble i:nth-child(2) { transform: rotate(7deg) translateY(-2px); animation-delay: -1.1s; color: var(--pink); }
.tumble i:nth-child(3) { transform: rotate(-4deg); animation-delay: -.6s; }
.tumble i:nth-child(4) { transform: rotate(11deg) translateY(3px); animation-delay: -2s; color: var(--sun-deep); }
.tumble i:nth-child(5) { transform: rotate(-12deg) translateY(-1px); animation-delay: -1.5s; }
.tumble i:nth-child(6) { transform: rotate(6deg) translateY(1px); animation-delay: -2.6s; color: var(--pink); }
@keyframes tumble { 50% { translate: 0 -2px; rotate: 6deg; } }
.no { font: 800 .95rem var(--display); color: var(--muted); }

.app { max-width: 480px; margin: 0 auto; padding: 4px 16px 28px; }

/* GuffBot and his bubble */
.host { display: flex; align-items: center; gap: 10px; margin: 8px 0 6px; min-height: 80px; }
.gb { position: relative; flex: none; width: 72px; height: 72px; animation: bob 3.2s ease-in-out infinite; }
.gb img { position: relative; width: 100%; height: 100%; display: block; }
.gb .beacon { position: absolute; left: 50%; top: 0; width: 26px; height: 22px; margin-left: -13px; border-radius: 50%; opacity: 0; }
.gb .sock { position: absolute; width: 40px; left: 22px; top: -14px; transform: rotate(14deg); transform-origin: 30% 10%; animation: dangle 2.6s ease-in-out infinite; }
@keyframes dangle { 50% { transform: rotate(4deg); } }
.gb .hat { display: none; position: absolute; width: 54px; left: 14px; top: -16px; transform: rotate(-8deg); }
.xmas .gb .hat { display: block; } .xmas .gb .sock { display: none; }
@keyframes bob { 50% { transform: translateY(-3px) rotate(-2deg); } }
.bubble { position: relative; flex: 1; margin: 0; background: var(--note); border: 2px solid var(--blue); border-radius: 16px;
  padding: 9px 13px; font: italic 500 1.02rem/1.32 var(--display); }
.bubble::before { content: ""; position: absolute; left: -9px; top: 50%; margin-top: -7px; border: 7px solid transparent; border-right-color: var(--blue); border-left: 0; }
body.playing .host { min-height: 0; margin-bottom: 2px; }
body.playing .gb { width: 48px; height: 48px; }
body.playing .gb .sock { width: 28px; left: 14px; top: -10px; }
body.playing .bubble { font-size: .94rem; padding: 6px 11px; }
/* the last five seconds: his beacon flashes under the sock */
body.hurry .gb .beacon { animation: beacon .5s steps(2) infinite; }
@keyframes beacon { 50% { opacity: 1; background: radial-gradient(#fff6c9, #ff8a00 60%, transparent 72%); box-shadow: 0 0 22px 10px rgba(255,140,0,.55); } }

/* the dryer: big and tumbling before the start, a compact clock while playing */
.dryer { display: flex; align-items: center; gap: 14px; margin: 10px auto 12px; padding: 12px 16px; width: fit-content;
  background: linear-gradient(#fff, #EEF2F4); border: 2px solid var(--chrome); border-radius: 18px; box-shadow: 0 6px 0 var(--chrome), 0 10px 22px rgba(35,48,58,.12); }
.door { position: relative; width: 104px; height: 104px; border-radius: 50%; padding: 8px;
  background: radial-gradient(circle at 35% 30%, #fff, #B8C4CC 70%); box-shadow: inset 0 0 0 2px #9AA8B2; }
.drum { position: relative; width: 100%; height: 100%; border-radius: 50%; overflow: hidden;
  background: radial-gradient(circle at 40% 35%, #CFE7F5, #6FA8C9 80%); box-shadow: inset 0 4px 14px rgba(0,0,0,.35); animation: spin 1.6s linear infinite; }
.drum b { position: absolute; width: 34%; height: 26%; border-radius: 40% 50% 45% 55%; background: var(--c); box-shadow: inset -4px -4px 0 rgba(0,0,0,.12); }
.drum b:nth-child(1) { left: 12%; top: 18%; } .drum b:nth-child(2) { left: 52%; top: 14%; border-radius: 20% 60%; }
.drum b:nth-child(3) { left: 56%; top: 52%; } .drum b:nth-child(4) { left: 16%; top: 56%; border-radius: 60% 20%; }
.drum b:nth-child(5) { left: 36%; top: 36%; width: 26%; height: 22%; }
.drum::after { content: ""; position: absolute; inset: 0; border-radius: 50%; background: linear-gradient(135deg, rgba(255,255,255,.45), transparent 45%); }
@keyframes spin { to { transform: rotate(360deg); } }
.panel { display: flex; flex-direction: column; align-items: center; gap: 10px; }
.led { font: 700 1.9rem/1 ui-monospace, "SF Mono", Menlo, monospace; letter-spacing: .04em; color: #7CFFB2; background: #13221B;
  padding: 8px 10px 7px; border-radius: 8px; box-shadow: inset 0 2px 6px rgba(0,0,0,.6); text-shadow: 0 0 8px rgba(124,255,178,.7); font-variant-numeric: tabular-nums; }
.knob { width: 34px; height: 34px; border-radius: 50%; background: radial-gradient(circle at 35% 30%, #fff, #AEBBC4); box-shadow: 0 2px 0 #8F9DA7; position: relative; }
.knob::after { content: ""; position: absolute; left: 50%; top: 4px; width: 3px; height: 11px; margin-left: -1.5px; background: var(--ink); border-radius: 2px; }
.dryer.running { padding: 8px 12px; gap: 12px; margin: 4px auto 10px; }
.dryer.running .door { width: 62px; height: 62px; padding: 5px; }
.dryer.running .drum { animation-duration: .9s; }
.dryer.running .panel { flex-direction: row; }
.dryer.running .led { font-size: 2.1rem; }
.dryer.running .knob { width: 28px; height: 28px; }
body.hurry .led { color: #FF8A7A; text-shadow: 0 0 10px rgba(255,90,70,.8); animation: blink .5s steps(2) infinite; }
body.hurry .dryer { animation: rattle .12s linear infinite; }
@keyframes blink { 50% { opacity: .45; } }
@keyframes rattle { 25% { transform: translate(-1px, 1px) rotate(-.5deg); } 75% { transform: translate(1px, -1px) rotate(.5deg); } }

/* the laundry */
.garment { position: relative; display: inline-grid; place-items: center; width: var(--t); height: var(--t); }
.garment svg { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; filter: drop-shadow(0 2px 2px rgba(0,0,0,.15)); }
.garment b { position: absolute; left: 50%; top: 56%; width: 56%; aspect-ratio: 1; transform: translate(-50%, -50%);
  display: grid; place-items: center; border-radius: 50%; background: #fff; border: 2px solid rgba(35,48,58,.22);
  box-shadow: 0 1px 3px rgba(0,0,0,.25); font: 900 calc(var(--t) * .4)/1 var(--body); color: #1B2630; }
.garment.sock b { left: 44%; top: 34%; width: 50%; }
.garment.boxers b { top: 50%; }
.garment.vest b { top: 60%; }
.garment.jumper b { top: 52%; }
.garment b:empty { display: none; }

/* the washing line: two lines, five on top and four below */
.line { margin: 4px -4px 14px; }
.row { position: relative; display: flex; justify-content: center; gap: 4px; padding-top: 14px; }
.row + .row { margin-top: 2px; }
.row::before { content: ""; position: absolute; left: 2%; right: 2%; top: 0; height: 22px;
  border-bottom: 2px solid var(--string); border-radius: 0 0 50% 50% / 0 0 100% 100%; }
.peg { position: relative; --t: var(--g); width: calc(var(--g) + 2px); height: calc(var(--g) + 12px); padding: 10px 0 0; border: 0; background: none;
  transform-origin: 50% 0; animation: sway 3.4s ease-in-out infinite; animation-delay: calc(var(--d) * -3); }
.row .peg:nth-child(1), .row .peg:nth-child(5) { margin-top: -2px; } .row .peg:nth-child(3) { margin-top: 5px; }
.row .peg:nth-child(2), .row .peg:nth-child(4) { margin-top: 3px; }
.row:last-child .peg:nth-child(2), .row:last-child .peg:nth-child(3) { margin-top: 5px; } .row:last-child .peg:nth-child(4) { margin-top: -2px; }
.peg::before { content: ""; position: absolute; left: 50%; top: 0; width: 8px; height: 18px; margin-left: -4px; border-radius: 2px;
  background: linear-gradient(90deg, #C99A62, #E4BE8A 50%, #C99A62); box-shadow: 0 1px 0 rgba(0,0,0,.2); z-index: 2; }
.peg .garment { transition: opacity .15s, transform .15s; }
.peg:active:not(:disabled) .garment { transform: translateY(3px) scale(.95); }
.peg.used .garment { opacity: 0; transform: translateY(14px) scale(.9); }
.peg:disabled { cursor: default; }
@keyframes sway { 0%, 100% { rotate: -2deg; } 50% { rotate: 2deg; } }
.board.landing .garment { animation: land .55s cubic-bezier(.3,1.6,.6,1) backwards; animation-delay: var(--d); }
@keyframes land { from { transform: translateY(-140px) rotate(-40deg); opacity: 0; } }

/* the basket: the word you're making */
.basket { display: flex; justify-content: center; gap: 2px; min-height: calc(var(--t) * .9 + 14px); margin: 2px 0 8px; padding: 6px 8px;
  border-radius: 10px 10px 22px 22px; cursor: pointer;
  background: repeating-linear-gradient(90deg, var(--wicker) 0 7px, var(--wicker-deep) 7px 9px), var(--wicker);
  box-shadow: inset 0 3px 0 rgba(255,255,255,.35), inset 0 -4px 0 rgba(0,0,0,.15), 0 3px 8px rgba(0,0,0,.12); }
.slot { width: calc(var(--t) * .9); height: calc(var(--t) * .9); display: grid; place-items: center; }
.slot .garment { --t: calc(min(9vw, 48px) * .9); animation: drop .18s ease-out; }
@keyframes drop { from { transform: translateY(-12px); opacity: .3; } }

/* buttons */
.controls { display: grid; grid-template-columns: auto 1fr; grid-template-areas: "edit bank" "done done"; gap: 10px; align-items: stretch; }
.edit { grid-area: edit; display: flex; gap: 6px; }
.ghost { border: 1px solid var(--line); background: var(--card); border-radius: 12px; padding: 0 14px; font-weight: 800; color: var(--muted); }
.fold, .start { border: 0; border-radius: 14px; background: var(--sun); color: #23303A; font: 900 1.2rem var(--body); padding: 14px 18px;
  box-shadow: 0 4px 0 var(--sun-deep); transition: transform .08s, box-shadow .08s; }
.controls .fold { grid-area: bank; }
.fold:active:not(:disabled), .start:active { transform: translateY(3px); box-shadow: 0 1px 0 var(--sun-deep); }
.fold:disabled { opacity: .45; cursor: default; }
.done { grid-area: done; border: 2px solid var(--blue); background: transparent; color: var(--blue-deep); border-radius: 14px; padding: 10px; font-weight: 800; }
.done.sure { background: var(--blue); color: #fff; }
.start { display: block; width: 100%; font-size: 1.35rem; padding: 18px; background: var(--blue); color: #fff; box-shadow: 0 5px 0 var(--blue-deep);
  animation: nudge 2.6s ease-in-out 1.2s infinite; }
@keyframes nudge { 0%, 86%, 100% { transform: none; } 90% { transform: translateY(-3px) rotate(-1deg); } 95% { transform: translateY(0) rotate(1deg); } }

/* folded words while playing: the last one counts */
.banked { list-style: none; padding: 0; margin: 14px 0 0; display: flex; flex-wrap: wrap; gap: 6px; }
.banked li { display: inline-flex; gap: 8px; align-items: baseline; background: var(--card); border: 1px solid var(--line); border-radius: 10px; padding: 5px 12px;
  box-shadow: 0 3px 0 -1px var(--card), 0 3px 0 0 var(--line); }
.banked li b { font: 800 1rem var(--display); letter-spacing: .05em; }
.banked li span { font-size: .8rem; color: var(--muted); }
.banked li em { font-style: normal; font-size: .72rem; font-weight: 900; text-transform: uppercase; letter-spacing: .06em; color: var(--blue-deep); }
.banked li.top { border-color: var(--blue); box-shadow: inset 0 0 0 1px var(--blue), 0 3px 0 -1px var(--card), 0 3px 0 0 var(--blue); }
.banked li.old { opacity: .5; } .banked li.old b { text-decoration: line-through; text-decoration-thickness: 2px; }
.banked li.pop { animation: pop .35s cubic-bezier(.3,1.8,.5,1); }
@keyframes pop { from { transform: scale(.4); opacity: 0; } }

/* the result */
.result { margin-top: 4px; }
.score { text-align: center; background: var(--card); border: 1px solid var(--line); border-radius: 18px; padding: 16px 12px 14px; position: relative; }
.score.max { border-color: var(--sun); box-shadow: 0 0 0 3px rgba(242,193,78,.35); }
.big { font: 500 1.1rem var(--display); }
.big b { font-size: 3.2rem; line-height: 1; margin-right: 4px; color: var(--blue-deep); }
.when { color: var(--muted); margin-top: 6px; } .when b { color: var(--ink); font-size: 1.15rem; }
.badge { position: absolute; top: -12px; right: 12px; background: var(--sun); color: #23303A; font-weight: 900; font-size: .85rem; border-radius: 999px; padding: 4px 10px; transform: rotate(5deg); box-shadow: 0 2px 0 var(--sun-deep); }
.mini { display: inline-flex; gap: 1px; vertical-align: middle; }
.mini .garment { --t: 34px; }
.mini.yours { margin-top: 10px; gap: 2px; } .mini.yours .garment { --t: 40px; }
.actions { margin: 14px 0 4px; } .actions .fold { width: 100%; }
.verdicts { list-style: none; padding: 0; margin: 0; }
.verdicts li { display: grid; grid-template-columns: 1fr auto 9.5em; gap: 10px; align-items: baseline; padding: 6px 2px; border-bottom: 1px dashed var(--line); }
.verdicts b { font: 800 1rem var(--display); letter-spacing: .05em; }
.verdicts span { color: var(--muted); font-size: .85rem; font-variant-numeric: tabular-nums; }
.verdicts em { font-style: normal; font-size: .85rem; text-align: right; font-weight: 700; }
.verdicts .ok em { color: var(--muted); } .verdicts .no em { color: var(--bad); } .verdicts .no b { text-decoration: line-through; opacity: .6; }
.verdicts .stands em { font-weight: 900; color: var(--good); }
.corner { display: flex; gap: 10px; align-items: flex-start; margin: 18px 0 6px; background: var(--note); border: 2px dashed var(--blue); border-radius: 14px; padding: 10px 12px; }
.corner img { flex: none; }
.corner p { margin: 2px 0 8px; } .corner small { color: var(--muted); }
.stats { display: grid; grid-template-columns: repeat(4, 1fr); gap: 6px; margin: 16px 0 4px; text-align: center; font-size: .78rem; color: var(--muted); }
.stats b { display: block; font: 800 1.35rem var(--display); color: var(--ink); }
.next { text-align: center; color: var(--muted); font-weight: 800; margin: 14px 0 0; }

/* how to play: quiet, under everything */
.how { margin: 24px 0 0; font-size: .92rem; color: var(--muted); }
.how summary { cursor: pointer; font-weight: 800; color: var(--blue-deep); }
.how p { margin: 6px 0; }
body.playing .how, body.playing .foot { display: none; }
.foot { margin: 22px 0 0; font-size: .82rem; color: var(--muted); text-align: center; }

.toast { position: fixed; left: 50%; bottom: calc(20px + env(safe-area-inset-bottom)); transform: translateX(-50%); background: var(--ink); color: var(--paper);
  padding: 10px 16px; border-radius: 12px; font-weight: 700; z-index: 30; }

/* the maximum-score party */
.party { position: fixed; inset: 0; pointer-events: none; overflow: hidden; z-index: 40; }
.drop { position: absolute; top: -60px; font-size: 34px; animation: fall 2.6s cubic-bezier(.4,.1,.7,1) forwards; }
@keyframes fall { to { transform: translateY(115vh) rotate(var(--r)); } }

@media (prefers-reduced-motion: reduce) { *, *::before, *::after { animation: none !important; transition: none !important; } }
.basket.empty::after { content: "Tap the washing to fill the basket"; align-self: center; font: italic 600 .9rem var(--display); color: rgba(60,40,15,.75); background: rgba(255,248,232,.8); padding: 3px 10px; border-radius: 999px; }
body:not(.playing) .basket.empty::after { content: "The basket's waiting"; }
