/* Word Search — the same brass lamp, over a page of letters. */

:root {
  --ink:        #12100C;
  --parchment:  #F0E4CC;
  --parchment-2:#C3B294;
  --parchment-3:#8B7C64;
  --brass:      #C79A45;
  --brass-2:    #8A6C31;
  --crimson:    #A9342B;
  --verdigris:  #3FA97A;

  --shell: 1px solid color-mix(in srgb, var(--brass) 34%, transparent);

  /* The board is sized once, here, and everything on it is a fraction of it.
     --n is the number of cells across and is set by the tier, on the grid. */
  --board: min(92vw, 58vh, 520px);
}

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

html, body { height: 100%; }

body {
  margin: 0;
  font-family: 'IBM Plex Mono', ui-monospace, 'SFMono-Regular', Menlo, monospace;
  color: var(--parchment);
  background:
    radial-gradient(130% 90% at 50% -20%, #33281D 0%, #1D1710 46%, #0D0A07 100%);
  background-attachment: fixed;
  -webkit-font-smoothing: antialiased;
}

[hidden] { display: none !important; }

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

/* -------------------------------------------------------------- layout -- */

.page {
  position: relative;
  z-index: 2;
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: clamp(10px, 2vh, 18px);
  padding: 12px 16px calc(16px + env(safe-area-inset-bottom));
  max-width: 980px;
  margin-inline: auto;
}

/* ----------------------------------------------------------- masthead -- */

.topbar {
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 10px 18px;
}

.masthead {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 8px 16px;
  min-width: 0;
}

.backlink {
  font-size: 10px;
  letter-spacing: .28em;
  text-transform: uppercase;
  color: var(--parchment-3);
  text-decoration: none;
  border-bottom: 1px solid transparent;
  padding-bottom: 2px;
  transition: color .2s, border-color .2s;
}
.backlink::before { content: '\27F5\2003'; }
.backlink:hover {
  color: var(--brass);
  border-bottom-color: color-mix(in srgb, var(--brass) 50%, transparent);
}

.title {
  font-family: 'Fraunces', Georgia, serif;
  font-variation-settings: 'SOFT' 50, 'opsz' 120, 'wght' 620;
  font-weight: 620;
  font-size: clamp(1.35rem, 3.2vw, 1.85rem);
  line-height: 1;
  margin: 0;
  letter-spacing: -.015em;
  text-shadow: 0 1px 0 #000, 0 0 34px rgba(199, 154, 69, .18);
}

.stamp {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 10px;
  margin: 0;
  font-size: 10px;
  font-weight: 500;
  letter-spacing: .3em;
  text-transform: uppercase;
  color: var(--brass);
}
.stamp__rule {
  width: 18px;
  height: 1px;
  background: linear-gradient(90deg, transparent, var(--brass-2), transparent);
}

/* --------------------------------------------------------------- tiers -- */

.tiers {
  display: flex;
  gap: 6px;
  padding: 4px;
  border: var(--shell);
  border-radius: 3px;
  background: rgba(9, 7, 5, .4);
}

.chip {
  font: inherit;
  font-size: 11px;
  font-weight: 500;
  letter-spacing: .12em;
  color: var(--parchment-3);
  background: none;
  border: 1px solid transparent;
  border-radius: 2px;
  padding: 7px 13px;
  cursor: pointer;
  transition: color .18s, background .18s, border-color .18s;
}
.chip:hover { color: var(--brass); }
.chip[aria-pressed='true'] {
  color: var(--ink);
  background: var(--brass);
  border-color: var(--brass);
}
.chip:focus-visible { outline: 2px solid var(--brass); outline-offset: 2px; }

/* The day's theme, worn like the sudoku's grade sticker. */
.sticker {
  margin: 0;
  padding: 6px 16px;
  font-size: 10px;
  font-weight: 600;
  letter-spacing: .3em;
  text-transform: uppercase;
  color: var(--ink);
  background: var(--brass);
  border-radius: 2px;
  transform: rotate(-.8deg);
  box-shadow: 0 6px 14px -8px rgba(0, 0, 0, .9);
}

.shelfnote {
  margin: -4px 0 0;
  font-family: 'Fraunces', Georgia, serif;
  font-variation-settings: 'ital' 1, 'wght' 500;
  font-style: italic;
  font-size: 13px;
  color: var(--parchment-3);
  text-align: center;
}

/* --------------------------------------------------------------- bench -- */

.bench {
  width: 100%;
  display: flex;
  align-items: flex-start;
  justify-content: center;
  gap: clamp(14px, 3vw, 32px);
}

/* --------------------------------------------------------------- board -- */

.board {
  position: relative;
  flex: 0 0 auto;
  width: var(--board);
  aspect-ratio: 1;
}

.grid {
  display: grid;
  grid-template-columns: repeat(var(--n, 10), 1fr);
  width: 100%;
  height: 100%;
  border: 2px solid var(--brass-2);
  border-radius: 3px;
  background: rgba(9, 7, 5, .45);
  box-shadow:
    0 24px 48px -28px rgba(0, 0, 0, .9),
    inset 0 0 60px -30px rgba(199, 154, 69, .35);
  overflow: hidden;
  /* A drag across the grid is the whole game, so the browser must not read it
     as a scroll. Without this a phone pans the page instead of tracing a word. */
  touch-action: none;
  user-select: none;
  -webkit-user-select: none;
}

.cell {
  position: relative;
  font: inherit;
  font-family: 'Fraunces', Georgia, serif;
  font-variation-settings: 'SOFT' 50, 'wght' 500;
  font-size: calc(var(--board) / var(--n, 10) * .52);
  line-height: 1;
  padding: 0;
  margin: 0;
  aspect-ratio: 1;
  display: grid;
  place-items: center;
  text-transform: uppercase;
  color: var(--parchment-2);
  background: transparent;
  border: 0;
  cursor: pointer;
  transition: color .12s, background .12s;
  -webkit-tap-highlight-color: transparent;
}

/* A letter under the run being dragged, and a letter under a word already
   taken. The lozenges do the shouting; the letters only lift a little. */
.cell.is-picked { color: var(--parchment); background: rgba(240, 228, 204, .1); }
.cell.is-struck { color: var(--parchment); }

.cell.is-wrong { animation: wrong .4s ease-out; }
@keyframes wrong {
  0%   { background: rgba(169, 52, 43, .45); }
  100% { background: rgba(169, 52, 43, 0); }
}

.cell:focus-visible { outline: 2px solid var(--brass); outline-offset: -2px; }

/* The anchor of a click-click selection, waiting for its second click. */
.grid.is-pending .cell.is-picked { animation: waiting 1.4s ease-in-out infinite; }
@keyframes waiting {
  0%, 100% { background: rgba(240, 228, 204, .1); }
  50%      { background: rgba(240, 228, 204, .26); }
}

/* --------------------------------------------------------------- marks -- */

/* One capsule per word found, plus the one being dragged. Laid out in
   percentages of the board and rotated onto the run, so they need nothing
   redrawn when the board changes size. */
.grid__marks {
  position: absolute;
  inset: 0;
  pointer-events: none;
}

.mark {
  position: absolute;
  border: 2px solid var(--pen);
  border-radius: 999px;
  background: color-mix(in srgb, var(--pen) 15%, transparent);
  animation: draw .28s cubic-bezier(.3, 1.3, .5, 1);
}
@keyframes draw {
  from { opacity: 0; }
  to   { opacity: 1; }
}

.mark--live {
  border-style: dashed;
  border-color: rgba(240, 228, 204, .8);
  background: rgba(240, 228, 204, .1);
  animation: none;
}

/* --------------------------------------------------------------- tally -- */

.tally {
  flex: 0 1 240px;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 14px 16px;
  border: var(--shell);
  border-radius: 3px;
  background:
    linear-gradient(160deg, rgba(255, 255, 255, .03), rgba(255, 255, 255, 0) 60%),
    rgba(9, 7, 5, .4);
}

.tally__title {
  margin: 0;
  font-size: 9px;
  font-weight: 500;
  letter-spacing: .3em;
  text-transform: uppercase;
  color: var(--brass-2);
  text-align: center;
}

.tally__words {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 3px;
}

.tally__word {
  position: relative;
  padding: 3px 4px 3px 16px;
  font-size: 12px;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--parchment-2);
  border-radius: 2px;
  transition: color .25s, opacity .25s;
}
/* The bullet is the word's own colour, so the list and the grid agree about
   which lozenge belongs to which word. */
.tally__word::before {
  content: '';
  position: absolute;
  left: 4px;
  top: 50%;
  width: 5px;
  height: 5px;
  margin-top: -2.5px;
  border-radius: 50%;
  border: 1px solid var(--pen);
  transition: background .25s;
}
/* A word the Unlabelled has not given up yet: a rule as long as the word is,
   drawn the way hangman draws a letter it has not been told. */
.tally__rule {
  display: inline-block;
  height: 1.05em;
  vertical-align: -.2em;
  /* The list is monospace, so a character is exactly 1ch — plus the tracking
     the row carries, or a nine-letter rule would come up short of its word. */
  width: calc(var(--len, 6) * (1ch + .06em));
  border-bottom: 1px dashed rgba(199, 154, 69, .45);
}

.tally__word.is-found {
  color: color-mix(in srgb, var(--pen) 72%, var(--parchment));
  text-decoration: line-through;
  text-decoration-color: color-mix(in srgb, var(--pen) 80%, transparent);
  background: color-mix(in srgb, var(--pen) 14%, transparent);
}
.tally__word.is-found::before { background: var(--pen); }

.tally__note {
  margin: 0;
  padding-top: 8px;
  border-top: 1px solid rgba(199, 154, 69, .16);
  font-size: 9px;
  letter-spacing: .2em;
  text-transform: uppercase;
  color: var(--parchment-3);
  text-align: center;
}
.tally__note span { color: var(--parchment); }

/* ------------------------------------------------------------- console -- */

.console {
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 12px;
  margin-top: auto;
  padding-top: 10px;
  border-top: 1px solid rgba(199, 154, 69, .16);
}

.counter { margin: 0; display: flex; align-items: baseline; gap: 10px; }
.counter__label {
  font-size: 10px;
  letter-spacing: .28em;
  text-transform: uppercase;
  color: var(--parchment-3);
}
.counter b {
  font-family: 'Fraunces', Georgia, serif;
  font-variation-settings: 'wght' 600;
  font-size: 1.3rem;
  color: var(--parchment);
  font-variant-numeric: tabular-nums;
}
.counter__sub {
  font-size: 10px;
  letter-spacing: .2em;
  text-transform: uppercase;
  color: var(--brass-2);
}

.actions { display: flex; gap: 6px; flex-wrap: wrap; }

.btn {
  font: inherit;
  font-size: 10px;
  font-weight: 500;
  letter-spacing: .2em;
  text-transform: uppercase;
  color: var(--parchment-2);
  background: rgba(255, 255, 255, .015);
  border: var(--shell);
  border-radius: 2px;
  padding: 9px 12px;
  cursor: pointer;
  transition: color .18s, background .18s, border-color .18s, transform .1s;
}
.btn:hover:not(:disabled) {
  color: var(--ink);
  background: var(--brass);
  border-color: var(--brass);
}
.btn:active:not(:disabled) { transform: translateY(1px); }
.btn:disabled { opacity: .3; cursor: default; }
.btn:focus-visible { outline: 2px solid var(--brass); outline-offset: 2px; }
.btn[aria-pressed='false'] { color: var(--parchment-3); border-style: dashed; }

/* --------------------------------------------------------------- howto -- */

.howto {
  width: 100%;
  font-size: 12px;
  line-height: 1.65;
  color: var(--parchment-2);
}
.howto summary {
  cursor: pointer;
  list-style: none;
  font-size: 10px;
  letter-spacing: .28em;
  text-transform: uppercase;
  color: var(--parchment-3);
  padding: 4px 0;
  transition: color .2s;
}
.howto summary::-webkit-details-marker { display: none; }
.howto summary::before { content: '\FF0B\2002'; color: var(--brass-2); }
.howto[open] summary::before { content: '\FF0D\2002'; }
.howto summary:hover { color: var(--brass); }
.howto ul { margin: 10px 0; padding-left: 1.1em; }
.howto li { margin-bottom: 5px; }
.howto b { color: var(--parchment); font-weight: 500; }
.howto kbd {
  font: inherit;
  font-size: 11px;
  padding: 1px 5px;
  border: 1px solid rgba(199, 154, 69, .3);
  border-radius: 2px;
  color: var(--parchment);
}
.howto__note {
  color: var(--parchment-3);
  border-left: 1px solid var(--brass-2);
  padding-left: 12px;
  max-width: 62ch;
}

/* ----------------------------------------------------------------- win -- */

.win {
  position: fixed;
  inset: 0;
  z-index: 60;
  display: grid;
  place-items: center;
  padding: 20px;
  background: rgba(10, 8, 5, .72);
  backdrop-filter: blur(7px) saturate(.8);
  -webkit-backdrop-filter: blur(7px) saturate(.8);
  animation: fade .4s ease both;
}
.win.is-instant { animation: none; }
@keyframes fade { from { opacity: 0; } to { opacity: 1; } }

.win__card {
  position: relative;
  width: min(400px, 100%);
  text-align: center;
  padding: 46px 30px 30px;
  color: #2A2117;
  border-radius: 3px;
  background:
    radial-gradient(120% 90% at 50% 0%, #FBF2DF 0%, #EFE1C4 60%, #E2D2B2 100%);
  box-shadow:
    0 30px 60px -20px rgba(0, 0, 0, .8),
    inset 0 0 0 1px rgba(255, 255, 255, .5),
    inset 0 0 0 6px rgba(63, 169, 122, .08);
  animation: rise .5s cubic-bezier(.25, 1.2, .4, 1) both;
}
.win.is-instant .win__card { animation: none; }
@keyframes rise {
  from { opacity: 0; transform: translateY(22px) scale(.96); }
  to   { opacity: 1; transform: none; }
}

.seal {
  position: absolute;
  top: -26px;
  left: 50%;
  width: 62px;
  height: 62px;
  transform: translateX(-50%) rotate(-8deg);
  border-radius: 50%;
  display: grid;
  place-items: center;
  color: rgba(255, 226, 216, .78);
  font-size: 22px;
  background: radial-gradient(circle at 34% 28%, #C4463A, #8E2A22 62%, #6E1E18 100%);
  box-shadow:
    inset 0 -3px 8px rgba(0, 0, 0, .5),
    inset 0 3px 6px rgba(255, 255, 255, .25),
    0 8px 16px -6px rgba(0, 0, 0, .7);
  clip-path: polygon(
    50% 0%, 66% 6%, 82% 4%, 92% 18%, 100% 32%, 96% 50%, 100% 68%, 90% 82%,
    80% 96%, 62% 96%, 46% 100%, 30% 94%, 16% 90%, 8% 74%, 0% 56%, 4% 38%,
    2% 20%, 18% 10%, 34% 6%);
}

.win__card h2 {
  font-family: 'Fraunces', Georgia, serif;
  font-variation-settings: 'SOFT' 50, 'opsz' 140, 'wght' 700;
  font-size: 2.1rem;
  margin: 6px 0 4px;
  letter-spacing: -.01em;
}

.win__theme {
  margin: 0 0 16px;
  font-family: 'Fraunces', Georgia, serif;
  font-variation-settings: 'ital' 1, 'wght' 500;
  font-style: italic;
  font-size: 1.15rem;
  letter-spacing: .04em;
  color: #7A6244;
}

.win__line { margin: 0 0 22px; font-size: 12px; line-height: 1.8; color: #574734; }
.win__line b { color: #2A2117; font-weight: 600; }

.win__next {
  margin: 0 0 22px;
  padding: 12px 0;
  border-top: 1px solid rgba(42, 33, 23, .16);
  border-bottom: 1px solid rgba(42, 33, 23, .16);
}
.win__next-label {
  display: block;
  font-size: 9px;
  letter-spacing: .3em;
  text-transform: uppercase;
  color: #8A7458;
  margin-bottom: 6px;
}
.win__clock {
  font-size: 1.5rem;
  font-weight: 500;
  font-variant-numeric: tabular-nums;
  letter-spacing: .06em;
  color: #2A2117;
}

.win__actions {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  align-items: center;
  gap: 8px;
}

.btn--ink {
  color: #574734;
  border-color: rgba(42, 33, 23, .3);
  background: transparent;
}
.btn--ink:hover:not(:disabled) {
  background: #2A2117;
  border-color: #2A2117;
  color: #EFE1C4;
}

/* The way onward. Filled rather than outlined so it reads as the one thing to
   do next, with an arrow that leans the way it goes and takes a step on hover.
   Which shelf it leads to is on the chips behind the card, so the face of the
   button stays a single word and the tier name rides on the label. */
.btn--next {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  padding-inline: 14px;
  color: #F2E6CE;
  background: linear-gradient(180deg, #493A29 0%, #2A2117 100%);
  border-color: #2A2117;
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, .13),
    0 3px 7px -3px rgba(42, 33, 23, .7);
}
.btn--next:hover:not(:disabled) {
  color: #FBF2DF;
  background: linear-gradient(180deg, #5B4934 0%, #372B1D 100%);
  border-color: #2A2117;
}
.btn--next:focus-visible { outline-color: #8E2A22; }

.btn__arrow {
  margin-block: -1px; /* optical: the rule sits on the cap height, not below it */
  transition: transform .2s cubic-bezier(.25, 1.2, .4, 1);
}
.btn--next:hover:not(:disabled) .btn__arrow { transform: translateX(3px); }
.btn--next:active:not(:disabled) .btn__arrow { transform: translateX(1px); }

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

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
  }
}

/* The list has to sit under the grid before the grid has to shrink for it, so
   the break is on width, and the board takes the whole width once it does. */
@media (max-width: 780px) {
  :root { --board: min(94vw, 52vh, 480px); }

  .page { padding-inline: 10px; }
  .topbar { flex-direction: column; align-items: stretch; gap: 8px; }
  .masthead { justify-content: center; gap: 4px 12px; }
  .stamp { justify-content: center; letter-spacing: .18em; }
  .stamp__rule { display: none; }
  .tiers { width: 100%; }
  .chip { flex: 1 1 0; min-width: 0; padding: 8px 4px; letter-spacing: .04em; }

  .bench { flex-direction: column; align-items: center; }
  .tally { flex: 0 0 auto; width: var(--board); max-width: 100%; }
  .tally__words { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 3px 8px; }

  .console { flex-direction: column; align-items: stretch; }
  .counter { justify-content: center; }
  .actions { justify-content: center; }
}

@media (max-width: 420px) {
  :root { --board: min(96vw, 48vh, 420px); }
  .tally__word { font-size: 11px; letter-spacing: .02em; }
}

/* ---------------------------------------------------------------- ledger -- */

/* The written half of the page: what the game is, and the way out to the
   others. Below the fold by design — the game gets the first screen. */
.ledger {
  position: relative;
  z-index: 2;
  max-width: 720px;
  margin: 0 auto;
  padding: 40px 20px calc(56px + env(safe-area-inset-bottom));
  display: grid;
  gap: 34px;
  border-top: 1px solid rgba(199, 154, 69, .16);
  font-size: 13px;
  line-height: 1.85;
  color: var(--parchment-2);
}

.ledger h2 {
  font-family: 'Fraunces', Georgia, serif;
  font-variation-settings: 'SOFT' 50, 'opsz' 90, 'wght' 600;
  font-weight: 600;
  font-size: 1.25rem;
  line-height: 1.2;
  margin: 0 0 14px;
  color: var(--parchment);
  letter-spacing: -.01em;
}

.ledger p { margin: 0 0 14px; }
.ledger p:last-child { margin-bottom: 0; }
.ledger strong { color: var(--parchment); font-weight: 500; }
.ledger em { color: var(--brass); font-style: italic; }

.ledger__more ul {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 10px;
}
.ledger__more li {
  padding-left: 14px;
  border-left: 1px solid rgba(199, 154, 69, .22);
}
.ledger a {
  color: var(--brass);
  text-decoration: none;
  border-bottom: 1px solid transparent;
  transition: border-color .2s;
}
.ledger a:hover { border-bottom-color: var(--brass); }
.ledger__home { margin-top: 18px; font-size: 11px; letter-spacing: .2em; text-transform: uppercase; }

.ledger__legal {
  grid-column: 1 / -1;
  display: flex;
  flex-wrap: wrap;
  gap: 6px 18px;
  padding-top: 18px;
  border-top: 1px solid rgba(199, 154, 69, .12);
  font-size: 10px;
  letter-spacing: .18em;
  text-transform: uppercase;
}
.ledger__legal a { color: var(--parchment-3); }
.ledger__legal a:hover { color: var(--brass); }

@media (min-width: 760px) {
  .ledger { max-width: 940px; grid-template-columns: 1.7fr 1fr; gap: 48px; }
}
