/* Bare-element form styling.
 *
 * The form views write plain form_with fields with no classes, so these style
 * elements directly rather than exposing .input/.btn like inputs.css does.
 *
 * Unscoped: a view opts in by linking this file. */
@layer components {
  .form-page {
    margin-inline: auto;
    max-inline-size: var(--form-width, 30em);
    padding: var(--block-space-double) var(--inline-space-double);
  }

  /* :where() so a subheading with its own class isn't forced to the page
     title's size — same reason as the button rule below */
  :where(h1) {
    font-size: var(--text-xx-large);
    font-weight: 800;
  }

  :where(h2) {
    font-size: var(--text-large);
    font-weight: 700;
  }

  nav:has(+ *) {
    margin-block-end: var(--block-space);
  }

  fieldset {
    border: 0;
    margin: 0 0 var(--block-space-double);
    min-inline-size: 0; /* default min-content prevents flexbox truncate */
    padding: 0;
  }

  legend {
    color: var(--color-ink-medium);
    font-weight: 700;
    margin-block-end: var(--block-space-half);
    padding: 0;
  }

  label {
    color: var(--color-ink-medium);
    font-size: var(--text-small);

    /* Mark the field that follows when it's required */
    &:has(+ :required)::after {
      color: var(--color-accent);
      content: '*';
    }
  }

  /* Stacked labels get air above them; labels paired with a box do not.
     Skips labels carrying a class, so component styling isn't overridden —
     this selector is specific enough to win against one otherwise. */
  fieldset > label:not([class]):not(:first-of-type):not(input[type=radio] + label):not(input[type=checkbox] + label) {
    display: block;
    margin-block-start: var(--block-space);
  }

  /* :where() again — an attribute selector in an :is() list would score higher
     than a component class and override things like a narrow select */
  :where(
    input[type=text],
    input[type=date],
    input[type=number],
    input[type=decimal],
    input[type=search],
    input[type=email],
    input[type=password],
    textarea,
    select
  ) {
    background-color: var(--input-background, transparent);
    border-radius: 0.5em;
    border: 1px solid var(--color-ink-light);
    color: var(--color-ink);
    display: block;
    font-size: max(16px, 1em); /* keeps iOS from zooming on focus */
    inline-size: 100%;
    line-height: var(--form-element-line-height);
    padding: var(--form-element-padding-block) var(--form-element-padding-inline);

    &:focus-visible {
      outline: var(--focus-ring);
      outline-offset: -1px;
    }

    /* Computed, non-editable values read as inert rather than empty */
    &:disabled {
      background-color: var(--color-ink-lightest);
      border-color: transparent;
      color: var(--color-ink-medium);
    }
  }

  input[type=search] {
    background-image: url("/assets/search-c58baf95.svg");
    /* `inline-start` is not a valid background-position keyword — the whole
       declaration would be dropped and the icon would fall to the corner */
    background-position: left 0.8em center;
    background-repeat: no-repeat;
    background-size: var(--icon-size, 1em);
    border-radius: 99rem;
    padding-inline-start: calc(var(--icon-size, 1em) + var(--form-element-padding-inline) * 2);
  }

  select:not([multiple]) {
    appearance: none;
    background-image: var(--caret-icon);
    background-position: right 0.8em center;
    background-repeat: no-repeat;
    background-size: 1em 1em;

    /* Same heroicons caret as .input--select, inked for each theme */
    --caret-icon: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 24 24' stroke-width='1.5' stroke='%236b7280'%3e%3cpath stroke-linecap='round' stroke-linejoin='round' d='m19.5 8.25-7.5 7.5-7.5-7.5'/%3e%3c/svg%3e");
    --caret-icon-dark: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 24 24' stroke-width='1.5' stroke='%239ca3af'%3e%3cpath stroke-linecap='round' stroke-linejoin='round' d='m19.5 8.25-7.5 7.5-7.5-7.5'/%3e%3c/svg%3e");

    html[data-theme="dark"] & {
      --caret-icon: var(--caret-icon-dark);
    }

    @media (prefers-color-scheme: dark) {
      html:not([data-theme]) & {
        --caret-icon: var(--caret-icon-dark);
      }
    }

    option {
      background-color: var(--color-canvas);
      color: var(--color-ink);
    }
  }

  /* A multi-select is the tap target for the native picker on touch devices */
  @media (hover: none) and (pointer: coarse) {
    select[multiple] {
      block-size: 0;
      inline-size: 0;
      opacity: 0;
      pointer-events: none;
      position: absolute;
    }
  }

  input[type=file] {
    display: block;
    inline-size: 100%;
  }

  :is([type=checkbox], [type=radio]) {
    appearance: none;
    block-size: 1rem;
    border: 1px solid var(--color-ink-light);
    cursor: pointer;
    inline-size: 1rem;
    vertical-align: middle;

    &:checked {
      background-image: var(--check-icon);
      background-position: center;
      background-repeat: no-repeat;
      background-size: 0.75em auto;
      background-color: var(--color-link);
      border-color: var(--color-link);
    }
  }

  [type=checkbox] { border-radius: 0.2em; }
  [type=radio] { border-radius: 50%; }

  /* :where() keeps this at zero specificity, so any component class on a
     button (.watch-toggle, .btn-danger, .sheet__close) overrides it without
     having to out-specify an :is() list */
  :where(button, input[type=submit], input[type=reset]) {
    background-color: var(--color-ink);
    border-radius: 0.3em;
    border: 0;
    color: var(--color-ink-inverted);
    cursor: pointer;
    font-size: var(--text-small);
    line-height: 1;
    padding: 0.8em 1em;

    @media (any-hover: hover) {
      &:hover {
        background-color: var(--color-accent-strong);
      }
    }
  }

  /* Secondary "details"/"Search" affordances render as plain links */
  button[formaction] {
    background: none;
    border: 0;
    color: var(--color-ink-medium);
    display: inline;
    font-size: var(--text-small);
    padding: 0;
    text-decoration: underline;

    @media (any-hover: hover) {
      &:hover {
        background: none;
        color: var(--color-ink);
      }
    }
  }

  form[method=dialog] > button {
    background: none;
    color: var(--color-link);
    padding: 0;

    @media (any-hover: hover) {
      &:hover {
        background: none;
      }
    }
  }

  .btn-danger {
    background-color: var(--color-negative);

    @media (any-hover: hover) {
      &:hover {
        background-color: var(--color-negative);
        filter: brightness(1.15);
      }
    }
  }


  /* A white check reads on both the link-blue fill and dark canvas */
  :is([type=checkbox], [type=radio]) {
    --check-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='white' stroke-width='4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='20 6 9 17 4 12'%3E%3C/polyline%3E%3C/svg%3E");
  }

  /* Feedback record — a label/value stack per field */
  .feedback {
    p {
      margin-block: var(--block-space);
    }

    strong {
      display: block;
      font-weight: 600;
      margin-block-end: var(--block-space-half);
    }
  }

  /* A narrow column for explanatory copy above a form */
  .form-page__intro {
    max-inline-size: 24rem;
  }

  /* Numbered steps keep their markers, so they stay a list rather than a flex row */
  .steps {
    list-style: decimal;
    padding-inline-start: 1.2em;

    li + li {
      margin-block-start: var(--block-space-half);
    }
  }

  /* Errors
  /* ------------------------------------------------------------------------ */

  .errors {
    background-color: oklch(var(--lch-red-lightest));
    border-radius: 0.3em;
    border: 1px solid var(--color-negative);
    color: var(--color-negative);
    font-size: var(--text-small);
    margin-block-end: var(--block-space);
    padding: var(--block-space-half) var(--inline-space-double);

    ul {
      list-style: none;
      margin: 0;
      padding: 0;
    }
  }

  .field_with_errors input,
  input.error {
    border-color: var(--color-negative);
  }

  /* Ticker symbols read as a unit, so they get their own weight and gutter */
  .txt-ticker {
    font-weight: 700;
    min-inline-size: 5ch;
  }
}
