/* =====================================================================
   Day 3/30 — Wetin You Mean

   The world is a Lagos hand-painted signboard. Warm exercise-book paper,
   ink-black lettering, and one signwriter's cobalt that is reserved for
   exactly one thing: the answer. Nothing else on the page is blue.

   Radius is 4px everywhere, no exceptions — sign painters do not do pills.
   Shadows are hard offsets with no blur, because these are physical objects
   sitting on paper, not floating cards.
   ===================================================================== */

:root {
  --paper: #EFE3CA;
  --paper-sheet: #F7EEDC;
  --paper-deep: #E4D5B6;
  --paper-line: #D3C09B;

  --ink: #1B1D1A;
  --ink-soft: #5C5648;      /* 5.7:1 on paper */

  --cobalt: #1C3FC4;        /* 6.5:1 on paper, 7.8:1 against chalk */
  --chalk: #FFF8EA;
  --alarm: #B02914;         /* 5.2:1 on paper, 6.3:1 against chalk */

  --r: 4px;
  --edge: 2px;

  --display: "Bricolage Grotesque", ui-sans-serif, system-ui, sans-serif;
  --body: "Instrument Sans", ui-sans-serif, system-ui, sans-serif;
  --label-face: "JetBrains Mono", ui-monospace, monospace;
}

*, *::before, *::after { box-sizing: border-box; }

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

body {
  margin: 0;
  min-height: 100dvh;
  padding:
    clamp(1.75rem, 6vw, 3rem)
    1.25rem
    calc(3.75rem + env(safe-area-inset-bottom));
  display: flex;
  justify-content: center;
  overflow-x: hidden;

  background-color: var(--paper);
  /* A little unevenness in the stock, so it does not read as flat #hex. */
  background-image:
    radial-gradient(120% 80% at 50% -10%, rgba(255, 250, 238, .55), transparent 60%),
    radial-gradient(90% 60% at 100% 105%, rgba(160, 140, 100, .16), transparent 65%);

  color: var(--ink);
  font-family: var(--body);
  font-size: 1rem;
  line-height: 1.5;
}

.stall { width: 100%; max-width: 34rem; }

.sr-only {
  position: absolute;
  width: 1px; height: 1px;
  margin: -1px; padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

:focus-visible {
  outline: 3px solid var(--cobalt);
  outline-offset: 2px;
  border-radius: 1px;
}

/* Drops the legacy 300ms tap delay on touch, and stops a double-tap on a
   control from zooming the page instead of firing the button. */
button,
textarea {
  touch-action: manipulation;
}

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

.head { margin-bottom: clamp(1.5rem, 5vw, 2.25rem); }

h1 {
  margin: 0;
  font-family: var(--display);
  font-size: clamp(2rem, 9vw, 2.75rem);
  font-weight: 800;
  line-height: 1;
  letter-spacing: -0.035em;
}

.sub {
  margin: 0.5rem 0 0;
  font-size: 0.9375rem;
  color: var(--ink-soft);
}

/* ---------- shared label ---------- */

.label {
  margin: 0 0 0.5rem;
  font-size: 0.8125rem;
  font-weight: 600;
  color: var(--ink-soft);
}

/* ---------- direction ---------- */

.direction {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  margin-bottom: 1.25rem;
}

.pair {
  display: flex;
  align-items: baseline;
  gap: 0.5rem;
  margin: 0;
  font-family: var(--display);
  font-size: 1.125rem;
  font-weight: 600;
  letter-spacing: -0.015em;
}

/* Always points at the target language. It never flips — the words swap,
   the arrow does not, or the pair reads as pointing back at the source. */
.arrow {
  font-size: 1.25rem;
  color: var(--ink-soft);
}

.lang-to { color: var(--cobalt); }

.swap {
  flex: none;
  min-height: 2.75rem;
  padding: 0 0.9375rem;
  display: inline-flex;
  align-items: center;
  gap: 0.4375rem;

  font-family: var(--body);
  font-size: 0.875rem;
  font-weight: 600;
  color: var(--ink);

  background: transparent;
  border: var(--edge) solid var(--ink);
  border-radius: var(--r);
  cursor: pointer;
  transition: background-color 160ms ease, color 160ms ease;
}

/* Feedback on the control the user actually pressed. The glyph is
   symmetrical, so it spins and lands looking identical — motion without
   leaving a changed state behind. */
.swap-glyph {
  font-size: 1rem;
  line-height: 1;
  display: inline-block;
  transition: transform 280ms cubic-bezier(.34, 1.4, .64, 1);
}

.swap[data-flip="true"] .swap-glyph { transform: rotate(180deg); }

.swap:active { background: var(--ink); color: var(--chalk); }

/* ---------- the sheet ---------- */

.sheet {
  --rule: 2rem;
  border: var(--edge) solid var(--ink);
  border-radius: var(--r);
  box-shadow: 4px 5px 0 rgba(27, 29, 26, .15);
  background-color: var(--paper-sheet);
  background-image: repeating-linear-gradient(
    to bottom,
    transparent 0,
    transparent calc(var(--rule) - 1.5px),
    var(--paper-line) calc(var(--rule) - 1.5px),
    var(--paper-line) var(--rule)
  );
  background-position: 0 0.8125rem;   /* aligns the rules under the text baselines */
  overflow: hidden;
}

textarea {
  display: block;
  width: 100%;
  padding: 0.8125rem 0.9375rem;
  border: 0;
  background: transparent;
  color: var(--ink);

  font-family: var(--body);
  font-size: 1.0625rem;   /* >16px so iOS does not zoom on focus */
  line-height: 2rem;      /* must equal --rule for the text to sit on the lines */
  resize: none;
}

textarea::placeholder { color: var(--ink-soft); opacity: .75; }
textarea:focus { outline: none; }
.sheet:focus-within { outline: 3px solid var(--cobalt); outline-offset: 2px; }

/* ---------- notes under the sheet ---------- */

.note {
  margin: 0.5rem 0 0;
  font-size: 0.8125rem;
  color: var(--ink-soft);
  font-variant-numeric: tabular-nums;
}

.note-error {
  color: var(--alarm);
  font-weight: 600;
}

.count.is-near { color: var(--alarm); font-weight: 600; }

/* ---------- primary action ---------- */

.go {
  width: 100%;
  min-height: 3.25rem;
  margin-top: 1.125rem;

  font-family: var(--display);
  font-size: 1.125rem;
  font-weight: 800;
  letter-spacing: -0.015em;
  color: var(--chalk);

  background: var(--ink);
  border: var(--edge) solid var(--ink);
  border-radius: var(--r);
  box-shadow: 4px 5px 0 var(--cobalt);
  cursor: pointer;

  transition: transform 120ms cubic-bezier(.2, .8, .3, 1),
              box-shadow 120ms cubic-bezier(.2, .8, .3, 1);
}

/* Physical push: the button travels onto its own shadow. */
.go:active {
  transform: translate(4px, 5px);
  box-shadow: 0 0 0 var(--cobalt);
}

.go[disabled] {
  opacity: .5;
  cursor: progress;
  transform: none;
  box-shadow: 4px 5px 0 var(--cobalt);
}

/* ---------- the board (the one authored moment) ---------- */

.result { margin-top: clamp(1.75rem, 6vw, 2.5rem); }

.board {
  position: relative;
  overflow: hidden;
  display: grid;
  align-items: center;
  min-height: 8.75rem;
  padding: 1.5rem 1.25rem;

  border: var(--edge) solid var(--ink);
  border-radius: var(--r);
  box-shadow: 6px 7px 0 var(--ink);
  transform: rotate(-1.1deg);   /* a plank, not a div */
}

.board-text {
  position: relative;
  margin: 0;
  font-family: var(--display);
  font-size: clamp(1.375rem, 6.2vw, 1.875rem);
  font-weight: 800;
  line-height: 1.18;
  letter-spacing: -0.025em;
  overflow-wrap: anywhere;
}

/* Unpainted board: nothing has been written on it yet. */
.board[data-state="empty"] {
  background: var(--paper-deep);
  border-style: dashed;
  box-shadow: 3px 4px 0 rgba(27, 29, 26, .08);
}

.board[data-state="empty"] .board-text {
  font-weight: 600;
  font-size: 1.0625rem;
  line-height: 1.45;
  letter-spacing: 0;
  color: var(--ink-soft);
}

.board[data-state="loading"],
.board[data-state="done"] {
  background: var(--cobalt);
  color: var(--chalk);
}

.board[data-state="loading"] .board-text {
  font-weight: 600;
  font-size: 1.0625rem;
  letter-spacing: 0;
  opacity: .8;
}

.board[data-state="error"] {
  background: var(--alarm);
  color: var(--chalk);
}

.board[data-state="error"] .board-text {
  font-weight: 600;
  font-size: 1.0625rem;
  line-height: 1.45;
  letter-spacing: 0;
}

/* The brush: a loaded stroke travelling across the board while we wait. */
.brush {
  position: absolute;
  inset: 0;
  opacity: 0;
  pointer-events: none;
  background: linear-gradient(
    100deg,
    transparent 0 38%,
    rgba(255, 248, 234, .26) 50%,
    transparent 62% 100%
  );
}

.board[data-state="loading"] .brush {
  opacity: 1;
  animation: sweep 1150ms cubic-bezier(.45, .05, .55, .95) infinite;
}

@keyframes sweep {
  from { transform: translateX(-105%); }
  to   { transform: translateX(105%); }
}

/* The signature: the answer is painted on, left to right, and the plank
   settles with a little overshoot as it lands. */
@keyframes plank-settle {
  0%   { transform: rotate(-3.6deg) translateY(8px) scale(.982); }
  62%  { transform: rotate(-0.1deg) translateY(-3px) scale(1.008); }
  100% { transform: rotate(-1.1deg) translateY(0) scale(1); }
}

@keyframes paint-in {
  from { clip-path: inset(0 100% 0 0); }
  to   { clip-path: inset(0 -2% 0 0); }
}

.board[data-state="done"] {
  animation: plank-settle 460ms cubic-bezier(.34, 1.42, .64, 1) both;
}

.board[data-state="done"] .board-text {
  animation: paint-in 560ms cubic-bezier(.16, 1, .3, 1) 90ms both;
}

/* ---------- copy ---------- */

.result-foot {
  display: flex;
  justify-content: flex-end;
  min-height: 2.75rem;
  margin-top: 0.875rem;
}

.copy {
  min-height: 2.75rem;
  padding: 0 1rem;
  font-family: var(--body);
  font-size: 0.875rem;
  font-weight: 600;
  color: var(--ink);
  background: transparent;
  border: var(--edge) solid var(--ink);
  border-radius: var(--r);
  cursor: pointer;
  transition: background-color 160ms ease, color 160ms ease;
}

.copy:active { background: var(--ink); color: var(--chalk); }
.copy[data-done="true"] { background: var(--cobalt); border-color: var(--cobalt); color: var(--chalk); }

/* ---------- examples ---------- */

.tryout { margin-top: clamp(1.75rem, 6vw, 2.5rem); }

.chips {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin: 0;
  padding: 0;
  list-style: none;
}

.chips button {
  min-height: 2.75rem;
  padding: 0 0.875rem;
  max-width: 100%;

  font-family: var(--body);
  font-size: 0.875rem;
  font-weight: 500;
  text-align: left;
  color: var(--ink);

  background: var(--paper-deep);
  border: 1.5px dashed var(--ink-soft);
  border-radius: var(--r);
  cursor: pointer;
  transition: border-color 160ms ease, background-color 160ms ease;
}

.chips button:active {
  background: var(--paper-sheet);
  border-color: var(--cobalt);
  border-style: solid;
}

/* ---------- the one consistent thread across all 30 days ---------- */

/* The label is fixed, so content would otherwise scroll underneath it.
   The page fades back into bare paper at the bottom edge instead. */
body::after {
  content: "";
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  height: 4.5rem;
  z-index: 50;
  pointer-events: none;
  background: linear-gradient(to top, rgb(239 227 202) 34%, rgb(239 227 202 / 0));
}

.day {
  position: fixed;
  z-index: 55;
  right: max(1rem, env(safe-area-inset-right));
  bottom: max(0.9rem, env(safe-area-inset-bottom));
  margin: 0;
  font-family: var(--label-face);
  font-size: 0.625rem;
  font-weight: 700;
  letter-spacing: 0.24em;
  color: var(--ink-soft);
  user-select: none;
}

/* ---------- paper grain ---------- */

.grain {
  position: fixed;
  inset: 0;
  z-index: 60;
  pointer-events: none;
  opacity: .38;
  mix-blend-mode: multiply;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)' opacity='.32'/%3E%3C/svg%3E");
}

/* ---------- larger screens ---------- */

@media (min-width: 34rem) {
  .day { font-size: 0.6875rem; }
  .chips button { font-size: 0.9375rem; }
}

/* Pointer devices get hover; touch never depends on it. */
@media (hover: hover) {
  .swap:hover { background: var(--ink); color: var(--chalk); }
  .copy:hover { background: var(--ink); color: var(--chalk); }
  .chips button:hover { border-color: var(--cobalt); border-style: solid; background: var(--paper-sheet); }
  .go:hover { box-shadow: 6px 7px 0 var(--cobalt); transform: translate(-1px, -1px); }
  .go[disabled]:hover { box-shadow: 4px 5px 0 var(--cobalt); transform: none; }
}

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

@media (prefers-reduced-motion: reduce) {
  .board[data-state="done"],
  .board[data-state="done"] .board-text,
  .board[data-state="loading"] .brush {
    animation: none;
  }
  .board[data-state="loading"] .brush { opacity: 0; }
  .go, .swap, .copy, .chips button, .swap-glyph { transition-duration: 1ms; }
}
