/* ---------------------------------------------------------
   LaughRecap
   pastel yellow, clouds, thick outlines, flat fills only
--------------------------------------------------------- */

:root {
  --butter:   #FFF3C7;
  --butter-2: #FFEAA6;
  --cream:    #FFFDF4;
  --ink:      #2C2318;
  --ink-soft: #6B5D48;
  --sun:      #FFD23F;
  --pink:     #FFB3C7;
  --blue:     #A9D9F5;
  --mint:     #B6E7C4;
  --lilac:    #D8C4F5;
  --tomato:   #FF7A59;

  --edge: 3px solid var(--ink);
  --pop: 6px 6px 0 var(--ink);
  --pop-sm: 4px 4px 0 var(--ink);
  --r-blob: 42px;
  --r-pill: 999px;
}

* { box-sizing: border-box; }

html { scroll-behavior: smooth; }

body {
  margin: 0;
  background: var(--butter);
  color: var(--ink);
  font-family: "Fredoka", ui-rounded, "SF Pro Rounded", "Segoe UI", system-ui, sans-serif;
  font-size: 17px;
  line-height: 1.55;
  overflow-x: hidden;
}

h1, h2, h3 { margin: 0; line-height: 1.1; font-weight: 600; letter-spacing: -0.02em; }
p { margin: 0; }
button { font-family: inherit; }

.mono-inline, .code {
  font-family: "DM Mono", ui-monospace, SFMono-Regular, Menlo, monospace;
}

/* ---------- floaty background ---------- */

.sky { position: fixed; inset: 0; pointer-events: none; z-index: 0; }

.cloud { position: absolute; fill: #FFFDF4; opacity: .85; }
.cloud-a { width: 260px; top: 8%;  left: -60px;  animation: drift 34s ease-in-out infinite; }
.cloud-b { width: 180px; top: 46%; right: -40px; animation: drift 44s ease-in-out infinite reverse; }
.cloud-c { width: 320px; bottom: 4%; left: 24%;  animation: drift 52s ease-in-out infinite; opacity: .55; }

.sun {
  position: absolute; top: 5%; right: 9%;
  width: 118px; height: 118px; border-radius: 50%;
  background: var(--sun); opacity: .5;
}

@keyframes drift {
  0%, 100% { transform: translate(0, 0); }
  50%      { transform: translate(34px, -18px); }
}

@media (prefers-reduced-motion: reduce) {
  .cloud { animation: none; }
}

/* ---------- top bar ---------- */

.topbar {
  position: relative; z-index: 2;
  display: flex; align-items: center; justify-content: space-between;
  gap: 16px;
  max-width: 1080px; margin: 0 auto; padding: 22px 24px 0;
}

.wordmark {
  display: inline-flex; align-items: center; gap: 9px;
  font-size: 21px; font-weight: 600; color: var(--ink); text-decoration: none;
  background: var(--cream); border: var(--edge); border-radius: var(--r-pill);
  padding: 7px 18px 7px 12px; box-shadow: var(--pop-sm);
}
.wordmark-face { width: 24px; height: auto; display: block; }
.wordmark:active { transform: translate(2px, 2px); box-shadow: 2px 2px 0 var(--ink); }

.topnav { display: flex; gap: 18px; }
.topnav a {
  color: var(--ink); text-decoration: none; font-weight: 500;
  border-bottom: 3px solid transparent; padding-bottom: 2px;
}
.topnav a:hover { border-bottom-color: var(--ink); }

/* the viewport is set to cover, so the notch and the home indicator are ours to avoid */
.topbar {
  padding-top: max(22px, env(safe-area-inset-top));
  padding-left: max(24px, env(safe-area-inset-left));
  padding-right: max(24px, env(safe-area-inset-right));
}
.foot { padding-bottom: max(54px, calc(env(safe-area-inset-bottom) + 24px)); }

.say-short { display: none; }

@media (max-width: 620px) {
  .topbar {
    padding-top: max(14px, env(safe-area-inset-top));
    padding-left: max(18px, env(safe-area-inset-left));
    padding-right: max(18px, env(safe-area-inset-right));
  }
  .wordmark { font-size: 18px; padding: 6px 14px 6px 10px; }
  .topnav { gap: 12px; }
  .topnav a {
    font-size: 15px; white-space: nowrap;
    display: flex; align-items: center; min-height: 44px;
  }
  .view { padding-left: 18px; padding-right: 18px; }
  .panel { padding: 26px 20px; border-radius: 32px; }
}



/* ---------- views ---------- */

main { position: relative; z-index: 1; }
.view { display: none; max-width: 1080px; margin: 0 auto; padding: 0 24px 80px; }
.view.is-active { display: block; }

/* ---------- hero ---------- */

.hero { text-align: center; padding: 54px 0 34px; }

.kicker {
  display: inline-block;
  background: var(--pink); border: var(--edge); border-radius: var(--r-pill);
  padding: 5px 16px; font-weight: 500; font-size: 15px;
  transform: rotate(-2deg); box-shadow: var(--pop-sm);
}

.hero h1 {
  /* the floor is low enough that the line break after "actually" still lands
     two tidy lines on a narrow phone instead of orphaning "gc?" on a third */
  font-size: clamp(32px, 8vw, 82px);
  font-weight: 700;
  margin: 20px 0 16px;
}

.squiggle-word {
  position: relative; display: inline-block;
  background: var(--sun); border: var(--edge); border-radius: 24px;
  padding: 0 18px; transform: rotate(-1.5deg);
  box-shadow: var(--pop);
}

.subhead {
  max-width: 520px; margin: 0 auto;
  font-size: 19px; color: var(--ink-soft);
}

/* ---------- dropzone ---------- */

.dropwrap { position: relative; max-width: 720px; margin: 108px auto 0; }

/* One outline rather than three circles. Three of them only read as a cloud
   while they overlap, and they stopped overlapping as soon as the card was
   wide enough to push them apart. This is their union, so it holds its shape
   at any width. The lower edge tucks behind the card, which is opaque and
   sits a layer above. */
.cloud-crown {
  position: absolute; left: 50%; bottom: 100%;
  transform: translateX(-50%);
  width: clamp(230px, 40%, 300px); height: auto;
  margin-bottom: -18px;
  fill: var(--cream); stroke: var(--ink); stroke-width: 3;
  stroke-linejoin: round;
  z-index: 0; pointer-events: none;
}

@media (max-width: 620px) {
  .dropwrap { margin-top: 88px; }
}

.dropzone {
  position: relative; z-index: 1;
  background: var(--cream);
  border: var(--edge);
  border-radius: var(--r-blob);
  box-shadow: var(--pop);
  padding: 44px 28px 38px;
  text-align: center;
  cursor: pointer;
  transition: transform .12s ease, box-shadow .12s ease, background .12s ease;
}
.dropzone:hover { transform: translate(-2px, -2px); box-shadow: 9px 9px 0 var(--ink); }
.dropzone:focus-visible { outline: 4px dashed var(--ink); outline-offset: 6px; }
.dropzone.is-hot { background: var(--butter-2); transform: scale(1.015); }

.drop-inner { position: relative; }

.drop-emoji { font-size: 52px; line-height: 1; margin-bottom: 12px; }
.dropzone.is-hot .drop-emoji { transform: rotate(-8deg) scale(1.1); }

.dropzone h2 { font-size: clamp(24px, 4vw, 34px); }
.mono-inline {
  background: var(--butter-2); border: 2px solid var(--ink);
  border-radius: 10px; padding: 1px 8px; font-size: .82em;
}

.drop-sub { color: var(--ink-soft); margin-top: 10px; }
.drop-foot { margin-top: 18px; font-size: 14px; color: var(--ink-soft); }

.btn {
  border: var(--edge); border-radius: var(--r-pill);
  padding: 12px 28px; font-size: 17px; font-weight: 600;
  cursor: pointer; box-shadow: var(--pop-sm);
  transition: transform .1s ease, box-shadow .1s ease;
}
.btn:active { transform: translate(4px, 4px); box-shadow: none; }
/* No margin here on purpose. This button sits in a flex row next to ghost
   buttons in five places, and a top margin on one of them knocks it out of
   line with its neighbours. The one spot that needs the gap asks for it. */
.btn-primary { background: var(--sun); color: var(--ink); }
.btn-ghost { background: var(--cream); color: var(--ink); }
.drop-inner .btn { margin-top: 20px; }

.linkbtn {
  background: none; border: none; padding: 0;
  font-size: inherit; font-weight: 600; color: var(--ink);
  text-decoration: underline; text-decoration-thickness: 3px;
  text-underline-offset: 4px; cursor: pointer;
}
.linkbtn:hover { color: var(--tomato); }
/* text links sit about 21px tall, which is a poor target on a phone. The
   negative margin cancels the padding so nothing moves, but the finger
   gets a 44px box. */
.linkbtn { padding: 12px 6px; margin: -12px -6px; }

.demo-line { text-align: center; margin-top: 22px; color: var(--ink-soft); }

/* ---------- the phone landing ---------- */
/* Stands where the drop zone would, so the clouds still sit on top of
   something and the page keeps its shape. */
.macnote {
  position: relative; z-index: 1;
  background: var(--cream);
  border: var(--edge);
  border-radius: var(--r-blob);
  box-shadow: var(--pop);
  padding: 40px 26px 34px;
  text-align: center;
}
.macnote-emoji { font-size: 46px; line-height: 1; margin-bottom: 12px; }
.macnote h2 { font-size: clamp(24px, 6vw, 32px); }
.macnote-sub { color: var(--ink-soft); margin-top: 12px; }
.macnote .btn { margin-top: 22px; }
.macnote-foot { margin-top: 16px; font-size: 14px; color: var(--ink-soft); }
.macnote-esc {
  margin-top: 20px; padding-top: 18px; font-size: 14px; color: var(--ink-soft);
  border-top: 3px solid var(--ink);
}

.drop-error {
  margin: 18px auto 0; max-width: 560px; text-align: center;
  background: var(--pink); border: var(--edge); border-radius: 22px;
  padding: 14px 18px; font-weight: 500; box-shadow: var(--pop-sm);
}

/* ---------- stickers ---------- */

.sticker-row {
  display: flex; flex-wrap: wrap; gap: 14px; justify-content: center;
  list-style: none; padding: 0; margin: 54px 0 0;
}
.sticker {
  display: inline-flex; align-items: center; gap: 9px;
  background: var(--cream); border: var(--edge); border-radius: var(--r-pill);
  padding: 9px 20px; font-weight: 500; box-shadow: var(--pop-sm);
}
.sticker-emoji { font-size: 19px; }
.s-pink  { background: var(--pink);  transform: rotate(-2deg); }
.s-blue  { background: var(--blue);  transform: rotate(1.5deg); }
.s-mint  { background: var(--mint);  transform: rotate(-1deg); }
.s-lilac { background: var(--lilac); transform: rotate(2deg); }

/* ---------- standalone pages ---------- */

.page { max-width: 1080px; margin: 0 auto; padding: 0 24px 80px; position: relative; z-index: 1; }
.page-head { text-align: center; padding: 54px 0 34px; }
.page-head h1 {
  font-size: clamp(38px, 7vw, 68px); font-weight: 700; margin: 18px 0 16px;
}
.page-head .subhead { margin-left: auto; margin-right: auto; }

.topnav a.is-here { border-bottom-color: var(--ink); }

.cta-row {
  display: flex; gap: 12px; justify-content: center; flex-wrap: wrap;
  margin-top: 40px;
}

.qa { margin-top: 26px; }
.qa h3 { font-size: 20px; margin-bottom: 8px; }
.qa p { color: var(--ink-soft); margin-top: 8px; }
.qa p b { color: var(--ink); }

.plainlist { margin: 20px 0 0; padding-left: 22px; }
.plainlist li { margin-bottom: 12px; color: var(--ink-soft); }
.plainlist li b { color: var(--ink); }

/* ---------- panels ---------- */

.panel {
  background: var(--cream); border: var(--edge); border-radius: var(--r-blob);
  box-shadow: var(--pop); padding: 34px 30px; margin-top: 64px;
}
.panel-title { font-size: clamp(24px, 4vw, 32px); }
.panel-title .tiny { font-size: 15px; color: var(--ink-soft); font-weight: 400; }
.panel-sub { color: var(--ink-soft); margin-top: 8px; }

.steps { list-style: none; padding: 0; margin: 26px 0 0; display: grid; gap: 20px; }
@media (min-width: 760px) { .steps { grid-template-columns: 1fr 1fr; } }

.step {
  position: relative;
  border: var(--edge); border-radius: 28px;
  padding: 26px 22px 22px; box-shadow: var(--pop-sm);
}
.step-1 { background: var(--pink); }
.step-2 { background: var(--blue); }
.step-3 { background: var(--mint); }
.step-4 { background: var(--lilac); }

.step-num {
  position: absolute; top: -18px; left: 18px;
  width: 42px; height: 42px; border-radius: 50%;
  background: var(--cream); border: var(--edge);
  display: grid; place-items: center; font-weight: 700; font-size: 20px;
}
.step h3 { font-size: 21px; margin-bottom: 8px; }
.step p { font-size: 16px; }
.step-note { margin-top: 10px; font-size: 15px; }

.code {
  display: block; background: var(--ink); color: #FFF3C7;
  border-radius: 16px; padding: 14px 16px; margin: 12px 0 0;
  font-size: 14px; line-height: 1.7; overflow-x: auto; white-space: pre;
}

.panel-note { background: var(--butter-2); }
.note-grid { display: grid; gap: 18px; margin-top: 24px; }
@media (min-width: 760px) { .note-grid { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1000px) { .note-grid { grid-template-columns: repeat(4, 1fr); } }
.note-card {
  background: var(--cream); border: var(--edge); border-radius: 26px;
  padding: 22px; box-shadow: var(--pop-sm);
}
.note-emoji { font-size: 30px; display: block; margin-bottom: 8px; }
.note-card h3 { font-size: 20px; margin-bottom: 6px; }
.note-card p { font-size: 16px; color: var(--ink-soft); }

/* ---------- results header ---------- */

.results-head {
  display: flex; align-items: center; gap: 20px; flex-wrap: wrap;
  padding: 40px 0 8px;
}
.results-title h1 { font-size: clamp(32px, 6vw, 54px); font-weight: 700; }
.results-meta { color: var(--ink-soft); margin-top: 6px; }

/* ---------- tabs ---------- */

.tabs { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 26px; }
.tab {
  background: var(--cream); border: var(--edge); border-radius: var(--r-pill);
  padding: 9px 18px; font-size: 16px; font-weight: 500; cursor: pointer;
  box-shadow: var(--pop-sm);
}
.tab.is-on { background: var(--sun); font-weight: 600; }
.tab:active { transform: translate(3px, 3px); box-shadow: none; }

.tabpanel { display: none; }
.tabpanel.is-on { display: block; }

/* ---------- podium ---------- */

.podium {
  display: grid; grid-template-columns: repeat(3, 1fr);
  gap: 14px; align-items: end; margin-top: 40px;
}
.pod {
  border: var(--edge); border-radius: 28px 28px 18px 18px;
  padding: 20px 12px; text-align: center; box-shadow: var(--pop);
  background: var(--cream);
}
.pod-1 { background: var(--sun);  padding-top: 46px; order: 2; }
.pod-2 { background: var(--blue); padding-top: 30px; order: 1; }
.pod-3 { background: var(--pink); padding-top: 22px; order: 3; }
.pod-medal { font-size: 34px; line-height: 1; }
.pod-name { font-size: clamp(17px, 3vw, 24px); font-weight: 700; margin-top: 8px; word-break: break-word; }
.pod-num { font-size: clamp(22px, 4vw, 34px); font-weight: 700; margin-top: 4px; }
.pod-lab { font-size: 13px; color: var(--ink-soft); }

/* ---------- leaderboards ---------- */

.board { margin-top: 22px; display: grid; gap: 10px; }

.row {
  display: grid;
  grid-template-columns: 44px minmax(90px, 1.1fr) 2fr auto;
  align-items: center; gap: 14px;
  background: var(--cream); border: var(--edge); border-radius: var(--r-pill);
  padding: 10px 18px 10px 10px; box-shadow: var(--pop-sm);
}
.row-top { background: var(--butter-2); }

.rank {
  width: 34px; height: 34px; border-radius: 50%;
  background: var(--sun); border: 2px solid var(--ink);
  display: grid; place-items: center; font-weight: 700; font-size: 15px;
}
.row-name { font-weight: 600; word-break: break-word; }

.bar-track {
  height: 16px; background: var(--butter); border: 2px solid var(--ink);
  border-radius: var(--r-pill); overflow: hidden;
}
.bar-fill { height: 100%; background: var(--tomato); border-radius: var(--r-pill); }
.bar-fill.f-2 { background: var(--blue); }
.bar-fill.f-3 { background: var(--mint); }
.bar-fill.f-4 { background: var(--lilac); }
.bar-fill.f-5 { background: var(--pink); }

.row-val { font-weight: 700; font-size: 18px; white-space: nowrap; }
.row-sub { display: block; font-size: 12px; color: var(--ink-soft); font-weight: 400; text-align: right; }

@media (max-width: 620px) {
  .row { grid-template-columns: 38px 1fr auto; padding-right: 14px; }
  .bar-track { display: none; }
}

/* ---------- chips ---------- */

.chips { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 20px; }
.chip {
  background: var(--cream); border: var(--edge); border-radius: var(--r-pill);
  padding: 7px 16px; font-weight: 500; cursor: pointer; box-shadow: var(--pop-sm);
  font-size: 15px;
}
.chip.is-on { background: var(--mint); font-weight: 600; }
.chip:active { transform: translate(3px, 3px); box-shadow: none; }

/* ---------- matrix ---------- */

/* The grid sizes itself from two variables so the whole thing can be fitted
   to the screen and then pinched larger, without a transform. A transform
   would become the containing block for the labels and break the sticky
   headers, which are the thing that makes a zoomed grid readable at all. */
.matrix-wrap { position: relative; }
.matrix-scroll {
  overflow: auto; margin-top: 24px; padding-bottom: 10px;
  scrollbar-color: var(--ink) var(--butter);
  overscroll-behavior: contain;
  max-height: 78vh;
  touch-action: pan-x pan-y;   /* we handle the pinch ourselves */
}
.matrix {
  display: grid;
  gap: var(--m-gap, 5px);
  width: max-content; min-width: max-content;
  --m-cell: 58px;
  --m-label: auto;
  --m-gap: 5px;
}

/* labels stay put while the grid is panned */
.m-head.m-col {
  position: sticky; top: 0; z-index: 2;
  background: var(--cream);
}
.m-head.m-side {
  position: sticky; left: 0; z-index: 2;
  background: var(--cream);
}
.m-head.m-corner {
  position: sticky; left: 0; top: 0; z-index: 3;
  background: var(--cream);
}

.matrix-hint {
  display: none;
  margin-top: 10px; font-size: 14px; color: var(--ink-soft); font-weight: 500;
}
.matrix-hint.is-on { display: block; }

.m-cell {
  width: var(--m-cell); height: calc(var(--m-cell) * 0.79);
  border: 2px solid var(--ink); border-radius: calc(var(--m-cell) * 0.2);
  display: grid; place-items: center;
  font-size: clamp(9px, calc(var(--m-cell) * 0.245), 15px); font-weight: 600;
}
/* block rather than grid, because text-overflow only ellipsises a block. A
   long unnamed handle used to spill out of its column and over the numbers. */
.m-head {
  border: none; font-weight: 600;
  font-size: clamp(9px, calc(var(--m-cell) * 0.235), 14px);
  display: block;
  width: var(--m-cell); height: calc(var(--m-cell) * 0.79);
  line-height: calc(var(--m-cell) * 0.79);
  text-align: center;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  min-width: 0;
}
.m-side {
  width: var(--m-label); max-width: var(--m-label);
  padding-right: 7px; text-align: right;
}
.m-self { background: var(--butter); color: var(--ink-soft); font-weight: 400; }

/* Squeezed small enough and the numbers turn to mush, so they step aside and
   let the colour carry the overview. Pinching brings them back. */
.matrix.is-tiny .m-cell { font-size: 0; }
.matrix.is-tiny .m-head { font-size: 9px; }

.h0 { background: var(--cream); color: var(--ink-soft); }
.h1 { background: #E4F3E0; }
.h2 { background: #C4E8BE; }
.h3 { background: #97D693; }
.h4 { background: #5FBE68; color: #fff; }
.h5 { background: #2F9A4B; color: #fff; }

.matrix-key {
  display: flex; align-items: center; gap: 7px; margin-top: 18px;
  font-size: 14px; color: var(--ink-soft);
}
.key { width: 26px; height: 18px; border: 2px solid var(--ink); border-radius: 7px; }
.k1 { background: #E4F3E0; } .k2 { background: #C4E8BE; } .k3 { background: #97D693; }
.k4 { background: #5FBE68; } .k5 { background: #2F9A4B; }

.facts { display: grid; gap: 12px; margin-top: 26px; }
.fact {
  background: var(--butter-2); border: var(--edge); border-radius: 22px;
  padding: 14px 20px; box-shadow: var(--pop-sm); font-weight: 500;
}
.fact b { font-weight: 700; }

/* ---------- hall of fame ---------- */

.hof { display: grid; gap: 16px; margin-top: 24px; }
.hof-card {
  background: var(--cream); border: var(--edge); border-radius: 26px;
  padding: 18px 22px; box-shadow: var(--pop-sm);
}
.hof-top { display: flex; align-items: center; justify-content: space-between; gap: 14px; }
.hof-who { font-weight: 700; }
.hof-count {
  display: inline-flex; align-items: center; flex-wrap: wrap; gap: 4px 10px;
  background: var(--sun); border: 2px solid var(--ink); border-radius: var(--r-pill);
  padding: 3px 13px; font-weight: 700; font-size: 15px;
  justify-content: flex-end;
}
/* one count and its reaction, kept together when the badge wraps */
.hof-tally { display: inline-flex; align-items: center; gap: 4px; white-space: nowrap; }
.hof-text { margin-top: 10px; font-size: 18px; }
.hof-text.is-blur { filter: blur(6px); user-select: none; }
.hof-date { margin-top: 8px; font-size: 13px; color: var(--ink-soft); }

/* ---------- empty ---------- */

.empty {
  background: var(--butter-2); border: var(--edge); border-radius: 24px;
  padding: 24px; text-align: center; color: var(--ink-soft); margin-top: 22px;
}

/* ---------- the copyable path ---------- */

.pathrow { display: flex; flex-wrap: wrap; gap: 10px; align-items: center; margin-top: 12px; }
.pathbox {
  flex: 1; min-width: 220px;
  background: var(--ink); color: #FFF3C7;
  border-radius: 16px; padding: 13px 16px;
  font-family: "DM Mono", ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 14px; overflow-x: auto; white-space: nowrap;
}
.pathrow .btn { padding: 11px 22px; font-size: 15px; }

.steps-3 { grid-template-columns: 1fr; }
@media (min-width: 860px) { .steps-3 { grid-template-columns: repeat(3, 1fr); } }

/* ---------- working screen ---------- */

.working-box { text-align: center; padding: 130px 0 90px; }
.working-box h1 { font-size: clamp(30px, 6vw, 50px); }
.working-note { color: var(--ink-soft); margin-top: 14px; }

.working-clouds { display: flex; gap: 14px; justify-content: center; margin-bottom: 34px; }
.working-clouds i {
  width: 26px; height: 26px; border-radius: 50%;
  background: var(--cream); border: var(--edge);
  animation: bob 1.1s ease-in-out infinite;
}
.working-clouds i:nth-child(2) { animation-delay: .16s; background: var(--pink); }
.working-clouds i:nth-child(3) { animation-delay: .32s; background: var(--blue); }

@keyframes bob {
  0%, 100% { transform: translateY(0); }
  50%      { transform: translateY(-15px); }
}
@media (prefers-reduced-motion: reduce) { .working-clouds i { animation: none; } }

/* ---------- chat picker ---------- */

.pick-head { text-align: center; padding: 48px 0 8px; }
.pick-head h1 { font-size: clamp(38px, 7vw, 64px); font-weight: 700; margin: 18px 0 14px; }

.chat-list { display: grid; gap: 14px; max-width: 720px; margin: 34px auto 0; }

.chat-card {
  display: flex; align-items: center; justify-content: space-between; gap: 16px;
  width: 100%; text-align: left; cursor: pointer;
  background: var(--cream); border: var(--edge); border-radius: 30px;
  padding: 20px 24px; box-shadow: var(--pop);
  font-family: inherit; color: var(--ink);
  transition: transform .1s ease, box-shadow .1s ease;
}
.chat-card:hover { transform: translate(-2px, -2px); box-shadow: 9px 9px 0 var(--ink); }
.chat-card:active { transform: translate(3px, 3px); box-shadow: 2px 2px 0 var(--ink); }
.c-0 { background: var(--sun); }
.c-1 { background: var(--blue); }
.c-2 { background: var(--pink); }
.c-3 { background: var(--mint); }

.chat-name { font-size: clamp(20px, 4vw, 26px); font-weight: 700; word-break: break-word; }
.chat-meta { font-size: 15px; margin-top: 4px; opacity: .75; }
.chat-go { font-size: 28px; font-weight: 700; }

/* ---------- naming people ---------- */

.contacts-box {
  display: flex; align-items: center; gap: 20px; flex-wrap: wrap;
  max-width: 660px; margin: 34px auto 0;
  background: var(--lilac); border: var(--edge); border-radius: 30px;
  padding: 22px 26px; box-shadow: var(--pop);
}
.contacts-box.is-hot { background: var(--mint); }
.contacts-copy { flex: 1; min-width: 240px; }
.contacts-copy h3 { font-size: 21px; margin-bottom: 6px; }
.contacts-copy p { font-size: 15px; }
.contacts-box .btn { white-space: nowrap; }

.vcf-result {
  max-width: 660px; margin: 16px auto 0; text-align: center;
  border: var(--edge); border-radius: 22px; padding: 12px 18px;
  font-weight: 500; box-shadow: var(--pop-sm);
}
.vcf-result[hidden] { display: none; }
.vcf-result.is-good { background: var(--mint); }
.vcf-result.is-bad { background: var(--pink); }

.name-list { display: grid; gap: 12px; max-width: 660px; margin: 26px auto 0; }

.name-row {
  display: flex; align-items: center; gap: 16px; flex-wrap: wrap;
  background: var(--cream); border: var(--edge); border-radius: var(--r-pill);
  padding: 10px 14px 10px 22px; box-shadow: var(--pop-sm);
}
.name-left { flex: 1; min-width: 150px; }
.name-handle {
  font-family: "DM Mono", ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 14px; word-break: break-all;
}
.name-count { font-size: 13px; color: var(--ink-soft); }

.name-input {
  flex: 1; min-width: 160px;
  font-family: inherit; font-size: 17px; font-weight: 600; color: var(--ink);
  background: var(--butter); border: var(--edge); border-radius: var(--r-pill);
  padding: 10px 18px;
}
.name-input:focus { outline: none; background: var(--sun); }
.name-input.is-matched { background: var(--mint); }
.name-input:disabled { opacity: .45; }

.name-toggle {
  border: var(--edge); border-radius: var(--r-pill);
  background: var(--mint); color: var(--ink);
  padding: 8px 18px; font-size: 15px; font-weight: 700; cursor: pointer;
  box-shadow: var(--pop-sm); min-width: 66px;
}
.name-toggle:active { transform: translate(3px, 3px); box-shadow: none; }
.name-row.is-out { opacity: .55; }
.name-row.is-out .name-toggle { background: var(--pink); }
.name-row.is-mystery .name-handle { font-style: italic; opacity: .8; }

/* your own row: it starts empty, and everyone you share with reads it */
.name-row.is-you { background: var(--butter-2); }
.name-row.is-you .name-input:placeholder-shown { background: var(--sun); }
.name-note { font-size: 12px; color: var(--ink-soft); margin-top: 2px; }

.quiet-hint {
  max-width: 660px; margin: 20px auto 0; text-align: center;
  background: var(--butter-2); border: var(--edge); border-radius: 22px;
  padding: 12px 20px; box-shadow: var(--pop-sm); font-weight: 500;
}
.quiet-hint[hidden] { display: none; }

/* ---------- reaction filter ---------- */

.kind-row {
  display: flex; align-items: center; gap: 14px; flex-wrap: wrap;
  margin-top: 26px;
}
.kind-row[hidden] { display: none; }
.kind-label { font-weight: 600; color: var(--ink-soft); }
.kind-row .chips { margin-top: 0; }
.kind-row .chip.is-on { background: var(--sun); }
.kind-row .chip { display: inline-flex; align-items: center; gap: 7px; }
.chip-icon { width: 19px; height: auto; display: block; }
.name-input::placeholder { font-weight: 400; color: var(--ink-soft); }

.name-actions {
  display: flex; gap: 12px; justify-content: center; flex-wrap: wrap;
  margin: 30px auto 0;
}

/* ---------- results header extras ---------- */

.results-head {
  align-items: flex-end; justify-content: space-between;
}
.results-actions { display: flex; flex-wrap: wrap; gap: 10px; }
/* an emoji has a taller line box than plain text, which was making the one
   button with an emoji in it 1.5px taller than its neighbours */
.results-actions .btn {
  display: inline-flex; align-items: center; justify-content: center;
  gap: 7px;                       /* flex eats the whitespace after the emoji */
  height: 46px; padding: 0 20px; font-size: 15px; line-height: 1;
}

@media (max-width: 780px) {
  .results-head { flex-direction: column; align-items: flex-start; gap: 16px; }
  .results-actions { width: 100%; }
  .results-actions .btn { flex: 1; white-space: nowrap; }
}

/* ---------- the phone read ----------
   Most people meet this site by tapping a link on a phone, so the results
   have to be the first thing on screen. Measured before this block, a phone
   had to scroll past 777px of header, buttons and tabs on an 812px screen
   to reach the podium. Everything here buys that space back.
------------------------------------------------------------------------ */

@media (max-width: 620px) {
  .say-long { display: none; }
  .say-short { display: inline; }

  .results-head { gap: 12px; padding: 22px 0 4px; }
  .results-title h1 { font-size: clamp(28px, 8vw, 38px); }
  .results-meta { font-size: 15px; margin-top: 4px; }

  /* buttons in one row, equal width */
  .results-actions { gap: 8px; }
  .results-actions .btn { height: 44px; padding: 0 10px; font-size: 14px; flex: 1 1 0; min-width: 0; gap: 5px; }

  /* On a shared recap the banner already says "make your own", so the third
     button would be the same offer twice. The function is not lost. */
  .results-actions .hide-on-phone { display: none; }

  .shared-banner {
    margin-top: 18px; padding: 10px 16px; gap: 10px;
    font-size: 14px; line-height: 1.3;
  }

  .kind-row { margin-top: 16px; gap: 8px; }
  .kind-label { font-size: 14px; }

  /* one scrolling strip instead of three wrapped rows */
  .tabs, .kind-row .chips {
    flex-wrap: nowrap;
    overflow-x: auto;
    scrollbar-width: none;
    -webkit-overflow-scrolling: touch;
    margin-left: -18px; margin-right: -18px;
    padding-left: 18px; padding-right: 18px;
    scroll-padding-left: 18px;
  }
  .tabs::-webkit-scrollbar, .kind-row .chips::-webkit-scrollbar { display: none; }
  /* these scroll sideways, so the hard offset shadow under each pill needs
     room inside the scroller or it gets sliced off. The negative margin puts
     the spacing back so nothing moves. */
  .tabs, .kind-row .chips { padding-bottom: 10px; margin-bottom: -10px; }
  .tabs { margin-top: 16px; }
  /* every chip, not just the reaction filter: the range chips and the
     hall of fame toggle are the same control and the same finger */
  .tab, .chip { flex: 0 0 auto; min-height: 44px; display: inline-flex; align-items: center; }
  .linkbtn { padding: 13px 6px; margin: -13px -6px; }

  .panel { margin-top: 34px; }
  .board { margin-top: 16px; }

  /* the podium is the payoff, so it gets the room */
  .podium { margin-top: 26px; gap: 10px; }
  .pod { padding: 16px 8px; }
  .pod-1 { padding-top: 34px; }
  .pod-2 { padding-top: 24px; }
  .pod-3 { padding-top: 20px; }
  .pod-num { font-size: clamp(26px, 8vw, 34px); }
  .pod-name { font-size: clamp(16px, 4.4vw, 20px); }
  .pod-lab { font-size: 13px; line-height: 1.25; }

  /* secondary numbers were 12px, which is too small to read on a phone */
  .row { padding: 9px 16px 9px 9px; gap: 10px; }
  .row-val { font-size: 17px; }
  .row-sub { font-size: 13px; }
  .rank { width: 32px; height: 32px; font-size: 14px; }

  .hof-date { font-size: 13px; }
  .hof-text { font-size: 17px; }
  .panel-sub { font-size: 15px; }

  /* the grid wants every pixel it can get, so this panel keeps less padding */
  .tabpanel[data-panel="matrix"] .panel { padding-left: 12px; padding-right: 12px; }
}

.shared-banner {
  display: flex; align-items: center; justify-content: center; gap: 12px;
  flex-wrap: wrap; text-align: center;
  background: var(--lilac); border: var(--edge); border-radius: var(--r-pill);
  padding: 11px 22px; box-shadow: var(--pop-sm); margin-top: 36px; font-weight: 500;
}
.shared-banner[hidden] { display: none; }

/* ---------- the recap ---------- */

body.no-scroll { overflow: hidden; }

.recap {
  position: fixed; inset: 0; z-index: 60;
  background: var(--butter);
  display: flex; align-items: stretch; justify-content: center;
}
.recap[hidden] { display: none; }

.recap-bars {
  position: absolute; top: 0; left: 0; right: 0; z-index: 3;
  display: flex; gap: 5px; padding: 14px 16px;
  padding-top: max(14px, env(safe-area-inset-top));
}
.recap-bars i {
  flex: 1; height: 7px; border-radius: var(--r-pill);
  border: 2px solid var(--ink); background: transparent;
  position: relative; overflow: hidden;
}
.recap-bars i::after {
  content: ""; position: absolute; inset: 0; width: 0;
  background: var(--ink);
}
.recap-bars i.is-done::after { width: 100%; }
.recap-bars i.is-run::after { animation: fillbar 6.2s linear forwards; }

@keyframes fillbar { from { width: 0; } to { width: 100%; } }

@media (prefers-reduced-motion: reduce) {
  .recap-bars i.is-run::after { animation-duration: 0s; width: 100%; }
}

.recap-close {
  position: absolute; z-index: 4; top: 34px; right: 18px;
  top: max(34px, calc(env(safe-area-inset-top) + 20px));
  right: max(18px, env(safe-area-inset-right));
  display: inline-flex; align-items: center; gap: 6px;
  min-height: 44px;
  background: var(--cream); border: var(--edge); border-radius: var(--r-pill);
  padding: 0 18px; font-size: 15px; font-weight: 600; cursor: pointer;
  box-shadow: var(--pop-sm); color: var(--ink);
}

.recap-zone {
  position: absolute; top: 0; bottom: 0; width: 22%;
  background: none; border: none; padding: 0; z-index: 2; cursor: pointer;
  opacity: 0;
}
.recap-prev { left: 0; }
.recap-next { right: 0; }

.recap-stage { position: relative; z-index: 1; flex: 1; display: flex; }

.slide {
  flex: 1; display: flex; align-items: center; justify-content: center;
  padding: 72px 26px 48px; text-align: center;
  animation: slidein .34s ease both;
  /* a short window, usually a phone turned sideways, gets to scroll rather
     than lose the bottom of the slide */
  overflow-y: auto;
  overscroll-behavior: contain;
}
/* auto margins keep a too-tall slide centred without clipping its top,
   which is what align-items alone would do inside a scroller */
.slide-inner { margin: auto 0; }
@keyframes slidein {
  from { opacity: 0; transform: translateY(14px) scale(.985); }
  to   { opacity: 1; transform: none; }
}
@media (prefers-reduced-motion: reduce) { .slide { animation: none; } }

.t-sun    { background: var(--sun); }
.t-pink   { background: var(--pink); }
.t-blue   { background: var(--blue); }
.t-mint   { background: var(--mint); }
.t-lilac  { background: var(--lilac); }
.t-tomato { background: var(--tomato); }

.slide-inner { max-width: 640px; }
/* on a laptop 640px forced chat names and jokes to wrap mid phrase while
   the screen sat half empty */
@media (min-width: 900px) { .slide-inner { max-width: 880px; } }

.slide-emoji {
  font-size: clamp(46px, 11vw, 74px); line-height: 1;
  transform: rotate(-7deg); margin-bottom: 14px;
}

.slide-kicker {
  display: inline-block;
  background: var(--cream); border: var(--edge); border-radius: var(--r-pill);
  padding: 6px 18px; font-weight: 600; font-size: clamp(14px, 3.4vw, 17px);
  box-shadow: var(--pop-sm); transform: rotate(-1.5deg);
}

.slide-big {
  font-size: clamp(64px, 19vw, 132px);
  font-weight: 700; line-height: .95; letter-spacing: -0.045em;
  margin: 22px 0 6px; word-break: break-word;
}
.slide-big.is-name { font-size: clamp(42px, 12vw, 92px); }

.slide-sub {
  font-size: clamp(19px, 4.6vw, 27px); font-weight: 600;
}

/* the winning message, in a bubble rather than as a giant number */
.slide-quote {
  margin: 22px 0 14px;
  background: var(--cream); border: var(--edge); border-radius: 34px 34px 34px 8px;
  padding: 22px 26px; box-shadow: var(--pop);
  font-size: clamp(22px, 5.4vw, 36px); font-weight: 600; line-height: 1.28;
  letter-spacing: -0.01em; word-break: break-word;
  transform: rotate(-.7deg);
}
.slide-quote.is-long { font-size: clamp(17px, 3.8vw, 25px); }

.slide-line {
  font-size: clamp(16px, 3.8vw, 20px); margin-top: 18px; opacity: .82;
}

.slide-joke {
  font-size: clamp(18px, 4.4vw, 24px); font-weight: 500;
  margin-top: 22px;
  background: var(--cream); border: var(--edge); border-radius: 28px;
  padding: 16px 22px; box-shadow: var(--pop);
  transform: rotate(.6deg);
}

.slide-actions {
  display: flex; flex-wrap: wrap; gap: 12px; justify-content: center;
  margin-top: 30px; position: relative; z-index: 5;
}

/* A short viewport is a phone held sideways. Everything steps down so the
   whole slide lands on screen instead of scrolling. */
@media (max-height: 560px) {
  .slide { padding: 54px 22px 28px; }
  .slide-emoji { font-size: clamp(28px, 8vh, 46px); margin-bottom: 6px; }
  .slide-kicker { font-size: 14px; padding: 5px 14px; }
  .slide-big { font-size: clamp(34px, 15vh, 74px); margin: 10px 0 4px; }
  .slide-big.is-name { font-size: clamp(26px, 11vh, 58px); }
  .slide-sub { font-size: clamp(16px, 5vh, 24px); }
  .slide-line { font-size: 14px; margin-top: 8px; }
  .slide-joke { font-size: 15px; margin-top: 12px; padding: 10px 16px; border-radius: 20px; }
  .slide-quote { font-size: clamp(16px, 6vh, 28px); padding: 14px 18px; margin: 12px 0 6px; }
  .slide-quote.is-long { font-size: clamp(14px, 4.5vh, 20px); }
  .slide-actions { margin-top: 14px; }
  .recap-bars { padding: 8px 14px; }
  .recap-close { top: max(12px, env(safe-area-inset-top)); min-height: 40px; }
}

/* ---------- toast ---------- */

.toast {
  position: fixed; z-index: 80; left: 50%; bottom: 28px;
  transform: translateX(-50%);
  background: var(--ink); color: var(--butter);
  border-radius: var(--r-pill); padding: 13px 24px;
  font-weight: 500; font-size: 16px; max-width: 90vw; text-align: center;
}
.toast[hidden] { display: none; }

/* ---------- footer ---------- */

.foot {
  position: relative; z-index: 1;
  text-align: center; padding: 40px 24px 54px; color: var(--ink-soft);
}
.foot-tiny { font-size: 14px; margin-top: 4px; }
