/*
 * Propshaft links every file in app/assets/stylesheets, A to Z, so this one comes first
 * and sets the order of the layers: later layers win. Colours come from theme.css and
 * fonts from fonts.css; use their variables rather than writing colours in here.
 */

@layer reset, theme, global, layout, components, utilities, states;

@layer global {
  html {
    background: var(--bg);
  }

  body {
    background: var(--bg);
    color: var(--fg);
    font-family: "Monaspace Argon", ui-monospace, Menlo, Consolas, monospace;
    font-size: clamp(0.875rem, 0.8rem + 0.3vw, 1.0625rem);
    font-weight: 400;
    line-height: 1.55;
    /* calt is Monaspace's texture healing; the stylistic sets are its code ligatures. */
    font-feature-settings: "calt" 1, "liga" 1, "ss01" 1, "ss02" 1, "ss03" 1, "ss04" 1, "ss05" 1, "ss06" 1, "ss07" 1, "ss08" 1;
  }

  * {
    line-height: inherit;
  }

  ::selection {
    background: var(--selection);
    color: var(--fg-strong);
  }

  pre {
    font: inherit;
  }

  ul {
    padding-left: 2ch;
  }
}

@layer layout {
  .terminal {
    display: flex;
    flex-direction: column;
    height: 100dvh;
    overflow: hidden;
  }

  .terminal--body {
    flex: 1;
    overflow-x: hidden;
    overflow-y: auto;
    overflow-wrap: anywhere;
    /* A centred column on wide screens, with the scrollbar still at the window's edge. */
    padding-block: var(--gutter);
    padding-inline: max(var(--gutter), calc((100% - var(--measure)) / 2));
    scrollbar-width: thin;
    scrollbar-color: var(--fg-faint) transparent;
  }

  /* Safari, which doesn't have scrollbar-color. */
  .terminal--body::-webkit-scrollbar { width: 8px; }
  .terminal--body::-webkit-scrollbar-track { background: transparent; }
  .terminal--body::-webkit-scrollbar-thumb { background: var(--fg-faint); border-radius: 4px; }
}

@layer components {
  .terminal--input {
    display: flex;
    align-items: baseline;
  }

  .terminal--input-form {
    flex: 1;
  }

  .terminal--input-field {
    width: 100%;
    padding: 0;
    border: none;
    outline: none;
    background: transparent;
    color: var(--fg);
    caret-color: var(--caret);
  }

  @supports (caret-shape: block) {
    .terminal--input-field {
      caret-shape: block;
    }
  }

  /* The prompt, like guest@benjaminb.dev:~$ (see home/_prompt_label). */
  .prompt {
    margin-right: 1ch;
    white-space: nowrap;
    font-weight: 500;
  }

  .prompt--user { color: var(--prompt-user); }
  .prompt--host { color: var(--prompt-host); }
  .prompt--path { color: var(--prompt-path); }
  .prompt--talker { color: var(--prompt-talker); }
  .prompt--punctuation { color: var(--fg-muted); }

  .terminal--welcome {
    margin-bottom: 1.5em;
  }

  /* Each command's output, and each talker line, fades in as it arrives. */
  .terminal--entry {
    animation: entry-in 150ms ease-out;
  }

  @keyframes entry-in {
    from { opacity: 0; translate: 0 0.25em; }
  }

  /* Lists of words, like `ls`: spaced apart, wrapping onto more lines as needed. */
  .listing {
    display: flex;
    flex-wrap: wrap;
    column-gap: 2ch;
  }

  .file--document { color: var(--file-document); }
  .file--code { color: var(--file-code); }
  .file--image { color: var(--file-image); }
  .file--archive { color: var(--file-archive); }
  .file--media { color: var(--file-media); }

  /* What `cat` shows: keep the file's own line breaks and spacing. */
  .terminal--file {
    white-space: pre-wrap;
  }

  /* ASCII art titles, shrunk to fit narrow screens: --columns is how wide the art is,
     and each character is 0.62em wide. Block characters only join up at a line
     height around the font's own (1.145). */
  .banner {
    --columns: 74;
    font-size: min(1em, calc((100vw - 2 * var(--gutter)) / (var(--columns) * 0.62)));
    line-height: 1.15;
    white-space: pre;
    width: fit-content;
    color: transparent;
    background-image: linear-gradient(90deg, var(--magenta), var(--blue), var(--cyan), var(--blue), var(--magenta));
    background-size: 200% 100%;
    background-clip: text;
    -webkit-background-clip: text;
    animation: banner-shimmer 12s linear infinite;
  }

  .banner--talker {
    --columns: 64;
    background-image: linear-gradient(90deg, var(--red), var(--orange), var(--yellow), var(--orange), var(--red));
  }

  @keyframes banner-shimmer {
    to { background-position: -200% 0; }
  }

  .banner + .tagline {
    margin-top: 0.5em;
  }

  .tagline {
    font-family: "Monaspace Radon", "Monaspace Argon", monospace;
    font-style: oblique 11deg;
    color: var(--fg-muted);
  }

  .heading {
    font-family: "Monaspace Xenon", "Monaspace Argon", monospace;
    font-weight: 600;
    color: var(--fg-strong);
  }

  /* Talker lines (see talker/_broadcast). */
  .username {
    font-weight: 600;
  }

  .username--0 { color: var(--username-0); }
  .username--1 { color: var(--username-1); }
  .username--2 { color: var(--username-2); }
  .username--3 { color: var(--username-3); }
  .username--4 { color: var(--username-4); }
  .username--5 { color: var(--username-5); }
  .username--6 { color: var(--username-6); }
  .username--7 { color: var(--username-7); }

  .talker--emote,
  .talker--social,
  .talker--notice {
    font-family: "Monaspace Radon", "Monaspace Argon", monospace;
  }

  .talker--emote,
  .talker--social {
    font-style: oblique 11deg;
  }

  .talker--notice {
    color: var(--fg-muted);
  }

  .talker--notice::before {
    content: "» ";
    color: var(--fg-faint);
  }

  .talker--tell {
    color: var(--whisper);
  }
}

@layer utilities {
  .command { color: var(--command); }
  .highlight { color: var(--highlight); }
  .muted { color: var(--fg-muted); }

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

  /* Colour codes in what people type (see the Printcodes model): ~F? is a colour, ~C?
     its bright version, ~B? a background. */
  .printcode--fk { color: var(--black); }
  .printcode--fr { color: var(--red); }
  .printcode--fg { color: var(--green); }
  .printcode--fy { color: var(--yellow); }
  .printcode--fb { color: var(--blue); }
  .printcode--fm { color: var(--magenta); }
  .printcode--ft { color: var(--cyan); }
  .printcode--fw { color: var(--white); }

  .printcode--ck { color: var(--bright-black); }
  .printcode--cr { color: var(--bright-red); }
  .printcode--cg { color: var(--bright-green); }
  .printcode--cy { color: var(--bright-yellow); }
  .printcode--cb { color: var(--bright-blue); }
  .printcode--cm { color: var(--bright-magenta); }
  .printcode--ct { color: var(--bright-cyan); }
  .printcode--cw { color: var(--bright-white); }

  .printcode--bk { background: var(--bg-black); }
  .printcode--br { background: var(--bg-red); }
  .printcode--bg { background: var(--bg-green); }
  .printcode--by { background: var(--bg-yellow); }
  .printcode--bb { background: var(--bg-blue); }
  .printcode--bm { background: var(--bg-magenta); }
  .printcode--bt { background: var(--bg-cyan); }
  .printcode--bw { background: var(--bg-white); }

  .printcode--bold { font-weight: 700; }
  .printcode--underline { text-decoration: underline; }
  .printcode--blink { animation: printcode-blink 1s step-end infinite; }

  @keyframes printcode-blink {
    50% { opacity: 0; }
  }
}

/* The CRT the phosphor themes are on: text glows in its own colour, with scanlines and
   a darker edge over the top (which clicks and selecting go straight through), and a
   faint refresh bar rolling down the screen. */
@layer components {
  :root:is([data-theme="amber"], [data-theme="green"]) {
    .terminal {
      position: relative;
      text-shadow: 0 0 1px currentColor, 0 0 6px color-mix(in srgb, currentColor 45%, transparent);
    }

    .terminal--input-field {
      text-shadow: inherit;
    }

    .banner {
      filter: drop-shadow(0 0 6px color-mix(in srgb, var(--fg) 45%, transparent));
    }

    .terminal::after {
      content: "";
      position: absolute;
      inset: 0;
      z-index: 1;
      pointer-events: none;
      background:
        repeating-linear-gradient(to bottom, transparent 0 2px, rgb(0 0 0 / 0.22) 2px 3px),
        radial-gradient(ellipse at center, transparent 55%, rgb(0 0 0 / 0.55) 100%);
    }

    .terminal::before {
      content: "";
      position: absolute;
      inset-inline: 0;
      top: 0;
      height: 20vh;
      z-index: 1;
      pointer-events: none;
      background: linear-gradient(to bottom, transparent, color-mix(in srgb, var(--fg) 6%, transparent), transparent);
      animation: crt-refresh 8s linear infinite;
    }
  }

  @keyframes crt-refresh {
    from { translate: 0 -20vh; }
    to { translate: 0 100vh; }
  }
}

@media (prefers-reduced-motion: reduce) {
  .printcode--blink,
  .banner,
  .terminal--entry {
    animation: none;
  }

  .terminal::before {
    display: none;
  }
}
