/* Gearturn: a clerk's notebook. Pen on graph paper, notes in the margin, nothing filled in. */

:root {
  --sl: max(12px, env(safe-area-inset-left, 0px));
  --sr: max(12px, env(safe-area-inset-right, 0px));
  --st: max(6px, env(safe-area-inset-top, 0px));
  --sb: max(10px, env(safe-area-inset-bottom, 0px));
  --strip: 56px;
  /* what the margin needs under the board when the phone is upright */
  --reserve: 262px;
  /* what it needs beside the board when the phone is on its side */
  --panel-min: 268px;
  --gap: 18px;
  --grid: color-mix(in srgb, var(--ak-ink) 20%, transparent);
  --wash-start: color-mix(in srgb, var(--ak-accent-2) 42%, var(--ak-bg));
  --wash-chain: color-mix(in srgb, var(--ak-surface) 76%, var(--ak-ink-muted));
  --pen: var(--ak-ink);
  --red: var(--ak-accent);
}

* { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  min-height: 100vh;
  min-height: 100dvh;
  background-color: var(--ak-bg);
  background-image: var(--ak-backdrop-layer, var(--ak-bg-art));
  background-size: auto, cover;
  background-position: center, center;
  background-repeat: no-repeat;
  color: var(--ak-ink);
  font-family: var(--ak-font-body);
  font-size: 17px;
  line-height: 1.4;
  overscroll-behavior: none;
}

.defs { position: absolute; width: 0; height: 0; overflow: hidden; }

button { font: inherit; color: inherit; }

.desk {
  --cols: 6;
  --rows: 8;
  display: flex;
  flex-direction: column;
  height: 100vh;
  height: 100dvh;
  padding: var(--st) var(--sr) var(--sb) var(--sl);
  overflow-x: hidden;
  overflow-y: auto;
  touch-action: manipulation;
}

/* ---- top strip: mute at the left, logo in the middle, the kit's ? button lands at the right ---- */

.strip {
  flex: none;
  display: grid;
  grid-template-columns: 48px 1fr 48px;
  align-items: center;
  height: var(--strip);
}

.strip-logo {
  grid-column: 2;
  justify-self: center;
  display: block;
  height: 38px;
  width: auto;
  max-width: 100%;
  object-fit: contain;
  /* the painted halo drops out and the letters read as pen ink on the paper */
  mix-blend-mode: multiply;
}

.mute {
  grid-column: 1;
  width: 48px;
  height: 48px;
  padding: 0;
  display: grid;
  place-items: center;
  background: transparent;
  border: 2px solid var(--ak-ink);
  border-radius: 50%;
  color: var(--ak-ink);
  cursor: pointer;
  touch-action: manipulation;
}

.mute svg { width: 28px; height: 28px; overflow: visible; }
.mute .spk { fill: var(--ak-ink); stroke: var(--ak-ink); stroke-width: 1.6; stroke-linejoin: round; }
.mute .wave, .mute .cut { fill: none; stroke: var(--ak-ink); stroke-width: 2.4; stroke-linecap: round; }
.mute .cut { display: none; stroke: var(--ak-accent); stroke-width: 3; }
.mute[aria-pressed="true"] .wave { display: none; }
.mute[aria-pressed="true"] .cut { display: inline; }
.mute:focus-visible { outline: 3px solid var(--ak-focus); outline-offset: 2px; }

/* ---- the page: board and margin ---- */

.page {
  flex: 1 0 auto;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 12px;
}

.board-wrap { flex: none; display: flex; justify-content: center; }

.board {
  --bw: max(
    calc(var(--cols) * 38px),
    min(
      calc(100vw - var(--sl) - var(--sr) - 6px),
      calc((100vh - var(--st) - var(--sb) - var(--strip) - var(--reserve)) * var(--cols) / var(--rows)),
      540px
    )
  );
  position: relative;
  flex: none;
  width: var(--bw);
  height: calc(var(--bw) * var(--rows) / var(--cols));
  background-color: var(--ak-bg);
  background-image:
    linear-gradient(to right, var(--grid) 1px, transparent 1px),
    linear-gradient(to bottom, var(--grid) 1px, transparent 1px);
  background-size: calc(100% / (var(--cols) * 2)) calc(100% / (var(--rows) * 2));
  border: 2px solid var(--ak-ink);
  border-radius: 3px 2px 4px 2px / 2px 4px 2px 3px;
  outline: 1px solid color-mix(in srgb, var(--ak-ink) 50%, transparent);
  outline-offset: 3px;
  user-select: none;
  -webkit-user-select: none;
}

@supports (width: 1dvw) {
  .board {
    --bw: max(
      calc(var(--cols) * 38px),
      min(
        calc(100dvw - var(--sl) - var(--sr) - 6px),
        calc((100dvh - var(--st) - var(--sb) - var(--strip) - var(--reserve)) * var(--cols) / var(--rows)),
        540px
      )
    );
  }
}

.belts, .gears, .tags { position: absolute; inset: 0; width: 100%; height: 100%; }
.belts { pointer-events: none; overflow: visible; }
.gears { z-index: 1; }
.tags { z-index: 3; pointer-events: none; }

.belt-run {
  fill: none;
  stroke: var(--ak-ink);
  stroke-width: 5px;
  stroke-dasharray: 7 3;
  stroke-linecap: butt;
  vector-effect: non-scaling-stroke;
}

.belt-edge {
  fill: none;
  stroke: var(--ak-bg);
  stroke-width: 9px;
  vector-effect: non-scaling-stroke;
}

.belt-label {
  position: absolute;
  transform: translate(-50%, -50%);
  padding: 0 6px;
  background: var(--ak-bg);
  border: 1.5px solid var(--ak-ink);
  font-family: var(--ak-font-display);
  font-style: italic;
  font-weight: 700;
  font-size: 15px;
  line-height: 1.25;
  color: var(--ak-ink);
}

/* ---- gears ---- */

.gear {
  position: absolute;
  margin: 0;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: transparent;
  aspect-ratio: 1;
  cursor: pointer;
  isolation: isolate;
  touch-action: manipulation;
  -webkit-tap-highlight-color: transparent;
  color: var(--pen);
}

.gear:disabled { cursor: default; }
.gear:focus-visible { outline: 3px solid var(--ak-focus); outline-offset: 3px; }

.gear > * { position: absolute; }
.spin, .art-last { inset: 0; width: 100%; height: 100%; }
.spin { display: block; transform-origin: 50% 50%; }
.spin svg { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; }

.art-last { display: block; object-fit: contain; pointer-events: none; }

.g-body {
  fill: var(--wash-chain);
  stroke: var(--ak-ink);
  stroke-width: 2.4px;
  stroke-linejoin: round;
  vector-effect: non-scaling-stroke;
  filter: url(#pen);
}

.gear[data-role="start"] .g-body { fill: var(--wash-start); stroke-width: 2.8px; }

.g-ring {
  fill: none;
  stroke: color-mix(in srgb, var(--ak-ink) 55%, transparent);
  stroke-width: 1.4px;
  vector-effect: non-scaling-stroke;
}

.g-hub { fill: var(--ak-bg); stroke: var(--ak-ink); stroke-width: 2px; vector-effect: non-scaling-stroke; }
.g-cross { fill: none; stroke: var(--ak-ink); stroke-width: 2px; stroke-linecap: round; vector-effect: non-scaling-stroke; }

.face {
  position: absolute;
  left: 50%;
  top: 50%;
  width: var(--face, 62%);
  aspect-ratio: 1;
  transform: translate(-50%, -50%);
  overflow: hidden;
  border-radius: 50%;
  border: 2px solid var(--ak-ink);
  background: var(--wash-start);
  pointer-events: none;
}

/* the painted first gear, cropped to its amber gear and arrow so the arrow reads big */
.face img {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 168%;
  max-width: none;
  transform: translate(-50%, -50%);
  display: block;
}

/* the player's pen marks */
.mark {
  left: 50%;
  top: 50%;
  width: var(--mark, 60%);
  aspect-ratio: 1;
  transform: translate(-50%, -50%);
  pointer-events: none;
  color: var(--ak-ink);
  overflow: visible;
  display: none;
}

.mark path { vector-effect: non-scaling-stroke; stroke-width: 4px; }
.gear[data-mark="cw"] .mark-cw,
.gear[data-mark="ccw"] .mark-ccw { display: block; }
.gear.is-example .mark-ccw { display: block; color: var(--ak-accent); }

/* rings: invite, clash, example, trace */
.ring {
  inset: -7px;
  width: calc(100% + 14px);
  height: calc(100% + 14px);
  pointer-events: none;
  overflow: visible;
  opacity: 0;
}

.ring circle {
  fill: none;
  stroke: var(--ak-accent);
  stroke-width: 3.2px;
  stroke-linecap: round;
  vector-effect: non-scaling-stroke;
}

.gear.is-invite .ring,
.gear.is-clash .ring,
.gear.is-example .ring,
.gear.is-traced .ring { opacity: 1; }

.gear.is-invite .ring circle { stroke-dasharray: 4 5; }
.gear.is-clash .ring circle { stroke-width: 4px; }

.tick {
  right: -9px;
  top: -9px;
  width: 24px;
  height: 24px;
  display: none;
  place-items: center;
  background: var(--ak-bg);
  border: 2px solid var(--ak-accent);
  border-radius: 50%;
  pointer-events: none;
}

.tick svg { width: 14px; height: 14px; overflow: visible; }
.tick path { fill: none; stroke: var(--ak-accent); stroke-width: 3px; stroke-linecap: round; stroke-linejoin: round; }
.gear.is-traced .tick { display: grid; }

.glow {
  inset: -9px;
  z-index: -1;
  border-radius: 50%;
  background: color-mix(in srgb, var(--ak-accent-2) 55%, transparent);
  display: none;
}

.gear.is-answer .glow { display: block; }

/* the answer written beside the last gear */
.tag {
  position: absolute;
  display: flex;
  align-items: center;
  gap: 4px;
  padding: 2px 8px 2px 4px;
  background: var(--ak-bg);
  border: 2px solid var(--ak-accent);
  color: var(--ak-accent);
  font-family: var(--ak-font-display);
  font-weight: 700;
  font-size: 19px;
  line-height: 1.1;
  white-space: nowrap;
}

.tag svg { width: 28px; height: 28px; flex: none; overflow: visible; }
.tag svg path { vector-effect: non-scaling-stroke; stroke-width: 3px; }

/* ---- the margin: notes, the two ruled boxes, the check ---- */

.margin {
  flex: none;
  width: min(100%, 520px);
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.note {
  margin: 0;
  min-height: 2.5em;
  padding: 2px 0 2px 12px;
  border-left: 3px solid var(--ak-accent);
  font-family: var(--ak-font-display);
  font-style: italic;
  font-weight: 700;
  font-size: 20px;
  line-height: 1.2;
  color: var(--ak-ink);
}

.note.is-wrong {
  border-left-width: 7px;
  font-style: normal;
  text-decoration: underline wavy color-mix(in srgb, var(--ak-accent) 70%, transparent);
  text-decoration-thickness: 1.5px;
  text-underline-offset: 4px;
  text-decoration-skip-ink: none;
}

.ask { display: flex; flex-direction: column; gap: 8px; }

.ask-label {
  margin: 0;
  font-size: 15px;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ak-ink-muted);
}

.boxes { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }

.box {
  display: flex;
  align-items: center;
  gap: 8px;
  min-height: 56px;
  padding: 6px 10px;
  background: var(--ak-choice-bg);
  color: var(--ak-choice-ink);
  border: 1.5px solid var(--ak-choice-border);
  border-top: 5px double var(--ak-choice-border);
  border-radius: var(--ak-radius);
  font-family: var(--ak-font-display);
  font-weight: 700;
  font-size: 19px;
  line-height: 1.05;
  text-align: left;
  cursor: pointer;
  touch-action: manipulation;
}

.box-arrow { width: 32px; height: 32px; flex: none; overflow: visible; }
.box-arrow path { vector-effect: non-scaling-stroke; stroke-width: 3px; }
.box-word { min-width: 0; hyphens: manual; overflow-wrap: normal; }

.box[aria-checked="true"] {
  background: var(--ak-choice-selected-bg);
  color: var(--ak-choice-selected-ink);
  border-color: var(--ak-choice-selected-border);
}

.box[aria-checked="true"]::after {
  content: "";
  flex: none;
  margin: 0 4px 3px auto;
  width: 8px;
  height: 15px;
  border: solid currentColor;
  border-width: 0 3.5px 3.5px 0;
  transform: rotate(40deg);
}

.box:focus-visible, .check:focus-visible, .gotit:focus-visible, .again:focus-visible, .change:focus-visible {
  outline: 3px solid var(--ak-focus);
  outline-offset: 3px;
}

.check, .gotit, .again {
  min-height: 56px;
  padding: 0 18px;
  background: var(--ak-btn-fill);
  color: var(--ak-btn-ink);
  border: 2px solid var(--ak-outline);
  border-radius: var(--ak-radius);
  box-shadow: var(--ak-shadow);
  font-family: var(--ak-font-display);
  font-weight: 700;
  font-size: 22px;
  letter-spacing: 0.03em;
  cursor: pointer;
  touch-action: manipulation;
}

.check:active, .gotit:active, .again:active { background: var(--ak-btn-active); transform: translateY(1px); box-shadow: none; }

.change {
  min-height: 56px;
  padding: 0 12px;
  background: var(--ak-choice-bg);
  color: var(--ak-choice-ink);
  border: 1.5px solid var(--ak-choice-border);
  border-bottom-width: 4px;
  border-radius: var(--ak-radius);
  font-family: var(--ak-font-display);
  font-weight: 700;
  font-size: 19px;
  cursor: pointer;
  touch-action: manipulation;
}

.ask[data-locked="true"] { opacity: 0.7; }
.ask[data-locked="true"] .box, .ask[data-locked="true"] .check { cursor: default; }

/* the worked step: a solid slip, never over the board */
.slip {
  padding: 10px 14px 12px;
  background: var(--ak-surface);
  color: var(--ak-ink);
  border: 2px solid var(--ak-ink);
  border-radius: var(--ak-radius);
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.slip[hidden], .ask[hidden], .result[hidden], .note[hidden] { display: none; }

.slip-label {
  margin: 0;
  font-size: 15px;
  font-weight: 700;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ak-ink-muted);
}

.slip-text {
  margin: 0;
  font-size: 19px;
  font-weight: 600;
  line-height: 1.3;
  color: var(--ak-ink);
}

.gotit { width: 100%; min-height: 60px; font-size: 24px; }

/* ---- the ending, in the margin beside the board ---- */

.result { display: flex; flex-direction: column; gap: 10px; }

.result-words { min-width: 0; }

.stamp {
  float: right;
  width: 84px;
  height: 84px;
  margin: 0 0 6px 10px;
  shape-outside: circle(50%);
  color: var(--ak-accent);
  position: relative;
}

.stamp img { display: block; width: 100%; height: 100%; object-fit: contain; transform: rotate(-7deg); }
.stamp.is-over { width: 116px; height: 62px; margin-top: 4px; }
.stamp .over { width: 100%; height: 100%; transform: rotate(-7deg); overflow: visible; }
.stamp .over text {
  font-family: var(--ak-font-display);
  font-weight: 700;
  font-size: 18px;
  letter-spacing: 0.04em;
  fill: currentColor;
}

.star {
  position: absolute;
  width: 22px;
  height: 22px;
  overflow: visible;
}

.star path {
  fill: none;
  stroke: var(--ak-accent);
  stroke-width: 2px;
  stroke-linejoin: round;
  stroke-linecap: round;
}

.star.s1 { left: -16px; top: -4px; }
.star.s2 { right: -4px; top: -12px; width: 16px; height: 16px; }
.star.s3 { left: 4px; bottom: -10px; width: 14px; height: 14px; }

.result-says {
  margin: 0;
  font-family: var(--ak-font-display);
  font-weight: 700;
  font-size: 21px;
  line-height: 1.18;
  color: var(--ak-ink);
}

.result-why {
  margin: 6px 0 0;
  padding-left: 10px;
  border-left: 3px solid var(--ak-accent);
  font-style: italic;
  font-size: 17px;
  line-height: 1.3;
  color: var(--ak-ink);
}

.result-actions { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; clear: both; }

/* ---- sideways: board on one side, margin on the other ---- */

@media (orientation: landscape) {
  .page { flex-direction: row; gap: var(--gap); }

  .board {
    --bh: max(
      calc(var(--rows) * 38px),
      min(
        calc(100vh - var(--st) - var(--sb) - var(--strip) - 6px),
        calc((100vw - var(--sl) - var(--sr) - var(--panel-min) - var(--gap)) * var(--rows) / var(--cols)),
        520px
      )
    );
    height: var(--bh);
    width: calc(var(--bh) * var(--cols) / var(--rows));
  }

  .margin { flex: 1 1 var(--panel-min); width: auto; max-width: 400px; min-width: 0; gap: 8px; }
  .note { min-height: 0; font-size: 19px; }
}

@supports (width: 1dvw) {
  @media (orientation: landscape) {
    .board {
      --bh: max(
        calc(var(--rows) * 38px),
        min(
          calc(100dvh - var(--st) - var(--sb) - var(--strip) - 6px),
          calc((100dvw - var(--sl) - var(--sr) - var(--panel-min) - var(--gap)) * var(--rows) / var(--cols)),
          520px
        )
      );
    }
  }
}

/* a short, narrow sideways phone: tighten the margin so it still fits */
@media (orientation: landscape) and (max-height: 420px) {
  .ask { gap: 6px; }
  .ask-label { font-size: 14px; }
  .box { min-height: 52px; font-size: 18px; }
  .check, .again, .change { min-height: 52px; font-size: 20px; }
  .slip-text { font-size: 18px; line-height: 1.25; }
  .gotit { min-height: 54px; }
  .result-says { font-size: 19px; }
  .result-why { font-size: 16px; }
  .stamp { width: 68px; height: 68px; }
}

/* ---- motion ---- */

@media (prefers-reduced-motion: no-preference) {
  .gear.is-settling { animation: settle 420ms cubic-bezier(0.34, 1.56, 0.64, 1); }
  .gear[data-mark="cw"] .mark-cw path,
  .gear[data-mark="ccw"] .mark-ccw path { stroke-dasharray: 60; animation: pen-draw 320ms ease-out both; }
  .gear.is-invite .ring circle { animation: invite 1400ms ease-in-out infinite; transform-origin: 50% 50%; }
  .gear.is-clash .ring circle { animation: shake 360ms ease-in-out; transform-origin: 50% 50%; }
  .gear.is-traced .ring circle { stroke-dasharray: 1; animation: ring-draw 380ms ease-out both; }
  .gear.is-traced .tick { animation: tick-pop 360ms cubic-bezier(0.34, 1.56, 0.64, 1) 160ms both; }
  .gear.is-answer .glow { animation: glow-in 520ms ease-out both; }
  .face img { animation: face-turn 9s linear infinite; }
  .desk.is-paused .face img { animation-play-state: paused; }
  .gear.is-spinning .spin { animation: gear-turn 1500ms cubic-bezier(0.45, 0, 0.25, 1) both; }
  .desk.is-paused .gear.is-spinning .spin,
  .desk.is-paused .gear.is-invite .ring circle { animation-play-state: paused; }
  .tag { animation: tag-in 380ms ease-out both; }
  .stamp img, .stamp .over { animation: stamp-land 560ms cubic-bezier(0.2, 0.9, 0.3, 1.25) both; }
  .star path { stroke-dasharray: 80; animation: pen-draw 480ms ease-out 480ms both; }
  .result { animation: slip-in 280ms ease-out both; }
  .box[aria-checked="true"] { animation: box-pop 220ms cubic-bezier(0.34, 1.56, 0.64, 1); }
}

@keyframes settle {
  0% { transform: rotate(0deg) scale(1); }
  30% { transform: rotate(-6deg) scale(1.07); }
  62% { transform: rotate(3deg) scale(0.98); }
  100% { transform: rotate(0deg) scale(1); }
}
@keyframes pen-draw { from { stroke-dashoffset: 60; } to { stroke-dashoffset: 0; } }
@keyframes invite {
  0%, 100% { transform: scale(1); opacity: 1; }
  50% { transform: scale(1.05); opacity: 0.55; }
}
@keyframes shake {
  0%, 100% { transform: translateX(0); }
  25% { transform: translateX(-2px); }
  75% { transform: translateX(2px); }
}
@keyframes ring-draw { from { stroke-dashoffset: 1; } to { stroke-dashoffset: 0; } }
@keyframes tick-pop { from { transform: scale(0); } to { transform: scale(1); } }
@keyframes glow-in { from { transform: scale(0.6); opacity: 0; } to { transform: scale(1); opacity: 1; } }
@keyframes face-turn {
  from { transform: translate(-50%, -50%) rotate(0deg); }
  to { transform: translate(-50%, -50%) rotate(360deg); }
}
@keyframes gear-turn { from { transform: rotate(0deg); } to { transform: rotate(var(--turn, 0deg)); } }
@keyframes tag-in { from { opacity: 0; translate: 0 6px; } to { opacity: 1; translate: 0 0; } }
@keyframes stamp-land {
  0% { opacity: 0; scale: 1.9; translate: 0 -26px; }
  55% { opacity: 1; scale: 0.92; translate: 0 2px; }
  100% { opacity: 1; scale: 1; translate: 0 0; }
}
@keyframes slip-in { from { opacity: 0; translate: 0 8px; } to { opacity: 1; translate: 0 0; } }
@keyframes box-pop { 0% { scale: 1; } 40% { scale: 1.04; } 100% { scale: 1; } }

@media (hover: hover) {
  .check:hover, .gotit:hover, .again:hover { background: var(--ak-btn-hover); }
  .box:hover { border-color: var(--ak-choice-selected-border); }
}
