/*
 * Ui engine — component styles (all components in a single file).
 *
 * Each ViewComponent in `app/components/ui/` has its CSS section here,
 * keyed by the component name. When adding a new component, append a new
 * section below (alphabetical order).
 *
 * Why one file instead of @imports?
 *   Propshaft does not rewrite @import paths to digested URLs, so
 *   aggregator files with relative @imports break in production. Keeping
 *   every rule here sidesteps that and reduces to a single HTTP request.
 *
 * Import order in consuming apps:
 *
 *   @import "ui/base";
 *   @import "ui/themes/indigo";   /* or another theme */
 *   @import "ui/components";
 */

/* ============================================================
   Ui::Button — primary interactive control.
   ============================================================ */

.ui-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--spacing-8);
  padding: var(--spacing-16);
  min-height: var(--touch-target-min);
  border-radius: var(--border-radius-sm);
  font-family: var(--font-family-paragraph);
  font-size: var(--font-size-16);
  font-weight: var(--font-weight-regular);
  line-height: var(--line-height-26);
  box-shadow: var(--shadow-xs);
  cursor: pointer;
  border: 0;
  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease;
  text-decoration: none;
}

.ui-btn:disabled,
.ui-btn[aria-disabled="true"] {
  cursor: not-allowed;
  opacity: 0.6;
}

.ui-btn--primary {
  background-color: var(--color-background-brand-default);
  color: var(--color-text-inverse-primary);
}

.ui-btn--secondary {
  background-color: var(--color-background-inverse-white);
  color: var(--color-text-neutral-medium);
  border: 1px solid var(--color-border-neutral-light);
}

.ui-btn--secondary:hover:not(:disabled) {
  background-color: var(--color-background-inverse-lightest);
}

.ui-btn--tertiary {
  background-color: var(--color-background-inverse-light);
  color: var(--color-text-brand-primary);
}

.ui-btn--tertiary:hover:not(:disabled) {
  background-color: var(--color-background-brand-light);
}

.ui-btn__label {
  display: block;
  -webkit-text-box-trim: both;
  -webkit-text-box-edge: cap alphabetic;
  text-box-trim: trim-both;
  text-box-edge: cap alphabetic;
}

.ui-btn--full {
  width: 100%;
}

/* ============================================================
   Ui divider — horizontal rule with optional inline label.
   No matching ViewComponent; use classes directly.
   ============================================================ */

.ui-divider {
  display: flex;
  align-items: center;
  gap: var(--spacing-16);
}

.ui-divider__line {
  flex: 1 1 auto;
  height: 1px;
  background-color: var(--color-border-neutral-light);
}

/* ============================================================
   Ui::Heading — display-style heading using the headline font.
   ============================================================ */

.ui-heading {
  margin: 0;
  font-family: var(--font-family-headline);
  letter-spacing: var(--letter-spacing-0);
  -webkit-text-box-trim: both;
  -webkit-text-box-edge: cap alphabetic;
  text-box-trim: trim-both;
  text-box-edge: cap alphabetic;
}

.ui-heading--xs {
  font-size: var(--font-size-24);
  line-height: var(--line-height-32);
}

.ui-heading--sm {
  font-size: var(--font-size-28);
  line-height: var(--line-height-38);
}

.ui-heading--md {
  font-size: var(--font-size-32);
  line-height: var(--line-height-44);
}

.ui-heading--medium { font-weight: var(--font-weight-medium); }
.ui-heading--bold   { font-weight: var(--font-weight-bold); }

.ui-heading--color-primary   { color: var(--color-text-neutral-dark); }
.ui-heading--color-secondary { color: var(--color-text-neutral-medium); }
.ui-heading--color-brand     { color: var(--color-text-brand-primary); }
.ui-heading--color-inverse   { color: var(--color-text-inverse-primary); }

.ui-heading--align-start  { text-align: start; }
.ui-heading--align-center { text-align: center; }
.ui-heading--align-end    { text-align: end; }

/* ============================================================
   Ui::Input — labelled form input.
   ============================================================ */

.ui-input {
  display: flex;
  flex-direction: column;
  gap: var(--spacing-8);
  width: 100%;
}

.ui-input__label {
  display: block;
  font-family: var(--font-family-paragraph);
  font-size: var(--font-size-16);
  font-weight: var(--font-weight-medium);
  line-height: var(--line-height-28);
  color: var(--color-text-neutral-dark);
  -webkit-text-box-trim: both;
  -webkit-text-box-edge: cap alphabetic;
  text-box-trim: trim-both;
  text-box-edge: cap alphabetic;
}

.ui-input__field {
  display: block;
  width: 100%;
  min-height: var(--touch-target-min);
  padding: var(--spacing-12) var(--spacing-16);
  background-color: var(--color-background-inverse-lightest);
  border: 1px solid var(--color-border-neutral-light);
  border-radius: var(--border-radius-sm);
  font-family: var(--font-family-paragraph);
  font-size: var(--input-font-size);
  font-weight: var(--font-weight-regular);
  line-height: var(--line-height-24);
  color: var(--color-text-neutral-dark);
  transition: border-color 150ms ease, box-shadow 150ms ease;
}

.ui-input__field::placeholder {
  color: var(--color-text-neutral-light);
}

.ui-input__field:focus {
  outline: none;
  border-color: var(--color-border-brand-secondary);
  box-shadow: 0 0 0 3px var(--color-border-brand-tertiary);
}

.ui-input__field:disabled {
  cursor: not-allowed;
  background-color: var(--color-background-inverse-light);
  border-color: var(--color-border-neutral-medium);
  color: var(--color-text-neutral-light);
}

.ui-input__help {
  margin: 0;
  font-family: var(--font-family-paragraph);
  font-size: var(--font-size-14);
  font-weight: var(--font-weight-regular);
  line-height: var(--line-height-24);
  color: var(--color-text-neutral-medium);
}

/* ============================================================
   Ui::Text — body text using the paragraph font.
   ============================================================ */

.ui-text {
  margin: 0;
  font-family: var(--font-family-paragraph);
  letter-spacing: var(--letter-spacing-0);
  -webkit-text-box-trim: both;
  -webkit-text-box-edge: cap alphabetic;
  text-box-trim: trim-both;
  text-box-edge: cap alphabetic;
}

.ui-text--xs { font-size: var(--font-size-12); line-height: var(--line-height-18); }
.ui-text--sm { font-size: var(--font-size-14); line-height: var(--line-height-24); }
.ui-text--md { font-size: var(--font-size-16); line-height: var(--line-height-26); }
.ui-text--lg { font-size: var(--font-size-18); line-height: var(--line-height-28); }
.ui-text--xl { font-size: var(--font-size-20); line-height: var(--line-height-30); }

.ui-text--regular  { font-weight: var(--font-weight-regular); }
.ui-text--medium   { font-weight: var(--font-weight-medium); }
.ui-text--semibold { font-weight: var(--font-weight-semibold); }
.ui-text--bold     { font-weight: var(--font-weight-bold); }

.ui-text--color-primary   { color: var(--color-text-neutral-dark); }
.ui-text--color-secondary { color: var(--color-text-neutral-medium); }
.ui-text--color-tertiary  { color: var(--color-text-neutral-light); }
.ui-text--color-brand     { color: var(--color-text-brand-primary); }
.ui-text--color-inverse   { color: var(--color-text-inverse-primary); }
.ui-text--color-error     { color: var(--color-text-danger-medium); }

.ui-text--align-start  { text-align: start; }
.ui-text--align-center { text-align: center; }
.ui-text--align-end    { text-align: end; }

/* ============================================================
   Firefox fallback — simulate text-box-trim with negative margins.

   Browsers that support `text-box-trim: trim-both` (Chrome 133+,
   Safari 18.2+, Edge 132+) natively trim the half-leading that
   line-height adds above and below text glyphs, making flex/grid
   gaps match Figma's auto-layout spacing exactly.

   Firefox does not support `text-box-trim` yet. Without trimming,
   each text element keeps invisible half-leading inside its line
   box, inflating the visual gap between adjacent elements.

   The fix: apply negative `margin-block` equal to the average of
   the top trim (line-box top → cap-height) and bottom trim
   (alphabetic baseline → line-box bottom). This collapses the
   line box to roughly cap-height → baseline, matching what
   `text-box-trim: trim-both; text-box-edge: cap alphabetic` does.

   Values were measured from actual font metrics via canvas
   TextMetrics (fontBoundingBoxAscent/Descent, actualBoundingBox).
   They are stable because font design metrics (ascender, descender,
   cap-height) are fixed properties of the font file — they do not
   change across weights (400–700) or with font-loading fallbacks
   (system-ui differs by < 0.5px).

   This entire block is ignored by browsers that support the
   property natively, and can be removed once Firefox ships support.
   ============================================================ */

@supports not (text-box-trim: trim-both) {
  /* Ui::Heading — Space Grotesk */
  .ui-heading--xs { margin-block: -8px; }  /* 24/32 */
  .ui-heading--sm { margin-block: -9px; }  /* 28/38 */
  .ui-heading--md { margin-block: -11px; } /* 32/44 */

  /* Ui::Text — Work Sans */
  .ui-text--xs { margin-block: -5px; } /* 12/18 */
  .ui-text--sm { margin-block: -7px; } /* 14/24 */
  .ui-text--md { margin-block: -8px; } /* 16/26 */
  .ui-text--lg { margin-block: -8px; } /* 18/28 */
  .ui-text--xl { margin-block: -8px; } /* 20/30 */

  /* Ui::Input label — Work Sans 16/28 */
  .ui-input__label { margin-block: -9px; }

  /* Ui::Button label — Work Sans 16/26 */
  .ui-btn__label { margin-block: -8px; }
}

/* ============================================================
   Ui::FileUploadBox
   ============================================================ */

/* -- Drop zone ------------------------------------------------ */

.ui-file-upload-box {
  display: flex;
  flex-direction: column;
  padding: var(--spacing-24);
  background-color: var(--color-background-inverse-lightest);
  border: 1px solid var(--color-border-neutral-light);
  border-radius: var(--border-radius-md);
  cursor: pointer;
}

.ui-file-upload-box__content {
  display: flex;
  align-items: center;
  gap: var(--spacing-12);
}

.ui-file-upload-box__icon {
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  width: 52px;
  height: 52px;
  border-radius: 100%;
  background-color: var(--color-background-brand-lightest);
  color: var(--color-background-brand-medium);
}

.ui-file-upload-box__icon-inner {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  border-radius: 100%;
  background-color: var(--color-background-brand-light);
}

.ui-file-upload-box__text {
  display: flex;
  flex-direction: column;
  gap: var(--spacing-4);
  min-width: 0;
}

.ui-file-upload-box__action {
  display: flex;
  flex-wrap: wrap;
  gap: var(--spacing-4);
  align-items: baseline;
  margin: 0;
  font-family: var(--font-family-paragraph);
  font-size: var(--font-size-14);
  line-height: var(--line-height-20);
  color: var(--color-text-neutral-medium);
}

.ui-file-upload-box__trigger {
  font-family: var(--font-family-paragraph);
  font-size: var(--font-size-14);
  line-height: var(--line-height-20);
  font-weight: var(--font-weight-medium);
  color: var(--color-background-brand-medium);
}

.ui-file-upload-box__drag-label {
  font-family: var(--font-family-paragraph);
  font-size: var(--font-size-14);
  line-height: var(--line-height-20);
  color: var(--color-text-neutral-medium);
}

.ui-file-upload-box__formats {
  margin: 0;
  font-family: var(--font-family-paragraph);
  font-size: var(--font-size-14);
  line-height: var(--line-height-20);
  color: var(--color-text-neutral-medium);
}

/* -- File thumbnail list ------------------------------------- */

.ui-file-upload-box__file-list {
  display: flex;
  flex-wrap: wrap;
  gap: var(--spacing-8);
  margin-top: var(--spacing-8);
}

.ui-file-upload-box__thumb {
  position: relative;
  width: 80px;
  height: 80px;
  flex-shrink: 0;
}

.ui-file-upload-box__thumb-content {
  width: 100%;
  height: 100%;
  border-radius: var(--border-radius-md);
  overflow: hidden;
  background-color: var(--color-background-brand-lightest);
  border: 1px solid var(--color-border-neutral-light);
}

.ui-file-upload-box__thumb-img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.ui-file-upload-box__thumb-file {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--spacing-4);
  width: 100%;
  height: 100%;
  padding: var(--spacing-8);
  color: var(--color-text-brand-primary);
}

.ui-file-upload-box__thumb-filename {
  font-family: var(--font-family-paragraph);
  font-size: var(--font-size-12);
  line-height: var(--line-height-18);
  font-weight: var(--font-weight-bold);
  color: inherit;
}

.ui-file-upload-box__thumb-remove {
  all: unset;
  position: absolute;
  top: -5px;
  right: -5px;
  display: flex;
  align-items: center;
  justify-content: center;
  width: var(--spacing-16);
  height: var(--spacing-16);
  border-radius: var(--border-radius-full);
  background-color: var(--color-black);
  border: 1.5px solid var(--color-background-inverse-white);
  color: var(--color-background-inverse-white);
  cursor: pointer;
}

.ui-file-upload-box__thumb-remove:hover {
  background-color: var(--color-text-neutral-dark);
}

.ui-file-upload-box__thumb-remove:focus-visible {
  outline: none;
  box-shadow: 0 0 0 var(--spacing-4) var(--color-border-brand-tertiary);
}

/* -- Error message ------------------------------------------- */

.ui-file-upload-box__error[hidden] { display: none; }

.ui-file-upload-box__error {
  display: flex;
  align-items: center;
  gap: var(--spacing-4);
  margin: var(--spacing-4) 0 0;
  font-family: var(--font-family-paragraph);
  font-size: var(--font-size-14);
  line-height: var(--line-height-24);
  font-weight: var(--font-weight-medium);
  color: var(--color-text-danger-default);
}

/* -- State modifiers ----------------------------------------- */

.ui-file-upload-box--disabled {
  cursor: not-allowed;
  opacity: 0.5;
}

.ui-file-upload-box--drag-over {
  background-color: var(--color-background-brand-lightest);
  border-color: var(--color-border-brand-tertiary);
}

.ui-file-upload-box--error {
  background-color: var(--color-background-danger-light);
  border-color: var(--color-text-danger-medium);
}

.ui-file-upload-box--error .ui-file-upload-box__icon {
  background-color: var(--color-background-danger-light);
  color: var(--color-text-danger-medium);
}

.ui-file-upload-box--error .ui-file-upload-box__icon-inner {
  background-color: var(--color-border-negative-light);
}

.ui-file-upload-box--error .ui-file-upload-box__trigger,
.ui-file-upload-box--error .ui-file-upload-box__drag-label,
.ui-file-upload-box--error .ui-file-upload-box__formats {
  color: var(--color-text-danger-medium);
}

