/* The rippling code: a code block printed in the inks of a hiking map, on a white page. The page is white, the block
   is pale map paper, the code is in the map's inks (contour brown, forest green, water blue, trail red) and the
   selection is a lake with its darker shore. */
:root {
  --page: #ffffff;          /* the page */
  --paper: #f1f5f0;         /* the block: pale map paper */
  --bar: #e7ede5;           /* the band of the tabs */
  --rule: #d5ddd3;          /* the hairlines */
  --ink: #16231c;           /* the words, and the pill of the chosen tab */
  --muted: #64746b;         /* the tabs not chosen */
  --water: #cfe5f6;         /* the selection: the lake */
  --shore: #6aa6d6;         /* the lake's shore, and the tick */
  --kw: #a04c17;            /* the words of the language: contour brown */
  --str: #2b7646;           /* texts in quotes: forest green */
  --fn: #1c5f9f;            /* functions: water blue */
  --type: #b7382a;          /* classes and types: trail red */
  --const: #874083;         /* constants and keys */
  --prop: #31453b;          /* names after a dot */
  --num: #ad6216;           /* figures */
  --pun: #84918a;           /* signs */
  --com: #8b9790;           /* comments */
}

* {
  box-sizing: border-box;
}

html {
  touch-action: manipulation;
}

html,
body {
  margin: 0;
}

body {
  min-height: 100svh;
  background: var(--page);
  color: var(--ink);
  font-family: 'Instrument Sans Variable', system-ui, sans-serif;
  -webkit-font-smoothing: antialiased;
}

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

/* the block hangs from the top: the code grows and shrinks downwards and the tabs never move */
.stage {
  min-height: 100svh;
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  justify-items: center;
  align-content: start;
  padding: max(32px, calc(50svh - 150px)) 16px 40px;
}

.snippet {
  width: min(600px, 100%);
  overflow: hidden;
  border-radius: 16px;
  background: var(--paper);
  box-shadow:
    0 0 0 1px var(--rule),
    0 1px 2px rgba(22, 35, 28, 0.06),
    0 18px 40px -22px rgba(22, 35, 28, 0.28);
}

/* ---------------------------------------------------------------- the band: the tabs and Copy */
.snippet__bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 8px 8px 8px 8px;
  border-bottom: 1px solid var(--rule);
  background: var(--bar);
}

.tabs {
  position: relative;
  min-width: 0;
}

.tabs__row {
  display: flex;
  gap: 2px;
}

.tab {
  position: relative;
  display: inline-flex;
  align-items: center;
  height: 34px;
  padding: 0 12px;
  border: 0;
  border-radius: 9px;
  background: transparent;
  color: var(--muted);
  font: 600 13.5px/1 'Instrument Sans Variable', system-ui, sans-serif;
  font-stretch: 100%;
  white-space: nowrap;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: color 0.2s ease, background-color 0.2s ease;
}

@media (hover: hover) {
  .tab:hover {
    color: var(--ink);
    background: rgba(22, 35, 28, 0.05);
  }
}

/* the chosen tab: a copy of the row, dark with light words, cut to the chosen tab with clip-path, so the words change
   colour exactly at the pill's edge as it slides */
.tabs__ink {
  position: absolute;
  inset: 0;
  background: var(--ink);
  pointer-events: none;
  clip-path: inset(0 100% 0 0 round 9px);
}

.tabs__ink .tab {
  color: var(--paper);
}

/* the Copy button */
.copy {
  position: relative;
  flex: none;
  display: inline-flex;
  align-items: center;
  gap: 7px;
  height: 34px;
  padding: 0 12px 0 10px;
  border: 0;
  border-radius: 9px;
  background: var(--paper);
  box-shadow: inset 0 0 0 1px var(--rule);
  color: var(--ink);
  font: 600 13.5px/1 'Instrument Sans Variable', system-ui, sans-serif;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: background-color 0.25s ease, box-shadow 0.25s ease, transform 0.16s ease-out;
}

@media (hover: hover) {
  .copy:hover {
    background: #fbfcfa;
    box-shadow: inset 0 0 0 1px #c3cdc1;
  }
}

.copy:active {
  transform: scale(0.96);
}

/* copied: the button is the spring of the lake */
.copy.is-done {
  background: var(--water);
  box-shadow: inset 0 0 0 1px var(--shore);
}

.copy__icon {
  width: 18px;
  height: 18px;
  overflow: visible;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.6;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* the word: what Copy and Copied share stays still, the rest changes in a slot of its own */
.copy__label {
  display: inline-flex;
  white-space: pre;
}

.copy__tail {
  position: relative;
  display: inline-block;
  overflow: hidden;
  text-align: left;
  /* room for the letters' tails and accents, given back by the margin */
  padding: 3px 0;
  margin: -3px 0;
}

.copy__tail > span {
  display: inline-block;
}

.tab:focus-visible,
.copy:focus-visible,
.code:focus-visible {
  outline: 2px solid var(--fn);
  outline-offset: 2px;
}

.code:focus-visible {
  outline-offset: -3px;
  border-radius: 0 0 16px 16px;
}

html[data-using='pointer'] .tab:focus-visible,
html[data-using='pointer'] .copy:focus-visible,
html[data-using='pointer'] .code:focus-visible {
  outline: none;
}

/* ---------------------------------------------------------------- the code */
.code {
  position: relative;
  overflow: hidden;
}

.code__inner {
  position: relative;
  padding: 18px 22px 20px;
}

/* the lake lies under the words */
.code__lake {
  position: absolute;
  left: 0;
  top: 0;
  overflow: visible;
  pointer-events: none;
}

.lake__shore {
  flood-color: var(--shore);
}

.lake__water {
  flood-color: var(--water);
}

.lake__line {
  fill: #000;
}

/* the code is a grid: every character a cell of the same width (the font is monospaced), so each cell knows where it
   is without being measured */
.code__grid {
  position: relative;
  --cw: 9.1px;              /* the width of a cell: measured by the script */
  --lh: 24px;               /* the height of a line */
  font-family: 'Martian Mono Variable', ui-monospace, monospace;
  font-size: 13px;
  font-weight: 400;
  font-stretch: 100%;
  line-height: var(--lh);
  color: var(--ink);
}

.ln {
  display: block;
  height: var(--lh);
  white-space: pre;
}

.c {
  display: inline-block;
  width: var(--cw);
  height: var(--lh);
  vertical-align: top;
  white-space: pre;
}

.probe {
  position: absolute;
  visibility: hidden;
  white-space: pre;
}

.k-kw { color: var(--kw); }
.k-str { color: var(--str); }
.k-fn { color: var(--fn); }
.k-type { color: var(--type); }
.k-const { color: var(--const); }
.k-prop { color: var(--prop); }
.k-num { color: var(--num); }
.k-pun { color: var(--pun); }
.k-com { color: var(--com); }

/* ---------------------------------------------------------------- reduced motion: nothing moves, colours still fade */
@media (prefers-reduced-motion: reduce) {
  .copy:active {
    transform: none;
  }
}

/* ---------------------------------------------------------------- phone */
@media (max-width: 480px) {
  .snippet__bar {
    gap: 6px;
    padding: 6px;
  }

  .tab {
    height: 32px;
    padding: 0 9px;
    font-size: 13px;
    font-stretch: 92%;
  }

  .copy {
    height: 32px;
    gap: 5px;
    padding: 0 10px 0 8px;
    font-size: 13px;
  }

  .copy__icon {
    width: 16px;
    height: 16px;
  }

  .code__inner {
    padding: 14px 14px 16px;
  }

  /* narrower letters on the width axis, so more of each line fits before it wraps */
  .code__grid {
    --lh: 21px;
    font-size: 12px;
    font-stretch: 75%;
  }
}

.copy__front {
  transition: stroke 0.25s ease;
}

.copy.is-done .copy__front {
  stroke: var(--fn);
}
