/* Copyright 2026 The Chromium Authors
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file. */

/* #css_wrapper_metadata_start
 * #type=style-lit
 * #import=//resources/cr_elements/cr_shared_vars.css.js
 * #scheme=relative
 * #css_wrapper_metadata_end */

:host {
  color: var(--toolbar-chip-fg-color, var(--color-toolbar-button-icon));
  display: inline-flex;
  align-items: center;
  flex-shrink: 0;
  font-family: var(--toolbar-chip-font-family);
  width: auto;
  min-width: max-content;

  /* Defaults to inherit from the page body (which loads text_defaults.css
     to get platform-specific font family and default size). */
  --toolbar-chip-font-family: inherit;
  --toolbar-chip-font-size: inherit;
  --toolbar-chip-font-weight: inherit;

  --toolbar-chip-ink-drop-hover-color: var(--color-toolbar-ink-drop-hover);
  --toolbar-chip-ink-drop-ripple-color: var(--color-toolbar-ink-drop-ripple);

  --toolbar-chip-height: var(--toolbar-button-height);
  --toolbar-chip-icon-size: var(--toolbar-button-icon-size);
  --toolbar-chip-icon-label-gap: 0px;
  --toolbar-chip-border-radius: calc(var(--toolbar-chip-height) / 2);
  --toolbar-chip-padding-start: 0px;
  --toolbar-chip-padding-end: 0px;

  /* External margins implemented as host padding to expand the clickable
   * hit target to the screen edges (Fitts's Law) without stretching the
   * internal visual button. Defaults to 0; currently used by the App Menu
   * button to extend its hit target to the screen corner. */
  padding-inline-end: var(--toolbar-chip-trailing-margin, 0);
  padding-inline-start: var(--toolbar-chip-leading-margin, 0);

  /* Animation durations matching Native Views parity. */
  /* (see views::kHighlightFadeOutOnHoverChangeDuration in
   * views/animation/ink_drop_host.cc) */
  --toolbar-chip-highlight-fade-duration: 250ms;
  /* (see views::FloodFillInkDropRipple::ACTION_TRIGGERED_FADE_OUT in
   * views/animation/flood_fill_ink_drop_ripple.cc) */
  --toolbar-chip-pressed-fade-duration: 300ms;
}

/* The base layer of the button, defining its shape, size, and base background
   color, etc. */
#button {
  align-items: center;
  background-color: var(--toolbar-chip-bg-color, transparent);
  border: none;
  border-radius: 50%; /* Default for icon-only chips */
  color: inherit;
  cursor: default;
  display: flex;
  font-family: inherit;
  font-size: inherit;
  font-weight: inherit;
  gap: 0;
  height: var(--toolbar-chip-height);
  justify-content: center;
  min-width: var(--toolbar-chip-height);
  outline: none;
  padding: 0;
  position: relative;
  user-select: none; /* Disables text selection on double-click/drag */
  width: 100%;

  /* Disables the default browser tap highlight so that our custom InkDrop
     overlay provides the sole visual feedback for taps. */
  -webkit-tap-highlight-color: transparent;
}

/* --- HIGHLIGHT ENGINE ---
 * Mimics views::InkDrop highlight and pressed states for 1:1 parity.
 * We use ::before for the hover highlight and ::after for the pressed
 * highlight.
 * Slotted elements are positioned (position: relative; z-index: 1) to paint
 * cleanly on top of these absolute background highlights. */

#button::before {
  border-radius: inherit;
  content: '';
  inset: 0;
  opacity: var(--toolbar-chip-highlight-opacity, 0);
  pointer-events: none;
  position: absolute;
  background-color: var(--toolbar-chip-ink-drop-hover-color);
  transition: opacity var(--toolbar-chip-highlight-fade-duration) ease-in-out;
}

#button::after {
  border-radius: inherit;
  content: '';
  inset: 0;
  opacity: var(--toolbar-chip-highlight-opacity, 0);
  pointer-events: none;
  position: absolute;
  background-color: var(--toolbar-chip-ink-drop-ripple-color);
  transition: opacity var(--toolbar-chip-pressed-fade-duration) ease-in-out;
}

/* HOVER STATE: Highlight layer fade-in.
 * SHOW_ON_RIPPLE compositing: Hover layer stays visible during active/menu
 * states. */
:host(:hover) #button::before,
:host([is-menu-open]) #button::before {
  opacity: 1;
}

/* --- PRESSED/MENU STATE ---
 * Pressed highlight layer fade-in. This layer composites on top of the hover
 * layer. */
:host(:active) #button::after,
:host([is-menu-open]) #button::after {
  opacity: 1;
  transition-duration: 0s; /* Instant for pressed state */
}

/* INSET FOCUS RING: Used by default mapping to native C++ ToolbarButton, which
 * natively creates an inset focus ring. Note that some subclasses manually
 * re-enable outset rings dynamically (e.g., App Menu, Avatar Button) when their
 * labels expand. */
#button:focus-visible,
:host([force-focus-ring]) #button {
  box-shadow: inset 0 0 0 2px var(--cr-focus-outline-color);
}

@media (forced-colors: active) {
  #button:focus-visible,
  :host([force-focus-ring]) #button {
    /* Use outline instead of box-shadow (which does not work) in Windows
       HCM. */
    outline: var(--cr-focus-outline-hcm);
  }
}

/* OUTSET FOCUS RING: Used for components mapping to native IconLabelBubbleView,
 * which always draws an outer boundary focus ring regardless of whether the
 * label is currently expanded (e.g., Page Actions, Content Settings).
 *
 * It is also used dynamically by some buttons (e.g., Avatar Button and App Menu
 * when they expand. */
:host([outset-focus-ring]) #button:focus-visible,
:host([outset-focus-ring][force-focus-ring]) #button {
  box-shadow: none;
  outline: 2px solid var(--cr-focus-outline-color);
  outline-offset: 2px;
}

#button ::slotted(*) {
  flex-shrink: 0;
  font-size: var(--toolbar-chip-font-size);
  font-weight: var(--toolbar-chip-font-weight);
  /* Stacks above absolute background pseudo-element highlights */
  position: relative;
  white-space: nowrap;
  z-index: 1;
}

#button ::slotted(cr-icon),
#button ::slotted([slot='prefix-icon']),
#button ::slotted([slot='suffix-icon']) {
  --icon-size: var(--toolbar-chip-icon-size);
  --iron-icon-width: var(--toolbar-chip-icon-size);
  --iron-icon-height: var(--toolbar-chip-icon-size);
}

:host([has-label]) {
  color: var(--toolbar-chip-fg-color, var(--color-toolbar-button-text));
}

/* Tonal look for chips with labels. */
:host([has-label]) #button {
  background-color: var(--toolbar-chip-bg-color,
                        var(--color-toolbar-background-subtle-emphasis));
  border-radius: var(--toolbar-chip-border-radius);
  color: inherit;
  gap: var(--toolbar-chip-icon-label-gap);

  /* Add extra padding to move button text away from rounded corners */
  --label-side-spacing: calc(round(down, var(--toolbar-chip-height) / 4, 1px));
  padding-inline-start: calc(var(--toolbar-chip-padding-start)
                             + var(--label-side-spacing));
  padding-inline-end: calc(var(--toolbar-chip-padding-end)
                           + var(--label-side-spacing));
}

/* If we have a prefix icon then we don't need padding to push the text start
 * away from the rounded corners */
:host([has-label][has-prefix-icon]) #button {
  padding-inline-start: var(--toolbar-chip-padding-start);
}

/* If we have a suffix icon then we don't need padding to push the text end
 * away from the rounded corners */
:host([has-label][has-suffix-icon]) #button {
  padding-inline-end: var(--toolbar-chip-padding-end);
}

/* --- SLIDING LABEL ANIMATION ---
 * Natively handles sliding expansion/collapse animations for the slotted label
 * text when the [has-label] attribute is toggled.
 *
 * When to use [animates-label]:
 * - Provide this attribute on chips that should slide open/closed (e.g.,
 *   page_action_icon, permission_chip).
 * - Omit this attribute on chips with static labels, or chips that should
 *   instantly appear/disappear without sliding.
 */
:host([animates-label]) {
  interpolate-size: allow-keywords;
}

/* Attach transition properties to the base button so they are always active.
 * This ensures properties animate smoothly in both directions (expanding and
 * collapsing) whenever the [has-label] state is toggled. */
:host([animates-label]) #button {
  transition:
      gap var(--toolbar-chip-expand-duration, 600ms)
          var(--ease-out-cubic-bezier),
      padding-inline-start var(--toolbar-chip-expand-duration, 600ms)
          var(--ease-out-cubic-bezier),
      padding-inline-end var(--toolbar-chip-expand-duration, 600ms)
          var(--ease-out-cubic-bezier),
      background-color var(--toolbar-chip-expand-duration, 600ms)
          var(--ease-out-cubic-bezier);
}

/* Target the label text (the slotted element that does not have a specific
 * "slot" attribute). When the chip expands, this transitions the text from 0
 * width and opacity up to its intrinsic max-content width and full opacity. */
:host([animates-label]) ::slotted(:not([slot])) {
  max-width: max-content;
  overflow: hidden;
  transition:
      max-width var(--toolbar-chip-expand-duration, 600ms)
          var(--ease-out-cubic-bezier),
      opacity var(--toolbar-chip-expand-duration, 600ms)
          var(--ease-out-cubic-bezier);
}

/* When the label is hidden, crush its width and opacity to 0. */
:host(:not([has-label])) ::slotted(:not([slot])) {
  max-width: 0;
  opacity: 0;
  overflow: hidden;
}

#button:disabled {
  opacity: var(--cr-disabled-opacity, 0.38);
  pointer-events: none;
}

:host-context(.help-anchor-highlight) #button {
  background-color: transparent;
}

:host-context(.help-anchor-highlight) #button::before {
  animation: pulse 1600ms infinite;
  background-color: var(--color-button-feature-attention-highlight);
  opacity: 1;
}

@keyframes pulse {
  0% {
    inset: 0;
    animation-timing-function: cubic-bezier(0.333, 0.667, 0.667, 1);
  }
  50% {
    inset: 3px;
    animation-timing-function: cubic-bezier(0.333, 0.667, 0.667, 1);
  }
  100% {
    inset: 0;
  }
}

@media (prefers-reduced-motion: reduce) {
  #button,
  #button::before,
  #button::after,
  ::slotted(*) {
    animation: none;
    transition: none !important;
  }
}
