/* The code that wraps: a code block from the docs of a small publishing SDK, on a white page. Hairline rules, the
   code in Recursive (its mono axis on, its weight and slant axes at work), greys for the grammar and one blue for
   the values. Every word is placed by the script: the block is a grid of columns and rows. */
:root {
  --page: #ffffff;          /* the page */
  --block: #fcfcfb;         /* the block */
  --rule: #e6e5e1;          /* the hairlines */
  --ink: #141414;           /* the words of the language and the names */
  --name: #3d3c3a;          /* the names after a dot */
  --grey: #a3a19c;          /* the signs, the comments and the line numbers */
  --mark: #d6d4cf;          /* the hairline joining the rows of a wrapped line */
  --accent: #2a45e8;        /* the values (texts, figures, true), the switch when it is on and the tick */
}

* {
  box-sizing: border-box;
}

/* a tap is a click at once: no wait for a double tap */
html {
  touch-action: manipulation;
}

html,
body {
  margin: 0;
  overflow-x: clip;
}

body {
  min-height: 100svh;
  background: var(--page);
  color: var(--ink);
  font-family: 'Recursive Variable', ui-monospace, monospace;
  font-variation-settings: 'MONO' 0, 'CASL' 0, 'wght' 440, 'slnt' 0, 'CRSV' 0.5;
  -webkit-font-smoothing: antialiased;
}

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

/* the block sits in the middle of the page; in a real page it sits in the flow of the docs, where it is */
.stage {
  min-height: 100svh;
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  justify-items: center;
  align-content: start;
  padding: max(32px, calc(50svh - 190px)) 16px 40px;
}

.snippet {
  position: relative;
  width: min(620px, 100%);
  border: 1px solid var(--rule);
  border-radius: 14px;
  background: var(--block);
  overflow: hidden;
}

/* ---------------------------------------------------------------- the bar: the file, Wrap lines and Copy */
.snippet__bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  height: 46px;
  padding: 0 8px 0 18px;
  border-bottom: 1px solid var(--rule);
}

.file {
  min-width: 0;
  overflow: hidden;
  color: var(--grey);
  font-size: 12.5px;
  font-variation-settings: 'MONO' 1, 'CASL' 0, 'wght' 420, 'slnt' 0, 'CRSV' 0.5;
  white-space: nowrap;
  text-overflow: ellipsis;
}

.tools {
  display: flex;
  flex: none;
  gap: 2px;
}

.tool {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 7px;
  height: 32px;
  margin: 0;
  padding: 0 11px 0 9px;
  border: 0;
  border-radius: 8px;
  background: transparent;
  color: var(--ink);
  font: inherit;
  font-size: 12.5px;
  line-height: 1;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: background-color 0.25s ease;
}

/* a hairline frame that only shows under the pointer or the keys */
.tool::before {
  content: '';
  position: absolute;
  inset: 0;
  border: 1px solid var(--rule);
  border-radius: inherit;
  opacity: 0;
  transition: opacity 0.25s ease;
  pointer-events: none;
}

@media (hover: hover) {
  .tool:hover::before {
    opacity: 1;
  }
}

.tool:focus {
  outline: none;
}

.tool:focus-visible::before {
  border-color: var(--ink);
  opacity: 1;
}

.tool__label {
  display: block;
  font-variation-settings: 'MONO' 0, 'CASL' 0, 'wght' 440, 'slnt' 0, 'CRSV' 0.5;
  transition: font-variation-settings 0.35s ease;
}

/* on, the word takes weight (Recursive keeps its width across weights, so nothing moves) */
.wrap[aria-checked='true'] .tool__label {
  font-variation-settings: 'MONO' 0, 'CASL' 0, 'wght' 620, 'slnt' 0, 'CRSV' 0.5;
}

/* the switch: a line that runs past the edge of the measure, or bends back before it */
.wrap__icon,
.copy__icon {
  flex: none;
  width: 18px;
  height: 18px;
  overflow: visible;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.4;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.wrap__edge {
  stroke: var(--grey);
  stroke-width: 1;
}

.wrap[aria-checked='true'] .wrap__line,
.wrap[aria-checked='true'] .wrap__head {
  stroke: var(--accent);
}

.wrap__line,
.wrap__head {
  transition: stroke 0.3s ease;
}

/* Copy: two sheets that fold away and a tick that draws itself */
.copy__tick {
  stroke: var(--accent);
  stroke-width: 1.7;
  stroke-dasharray: 1;
  stroke-dashoffset: 1;
}

.copy__label {
  display: block;
  overflow: hidden;
  min-width: 6.4ch;
  padding: 2px 0;
  text-align: left;
}

.copy__label > span {
  display: block;
  font-variation-settings: 'MONO' 0, 'CASL' 0, 'wght' 440, 'slnt' 0, 'CRSV' 0.5;
}

/* ---------------------------------------------------------------- the code */
.code {
  --fs: 13.5px;             /* the size of the code (the script reads it) */
  --lh: 23px;               /* the height of a row (the script reads it) */
  --gutter: 46px;           /* the column of the line numbers */
  --pad-top: 16px;
  --pad-x: 20px;
  position: relative;
  height: 240px;
}

.code:focus {
  outline: none;
}

.code:focus-visible {
  box-shadow: inset 0 0 0 1px var(--ink);
}

.code__gutter {
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  width: var(--gutter);
  pointer-events: none;
}

/* a line of the gutter: the script moves it with the first row of its line */
.ln {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: var(--lh);
  will-change: transform;
}

/* nothing shows before the font has come and every word is in its place */
.snippet:not(.is-ready) .tk,
.snippet:not(.is-ready) .ln {
  visibility: hidden;
}

/* a line number: a datum, small and grey, on the first row of its line */
.num {
  position: absolute;
  top: 0;
  right: 12px;
  color: var(--grey);
  font-size: 11px;
  line-height: var(--lh);
  font-variation-settings: 'MONO' 1, 'CASL' 0, 'wght' 400, 'slnt' 0, 'CRSV' 0.5;
  font-variant-numeric: tabular-nums;
}

/* the hairline that joins the rows of a wrapped line, down the edge of the gutter */
.join {
  position: absolute;
  top: 0;
  right: 4px;
  width: 1px;
  background: var(--mark);
  transform-origin: 50% 0;
}

/* the view scrolls sideways while the lines run long; a soft edge says there is more */
@property --fade-r {
  syntax: '<length>';
  inherits: false;
  initial-value: 0px;
}

@property --fade-l {
  syntax: '<length>';
  inherits: false;
  initial-value: 0px;
}

.code__view {
  --fade-r: 0px;
  --fade-l: 0px;
  position: absolute;
  inset: 0 0 0 var(--gutter);
  overflow-x: hidden;
  overflow-y: hidden;
  scrollbar-width: none;
  -webkit-mask-image: linear-gradient(to right, transparent 0, #000 var(--fade-l), #000 calc(100% - var(--fade-r)), transparent 100%);
  mask-image: linear-gradient(to right, transparent 0, #000 var(--fade-l), #000 calc(100% - var(--fade-r)), transparent 100%);
  transition: --fade-r 0.45s ease, --fade-l 0.45s ease;
  overscroll-behavior-x: contain;
}

.code__view::-webkit-scrollbar {
  display: none;
}

.code__view.is-long {
  overflow-x: auto;
}

.code__view.more-right {
  --fade-r: 64px;
}

.code__view.more-left {
  --fade-l: 28px;
}

.code__sheet {
  position: relative;
  height: 100%;
  font-size: var(--fs);
  line-height: var(--lh);
}

/* a word of the code: the script places it on its column and its row, and moves it there on a spring */
.tk {
  position: absolute;
  top: 0;
  left: 0;
  white-space: pre;
  font-variation-settings: 'MONO' 1, 'CASL' 0, 'wght' 400, 'slnt' 0, 'CRSV' 0.5;
  will-change: transform;
}

.tk--kw { color: var(--ink); }
.tk--id { color: var(--ink); }
.tk--fn { color: var(--ink); }
.tk--prop { color: var(--name); }
.tk--pun { color: var(--grey); }
.tk--str { color: var(--accent); }
.tk--num { color: var(--accent); }
.tk--com { color: var(--grey); }

/* ---------------------------------------------------------------- a phone */
@media (max-width: 480px) {
  .snippet__bar {
    padding-left: 14px;
  }

  .tool {
    padding: 0 9px 0 7px;
  }

  .code {
    --fs: 12px;
    --lh: 21px;
    --gutter: 34px;
    --pad-top: 14px;
    --pad-x: 12px;
  }

  .num {
    right: 9px;
    font-size: 10px;
  }

  .join {
    right: 3px;
  }
}

@media (max-width: 360px) {
  .file {
    display: none;
  }

  .snippet__bar {
    justify-content: flex-end;
  }
}
