/* ============================================================
   LIFE SUPPORT SERVICES — component styles
   Ported from the design-system React primitives
   (Button, Badge, Card, Input, Select, Checkbox, Alert).
   ============================================================ */

/* ---------- Button ---------- */
.lss-btn{
  --_bg:var(--action); --_bgh:var(--action-hover); --_bga:var(--action-active);
  --_fg:var(--action-text); --_bd:transparent;
  display:inline-flex; align-items:center; justify-content:center; gap:8px;
  font-family:var(--font-sans); font-weight:var(--fw-semibold); line-height:1;
  border:1px solid var(--_bd); border-radius:var(--radius-md);
  background:var(--_bg); color:var(--_fg); cursor:pointer;
  text-decoration:none; white-space:nowrap; user-select:none;
  transition:background var(--dur-fast) var(--ease-standard),
             border-color var(--dur-fast) var(--ease-standard),
             box-shadow var(--dur-fast) var(--ease-standard),
             transform var(--dur-fast) var(--ease-standard);
}
.lss-btn:hover{ background:var(--_bgh); text-decoration:none; }
.lss-btn:active{ background:var(--_bga); transform:translateY(1px); }
.lss-btn:focus-visible{ outline:none; box-shadow:var(--shadow-focus); }
.lss-btn[disabled],.lss-btn[aria-disabled="true"]{ opacity:.45; cursor:not-allowed; transform:none; pointer-events:none; }

.lss-btn--sm{ height:34px; padding:0 14px; font-size:13px; }
.lss-btn--md{ height:42px; padding:0 20px; font-size:15px; }
.lss-btn--lg{ height:52px; padding:0 28px; font-size:17px; }
/* BLOCK_BTN_WRAP_2026-09-20 — a block button's width comes from its
   container, so the nowrap it inherits from .lss-btn has nothing to gain and
   one thing to lose: a label wider than the button does not shrink the label,
   it sends it out through the side. Found with "Sign in with Face ID or Touch
   ID", which clears the button's right edge at 320px and touches it at 390.

   Only affects labels that do not fit, which today overflow instead — so no
   existing button changes height. */
.lss-btn--block{ width:100%; white-space:normal; }

/* @dead audit-2026-07-17 — .lss-btn--secondary has zero runtime references. Kept commented pending 30-day soak.
.lss-btn--secondary{ --_bg:var(--action-navy); --_bgh:var(--action-navy-hover); --_bga:var(--action-navy-active); --_fg:#fff; }
.lss-btn--secondary:focus-visible{ box-shadow:var(--shadow-focus-navy); }
*/
.lss-btn--outline{ --_bg:transparent; --_bgh:var(--lss-navy-50); --_bga:var(--lss-navy-100); --_fg:var(--lss-navy-700); --_bd:var(--lss-navy-300); }
.lss-btn--ghost{ --_bg:transparent; --_bgh:var(--lss-ink-100); --_bga:var(--lss-ink-200); --_fg:var(--lss-navy-700); }
.lss-btn--danger{ --_bg:var(--lss-emergency); --_bgh:#b81f1f; --_bga:#9c1a1a; --_fg:#fff; }
.lss-btn__icon{ display:inline-flex; width:1.15em; height:1.15em; }
.lss-btn__icon svg, .lss-btn__icon img{ width:100%; height:100%; display:block; }

/* ---------- Badge ---------- */
.lss-badge{
  display:inline-flex; align-items:center; gap:6px;
  font-family:var(--font-sans); font-weight:var(--fw-bold);
  font-size:12px; line-height:1; letter-spacing:.02em;
  padding:5px 10px; border-radius:var(--radius-pill);
  background:var(--lss-ink-100); color:var(--lss-ink-700);
  white-space:nowrap;
}
.lss-badge--solid{ color:#fff; }
.lss-badge__dot{ width:7px; height:7px; border-radius:50%; background:currentColor; }
.lss-badge--emergency{ background:var(--lss-emergency-bg); color:var(--lss-emergency); }
.lss-badge--success{ background:var(--lss-success-bg); color:var(--lss-success); }
.lss-badge--warning{ background:var(--lss-warning-bg); color:#9a6406; }
/* @dead audit-2026-07-17 — .lss-badge--info and .lss-badge--navy zero refs (parent .lss-badge widely used).
.lss-badge--info{ background:var(--lss-info-bg); color:var(--lss-info); }
.lss-badge--navy{ background:var(--lss-navy-100); color:var(--lss-navy-700); }
*/
.lss-badge--accent{ background:var(--lss-orange-100); color:var(--lss-orange-700); }
.lss-badge--emergency.lss-badge--solid{ background:var(--lss-emergency); color:#fff; }
.lss-badge--success.lss-badge--solid{ background:var(--lss-success); color:#fff; }
.lss-badge--warning.lss-badge--solid{ background:var(--lss-warning); color:#3a2600; }
.lss-badge--info.lss-badge--solid{ background:var(--lss-info); color:#fff; }
.lss-badge--navy.lss-badge--solid{ background:var(--lss-navy-700); color:#fff; }
.lss-badge--accent.lss-badge--solid{ background:var(--lss-orange-500); color:#fff; }

/* ---------- Card ---------- */
.lss-card{
  background:var(--surface-card); border:1px solid var(--border-subtle);
  border-radius:var(--radius-lg); box-shadow:var(--shadow-sm);
  overflow:hidden; transition:box-shadow var(--dur-base) var(--ease-standard),
             transform var(--dur-base) var(--ease-standard), border-color var(--dur-base) var(--ease-standard);
}
.lss-card--accent{ border-top:3px solid var(--lss-orange-500); }
.lss-card__body{ padding:var(--space-7); }

/* ---------- Input ---------- */
.lss-field{ display:flex; flex-direction:column; gap:6px; font-family:var(--font-sans); }
.lss-field__label{ font-size:13px; font-weight:var(--fw-semibold); color:var(--text-strong); display:flex; gap:5px; align-items:center; }
.lss-field__req{ color:var(--lss-emergency); }
.lss-field__hint{ font-size:12px; color:var(--text-muted); }
/* @dead audit-2026-07-17 — .lss-field__hint--error zero refs. Kept commented pending 30-day soak. */
/* .lss-field__hint--error{ color:var(--lss-emergency); } */
.lss-input{
  display:flex; align-items:center; gap:9px;
  background:#fff; border:1px solid var(--border-default); border-radius:var(--radius-md);
  padding:0 12px; height:42px; transition:border-color var(--dur-fast) var(--ease-standard), box-shadow var(--dur-fast) var(--ease-standard);
}
.lss-input:focus-within{ border-color:var(--lss-orange-400); box-shadow:var(--shadow-focus); }
/* @dead audit-2026-07-17 — .lss-input--error zero refs. Kept commented pending 30-day soak. */
/* .lss-input--error{ border-color:var(--lss-emergency); } */
.lss-input__icon{ display:inline-flex; width:18px; height:18px; color:var(--text-faint); flex:none; }
.lss-input__icon svg, .lss-input__icon img{ width:100%; height:100%; }
.lss-input input{
  border:0; outline:0; background:transparent; width:100%; height:100%;
  font-family:var(--font-sans); font-size:15px; color:var(--text-strong);
  /* SAFARI_CARET_2026-08-08 — the caret rendered BELOW the box in Safari.
     The input sets height:100% (so the whole 42px wrapper is clickable)
     but declared no line-height, so it inherited the document's ~1.5.
     Chrome ignores line-height for the caret in a fixed-height input;
     Safari does not — it lays the text line out at the inherited height
     inside a 42px box and the caret is drawn at the bottom of that line,
     visibly under the text. `normal` ties the line box to the font rather
     than to whatever the page inherited. Applies to select/textarea too,
     which share the same wrapper and the same inheritance. */
  line-height:normal;
}
.lss-input select, .lss-input textarea{ line-height:normal; }
.lss-input input::placeholder{ color:var(--text-faint); }
/* 2026-07-14: selects + textareas inside an .lss-input wrapper kept their
   own native border/focus ring ON TOP of the wrapper's :focus-within ring
   — the "double outline" seen on repeater dropdowns, comment boxes, and
   anywhere else the wrapper pattern is used. Reset them like inputs; the
   wrapper alone shows the focus state (keyboard visibility preserved). */
.lss-input select,
.lss-input textarea{
  border:0; outline:0; background:transparent; width:100%;
  font-family:var(--font-sans); font-size:15px; color:var(--text-strong);
}
.lss-input select{ height:100%; cursor:pointer; }
.lss-input textarea::placeholder{ color:var(--text-faint); }
.lss-input--disabled{ background:var(--lss-ink-100); cursor:not-allowed; }
.lss-input--disabled input{ cursor:not-allowed; }

/* ============================================================
   Textarea + select inside .lss-input — global typography fix.
   The wrapper was originally designed for one <input>, so without
   these rules textareas fall through to platform-native styling
   (beige monospace on macOS) and selects show platform-native
   chevrons that don't match the input look. Applies portal-wide.
   ============================================================ */
.lss-input { box-sizing: border-box; }
.lss-input:has(textarea) {
  height: auto;
  min-height: 80px;
  padding: 8px 12px;
  align-items: stretch;
}
@supports not (selector(:has(*))) {
  /* Without :has() the wrapper stays 42 px tall — give the textarea
     a little breathing room so it doesn't overflow the parent.    */
  .lss-input textarea { margin: 6px 0; }
}
.lss-input textarea {
  width: 100%;
  border: 0;
  outline: 0;
  background: transparent;
  font-family: var(--font-sans);
  font-size: 14.5px;
  color: var(--text-strong);
  line-height: 1.5;
  resize: vertical;
  min-height: 60px;
  padding: 0;
}
.lss-input textarea::placeholder{ color: var(--text-faint); }
.lss-input select {
  width: 100%;
  border: 0;
  outline: 0;
  background: transparent;
  font-family: var(--font-sans);
  font-size: 14.5px;
  color: var(--text-strong);
  appearance: none;
  -webkit-appearance: none;
  /* Leave room on the right for the brand-painted chevron. */
  padding: 0 30px 0 0;
  height: 100%;
  cursor: pointer;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='14' height='10' viewBox='0 0 14 10'><polyline points='1,2 7,8 13,2' fill='none' stroke='%23232160' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/></svg>");
  background-repeat: no-repeat;
  background-position: right 4px center;
  background-size: 14px 10px;
  text-overflow: ellipsis;
}
.lss-input select::-ms-expand{ display: none; }
.lss-input select option { font-family: var(--font-sans); }

/* DOUBLE_BORDER_FIX_2026-07-19: some pages emit `<select class="lss-input">`
   or `<input class="lss-input">` directly (form-builder dropdown/radio
   options render, a handful of admin pages) instead of the wrapper
   pattern <div class="lss-input"><select>. The wrapper styles above
   assume .lss-input is on a container; when it's applied directly to
   a <select>, the browser's NATIVE select chrome (chevron area on
   Chrome/Safari, dropdown box on Firefox) sits INSIDE our custom
   border and reads as a second box within the first. Same shape can
   surface on bare <input class="lss-input"> because the input keeps
   its default UA appearance. Reset appearance + repaint the chevron
   so a "one-class" select matches the wrapped-select look. */
select.lss-input,
input.lss-input,
textarea.lss-input {
  appearance: none;
  -webkit-appearance: none;
  -moz-appearance: none;
  font: inherit;
  font-size: 15px;
  color: var(--text-strong);
}
/* TEXTAREA_LSS_INPUT_2026-08-06 (Andrew's phone screenshot: "not enough room
   in the body to reasonably see a full paragraph" — the Message Public Users
   modal). .lss-input carries height:42px + display:flex because it doubles
   as the one-line input wrapper. Put directly on a <textarea> (six pages do:
   public-users, public-user, my-account, request-account, migrations,
   includes/forms), that fixed height crushed rows="7" down to ONE visible
   line. Textareas opt back into their natural multi-line box: auto height
   with a paragraph-sized floor, top-aligned padding, vertical resize. */
textarea.lss-input {
  height: auto;
  min-height: 120px;
  padding: 10px 12px;
  line-height: 1.5;
  resize: vertical;
  display: block;
  width: 100%;
}

select.lss-input {
  padding-right: 32px;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='14' height='10' viewBox='0 0 14 10'><polyline points='1,2 7,8 13,2' fill='none' stroke='%23232160' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/></svg>");
  background-repeat: no-repeat;
  background-position: right 10px center;
  background-size: 12px 9px;
  cursor: pointer;
  text-overflow: ellipsis;
}
select.lss-input::-ms-expand { display: none; }
select.lss-input:focus-within,
select.lss-input:focus {
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='14' height='10' viewBox='0 0 14 10'><polyline points='1,8 7,2 13,8' fill='none' stroke='%23ef6a2e' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/></svg>");
}
.lss-input:has(select){ height: 42px; }
/* Make the chevron flip when the wrapper is focused — cheap signal that
   the field is interactive. Works because select is the only child that
   matters; chevron lives on the select. */
.lss-input:focus-within select {
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='14' height='10' viewBox='0 0 14 10'><polyline points='1,8 7,2 13,8' fill='none' stroke='%23ef6a2e' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/></svg>");
}

/* ---------- Select ---------- */
/* @dead audit-2026-07-17 — .lss-select-wrap + .lss-select-wrap__label have zero
   runtime references. The sibling .lss-select module below IS used and stays live.
   Kept commented pending 30-day soak.
.lss-select-wrap{ display:flex; flex-direction:column; gap:6px; font-family:var(--font-sans); }
.lss-select-wrap__label{ font-size:13px; font-weight:var(--fw-semibold); color:var(--text-strong); }
*/
.lss-select{ position:relative; display:flex; align-items:center; }
.lss-select select{
  appearance:none; -webkit-appearance:none;
  width:100%; height:42px; padding:0 38px 0 12px;
  font-family:var(--font-sans); font-size:15px; color:var(--text-strong);
  background:#fff; border:1px solid var(--border-default); border-radius:var(--radius-md);
  cursor:pointer; transition:border-color var(--dur-fast) var(--ease-standard), box-shadow var(--dur-fast) var(--ease-standard);
}
.lss-select select:focus{ outline:0; border-color:var(--lss-orange-400); box-shadow:var(--shadow-focus); }
.lss-select__chevron{ position:absolute; right:13px; pointer-events:none; width:14px; height:14px; color:var(--text-muted); }
.lss-select__chevron svg{ width:100%; height:100%; }

/* ---------- Checkbox ---------- */
.lss-check{ display:inline-flex; align-items:flex-start; gap:10px; font-family:var(--font-sans); cursor:pointer; user-select:none; }
.lss-check input{ position:absolute; opacity:0; width:0; height:0; }
.lss-check__box{
  flex:none; width:20px; height:20px; margin-top:1px;
  border:1.5px solid var(--border-strong); background:#fff;
  border-radius:var(--radius-xs);
  display:flex; align-items:center; justify-content:center;
  transition:background var(--dur-fast) var(--ease-standard), border-color var(--dur-fast) var(--ease-standard);
}
.lss-check__box svg{ width:13px; height:13px; color:#fff; opacity:0; transform:scale(.6); transition:opacity var(--dur-fast), transform var(--dur-fast) var(--ease-out); }
.lss-check input:checked + .lss-check__box{ background:var(--lss-orange-500); border-color:var(--lss-orange-500); }
.lss-check input:checked + .lss-check__box svg{ opacity:1; transform:scale(1); }
.lss-check input:focus-visible + .lss-check__box{ box-shadow:var(--shadow-focus); }
.lss-check__label{ font-size:14px; color:var(--text-body); line-height:1.4; }

/* ---------- Alert ---------- */
.lss-alert{
  display:flex; gap:12px; align-items:flex-start;
  font-family:var(--font-sans);
  padding:14px 16px; border-radius:var(--radius-md);
  border:1px solid var(--border-subtle); background:#fff;
  border-left:3px solid var(--lss-navy-500);
}
.lss-alert__icon{ flex:none; width:20px; height:20px; margin-top:1px; color:var(--lss-navy-600); }
.lss-alert__icon svg{ width:100%; height:100%; }
.lss-alert__body{ flex:1; min-width:0; }
.lss-alert__title{ font-size:14px; font-weight:var(--fw-bold); color:var(--text-strong); margin:0 0 2px; }
.lss-alert__msg{ font-size:13px; color:var(--text-muted); margin:0; line-height:1.5; }
.lss-alert__close{ flex:none; background:none; border:0; cursor:pointer; color:var(--text-faint); padding:2px; line-height:0; border-radius:var(--radius-xs); }
.lss-alert__close:hover{ color:var(--text-body); background:var(--lss-ink-100); }
.lss-alert__close svg{ width:16px; height:16px; }
.lss-alert--emergency{ border-left-color:var(--lss-emergency); background:var(--lss-emergency-bg); }
.lss-alert--emergency .lss-alert__icon{ color:var(--lss-emergency); }
.lss-alert--success{ border-left-color:var(--lss-success); background:var(--lss-success-bg); }
.lss-alert--success .lss-alert__icon{ color:var(--lss-success); }
.lss-alert--warning{ border-left-color:var(--lss-warning); background:var(--lss-warning-bg); }
.lss-alert--warning .lss-alert__icon{ color:#9a6406; }
.lss-alert--info{ border-left-color:var(--lss-info); background:var(--lss-info-bg); }
.lss-alert--info .lss-alert__icon{ color:var(--lss-info); }

/* ---------- Banner (CSS_GAPS_2026-09-19) ----------
   Nine call sites have used .lss-banner since long before today and nothing
   ever defined it, so every one of them rendered as unstyled body text — including
   the error messages on request-account.php and claim-account.php, which are
   public-facing. Written now rather than stripping the class, because the
   markup is right: a one-element status line IS a thing this app needs, and
   .lss-alert is the three-part version (icon / title / message) that these
   call sites do not use.

   Deliberately the same visual language as .lss-alert above — same radius,
   same 3px left rule, same tint tokens — so the two read as one family. */
.lss-banner{
  display:block; font-family:var(--font-sans);
  font-size:13.5px; line-height:1.5; color:var(--text-strong);
  padding:12px 14px; border-radius:var(--radius-md);
  border:1px solid var(--border-subtle); background:#fff;
  border-left:3px solid var(--lss-navy-500);
}
.lss-banner--success{ border-left-color:var(--lss-success);   background:var(--lss-success-bg); }
.lss-banner--warning{ border-left-color:var(--lss-warning);   background:var(--lss-warning-bg); }
.lss-banner--emergency{ border-left-color:var(--lss-emergency); background:var(--lss-emergency-bg); }

/* ---------- PHP-app additions ---------- */
/* Sidebar items are links in the PHP build */
a.psb__item{ text-decoration:none; }
a.psb__item:hover{ text-decoration:none; }
a.psb__user{ text-decoration:none; }
/* @dead audit-2026-07-17 — .lss-btn--asform zero runtime references. Kept commented pending 30-day soak. */
/* .lss-btn--asform{ display:inline-flex; } */
form.inline{ display:inline-flex; margin:0; }
.toast-host .lss-alert{ box-shadow:var(--shadow-lg); }

/* ==============================================================
   Mobile defaults (≤480px) — applied portal-wide. Companion to the
   ≤820px rules in portal.css; this tier targets phone-only fixes
   that surfaced in the 2026-06-15 sweep:
     - tap-target floor for small buttons (was 34 px, below WCAG 44)
     - images / SVGs / videos never bleed past their parent
     - flex/grid children allowed to shrink (min-width: 0)
   (Input 16-px font-size is already handled in portal.css ≤820px.)
   Desktop is unaffected — all rules sit inside a media query.
   ============================================================== */
@media (max-width: 480px) {
  /* Buttons: bump small-size to a real tap target. The padding
     stays the same; only height + font-size change so labels
     stay readable inside the bigger target. */
  .lss-btn--sm { min-height: 40px; height: auto; padding: 8px 14px; font-size: 14px; }
  .lss-btn--md { min-height: 44px; height: auto; padding: 10px 18px; }
  .lss-btn--lg { min-height: 50px; height: auto; padding: 12px 24px; }

  /* Media defaults — never bleed past parent. Saves repeating
     `max-width:100%; height:auto` everywhere in templates. The
     :not() guard keeps button icons at their authored em-size. */
  img, video, iframe, canvas {
    max-width: 100%;
    height: auto;
  }
  svg:not(.lss-btn__icon svg):not(.lss-input__icon svg) {
    max-width: 100%;
  }

  /* Allow flex/grid children to shrink below intrinsic content size.
     Common cause of horizontal-scroll bugs on mobile. */
  .lss-form__field, .lss-form__grid > *,
  .ptb > *, .pmodal__head > *, .pdrawer__head > * { min-width: 0; }
}
