/* ============================== COMPONENTS ============================== */

/* Buttons (btn.postcss:6-186) */
/* CD does NOT center universally (btn.postcss): text sits left; only
   btn--icon-only and btn--full-width are centered. Universal centering broke
   down on multiline labels in login gates (Item 2.21). */
/* NO gap and NO block padding on .btn itself (btn.postcss:6-13: px-4 only):
   .btn__text alone provides vertical space (py-2), and icon-left/right offsets
   alone provide icon spacing. Previously base padding + wrapper padding gave
   the same variant two different button heights depending on markup. */
.btn { display:inline-flex; align-items:center;
  min-height:var(--target-min); padding:0 var(--sp-4); border-radius:var(--radius-sm); border:var(--stroke-1) solid transparent;
  font:inherit; font-weight:var(--fw-regular); font-size:var(--text-base); cursor:pointer; text-decoration:none;
  transition:background var(--duration-fast),color var(--duration-fast),border-color var(--duration-fast); line-height:var(--line-5); }
.btn--icon-only, .btn--full-width { justify-content:center; }
.btn__text          { padding-block:var(--sp-2); text-align:left; overflow-wrap:anywhere; }
.btn__text-centered { padding-block:var(--sp-2); text-align:center; width:100%; overflow-wrap:anywhere; }
.btn:where(:hover,:active) { text-decoration:none; }
.btn--outline { background:transparent; border-color:var(--color-primary-600); color:var(--color-primary-600); }
.btn--outline:where(:hover,:active) { border-color:var(--color-primary-700); color:var(--color-primary-700); }
.btn--outline:active { background:var(--color-primary-50); }
.btn--filled { background:var(--color-secondary-500); border-color:var(--color-secondary-500); color:var(--color-text-negative); font-weight:var(--fw-bold); }
.btn--filled:hover { color:var(--color-secondary-100); }
.btn--filled:active { background:var(--color-secondary-600); border-color:var(--color-secondary-600); color:var(--color-text-negative); }
.btn--bare { background:none; border:0; color:var(--color-secondary-800); padding-left:var(--sp-2); padding-right:var(--sp-2); }   /* border:0 like the other borderless variants (CD btn--bare has no border) */
.btn--bare:where(:hover,:active) { color:var(--color-primary-600); }
.btn--bare:active { color:var(--color-primary-700); }
/* Negative variants (on dark backgrounds, e.g. top bar/footer): CD btn.postcss:78-109 */
.btn--outline-negative { background:var(--color-secondary-500); border-color:var(--color-text-negative); color:var(--color-text-negative); font-weight:var(--fw-bold); }
.btn--outline-negative:hover { background:var(--color-secondary-500); border-color:var(--color-secondary-100); color:var(--color-secondary-100); }
.btn--outline-negative:active { background:var(--color-secondary-600); border-color:var(--color-text-negative); color:var(--color-text-negative); }
.btn--bare-negative { background:none; border:0; color:var(--color-text-negative); }   /* keeps CD's px-4; only .btn--bare has px-2 (btn.postcss:28,101-109) */
.btn--bare-negative:hover { background:none; color:var(--color-secondary-100); }
.btn--bare-negative:active { color:var(--color-secondary-50); }
/* Link variants keep the full CD height ramp (btn.postcss:112-117 applies to
   EVERY variant); min-height:0 compressed the touch target to ~27px. CD padding pr-2 pl-0. */
.btn--link-negative { background:none; border:0; color:var(--color-text-negative); text-decoration:underline; text-underline-offset:var(--stroke-2); padding:0 var(--sp-2) 0 0; }
.btn--link-negative:hover { color:var(--color-secondary-100); }
.btn--link-negative:active { color:var(--color-secondary-50); }
.btn--link { background:none; border:0; color:var(--color-primary-600); padding:0 var(--sp-2) 0 0; }
.btn--link:hover { color:var(--color-primary-700); }   /* CD btn.postcss:38-41: hover darkens (600→700), never underlines */
.btn--link:active { color:var(--color-primary-800); }
.btn--sm { min-height:var(--control-size-compact); font-size:var(--text-sm); line-height:var(--line-4); }
/* btn.postcss:171-191 — icon-left nudges the icon; btn--back floats the button
   out of the text flow. `.back-link-row` gives that float something to clear. */
.btn--icon-left .btn__icon { position:relative; right:.1em; margin-right:.2em; }
.btn--icon-right { flex-direction:row-reverse; }
.btn--icon-right .btn__icon { position:relative; left:.1em; margin-left:.2em; }
.btn--back { float:left; margin-top:.4em; }
@media (min-width:1024px){ .btn--back { margin-top:var(--sp-1); } }
.back-link-row { display:flow-root; padding-bottom:var(--sp-4); }
.btn--lg { min-height:var(--sp-12); font-size:var(--text-lg); line-height:var(--line-6); }
/* CD line-height ramp (btn.postcss:112-129): base leading-5 lg:leading-6, sm
   leading-4 lg:leading-5, lg leading-6; fixed rem steps, jump at lg. Applies
   only to multiline labels; min-height governs single-line labels. */
@media (min-width:1024px){ .btn, .btn--base { line-height:var(--line-6); } .btn--sm { line-height:var(--line-5); } }
@media (min-width:1280px){ .btn, .btn--base { min-height:var(--control-size-md); } .btn--sm { min-height:var(--sp-10); } .btn--lg { min-height:var(--control-size-lg); } }
@media (min-width:1920px){ .btn, .btn--base { min-height:var(--control-size-lg); } .btn--sm { min-height:var(--control-size-sm); } .btn--lg { min-height:var(--sp-14); } }
/* The back button carries the 44px touch floor instead of following the
   `btn--sm` ramp (40px at 1440). It is the one control in the detail bar a
   reader aims at, and the tenant portal already floors it there on the same
   WCAG 2.5.5 reasoning — so the two bars now measure the same height. Scoped to
   `.btn--back`; `.btn--sm` keeps CD's ramp everywhere else. Declared after the
   ramp's media queries, which is what lets it win at every width. */
.btn.btn--back { min-height:var(--target-min); }
/* The compact CD button remains on fine desktop pointers. Up through tablet
   and on coarse pointers, the portal brief's 44px target size applies. */
@media (max-width:1023.98px), (pointer:coarse), (hover:none){
  .btn--sm { min-height:var(--target-min); }
}
/* Icons grow with the button, intentionally, at higher specificity (0,2,0)
   than any .icon--* size class (0,1,0). Thus `icon('X','icon--base')` INSIDE a
   button has no effect; a custom size needs a rule in button context (see
   .btn .catbar__chev). A square 1.4em box replaces CD's h-full because mask
   technique needs an intrinsic box. transition-transform follows CD
   (btn.postcss:147-152); additional color transitions on .btn remain as
   deliberate polish. */
.btn .icon, .btn__icon { width:1.4em; height:1.4em; flex:none; transition:transform var(--duration); }
/* As in CD's Btn.vue, the icon comes first in the DOM for both variants;
   `.btn--icon-right` therefore reverses visual order with row-reverse. */
/* CD w-8 for link icons (btn.postcss:43-47), larger than the 1.4em base. */
.btn--link .btn__icon, .btn--link-negative .btn__icon { width:var(--sp-8); }
.btn--full-width { width:100%; }
.btn--icon-only { padding-left:.625em; padding-right:.625em; }   /* CD px-[0.625em], scales with type */
/* Access card (C.accessCard): the button sits at the top and provides spacing
   to explanatory text below. Full width gives the four states (open, sign in,
   external, disabled) the same silhouette so switching does not make the card jump. */
.access-card__action { margin:0 0 var(--sp-3); }
/* Session context, access notice and step list are separate paragraphs with
   m-0; without this rule they touched and read as one sentence. */
.access-card p + p, .access-card p + ul { margin-top:var(--sp-2); }
.access-card__action > .btn { width:100%; justify-content:space-between; text-align:left; }
.access-card__action > .btn.btn--icon-left { justify-content:flex-start; gap:var(--sp-2); }

/* State contract. Native/ARIA attributes are the preferred API; BEM aliases
   support non-native hosts. Focus keeps CDs default colours and the global
   purple ring, with the lighter CD ring on negative chrome. */
.btn--outline:focus-visible { color:var(--color-primary-600); border-color:var(--color-primary-600); }
.btn--filled:focus-visible { color:var(--color-text-negative); }
.btn:where(.btn--outline-negative,.btn--bare-negative,.btn--link-negative):focus-visible {
  color:var(--color-text-negative); outline-color:var(--color-focus-ring-negative); }
.btn--outline-negative:focus-visible { border-color:var(--color-text-negative); }

.btn:is(.btn--empty,[data-empty="true"]) {
  color:var(--color-text-muted); background:var(--color-secondary-50); border-color:var(--color-secondary-200); }
.btn:is(.btn--loading,[aria-busy="true"]) {
  cursor:progress; pointer-events:none; box-shadow:var(--state-ring-primary-soft); }
.btn:is(.btn--error,[aria-invalid="true"]) {
  color:var(--color-error-text); border-color:var(--color-error); }
.btn--filled:is(.btn--error,[aria-invalid="true"]) { background:var(--color-error-bg-subtle); }
.btn:where(.btn--outline-negative,.btn--bare-negative,.btn--link-negative):is(.btn--error,[aria-invalid="true"]) {
  color:var(--color-error-200); border-color:var(--color-error-300); }
/* Unavailable targets also render as <span aria-disabled>. The shared recipe
   matches CD btn.postcss:21-24, so native state, ARIA attribute and BEM modifier
   receive the same presentation. */
.btn:is(:disabled,[aria-disabled="true"],.btn--disabled) {
  cursor:not-allowed; pointer-events:none; opacity:1; text-decoration:none; }
.btn--outline:is(:disabled,[aria-disabled="true"],.btn--disabled) {
  color:var(--color-secondary-300); border-color:var(--color-secondary-200); background:transparent; }
.btn--filled:is(:disabled,[aria-disabled="true"],.btn--disabled) {
  color:var(--color-text-negative); border-color:var(--color-secondary-200); background:var(--color-secondary-200); }
.btn:where(.btn--bare,.btn--link):is(:disabled,[aria-disabled="true"],.btn--disabled) {
  color:var(--color-secondary-300); background:transparent; }
.btn:where(.btn--outline-negative,.btn--bare-negative,.btn--link-negative):is(:disabled,[aria-disabled="true"],.btn--disabled) {
  color:var(--color-secondary-200); background:transparent; }
.btn--outline-negative:is(:disabled,[aria-disabled="true"],.btn--disabled) {
  border-color:var(--color-secondary-300); }

/* State carrier for bespoke controls whose shape belongs to another block
   (viewer arrows, tree rows, media tiles). Their component keeps default and
   hover visuals; this one low-specificity contract supplies the shared target,
   active, focus, disabled, loading, error and empty behavior. */
.interactive-control { min-width:var(--target-min); min-height:var(--target-min); }
.interactive-control:active { filter:brightness(.85); }
.interactive-control[aria-invalid="true"] { outline:var(--stroke-2) solid var(--color-error); }
.interactive-control:focus-visible { outline:var(--stroke-2) solid var(--color-focus-ring); outline-offset:var(--stroke-2); }
.interactive-control--negative:focus-visible { outline-color:var(--color-focus-ring-negative); }
.interactive-control:is(:disabled,[aria-disabled="true"],.interactive-control--disabled) {
  cursor:not-allowed; opacity:.55; pointer-events:none; }
.interactive-control:is([aria-busy="true"],.interactive-control--loading) {
  cursor:progress; opacity:.7; pointer-events:none; }
.interactive-control:is([data-empty="true"],.interactive-control--empty) {
  cursor:default; opacity:.55; }
.download-item[aria-disabled="true"] { cursor:not-allowed; opacity:.65; }
.download-item[aria-disabled="true"]:hover { background:transparent; }
.download-item[aria-disabled="true"]:hover .download-item__title { color:inherit; text-decoration:none; }

