/* ==========================================================================
   Components — reusable pieces shared across pages: buttons, badges, tags,
   chips, status pills, form fields, checkbox rows and the modal shells.
   ========================================================================== */

/* ---- Buttons ---- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-xs);
  height: 56px;
  padding-inline: var(--space-lg);
  border-radius: var(--radius-pill);
  font-size: var(--fs-body);
  font-weight: var(--fw-semibold);
  white-space: nowrap;
  transition: background var(--duration-base) var(--ease-standard),
    color var(--duration-base) var(--ease-standard),
    border-color var(--duration-base) var(--ease-standard),
    transform var(--duration-fast) var(--ease-standard);
}

.btn:active {
  transform: scale(0.98);
}

.btn__icon {
  flex-shrink: 0;
}

/* ---- Disabled buttons ----
   One shared treatment for every .btn variant, whether disabled via the
   native [disabled] attribute (real buttons) or [aria-disabled="true"]
   (inert links standing in for a button, e.g. the consent modal's Begin
   Evaluation before every statement is checked).

   Two treatments only:
   - Filled/primary CTAs (solid background, no border) desaturate to a
     shared muted gold with muted dark text, rather than each falling back
     to its own resting color or an unrelated grey — a disabled primary
     button should still read as gold-family, not as a different button.
   - Outlined/secondary buttons (transparent background, visible border)
     keep their own colors and dim by opacity instead of swapping to a
     fixed color — .btn--outline-light is white-on-navy while the other
     outline variants are navy/grey-on-white, so no single muted color
     could work for both, but dimming either one by the same opacity does.

   A future variant only needs adding to whichever list below matches its
   resting style to inherit this automatically. */
.btn[disabled],
.btn[aria-disabled='true'] {
  cursor: not-allowed;
  pointer-events: none;
}

.btn[disabled]:active,
.btn[aria-disabled='true']:active {
  transform: none;
}

.btn--primary[disabled],
.btn--primary[aria-disabled='true'],
.btn--navy[disabled],
.btn--navy[aria-disabled='true'],
.btn--gold-gradient[disabled],
.btn--gold-gradient[aria-disabled='true'] {
  background: var(--color-btn-disabled-bg);
  color: var(--color-btn-disabled-text);
}

.btn--outline-dark[disabled],
.btn--outline-dark[aria-disabled='true'],
.btn--outline-light[disabled],
.btn--outline-light[aria-disabled='true'],
.btn--outline-muted[disabled],
.btn--outline-muted[aria-disabled='true'],
.btn--light[disabled],
.btn--light[aria-disabled='true'] {
  opacity: var(--btn-disabled-opacity);
}

.btn--sm {
  height: 44px;
  padding-inline: var(--space-md);
  font-size: var(--fs-body-sm);
}

.btn--lg {
  height: 56px;
}

.btn--block {
  width: 100%;
}

.btn--primary {
  background: var(--color-gold-300);
  color: var(--color-navy-700);
  /* Overrides the shared .btn transition list above with the same four
     properties, only background at its own 200ms rather than the base
     250ms — color/border-color/transform keep their original timing
     (transform is what drives the :active press on every button variant,
     this one included, so it stays rather than being dropped). */
  transition: background 200ms var(--ease-standard),
    color var(--duration-base) var(--ease-standard),
    border-color var(--duration-base) var(--ease-standard),
    transform var(--duration-fast) var(--ease-standard);
}

.btn--primary:hover {
  background: #b88f2f;
}

.btn--outline-dark {
  background: var(--color-white);
  color: var(--color-navy-700);
  border: 1.5px solid var(--color-navy-700);
  /* Repeats the shared .btn list above so background can run its own
     200ms instead of the base 250ms, without dropping color/border-color/
     transform (transform is the :active press, used by every variant).
     Border-color and color are still listed even though this hover no
     longer changes either — border/text/the arrow icon inside this button
     all stay navy — so a future hover state that does touch them inherits
     the same timing instead of the base 250ms by default. */
  transition: background 200ms var(--ease-standard),
    color var(--duration-base) var(--ease-standard),
    border-color var(--duration-base) var(--ease-standard),
    transform var(--duration-fast) var(--ease-standard);
}

.btn--outline-dark:hover {
  background: #e8edf3;
}

.btn--outline-light {
  background: transparent;
  color: var(--color-white);
  border: 1px solid var(--color-white);
}

.btn--outline-light:hover {
  background: var(--color-white);
  color: var(--color-navy-800);
}

.btn--light {
  background: var(--color-white);
  color: var(--color-navy-900);
  /* Repeats the shared .btn list above so background can run its own
     200ms instead of the base 250ms, without dropping color/border-color/
     transform (transform is the :active press, used by every variant). */
  transition: background 200ms var(--ease-standard),
    color var(--duration-base) var(--ease-standard),
    border-color var(--duration-base) var(--ease-standard),
    transform var(--duration-fast) var(--ease-standard);
}

.btn--light:hover {
  background: #f2f2f2;
}

/* This particular button is also a scroll-reveal target (see main.js),
   which tags it data-reveal — and .js-reveal [data-reveal] in base.css
   (one class + one attribute selector, equal specificity to two classes)
   sets its own transition shorthand for the entrance fade. Shorthands
   replace rather than merge, so without a same-or-higher-specificity rule
   here, that would silently drop the hover transition above on this one
   button. Same fix as .audience-card elsewhere: repeat the list on a
   selector specific enough to hold its place. transform appears once, at
   the button's own fast press timing rather than the reveal's — listing a
   property twice at two durations doesn't blend them, the later entry
   simply wins for every future change, which would slow the :active press
   down to the reveal's 800ms. The trade-off runs the other way instead:
   the one-time entrance slide-up plays on the faster timing, settling
   before the opacity fade. */
.stand-banner__content .btn--light {
  transition: background 200ms var(--ease-standard),
    color var(--duration-base) var(--ease-standard),
    border-color var(--duration-base) var(--ease-standard),
    transform var(--duration-fast) var(--ease-standard),
    opacity var(--duration-reveal) var(--ease-reveal);
}

/* Muted outline — dialog secondary action. */
.btn--outline-muted {
  background: transparent;
  color: var(--color-navy-800);
  border: 1px solid #7a8596;
}

.btn--outline-muted:hover {
  background: rgba(122, 133, 150, 0.12);
}

/* Gold gradient — attorney partnership CTA. */
.btn--gold-gradient {
  background-color: #cfa63a;
  color: var(--color-navy-ink);
}

.btn--gold-gradient:hover {
  background-color: #b88f2f;
}

/* Navy solid — evaluation flow primary. */
.btn--navy {
  background: var(--color-form-ink);
  color: var(--color-white);
}

.btn--navy:hover {
  background: var(--color-navy-700);
}

/* ---- AI badge (hero) ---- */
.badge {
  display: inline-flex;
  align-items: center;
  gap: var(--space-xs);
  padding: 6px var(--space-md);
  border-radius: var(--radius-pill);
  background: #fff8eb;
  box-shadow: var(--shadow-xs), inset 0 0 0 0.5px rgba(223, 194, 122, 0.35);
  font-size: var(--fs-caption);
  font-weight: var(--fw-semibold);
  color: var(--color-navy-700);
}

.badge__icon {
  display: inline-flex;
  width: 20px;
  height: 20px;
  align-items: center;
  justify-content: center;
}

.badge__divider {
  width: 1px;
  height: 14px;
  background: rgba(223, 194, 122, 0.55);
}

/* ---- Tags (visa category cards) ---- */
.tag {
  display: inline-flex;
  align-items: center;
  padding: 6px var(--space-md);
  border-radius: var(--radius-pill);
  font-size: var(--fs-caption);
  font-weight: var(--fw-semibold);
  white-space: nowrap;
}

.tag--free {
  background: var(--color-green-bg);
  color: var(--color-green-text);
}

.tag--specialist {
  background: var(--color-gold-tint);
  color: var(--color-gold-text);
  letter-spacing: 0.02em;
}

.tag--category {
  background: var(--color-blue-tag-bg);
  color: var(--color-blue-tag);
  letter-spacing: 0.025em;
}

/* ---- Chips (pricing / memo status) ---- */
.chip {
  display: inline-flex;
  align-items: center;
  padding: 6px var(--space-md);
  border-radius: var(--radius-pill);
  font-size: var(--fs-caption);
  font-weight: var(--fw-semibold);
  white-space: nowrap;
}

.chip--neutral {
  background: rgba(77, 92, 112, 0.6);
  color: var(--color-white);
}

.chip--highlight {
  background: var(--color-white);
  color: var(--color-gold-text);
}

.chip--strong {
  background: var(--color-green-bg);
  color: var(--color-green-text);
}

/* Gold-on-gold left this text at 1:1 -- effectively invisible. The fill
   stays; the text takes the readable gold (4.3:1 on this tint). */
.chip--develop,
.chip--gap {
  background: rgba(203, 166, 72, 0.3);
  /* One step darker than --color-gold-text: against this gold tint that
     token lands at 4.17:1, just under AA for 12px. */
  color: #7d5c14;
}

/* ---- Status pill (report card) ---- */
.status-pill {
  display: inline-flex;
  align-items: center;
  /* Both host cards (.report-card__body, .memo-card__body) are column
     flex containers, which stretch children to full width by default —
     inline-flex alone isn't enough to keep this fit-content there. */
  align-self: flex-start;
  gap: var(--space-xs);
  padding: 6px var(--space-md);
  border-radius: var(--radius-pill);
  font-size: var(--fs-caption);
  font-weight: var(--fw-semibold);
}

.status-pill--strong {
  background: var(--color-green-bg);
  color: var(--color-green-text);
}

.status-pill__dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--color-green-text);
}

/* The comp only draws the strong state, because the sample report only ever
   shows that one. A live evaluation also comes back "Developing Profile" or
   "Preliminary Stage", so those take the amber and grey the criteria rows
   below already use for the same two verdicts. The dot is repainted with
   them: its own rule hardcodes the green. */
.status-pill--develop {
  background: rgba(203, 166, 72, 0.18);
  color: var(--color-gold-300);
}

.status-pill--develop .status-pill__dot {
  background: var(--color-gold-400);
}

.status-pill--unclear {
  background: rgba(107, 114, 128, 0.1);
  color: var(--color-grey-dot);
}

.status-pill--unclear .status-pill__dot {
  background: var(--color-grey-dot);
}

/* ---- Modal dialog (shared shell) ----
   Native <dialog>, so the browser supplies the top layer, the focus trap
   and Esc-to-close; main.js only opens it, handles a backdrop click, and
   validates. Figma: Resources / popup, node 3021:4836. */
.modal {
  width: min(var(--modal-width, 496px), calc(100vw - 2rem));
  /* base.css resets every margin to 0, which overrides the UA stylesheet's
     margin:auto on <dialog> and pins the modal to the top-left corner. */
  margin: auto;
  padding: 0;
  border: none;
  border-radius: 16px;
  background: var(--color-white);
  box-shadow: var(--shadow-lg);
  color: var(--color-text-body);
}

.modal::backdrop {
  background: rgba(12, 32, 60, 0.55);
}

.modal--wide {
  --modal-width: 640px;
}

.modal--md {
  --modal-width: 560px;
}

.modal__panel {
  display: flex;
  flex-direction: column;
  gap: var(--space-lg);
  padding: var(--space-lg);
}

.modal__head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-lg);
}

.modal__intro {
  display: flex;
  flex-direction: column;
  gap: var(--space-md);
  min-width: 0;
}

.modal__title {
  font-family: var(--font-display);
  font-size: 2rem;
  font-weight: var(--fw-semibold);
  line-height: 1.19;
  color: var(--color-text-heading);
}

.modal__desc {
  max-width: none;
  font-size: var(--fs-body-sm);
  line-height: 1.45;
  color: var(--color-text-body);
}

.modal__close {
  display: inline-flex;
  flex-shrink: 0;
  width: 24px;
  height: 24px;
  border-radius: var(--radius-sm);
  opacity: 0.8;
  transition: opacity var(--duration-fast) var(--ease-standard);
}

.modal__close:hover {
  opacity: 1;
}

.modal__field {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.modal__label {
  font-size: var(--fs-body); /* 16px — same at every breakpoint */
  line-height: 1.25;
  color: var(--color-form-ink);
}

.modal__required {
  color: #d4a52f;
}

.modal__input {
  height: 52px;
  padding-inline: 19px;
  border: 1.33px solid rgba(10, 29, 56, 0.6);
  border-radius: 8px;
  background: var(--color-white);
  font-size: var(--fs-body);
  color: var(--color-navy-ink);
  transition: border-color var(--duration-fast) var(--ease-standard);
}

.modal__input::placeholder {
  font-size: var(--fs-body);
  color: var(--color-text-placeholder);
}

.modal__input:hover {
  border-color: var(--color-gold-400);
}

.modal__input[aria-invalid="true"] {
  border-color: var(--color-red-dot);
}

.modal__error {
  font-size: var(--fs-body-sm);
  color: var(--color-red-dot);
}

.modal__error:empty {
  display: none;
}

.modal__actions {
  display: flex;
  flex-direction: column;
  gap: var(--space-md);
}

.modal__buttons {
  display: flex;
  gap: var(--space-md);
}

/* Both actions share the row evenly, as in the comp. */
.modal__buttons .btn {
  flex: 1 1 0;
  min-width: 0;
}

.modal__status {
  font-size: var(--fs-body-sm);
  color: var(--color-green-text);
}

.modal__status:empty {
  display: none;
}

.modal__status--error {
  color: var(--color-red-dot);
}

.modal__fineprint {
  max-width: none;
  font-size: var(--fs-caption);
  line-height: 20px;
  color: var(--color-text-body);
}

/* ---- Pill badge ----
   Gold-tinted pill with a haloed dot. Shared by the attorney hero and the
   evaluation flow; the border is optional so both comps are covered. */
.pill-badge {
  display: inline-flex;
  align-items: center;
  gap: var(--space-xs);
  padding: 6px var(--space-md);
  border-radius: var(--radius-pill);
  background: rgba(197, 156, 56, 0.2);
  font-size: var(--fs-caption);
  font-weight: var(--fw-semibold);
  line-height: 1;
  letter-spacing: 0.06em;
  color: #a18b4c;
}

.pill-badge--bordered {
  border: 1px solid rgba(197, 156, 56, 0.35);
}

/* The comp draws the dot as a 6px square with a 3px radius, not a circle. */
.pill-badge__dot {
  width: 6px;
  height: 6px;
  flex-shrink: 0;
  border-radius: 3px;
  background: var(--color-gold-500);
  box-shadow: 0 0 0 3px rgba(197, 156, 56, 0.25);
}

/* ---- Form field ----
   Label + control pair used by the evaluation form. Native controls are
   styled directly rather than replaced, so keyboard, validation and
   autofill keep working.  */
.field {
  display: flex;
  flex-direction: column;
  gap: var(--space-xs);
}

.field__label {
  font-size: var(--fs-body); /* 16px — same at every breakpoint */
  line-height: 1.25;
  color: var(--color-form-ink);
}

.field__required {
  color: var(--color-gold-text);
}

.field__control {
  width: 100%;
  min-height: 48px;
  padding: 13px 17px;
  border: 1px solid rgba(10, 29, 56, 0.6);
  border-radius: 8px;
  background: var(--color-white);
  font-size: var(--fs-body);
  line-height: 1.25;
  color: var(--color-navy-ink);
  transition: border-color var(--duration-fast) var(--ease-standard),
    box-shadow var(--duration-fast) var(--ease-standard);
}

.field__control::placeholder {
  font-size: var(--fs-body);
  color: var(--color-text-placeholder);
}

.field__control:hover {
  border-color: var(--color-gold-400);
}

.field__control[aria-invalid="true"] {
  border-color: var(--color-red-dot);
}

textarea.field__control {
  min-height: 101px;
  resize: vertical;
}

/* Native select keeps its own arrow off and uses the comp's chevron. */
select.field__control {
  appearance: none;
  padding-right: 44px;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='20' height='20' viewBox='0 0 20 20' fill='none'%3E%3Cpath d='M5 7.5l5 5 5-5' stroke='%236b7280' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 15px center;
}

/* A select showing its empty first option is showing a placeholder, so it
   takes the same muted colour as an input's ::placeholder — which a select
   cannot use, having no placeholder pseudo-element of its own. The real
   options would otherwise inherit that muted colour inside the open
   dropdown list, so they get the normal input colour pinned back. */
select.field__control:has(option[value=""]:checked) {
  color: var(--color-text-placeholder);
}

select.field__control option:not([value=""]) {
  color: var(--color-navy-ink);
}

/* Character allowance readout under a limited textarea. */
.field__counter {
  align-self: flex-end;
  font-size: var(--fs-caption);
  font-variant-numeric: tabular-nums;
  color: var(--color-text-placeholder);
}

.field__counter--near {
  color: var(--color-red-dot);
  font-weight: var(--fw-medium);
}

.field__error {
  font-size: var(--fs-body-sm);
  color: var(--color-red-dot);
}

.field__error:empty {
  display: none;
}

/* ---- Checkbox rows (consent statements, criteria list) ---- */
.check-row {
  display: flex;
  align-items: flex-start;
  gap: var(--space-md);
}

.check-row__box {
  appearance: none;
  flex-shrink: 0;
  width: 24px;
  height: 24px;
  margin: 3px 0 0;
  background: url('../assets/icons/icon-checkbox-unchecked.svg') center / contain no-repeat;
}

.check-row__box:checked {
  background-image: url('../assets/icons/icon-checkbox-checked.svg');
}

.check-row__label {
  font-size: var(--fs-body);
  line-height: 1.6;
  color: var(--color-text-body);
  cursor: pointer;
}

/* ---- Consent dialog ("Before we begin") ----
   Figma: Free evaluation / Main Modal Container, node 3021:5354. Header and
   footer stay put while the statement list scrolls, so the dialog fits any
   viewport without the actions moving out of reach. */
.consent-modal__panel {
  position: relative;
  gap: 0;
  padding: 0;
  max-height: min(883px, 90vh);
}

/* A real, non-scrolling bar at every breakpoint — not a floating icon over
   the content — so statement text (and, unlike before, the heading too)
   never runs underneath it regardless of screen size. */
.consent-modal__topbar {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  flex: 0 0 auto;
  height: 52px;
  padding-inline: var(--space-lg); /* 24px on desktop/tablet, 16px on
    mobile below — matches the popup's side padding at each breakpoint */
  background: var(--color-white);
  border-bottom: 1px solid #e6eaf0;
  box-shadow: var(--shadow-xs);
}

/* The single scroll container at every breakpoint: heading, description
   and statements all move together underneath the fixed topbar, above the
   fixed footer. Takes the panel's remaining flex space, capped by its
   max-height above. */
.consent-modal__scroll {
  display: flex;
  flex-direction: column;
  gap: var(--space-md); /* 16px between the heading block and the statements */
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
}

.consent-modal__head {
  display: flex;
  flex-direction: column;
  gap: var(--space-xs); /* 8px — same at every breakpoint */
  padding-block: var(--space-md); /* 16px — same at every breakpoint */
  padding-inline: var(--space-lg); /* 24px desktop/tablet, 16px mobile */
  background: var(--color-white);
}

.consent-modal__title {
  font-family: var(--font-display);
  font-size: 2.25rem;
  font-weight: var(--fw-semibold);
  line-height: 1.11;
  color: var(--color-dialog-heading);
}

.consent-modal__desc {
  max-width: none;
  font-size: var(--fs-body-sm);
  line-height: 1.45;
  color: var(--color-text-body);
}

.consent-modal__close {
  display: inline-flex;
  flex-shrink: 0;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  border-radius: 50%;
}

.consent-modal__close:hover {
  background: rgba(10, 29, 56, 0.06);
}

.consent-modal__body {
  flex: 0 0 auto;
  min-height: auto;
  overflow-y: visible;
  padding-block: 0 var(--space-md); /* bottom 16px — same at every breakpoint */
  padding-inline: var(--space-lg); /* 24px desktop/tablet, 16px mobile */
}

.consent-list {
  counter-reset: consent-item;
}

.consent-list__item {
  display: flex;
  align-items: flex-start;
  gap: var(--space-md);
  padding-block: var(--space-md); /* 16px — same at every breakpoint */
  border-bottom: 1px solid #e8e8e8;
  counter-increment: consent-item;
}

.consent-list__box {
  appearance: none;
  width: 24px;
  height: 24px;
  margin-top: 2px;
  background: url('../assets/icons/icon-checkbox-unchecked.svg') center / contain no-repeat;
}

.consent-list__box:checked {
  background-image: url('../assets/icons/icon-checkbox-checked.svg');
}

.consent-list__label {
  display: flex;
  flex-direction: column;
  gap: var(--space-xs);
  cursor: pointer;
}

.consent-list__title {
  font-size: var(--fs-body-lg);
  font-weight: var(--fw-semibold);
  color: var(--color-dialog-heading);
}

.consent-list__title::before {
  content: counter(consent-item) '. ';
}

@media (max-width: 639px) {
  .consent-list__title {
    font-size: var(--fs-body);
  }
}

.consent-list__text {
  font-size: var(--fs-body-sm);
  line-height: 1.45;
  color: var(--color-text-body);
}

.consent-modal__note {
  display: flex;
  align-items: flex-start;
  gap: var(--space-xs);
  max-width: none;
  padding-top: var(--space-lg);
  font-size: var(--fs-body-sm);
  line-height: 1.45;
  color: var(--color-text-body);
}

.consent-modal__note-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  width: 18px;
  height: 18px;
  margin-top: 2px;
  border: 1px solid currentColor;
  border-radius: 50%;
  font-size: 0.6875rem;
  font-style: italic;
  line-height: 1;
}

.consent-modal__footer {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: var(--space-lg);
  padding-block: var(--space-md); /* 16px — same at every breakpoint */
  padding-inline: var(--space-lg); /* 24px desktop/tablet, 16px mobile */
  border-top: 1px solid #d8d8d8;
  background: #fcfbf8;
}

/* ---- Acknowledgment progress ---- */
.consent-modal__progress {
  min-width: 0;
}

.consent-modal__progress-count {
  font-size: var(--fs-body-sm);
  font-weight: var(--fw-semibold);
  color: var(--color-dialog-heading);
}

.consent-modal__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-md);
}

.consent-modal__actions .btn {
  flex: 0 0 auto;
  height: 44px;
}

/* Disabled state (inert until every statement is ticked) comes from the
   shared .btn--primary[aria-disabled='true'] rule above — this element
   carries that class too. */
.consent-modal__begin {
  min-width: 200px;
}

@media (max-width: 639px) {
  .consent-modal__topbar,
  .consent-modal__head,
  .consent-modal__body,
  .consent-modal__footer {
    padding-inline: var(--space-md); /* 16px */
  }

  .consent-modal__footer {
    flex-direction: column;
    align-items: stretch;
    gap: var(--space-md); /* 16px */
  }

  .consent-modal__actions {
    flex-direction: column;
  }

  .consent-modal__actions .btn {
    /* flex-basis, not width — a bare 100% here would win over the 44px
       height rule once the parent is column-direction, since flex-basis
       overrides height on the main axis. width:100% + the parent's default
       align-items: stretch already makes these full-width; flex-basis
       stays auto so the explicit height is what sizes them. */
    flex: 0 0 auto;
    width: 100%;
  }
}
