/*
 * What every view's controls are made of: the material of the editor's own floating controls, the button, a
 * filled capsule that answers a pointer and a press, the symbol a button may carry, the mark for what went
 * wrong, the field, and the edge the editor's own content scrolls under. The menu a button opens is in menu.css.
 */
@layer base, editor, utilities;

@layer editor {
  /*
   * A symbol: one of the editor's own, whose HTML holds only its path, on a grid of 20 by 20. How it is drawn
   * is said here once: one round stroke and no fill, in the colour of the words beside it, at a size that
   * follows the size of the text. It is never what a pointer finds: that is the control it is drawn in.
   */
  .sym {
    display: block;
    flex: none;
    inline-size: 1.25rem;
    block-size: 1.25rem;
    fill: none;
    stroke: currentcolor;
    stroke-width: 1.8;
    stroke-linecap: round;
    stroke-linejoin: round;
    pointer-events: none;
  }
  .sym.mid {
    inline-size: 1.125rem;
    block-size: 1.125rem;
  }
  /* Beside small words a symbol is small too, and drawn heavier, so that it is no fainter than they are. */
  .sym.small {
    inline-size: 0.875rem;
    block-size: 0.875rem;
    stroke-width: 2.3;
  }

  /*
   * What went wrong, where it is said in a line of words: the editor's own symbol for it stands before the
   * words, in their colour. It is drawn by the stylesheet, as a shape cut out of that colour, so the words are
   * all there is to read; where a browser can't cut it, the words stand without it. It takes a line's height,
   * so the line is no taller for it.
   */
  @supports (mask-image: linear-gradient(transparent, transparent)) {
    .change-note[data-state="failed"]::before,
    .goal-wrong::before,
    .way-wrong:not(:empty)::before,
    .status[data-state="failed"] #status-text::before {
      content: "";
      display: inline-block;
      inline-size: 1.125rem;
      block-size: 1lh;
      margin-inline-end: 0.3125rem;
      vertical-align: top;
      background-color: currentcolor;
      mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20' fill='none' stroke='%23000' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='10' cy='10' r='6.8'/%3E%3Cpath d='M10 6.7v4M10 13.3v.1'/%3E%3C/svg%3E");
      mask-position: center;
      mask-repeat: no-repeat;
      mask-size: 1.125rem;
    }
  }

  /*
   * Where a view's own content scrolls under its controls, they stay at the head of the screen, with no bar
   * and no line behind them: the canvas's own colour, frosted, fading out along its lower edge. At rest
   * nothing is beneath it, so it cannot be seen. Where the browser can't frost it, it is the canvas, opaque.
   */
  .scroll-edge {
    position: sticky;
    inset-block-start: 0;
    z-index: 5;
  }
  .scroll-edge::before {
    content: "";
    position: absolute;
    inset: 0;
    z-index: -1;
    background: var(--bg);
    pointer-events: none;
  }
  @supports (backdrop-filter: blur(1px)) and (mask-image: linear-gradient(transparent, transparent)) {
    .scroll-edge::before {
      inset-block-end: var(--strip-reach);
      background: var(--strip);
      backdrop-filter: var(--strip-backdrop);
      mask-image: var(--strip-mask);
    }
  }
  /*
   * Asked for more contrast, the edge is opaque, and a line is drawn along it as soon as a view says that
   * something of its own lies beneath (data-under, which its script sets).
   */
  @media (prefers-contrast: more) {
    [data-under] .scroll-edge::before {
      border-block-end: 1px solid var(--separator);
    }
  }

  /*
   * The material. It takes its depth from its fill, an edge and a lit rim half a pixel wide, and one soft shadow:
   * no line is drawn round it. Opaque, unless the browser can blur what lies under it.
   */
  .glass {
    border: 1px solid var(--glass-border);
    background-color: var(--glass-solid);
    color: var(--label);
    box-shadow:
      inset 0 0 0 0.5px var(--glass-edge),
      inset 0 1px 0 var(--glass-rim),
      inset 0 0 8px var(--glass-glow),
      var(--glass-shadow);
  }
  @supports (backdrop-filter: blur(1px)) {
    .glass {
      background-color: var(--glass);
    }
  }

  /* A button: a capsule as tall as a control is, 36px with a mouse and 44px on touch or at a phone's width. */
  .btn {
    display: inline-flex;
    /* As wide as its words, whatever row it is in: it is never squeezed, and what is beside it gives way. */
    flex: none;
    align-items: center;
    justify-content: center;
    gap: 0.375rem;
    min-inline-size: var(--control);
    min-block-size: var(--control);
    border: 1px solid var(--control-border);
    border-radius: 999px;
    padding: 0 0.9375rem;
    background-color: var(--fill);
    color: var(--label);
    font: var(--t-headline);
    text-decoration: none;
    white-space: nowrap;
    cursor: pointer;
    touch-action: manipulation;
    transition-property: background-color, transform;
    transition-duration: 0.1s;
  }
  /*
   * A button's words are not text to select: a long press on one is a press, and brings up no handles and no
   * menu. Safari knows this only by its own name for it.
   */
  @supports (user-select: none) {
    .btn,
    .menu-item {
      user-select: none;
    }
  }
  @supports (-webkit-user-select: none) {
    .btn,
    .menu-item {
      -webkit-user-select: none;
    }
  }
  /* One made of the material keeps the material's fill, and is tinted over it under a pointer and when pressed. */
  .btn.glass {
    border-color: var(--glass-border);
    background-color: var(--glass-solid);
  }
  @supports (backdrop-filter: blur(1px)) {
    .btn.glass {
      background-color: var(--glass);
    }
  }
  /*
   * A button that is a symbol and no words: a circle. Its words are still in it, for a screen reader, and are
   * its title for a pointer that rests on it.
   */
  .btn.round {
    inline-size: var(--control);
    padding: 0;
  }
  /* A symbol before a button's words sits a little into the room round it, so that the two read as one. */
  .btn .sym {
    margin-inline: -0.125rem;
  }
  /* Alone in a circle, it keeps to its own size, in the middle. */
  .btn.round .sym {
    margin: 0;
  }
  /*
   * The one tinted control of a view: a flat fill in the product's own colour, whatever else it is made of. A
   * view marks the control that may be it (primary), and two that are marked stand down, to be drawn as what
   * they are made of. Share stands down while the page has a draft to publish: Publish is its one then. And the
   * answer in the goal's line with a page's responses always does, since that view has no tinted control. Who
   * stands down weighs nothing in the three rules that say so, which rank among the rules round them as they would
   * without it.
   */
  .btn.primary:where(:not(.build:has(#publish:not([hidden])) #share, #goal-in-responses .goal-yes)) {
    background-color: var(--accent);
    background-image: none;
    color: var(--accent-ink);
    box-shadow: none;
  }
  .btn:disabled {
    opacity: 0.45;
    cursor: default;
  }
  /* Under a pointer, where there is one that hovers, a button is a step deeper: half of the way to pressed. */
  @media (hover: hover) {
    .btn:not(.glass):hover:not(:disabled) {
      background-color: var(--fill-hover);
    }
    .btn.glass:hover:not(:disabled) {
      background-image: linear-gradient(var(--glass-hover), var(--glass-hover));
    }
    .btn.primary:where(:not(.build:has(#publish:not([hidden])) #share, #goal-in-responses .goal-yes)):hover:not(
        :disabled
      ) {
      background-color: var(--accent-hover);
      background-image: none;
    }
  }
  /*
   * Pressed: a step deeper again, whatever the button is made of. These come after the pointer's rules and must
   * stay there: a button pressed with a mouse is under the pointer too, the two rules weigh the same, and it is
   * the press that has to show.
   */
  .btn:not(.glass):active:not(:disabled) {
    background-color: var(--fill-press);
  }
  .btn.glass:active:not(:disabled) {
    background-image: linear-gradient(var(--glass-press), var(--glass-press));
  }
  .btn.primary:where(:not(.build:has(#publish:not([hidden])) #share, #goal-in-responses .goal-yes)):active:not(
    :disabled
  ) {
    background-color: var(--accent-press);
    background-image: none;
  }
  /* A press pushes a button in a little, for those who don't ask for less motion. */
  @media (prefers-reduced-motion: no-preference) {
    .btn:active:not(:disabled) {
      transform: scale(0.97);
    }
  }

  /*
   * A field, which is typed in or picked from: a capsule as a button is, set into the canvas by its fill. Its
   * words are no smaller than 16px, since an iPhone zooms the whole editor in when a smaller field is tapped.
   */
  .field {
    min-inline-size: 0;
    min-block-size: var(--control);
    border: 1px solid var(--control-border);
    border-radius: 999px;
    padding: 0 0.875rem;
    background-color: var(--fill);
    color: var(--label);
    font: var(--t-field);
    caret-color: var(--ring);
  }
  .field::placeholder {
    color: var(--label-2);
    opacity: 1;
  }
}
