/*
 * The shared controls of every Code Villain web surface, written once.
 *
 * The rules are studio/design/components.md; the numbers come from studio/design/tokens
 * (color.css, type.css, shape.css must load first). Forge, Layer, Glyph,
 * Raven and the site copy this file and use these classes instead of their own. Caster
 * draws the same recipes in AppKit.
 *
 * Everything sits in the `components` layer, so an app's own rules and
 * Tailwind utilities still win where a view needs to adjust a detail.
 * Unlayered CSS beats any layer, so an app's global resets (a bare
 * `a { text-decoration: none }`, say) belong in `@layer base`, which this
 * order puts under the components. Tailwind declares the same order.
 */

@layer base, components;

@layer components {
  /* Type for anything clicked: buttons, chips. */
  .ui-control {
    font-size: var(--type-control-size);
    font-weight: var(--type-control-weight);
    line-height: var(--type-control-leading);
  }

  /*
   * Button: 28px, the control role, 6px corners, no border. A block, so it
   * never reads as a tab, a link or a label: fg at button-tint, fg text.
   */
  .ui-button {
    display: inline-flex;
    flex-shrink: 0;
    align-items: center;
    justify-content: center;
    gap: 0.5rem;
    height: 28px;
    padding: 0 0.75rem;
    border: 0;
    border-radius: var(--radius-md);
    background: color-mix(in srgb, var(--fg) var(--button-tint), transparent);
    color: var(--fg);
    font-family: inherit;
    font-size: var(--type-control-size);
    font-weight: var(--type-control-weight);
    line-height: var(--type-control-leading);
    white-space: nowrap;
    cursor: pointer;
  }
  .ui-button:hover:not(:disabled) {
    background: color-mix(in srgb, var(--fg) var(--button-hover-tint), transparent);
    color: var(--fg);
  }
  .ui-button:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 2px;
  }
  .ui-button:disabled {
    opacity: 0.45;
    cursor: default;
  }
  /* The one action the screen's state needs: poison with dark ink. */
  .ui-button-primary {
    background: var(--primary);
    color: var(--on-primary);
  }
  .ui-button-primary:hover:not(:disabled) {
    background: var(--primary-hover);
    color: var(--on-primary);
  }
  /* A destructive secondary action: the same fill, status ink; never a red block. */
  .ui-button-danger {
    color: var(--status-danger-ink);
  }
  .ui-button-danger:hover:not(:disabled) {
    color: var(--status-danger-ink);
  }
  /*
   * A quiet 28px square for an icon; the icon marks it as a control, so it
   * has no fill until hover. It needs an accessible name.
   */
  .ui-icon-button {
    width: 28px;
    padding: 0;
    background: transparent;
    color: var(--muted);
  }
  .ui-icon-button:hover:not(:disabled) {
    background: var(--hover);
  }

  /* Field: a tone step with no border; one ring on the edge when focused. */
  .ui-field {
    border: 1px solid transparent;
    border-radius: var(--radius-md);
    background: var(--field);
    color: var(--fg);
    font-family: inherit;
    font-size: var(--type-ui-size);
    line-height: var(--type-ui-leading);
    outline: none;
  }
  .ui-field::placeholder {
    color: var(--faint);
  }
  .ui-field:hover {
    background: var(--field-hover);
  }
  .ui-field:focus,
  .ui-field:focus-within {
    border-color: var(--accent);
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 22%, transparent);
  }

  /* Link: ink, bold, underlined; the underline firms on hover. */
  .ui-link {
    color: var(--fg);
    font-weight: 700;
    text-decoration: underline;
    text-decoration-color: color-mix(in srgb, var(--fg) 45%, transparent);
    text-underline-offset: 3px;
  }
  .ui-link:hover {
    text-decoration-color: var(--fg);
  }
  /*
   * A link that opens another app is a <button>. It keeps the link's look,
   * at the control size: it stands among controls, not in prose.
   */
  button.ui-link {
    padding: 0;
    border: 0;
    background: transparent;
    font-family: inherit;
    font-size: var(--type-control-size);
    line-height: var(--type-control-leading);
    cursor: pointer;
  }
  button.ui-link:hover:not(:disabled) {
    background: transparent;
    color: var(--fg);
  }

  /*
   * Tabs: switch what one place shows. Text, and a 2px fg line under the
   * current tab; no fill, so a tab never looks like a button. Put
   * role="tablist" on the strip and aria-selected="true" on the current tab.
   */
  .ui-tabs {
    display: flex;
    align-items: stretch;
    gap: 20px;
  }
  .ui-tab {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    min-height: 34px;
    padding: 0;
    border: 0;
    border-radius: 0;
    background: transparent;
    box-shadow: inset 0 -2px 0 transparent;
    color: var(--muted);
    font-family: inherit;
    font-size: var(--type-control-size);
    font-weight: var(--type-control-weight);
    line-height: var(--type-control-leading);
    white-space: nowrap;
    cursor: pointer;
  }
  .ui-tab:hover {
    color: var(--fg);
  }
  .ui-tab:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 2px;
  }
  .ui-tab[aria-selected="true"],
  .ui-tab[aria-current="page"],
  .ui-tab.is-active {
    box-shadow: inset 0 -2px 0 var(--fg);
    color: var(--fg);
    font-weight: 700;
  }
  /* A count beside a tab's label. */
  .ui-tab-count {
    color: var(--faint);
    font-size: var(--type-ui-small-size);
    font-weight: 400;
  }

  /*
   * Segmented control: one value of a few. A track on the chip tint; the
   * chosen option (aria-pressed="true") wears the button's hover fill.
   */
  .ui-segmented {
    display: inline-flex;
    gap: 2px;
    padding: 2px;
    border-radius: var(--radius-md);
    background: color-mix(in srgb, var(--fg) var(--chip-tint), transparent);
  }
  .ui-segment {
    display: inline-flex;
    align-items: center;
    height: 24px;
    padding: 0 0.6rem;
    border: 0;
    border-radius: var(--radius-sm);
    background: transparent;
    color: var(--muted);
    font-family: inherit;
    font-size: var(--type-control-size);
    font-weight: var(--type-control-weight);
    line-height: var(--type-control-leading);
    white-space: nowrap;
    cursor: pointer;
  }
  .ui-segment:hover:not(:disabled) {
    background: transparent;
    color: var(--fg);
  }
  .ui-segment:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 2px;
  }
  .ui-segment:disabled {
    opacity: 0.45;
    cursor: default;
  }
  .ui-segment[aria-pressed="true"],
  .ui-segment[aria-pressed="true"]:hover:not(:disabled) {
    background: color-mix(in srgb, var(--fg) var(--button-hover-tint), transparent);
    color: var(--fg);
    font-weight: 700;
  }

  /* Chip: detail, not a signal. Muted text on fg at chip-tint. */
  .ui-chip {
    border-radius: var(--radius-full);
    background: color-mix(in srgb, var(--fg) var(--chip-tint), transparent);
    color: var(--muted);
    font-size: var(--type-control-size);
    font-weight: var(--type-control-weight);
    line-height: var(--type-control-leading);
  }

  /*
   * Status pill: the status hue at status-tint, translucent over its host,
   * with the status ink for text and dot. Set --status-color and
   * --status-ink, or use a .ui-status-<name> helper.
   */
  .ui-status {
    border-radius: var(--radius-full);
    background: color-mix(in srgb, var(--status-color, var(--muted)) var(--status-tint), transparent);
    color: var(--status-ink, var(--status-neutral-ink));
    font-size: var(--type-control-size);
    font-weight: 700;
    line-height: var(--type-control-leading);
  }
  .ui-status-ok { --status-color: var(--ok); --status-ink: var(--status-ok-ink); }
  .ui-status-warn { --status-color: var(--warn); --status-ink: var(--status-warn-ink); }
  .ui-status-danger { --status-color: var(--danger); --status-ink: var(--status-danger-ink); }
  .ui-status-info { --status-color: var(--info); --status-ink: var(--status-info-ink); }

  /* A status-tinted note or diff run: the same recipe on a block. */
  .ui-tint-ok { background: color-mix(in srgb, var(--ok) var(--status-tint), transparent); color: var(--status-ok-ink); }
  .ui-tint-warn { background: color-mix(in srgb, var(--warn) var(--status-tint), transparent); color: var(--status-warn-ink); }
  .ui-tint-danger { background: color-mix(in srgb, var(--danger) var(--status-tint), transparent); color: var(--status-danger-ink); }
  .ui-tint-info { background: color-mix(in srgb, var(--info) var(--status-tint), transparent); color: var(--status-info-ink); }

  /* Row: no dividers; hover and selection are tone steps. */
  .ui-row {
    border-radius: var(--radius-md);
  }
  .ui-row:hover {
    background: var(--hover);
  }
  .ui-row[aria-selected="true"],
  .ui-row[aria-current="page"],
  .ui-row.is-selected {
    background: var(--selected);
    color: var(--fg);
  }

  /*
   * Disclosure: a chevron before a faint label; muted on hover, the chevron
   * turning down when open. A button with aria-expanded.
   */
  .ui-disclosure {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    padding: 0;
    border: 0;
    background: transparent;
    color: var(--faint);
    font-family: inherit;
    font-size: var(--type-control-size);
    font-weight: var(--type-control-weight);
    line-height: var(--type-control-leading);
    cursor: pointer;
  }
  .ui-disclosure:hover {
    color: var(--muted);
  }
  .ui-disclosure:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 2px;
    border-radius: var(--radius-sm);
  }
  .ui-disclosure > svg {
    flex-shrink: 0;
    transition: rotate 150ms;
  }
  .ui-disclosure[aria-expanded="true"] > svg {
    rotate: 90deg;
  }

  /* Menu: the line token is allowed on menus and tables. */
  .ui-menu {
    max-width: calc(100vw - 1rem);
    border: 1px solid var(--line);
    border-radius: var(--radius-md);
    background: var(--surface);
  }
  /* The option the arrow keys move: fg at highlight-tint, on any host. */
  .ui-option {
    border-radius: var(--radius-md);
  }
  .ui-option[data-highlighted],
  .ui-option[aria-selected="true"],
  .ui-option.is-active {
    background: color-mix(in srgb, var(--fg) var(--highlight-tint), transparent);
  }

  /* Dialog: the dialog tone over a dimmed backdrop; its fields step down. */
  .ui-dialog {
    --field: var(--dialog-field);
    --field-hover: var(--dialog-field-hover);
    max-height: calc(100dvh - 2rem);
    overflow-y: auto;
    border-radius: var(--radius-lg);
    background: var(--dialog);
  }
  .ui-backdrop {
    /* stylelint-disable-next-line function-disallowed-list -- black at the backdrop token */
    background: rgb(0 0 0 / var(--backdrop-tint));
  }

  /* Live dot: something happening now, in signal. */
  .ui-live-dot {
    display: inline-block;
    width: 6px;
    height: 6px;
    flex: none;
    border-radius: 50%;
    background: var(--signal);
  }

  /* Key hint: radius-sm on the chip tint. */
  .ui-kbd {
    padding: 0 0.3em;
    border-radius: var(--radius-sm);
    background: color-mix(in srgb, var(--fg) var(--chip-tint), transparent);
    color: var(--muted);
    font-family: var(--font-mono);
    font-size: var(--type-ui-small-size);
    line-height: var(--type-ui-small-leading);
  }
}
