/*
 * The screener (screeners/*): the filter builder — a ruled box of tabs, each
 * a grid of indicators whose values are edited where they stand, with the
 * indicator search at the end of the tab bar and a line about the row under
 * the pointer at the foot — and the panels it opens, then the results grid
 * and its pages.
 *
 * Every open/closed state here is an attribute the markup already has: a
 * panel is `hidden` or not (the `dropdown` and `filter-builder` controllers
 * set it), a toggle is a checkbox that is `:checked` or not, the current tab
 * is `aria-current`. The tab bar shows the picker is open with `:has()`, so
 * the controller holds no class of its own.
 */
@layer pages {
  .filter-builder {
    margin-block-end: var(--space-md);
  }

  /* The filter grid and the results hang, as the saved screens' strip
     above them does: their text — the tabs, the pills' edges, the table's
     first and last columns — sits on the page's text edge, and their grounds
     and rules reach a bleed past it on both sides (owner, 2026-10-05). */
  .filter-grid,
  .screener-results {
    --screener-bleed: var(--space-sm);
  }

  /* The box: an ink frame around the tabs, the rows and the footer, hung by
     the bleed and its own rule. */
  .filter-grid {
    display: block;
    margin-inline: calc(-1 * (var(--screener-bleed) + var(--rule-width)));
    border: var(--rule-width) solid var(--color-rule-strong);
  }

  /* A query the server could not read, under the box. */
  .filter-builder > .flash {
    margin-block-start: var(--space-sm);
  }

  /* The tab bar, and the search at its end. The positioning context of the
     picker, which drops over the rows under it. */
  .filter-grid__head {
    position: relative;
    display: flex;
    flex-wrap: wrap;
    align-items: stretch;
    gap: 0 var(--space-lg);
    padding-inline: var(--screener-bleed);
    border-block-end: var(--rule-width) solid var(--color-rule);
    background-color: var(--color-surface-raised);
  }

  .filter-grid__tabs {
    flex: 1 1 auto;
    min-inline-size: 0;
    border-block-end: 0;
  }

  .filter-grid__count {
    font-weight: var(--weight-medium);
  }

  /* This screen: the screen as it stands, not a set of indicators to filter
     on, so it is set in ink, its count in a filled badge, and ruled off from
     the filter tabs after it. */
  .tabs__tab.filter-grid__screen-tab {
    padding-inline-end: var(--space-lg);
    border-inline-end: var(--rule-hairline);
    color: var(--color-ink);

    &:hover {
      color: var(--color-ink);
    }
  }

  .filter-grid__screen-count {
    display: inline-grid;
    place-items: center;
    min-inline-size: 1.5rem;
    block-size: 1.25rem;
    padding-inline: var(--space-2xs);
    border-radius: var(--radius-pill);
    background-color: var(--color-ink);
    color: var(--color-ink-inverse);
    font-variant-numeric: tabular-nums;
    letter-spacing: 0;
  }

  /* As many columns of rows as fit at a width that leaves a name room
     beside its periods and field — three on a wide screen, one on a phone —
     read across, a row at a time. No breakpoint can say that, because it
     turns on the row's own width. The positioning context of the sector and
     industry panels, which open under the rows. */
  .filter-grid__rows {
    position: relative;
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(min(100%, 34rem), 1fr));
    gap: var(--space-xs);
    padding: var(--space-sm) var(--screener-bleed);
  }

  /* The row under the pointer, said in words, and the query syntax. */
  .filter-grid__footer {
    position: relative;
    display: flex;
    flex-wrap: wrap;
    align-items: start;
    gap: var(--space-2xs) var(--space-lg);
    padding: var(--space-xs) var(--screener-bleed);
    border-block-start: var(--rule-width) solid var(--color-rule);
    color: var(--color-ink-muted);
    font-size: var(--text-ui-sm);
  }

  /* Two lines tall whatever it says, a longer meaning cut short. */
  .filter-grid__description {
    display: -webkit-box;
    flex: 1 1 32rem;
    block-size: 2lh;
    max-inline-size: 80ch;
    overflow: hidden;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 2;
    line-clamp: 2;

    & > * + * {
      margin-inline-start: var(--space-xs);
    }

    & strong {
      color: var(--color-ink);
      font-weight: var(--weight-semibold);
    }
  }

  .filter-grid__syntax {
    margin-inline-start: auto;
  }

  /* One indicator, as a pill: a bordered chip on a raised ground, set apart
     from the next by the grid's gap (owner, 2026-10-05: ruled rows ran
     together), with the eye, the name, the period switch, the field and its
     unit, the number/plot switch, and on This screen the remove ×. The
     columns are fixed, so the fields line up down the grid; on a phone the
     periods take a line of their own under the name and the field, and the
     name wraps rather than being cut short. The name is
     bold once the screen holds the row, and the row green on a green tint
     once it narrows the screen (Screeners::Criterion#filtering?). */
  .filter-row {
    --filter-row-switch: 2.125rem;

    display: grid;
    grid-template-columns: var(--filter-row-switch) minmax(0, 1fr) auto var(--filter-row-switch) auto;
    grid-template-areas:
      "eye name field plot remove"
      "eye periods periods plot remove";
    align-items: center;
    gap: 0 var(--space-2xs);
    min-block-size: 2.75rem;
    padding: var(--space-3xs) var(--space-2xs);
    border: var(--rule-width) solid var(--color-rule);
    background-color: var(--color-surface-raised);
    color: var(--color-ink);
    font-size: var(--text-ui);

    & .icon {
      fill: var(--color-ink-subtle);
    }

    @media (width >= 640px) {
      grid-template-columns: var(--filter-row-switch) minmax(0, 1fr) auto 9rem var(--filter-row-switch) auto;
      grid-template-areas: "eye name periods field plot remove";
    }

    @media (pointer: coarse) {
      --filter-row-switch: var(--target-min);
    }
  }

  .filter-row--in-screen {
    & .filter-row__eye .icon {
      fill: var(--color-ink);
    }

    & .filter-row__name {
      font-weight: var(--weight-semibold);
    }
  }

  .filter-row--filtering {
    border-color: var(--color-accent-line);
    background-color: var(--color-accent-tint);

    & .icon,
    & .filter-row__eye .icon {
      fill: var(--color-accent-strong);
    }

    & .filter-row__name {
      color: var(--color-accent-strong);
    }
  }

  .filter-row__eye { grid-area: eye; }
  .filter-row__periods { grid-area: periods; }
  .filter-row__field { grid-area: field; }
  .filter-row__plot { grid-area: plot; }
  .filter-row__remove {
    grid-area: remove;
    min-inline-size: var(--filter-row-switch);
  }

  .filter-row__name {
    grid-area: name;

    @media (width >= 640px) {
      overflow: hidden;
      text-overflow: ellipsis;
      white-space: nowrap;
    }
  }

  /* The field and its unit, or a lock. */
  .filter-row__field {
    display: flex;
    align-items: center;
    gap: var(--space-2xs);
    min-inline-size: 0;
  }

  /* The periods written out in small capitals, in a slot each — daily or
     TTM, quarterly, annual — so they line up down a column; the current one
     carries the ink underline the tabs do. */
  .filter-row__periods {
    display: grid;
    grid-template-columns: 3em 6em 4.25em;
    column-gap: 0.625em;
    margin-inline-end: var(--space-xs);
    font-size: var(--text-caps-xs);
  }

  .filter-row__period {
    display: grid;
    place-items: center;
    block-size: 1.75rem;
    border-block-end: 2px solid transparent;
    color: var(--color-ink-muted);
    font-weight: var(--weight-semibold);
    letter-spacing: var(--tracking-caps);
    text-transform: uppercase;
    cursor: pointer;

    &:hover {
      color: var(--color-ink);
    }

    &:has(input:checked) {
      border-block-end-color: var(--color-ink);
      color: var(--color-ink);
    }

    &:has(input:focus-visible) {
      outline: var(--focus-ring);
      outline-offset: var(--focus-offset);
    }

    @media (pointer: coarse) {
      block-size: var(--target-min);
    }
  }

  /* The query, "any" until something is typed, and as tall as the row
     lets it be. */
  .filter-row__input,
  .filter-row__chip {
    flex: none;
    inline-size: 6rem;
    min-block-size: 2.25rem;
    padding-inline: var(--space-2xs);
    border: var(--rule-width) solid var(--color-rule-control);
    background-color: var(--color-field);
    font-family: var(--font-data);
    font-size: var(--text-input);
    text-align: center;

    &::placeholder {
      color: var(--color-ink-subtle);
    }

    .filter-row--filtering & {
      border-color: var(--color-ink);
    }

    @media (pointer: coarse) {
      min-block-size: var(--target-min);
    }

    @media (width >= 640px) {
      inline-size: 7.5rem;
    }
  }

  /* A list's selection, drawn as a field: "any", "2 of 11", "AAPL, MSFT". */
  .filter-row__chip {
    overflow: hidden;
    color: var(--color-ink-subtle);
    text-overflow: ellipsis;
    white-space: nowrap;
    cursor: pointer;

    .filter-row--filtering & {
      color: var(--color-ink);
    }

    &:hover {
      color: var(--color-ink);
    }
  }

  /* As wide whether or not there is a unit, so the fields line up. */
  .filter-row__unit {
    min-inline-size: 0.75rem;
    color: var(--color-ink-muted);
  }

  /* The field and the presets it drops down, which hang from its right edge
     over the rows below. */
  .filter-row__query {
    position: relative;
  }

  /* Long enough lists scroll inside the panel rather than past the page. */
  .filter-row__presets {
    position: absolute;
    inset-block-start: calc(100% + var(--space-3xs));
    inset-inline-end: 0;
    z-index: 30;
    display: grid;
    min-inline-size: 19rem;
    max-block-size: min(70vh, 28rem);
    overflow-y: auto;
    border: var(--rule-width) solid var(--color-rule-strong);
    background-color: var(--color-surface);
    box-shadow: var(--shadow-overlay);
  }

  /* A rule between each kind of preset, where a heading used to be. "Any",
     a button the width of the list, sits above them. */
  .filter-row__preset-group {
    display: grid;
    padding-block: var(--space-2xs);

    & + & {
      border-block-start: var(--rule-hairline);
    }
  }

  .filter-row__preset-group--any {
    padding: var(--space-xs) var(--space-sm);
  }

  /* Centred, not on the baseline, which set the label at the top of its
     2rem and left the hover's band heavy underneath. */
  .filter-row__preset {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-md);
    min-block-size: 2rem;
    padding-inline: var(--space-sm);
    color: var(--color-ink);
    font-size: var(--text-ui-sm);
    text-align: start;
    cursor: pointer;

    &:hover,
    &:focus-visible {
      background-color: var(--color-row-hover);
    }

    &[aria-pressed="true"] {
      font-weight: var(--weight-semibold);
    }

    @media (pointer: coarse) {
      min-block-size: var(--target-min);
    }
  }

  .filter-row__preset-query {
    color: var(--color-ink-muted);
    font-family: var(--font-data);
  }

  /*
   * A row's switches — shown as a column, drawn as a plot, the flag's tick
   * box. Each is a visually hidden checkbox inside its label with two glyphs,
   * one per state; the label is the 34px (44px on touch) target and draws the
   * focus ring its checkbox cannot.
   */
  .toggle {
    display: inline-grid;
    place-items: center;
    inline-size: 2.125rem;
    block-size: 2.125rem;
    cursor: pointer;

    &:hover {
      background-color: color-mix(in srgb, var(--color-ink) 6%, transparent);
    }

    &:has(input:focus-visible) {
      outline: var(--focus-ring);
      outline-offset: var(--focus-offset);
    }

    @media (pointer: coarse) {
      inline-size: var(--target-min);
      block-size: var(--target-min);
    }
  }

  .toggle__on {
    display: none;
  }

  .toggle:has(input:checked) {
    & .toggle__on {
      display: block;
    }

    & .toggle__off {
      display: none;
    }
  }

  /* A panel a row or the search opens: the lists under the rows, the picker
     over them, each as wide as the box. */
  .criterion-panel,
  .picker {
    position: absolute;
    inset-inline: 0;
    inset-block-start: 100%;
    z-index: 20;
    display: flex;
    flex-direction: column;
    overflow: hidden;
    border: var(--rule-width) solid var(--color-rule-strong);
    background-color: var(--color-surface);
    box-shadow: var(--shadow-overlay);
    color: var(--color-ink);
    font-size: var(--text-ui-sm);
    cursor: default;
  }

  .picker {
    block-size: 65vh;
  }

  .criterion-panel__head {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-2xs) var(--space-md);
    padding: var(--space-sm) var(--space-lg);
    border-block-end: var(--rule-width) solid var(--color-rule);
    background-color: var(--color-surface-raised);
    color: var(--color-ink-soft);

    & > :last-child {
      margin-inline-start: auto;
    }
  }

  .criterion-panel__body {
    display: grid;
    gap: var(--space-sm);
    max-block-size: 65vh;
    overflow-y: auto;
    padding: var(--space-md) var(--space-lg);
    line-height: 1.55;
  }

  /* A piece of query syntax, set as something to type. */
  .query-code {
    padding: 0 var(--space-2xs);
    border: var(--rule-width) solid var(--color-warn-line);
    background-color: var(--color-warn-tint);
    font-family: var(--font-data);
    white-space: nowrap;
  }

  /* The sector and industry lists. */
  .checkbox-grid {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--space-3xs) var(--space-md);

    @media (width >= 768px) {
      grid-template-columns: repeat(4, minmax(0, 1fr));
    }

    & .checkbox-field {
      min-block-size: 2rem;

      @media (pointer: coarse) {
        min-block-size: var(--target-min);
      }
    }
  }

  /* The search, for every indicator the tabs leave out: a field boxed in
     ink on the field ground, the glass inside it, on the tab bar's line
     while there is room and a line of its own when there is not. It is the
     way to the other three hundred, so it is drawn to be found. */
  .picker-query {
    position: relative;
    display: flex;
    flex: 1 1 18rem;
    align-items: center;
    max-inline-size: 26rem;
    margin-block: var(--space-xs);
    margin-inline-start: auto;
  }

  .picker-query__icon {
    position: absolute;
    inset-inline-start: var(--space-sm);
    pointer-events: none;

    &.icon {
      fill: var(--color-ink);
    }
  }

  .picker-query__input {
    flex: 1;
    min-inline-size: 0;
    min-block-size: 2.5rem;
    padding-inline: calc(var(--space-sm) + 1.5rem) var(--space-sm);
    border: var(--rule-width) solid var(--color-ink);
    background-color: var(--color-field);
    font-size: var(--text-input);

    &::placeholder {
      color: var(--color-ink-soft);
    }

    &:hover,
    .filter-grid__head:has(.picker:not([hidden])) &,
    &:focus {
      outline: var(--rule-width) solid var(--color-ink);
    }

    @media (pointer: coarse) {
      min-block-size: var(--target-min);
    }
  }

  .picker__frame {
    display: flex;
    flex: 1;
    gap: var(--space-md);
    overflow: hidden;
    padding: var(--space-sm) var(--space-lg);
  }

  .picker__frame > .skeleton {
    flex: 1;
  }

  .picker__groups {
    flex: none;
    display: grid;
    align-content: start;
    inline-size: min(40%, 18rem);
    overflow-y: auto;
    font-size: var(--text-ui-sm);

    & a {
      display: flex;
      align-items: center;
      min-block-size: 2rem;
    }
  }

  .picker__results {
    flex: 1;
    overflow-y: auto;
  }

  /* With the tiers on (M09-D4): the category headings, the "Show all
     indicators" / "Core only" switch under the column (categories then,
     rather than groups), and the periods and one-line meaning under a
     concept's name. */
  .picker__heading {
    margin-block: var(--space-sm) var(--space-2xs);
    padding-inline: var(--space-sm);
    color: var(--color-ink-muted);

    &:first-child {
      margin-block-start: 0;
    }
  }

  .picker__scope {
    margin-block-start: var(--space-sm);
    padding-block-start: var(--space-xs);
    border-block-start: var(--rule-width) solid var(--color-rule);
  }

  .picker__result-meta {
    display: block;
    color: var(--color-ink-subtle);
    font-size: var(--text-meta-xs);
    line-height: var(--leading-meta-xs);
  }

  .picker__result {
    display: block;
    inline-size: 100%;
    min-block-size: 2.25rem;
    padding: var(--space-xs) var(--space-sm);
    border-radius: var(--radius-md);
    font-size: var(--text-ui);
    text-align: start;
    cursor: pointer;

    &:hover,
    &[aria-selected="true"] {
      background-color: var(--color-row-hover);
    }
  }

  /* An F-8 criterion the reader's plan does not screen on (M13-D8): the row
     is a link to Powerpack, in the ink of the rows around it, with the lock's
     badge after its name. */
  .picker__result--locked {
    color: var(--color-ink);
    text-decoration: none;

    & .lock {
      margin-inline-start: var(--space-2xs);
    }
  }

  /* A screen the reader's plan cannot run (M13-D8): the Powerpack lock over
     the sentence that names the criteria, and the button that drops them. */
  .results-locked {
    display: grid;
    justify-items: center;
    gap: var(--space-sm);
    padding-block: var(--space-md);
  }

  .picker__note {
    padding: var(--space-xs) var(--space-sm);
    color: var(--color-ink-muted);
    font-size: var(--text-ui-sm);
  }

  /* Above the grid: the count, and — when a column is a plot — a key to the
     lines drawn on the plot images. The images are gnuplot's, with their
     colours baked in, so the key matches them rather than the tokens' chart
     marks (tasks/11 §9). */
  .results-summary {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-2xs) var(--space-lg);
    margin-block-end: var(--space-sm);
    color: var(--color-ink-muted);
    font-size: var(--text-ui-sm);
  }

  /* The line a screen cut to the reader's tier says it with (M04-D6), set
     in the summary's own muted text, with its locks after it. */
  .results-summary__limit {
    max-inline-size: 72ch;
    line-height: 1.5;

    & .lock {
      margin-inline-start: var(--space-3xs);
    }
  }

  .plot-key {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2xs);

    &::before {
      content: "";
      inline-size: 1.25rem;
      border-block-start: 2px solid currentColor;
    }
  }

  .plot-key--median::before { border-block-start-style: dashed; border-block-start-color: var(--color-loss); }
  .plot-key--mean::before { border-block-start-color: var(--color-link); }
  .plot-key--thirds::before { border-block-start: 1px dotted var(--color-ink-muted); }

  /* The results grid. Header cells are sort buttons; the widths are the
     three header kinds' own (ScreenersHelper#screener_header_width). */
  /* Hung by the bleed, its first and last columns set in by as much. */
  .screener-results {
    max-inline-size: none;
    margin-inline: calc(-1 * var(--screener-bleed));
  }

  .screener-table {
    & th {
      padding: 0;
    }

    & th:first-child .sort-button,
    & td:first-child {
      padding-inline-start: var(--screener-bleed);
    }

    & th:last-child .sort-button,
    & td:last-child {
      padding-inline-end: var(--screener-bleed);
    }

    & td {
      vertical-align: middle;
    }
  }

  .screener-table__col--ticker { inline-size: 6rem; }
  .screener-table__col--value { max-inline-size: 6.25rem; }
  .screener-table__col--default { inline-size: 11rem; }

  .screener-table__company {
    display: block;
    max-inline-size: 16rem;
    overflow: hidden;
    font-size: var(--text-ui);
    text-overflow: ellipsis;
  }

  .screener-table__plot {
    inline-size: 280px;
    max-inline-size: none;
    block-size: 210px;
    margin-inline-start: auto;
  }

  .empty-state {
    display: grid;
    justify-items: center;
    gap: var(--space-sm);
    padding-block: var(--space-3xl);
    color: var(--color-ink-muted);
    text-align: center;
  }

  .empty-state__title {
    display: flex;
    align-items: center;
    gap: var(--space-sm);
    color: var(--color-loss);
    font-family: var(--font-prose);
    font-size: var(--text-h3);
    font-weight: var(--weight-semibold);
  }
}
