/* The playground: a FormaLang editor on the right of each page. See
   playground.js. The landing page and the book both load this sheet, and
   their root font sizes differ, so the sizes here are in px.

   `--fl-split` is the fraction of the window where the page ends and the
   playground starts. The seam writes it when the reader drags. */

:root {
  --fl-split: 0.6;
  --fl-rail: 32px;
  --fl-width: calc(100% * (1 - var(--fl-split)));
  --fl-taken: var(--fl-width);

  /* Catppuccin Mocha, as in theme/css/variables.css. */
  --fl-crust: #11111b;
  --fl-mantle: #181825;
  --fl-surface0: #313244;
  --fl-text: #cdd6f4;
  --fl-mauve: #cba6f7;
}

html.fl-closed {
  --fl-taken: var(--fl-rail);
}

/* The page keeps clear of the playground. */
html.fl-has-playground {
  padding-inline-end: var(--fl-taken);
}

/* On a wide window, the page scrolls in its own column, so its scrollbar
   stands left of the playground and not at the edge of the window. The
   book shows its bar by the scroll of the window, which no longer moves,
   so the bar stays at the top. */
@media (min-width: 800px) {
  html.fl-has-playground {
    block-size: 100%;
    overflow: hidden;
    padding-inline-end: 0 !important;
  }

  html.fl-has-playground body {
    box-sizing: border-box;
    block-size: 100%;
    min-block-size: 0;
    overflow-y: auto;
    margin-inline-end: var(--fl-taken);
    /* An anchor stops under the bar of the book, not behind it. */
    scroll-padding-block-start: var(--menu-bar-height, 0px);
  }

  html.fl-has-playground #menu-bar {
    position: sticky;
    top: 0 !important;
  }
}

/* The arrow to the next chapter of the book is fixed to the right edge. */
html.fl-has-playground .nav-chapters.next {
  right: var(--fl-taken);
}

/* The book picks its arrows by the width of the window. The open
   playground makes the page narrow, so the book uses its narrow arrows,
   under the text, and not the arrows on the edges. */
html.fl-has-playground:not(.fl-closed) .nav-wide-wrapper {
  display: none;
}

html.fl-has-playground:not(.fl-closed) .nav-wrapper {
  display: block;
}

/* No text selection and no transition while a seam moves. */
html.fl-dragging,
html.fl-dragging * {
  user-select: none !important;
}

.fl-playground {
  position: fixed;
  inset-block: 0;
  inset-inline-end: 0;
  z-index: 200;
  display: grid;
  grid-template-columns: var(--fl-rail) minmax(0, 1fr);
  inline-size: var(--fl-width);
  /* The editor is dark, and so are the scrollbars on it. */
  color-scheme: dark;
  background: var(--fl-crust);
  border-inline-start: 1px solid var(--fl-surface0);
  font-family: "Inter", ui-sans-serif, system-ui, sans-serif;
  font-size: 14px;
  line-height: 1.5;
}

html.fl-closed .fl-playground {
  inline-size: var(--fl-rail);
}

html.fl-closed .fl-body,
html.fl-closed .fl-playground > .fl-seam {
  display: none;
}

/* The rail opens and closes the playground. */
.fl-rail {
  all: unset;
  box-sizing: border-box;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
  padding-block: 17px;
  background: var(--fl-mantle);
  border-inline-end: 1px solid var(--fl-surface0);
  color: #9399b2;
  cursor: pointer;
}

.fl-rail:hover,
.fl-rail:focus-visible {
  color: var(--fl-mauve);
}

.fl-rail:focus-visible {
  outline: 2px solid var(--fl-mauve);
  outline-offset: -2px;
}

.fl-rail svg {
  flex: none;
  inline-size: 16px;
  block-size: 16px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.8;
  stroke-linecap: round;
  stroke-linejoin: round;
  transition: transform 0.15s;
}

html.fl-closed .fl-rail svg {
  transform: rotate(180deg);
}

.fl-rail-label {
  writing-mode: vertical-rl;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

/* The editor and the output, and the seam between them. One cell, so the
   pad fills the frame at every height. */
.fl-body {
  position: relative;
  display: grid;
  grid-template: minmax(0, 1fr) / minmax(0, 1fr);
  min-block-size: 0;

  /* Where the seam stands, as a fraction of the height. */
  --pad-share: 0.65;
  --seam-at: calc(100% * var(--pad-share));
}

/* On the element itself: the defaults of formapad are on the element, and
   an inherited value loses to them. */
.fl-body forma-pad {
  display: grid;
  min-block-size: 0;
  --pad-editor-height: calc(100% * var(--pad-share) - var(--pad-header-height));

  --pad-bg: var(--fl-crust);
  --pad-fg: var(--fl-text);
  --pad-muted: #9399b2;
  --pad-placeholder: #7f849c;
  --pad-rule: var(--fl-surface0);
  --pad-accent: var(--fl-mauve);
  --pad-on-accent: var(--fl-crust);
  --pad-selection: rgb(203 166 247 / 0.25);
  --pad-error: #f38ba8;
  --pad-font: "JetBrains Mono", ui-monospace, SFMono-Regular, Menlo, monospace;
  --pad-font-size: 13px;
  --pad-line-height: 1.7;
  --pad-header-font: "Inter", ui-sans-serif, system-ui, sans-serif;
  /* As high as the bar of the book, so the lines under the two meet. */
  --pad-header-height: 50px;
  --pad-gutter: 16px;

  --pad-keyword: #cba6f7;
  --pad-constant: #fab387;
  --pad-type: #f9e2af;
  --pad-function: #89b4fa;
  --pad-property: #94e2d5;
  --pad-string: #a6e3a1;
  --pad-number: #fab387;
  --pad-comment: #7f849c;
  --pad-operator: #9399b2;
}

.fl-body forma-pad::part(header) {
  font-size: 13px;
  background: var(--fl-mantle);
}

/* A narrow header cuts the version, and keeps the buttons whole. */
.fl-body forma-pad::part(version) {
  min-width: 0;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}

.fl-body forma-pad::part(reset),
.fl-body forma-pad::part(run) {
  height: 30px;
  min-width: 64px;
  padding: 0 14px;
  border-radius: 6px;
  font-size: 13px;
  font-weight: 500;
  line-height: 1;
}

/* A disabled button is plainly off, and its label stays legible: at least
   4.5:1 against its background. formapad only dims it, to 2.5:1 or less. */
.fl-body forma-pad::part(reset):disabled {
  opacity: 1;
  color: #9399b2;
  border-color: #45475a;
}

.fl-body forma-pad::part(run):disabled {
  opacity: 1;
  color: #a6adc8;
  background: var(--fl-surface0);
  border-color: var(--fl-surface0);
}

/* The start text, before the script defines the element: in the rows of
   the pad, where the editor puts its first line, so nothing moves when
   the script loads. */
.fl-body forma-pad:not(:defined) {
  grid-template-rows:
    var(--pad-header-height)
    minmax(0, var(--pad-editor-height))
    minmax(0, 1fr);
  background: var(--pad-bg);
}

.fl-body forma-pad:not(:defined) pre {
  grid-row: 2;
  margin: 0;
  padding-block-start: calc(var(--pad-gutter) * 0.75 - 1px);
  /* The gutter of two-digit line numbers, and the inset of a line. */
  padding-inline-start: calc(var(--pad-gutter) * 0.5 + 14px + 2ch);
  overflow: hidden;
  border: 0;
  border-block: 1px solid var(--pad-rule);
  border-radius: 0;
  background: none !important;
  font-family: var(--pad-font);
  font-size: var(--pad-font-size);
  line-height: var(--pad-line-height);
  color: var(--pad-muted);
}

/* A seam is a strip wider than its line, so a pointer finds it. The line
   shows on hover, while the seam moves, and when it has focus. */
.fl-seam {
  --grip: 9px;
  position: absolute;
  z-index: 3;
  touch-action: none;
  outline: none;
}

.fl-seam.upright {
  inset-block: 0;
  inset-inline-start: 0;
  inline-size: var(--grip);
  margin-inline-start: calc(var(--grip) / -2 - 1px);
  cursor: col-resize;
}

.fl-seam:not(.upright) {
  inset-inline: 0;
  inset-block-start: var(--seam-at, 0);
  block-size: var(--grip);
  margin-block-start: calc(var(--grip) / -2);
  cursor: row-resize;
}

.fl-seam::after {
  content: "";
  position: absolute;
  background: var(--fl-mauve);
  opacity: 0;
  transition: opacity 0.15s;
}

.fl-seam.upright::after {
  inset-block: 0;
  inset-inline-start: calc(50% - 1px);
  inline-size: 2px;
}

.fl-seam:not(.upright)::after {
  inset-inline: 0;
  inset-block-start: calc(50% - 1px);
  block-size: 2px;
}

.fl-seam:hover::after,
.fl-seam:active::after,
.fl-seam:focus-visible::after {
  opacity: 1;
}

/* A narrow window: the open playground covers the page, and the closed
   one is a button in the corner. */
@media (max-width: 799px) {
  html.fl-has-playground {
    padding-inline-end: 0;
  }

  html.fl-has-playground .nav-chapters.next {
    right: 0;
  }

  .fl-playground {
    inline-size: 100%;
    border-inline-start: 0;
  }

  .fl-playground > .fl-seam {
    display: none;
  }

  html.fl-closed .fl-playground {
    inset-block: auto 16px;
    inset-inline-end: 16px;
    inline-size: auto;
    block-size: auto;
    display: block;
    background: none;
    border: 0;
  }

  html.fl-closed .fl-rail {
    flex-direction: row;
    padding: 10px 16px;
    border: 1px solid var(--fl-surface0);
    border-radius: 999px;
    box-shadow: 0 4px 16px rgb(0 0 0 / 0.4);
  }

  html.fl-closed .fl-rail-label {
    writing-mode: horizontal-tb;
  }
}
