/* ==========================================================================
   Long Life Health Care — storefront integration layer
   --------------------------------------------------------------------------
   storefront.css is the design template exactly as it was drawn. This file is
   everything a running application needs and a static template never has:
   flash messages, model-state validation, missing media, disabled controls,
   and the small set of named utilities the views use instead of a style
   attribute.

   Nothing here restates a colour literal. The :root block in storefront.css
   remains the single place a rebrand happens.
   ========================================================================== */

/* -- flash and inline messages -------------------------------------------- */
.alert {
  display: flex;
  align-items: flex-start;
  gap: .6rem;
  padding: .85rem 1.05rem;
  border: var(--line);
  border-left: 3px solid var(--ink-faint);
  border-radius: var(--radius);
  background: var(--surface);
  font-size: .92rem;
  margin-bottom: var(--gap-sm);
}
.alert p:last-child { margin-bottom: 0; }
.alert--ok    { border-left-color: var(--leaf);  background: #edf4ea; }
.alert--warn  { border-left-color: var(--gold);  background: var(--gold-wash); }
.alert--error { border-left-color: var(--clay);  background: #f9eceb; }
.alert--info  { border-left-color: var(--brand); background: #eef3fb; }
.alert-mark { flex-shrink: 0; margin-top: .15rem; }

/* A validation summary with nothing to say still renders its wrapper. Hiding
   it here rather than in each view keeps a stray empty box off the page. */
.validation-summary-valid { display: none; }
.validation-summary-errors ul { margin: 0; padding-left: 1.1rem; }
.validation-summary-errors li { font-size: .9rem; }

.field-error,
.field-validation-error {
  display: block;
  font-size: .8rem;
  color: var(--clay);
  margin-top: .3rem;
}
.input.input-validation-error,
.select.input-validation-error,
.textarea.input-validation-error { border-color: var(--clay); }

/* -- controls the template did not draw ----------------------------------- */
.btn:disabled,
.btn[aria-disabled="true"] {
  opacity: .5;
  cursor: not-allowed;
  pointer-events: none;
}
.btn--danger { background: var(--clay); color: #fff; }
.btn--danger:hover { background: #8e2f27; }
.btn--link {
  background: none; border-color: transparent; color: var(--brand);
  padding-inline: .35rem; text-decoration: underline; font-weight: 500;
}
.btn--link:hover { background: none; color: var(--brand-deep); }
.qty button:disabled { opacity: .35; cursor: not-allowed; }

/* A radio card: choose an address, a variant, a payment method. It shares its
   shape with .pay-option so the two cannot drift apart. */
.choice {
  display: flex; gap: .8rem; align-items: flex-start;
  border: 1px solid var(--mist-deep); border-radius: var(--radius);
  padding: .85rem 1rem; margin-bottom: .55rem; cursor: pointer;
}
.choice:hover { border-color: var(--brand); }
.choice:has(input:checked) { border-color: var(--brand); background: #f7f9fd; }
.choice:has(input:disabled) { opacity: .55; cursor: not-allowed; }
.choice input { accent-color: var(--brand); margin-top: .3rem; flex-shrink: 0; }
.choice-body { flex: 1; min-width: 0; }
.choice strong { display: block; font-size: .95rem; }
.choice .note { display: block; font-size: .84rem; color: var(--ink-soft); }

fieldset { border: 0; margin: 0; padding: 0; min-width: 0; }
legend { padding: 0; }
.option-set legend {
  display: block; font-size: .82rem; font-weight: 600; margin-bottom: .45rem;
}

/* A swatch that is a real radio button. The template drew these as buttons whose
   state lived in JavaScript; wrapping the input means the choice posts with the
   form whether or not the script ran, and the keyboard gets arrow-key selection
   for free. :has() paints the chosen one, and storefront.js sets the same class
   for browsers that do not support it. */
.swatch input[type="radio"] { position: absolute; width: 1px; height: 1px; opacity: 0; }
.swatch:has(input:checked), .swatch.is-on { border-color: var(--brand); background: #eef1e9; font-weight: 600; }
.swatch:has(input:focus-visible) { outline: 2px solid var(--gold); outline-offset: 2px; }
.swatch:has(input:disabled) { opacity: .5; cursor: not-allowed; text-decoration: line-through; }

/* -- category tiles -------------------------------------------------------- */
/* The template drew exactly six categories and fixed the grid at six columns. A
   real catalogue has as many as it has, and six columns with four categories in
   them leaves two empty tracks and four tiles too narrow to read. auto-fit keeps
   the row full at any count, at every width. */
.cat-grid { grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); }

/* -- the category facet ---------------------------------------------------- */
/* Links, not checkboxes: one category at a time is what the query supports, and
   a checkbox that behaves like a radio is a control that lies about what it does.
   They borrow .check so the rail reads as one list either way. */
.filter-body a.check { color: inherit; padding-block: .1rem; }
.filter-body a.check:hover { color: var(--brand); }
.filter-body a.check[aria-current="page"] { color: var(--brand); font-weight: 600; }
.facet-thumb {
  width: 22px; height: 22px; border-radius: 50%;
  object-fit: cover; background: #eef1e9; flex-shrink: 0;
}

/* The chip's dismiss control is a link here, because removing a filter is a
   navigation to a narrower URL rather than a script that mutates this page. */
.chip a { color: var(--ink-faint); line-height: 1; text-decoration: none; }
.chip a:hover { color: var(--clay); }

/* -- pill filters (order status, ticket status) --------------------------- */
.pills { display: flex; flex-wrap: wrap; gap: .35rem; margin-bottom: var(--gap); }
.pill {
  display: inline-flex; align-items: center; gap: .35rem;
  border: 1px solid var(--mist-deep); background: var(--surface);
  border-radius: 999px; padding: .3rem .8rem; font-size: .85rem;
}
.pill:hover { border-color: var(--brand); }
.pill[aria-current="page"] {
  background: var(--brand); border-color: var(--brand); color: #fff; font-weight: 600;
}

/* -- the product card's image frame --------------------------------------- */
/* storefront.css draws .card-media as `aspect-ratio: 1 / 1` with an image at
   `height: 100%`, and in the template the <img> is a direct child of it. The
   application wraps the image in a link to the product, and that one extra
   element breaks the frame:

     .card-media > a is an INLINE box of auto height, so the image's
     `height: 100%` has nothing definite to resolve against and falls back to
     auto. The image then takes its own proportions, and because aspect-ratio
     is only a PREFERRED size -- content taller than the ratio still stretches
     the box -- the whole frame grows with it.

   Measured on a 600x900 photograph in a three-across grid: the frame came out
   287x431 instead of 287x287, so one portrait picture made its card taller
   than the two beside it and the row of prices stopped lining up.

   Two lines fix it. The link fills the frame, which gives `height: 100%` a
   definite containing block, and overflow: hidden makes the ratio a limit
   rather than a suggestion for anything else that lands in there. */
.card-media { overflow: hidden; }
.card-media > a { display: block; width: 100%; height: 100%; }

/* -- media that is missing ------------------------------------------------ */
/* Drawn in CSS rather than served as a placeholder file: a product with no
   photograph should not cost a request, and an empty alt keeps the frame
   silent to a screen reader. */
.placeholder-media {
  display: grid; place-items: center;
  width: 100%; height: 100%; min-height: 3rem;
  background: repeating-linear-gradient(45deg, #eef1e9, #eef1e9 8px, #e7ebe3 8px, #e7ebe3 16px);
  color: var(--ink-faint);
}
.placeholder-media svg { width: 28%; max-width: 56px; height: auto; opacity: .55; }
.thumb-sm {
  width: 52px; height: 52px; object-fit: cover;
  background: #eef1e9; border-radius: var(--radius); flex-shrink: 0;
}
.thumb-frame {
  width: 52px; height: 52px; border-radius: var(--radius);
  overflow: hidden; flex-shrink: 0; background: #eef1e9;
}

/* -- rich text authored in the admin editor ------------------------------- */
.richtext { max-width: 68ch; color: var(--ink-soft); }
.richtext :where(h1, h2, h3, h4) { color: var(--ink); margin-top: 1.5rem; }
.richtext :where(h1, h2, h3, h4):first-child { margin-top: 0; }
.richtext img { border-radius: var(--radius); margin-block: 1rem; }
.richtext ul, .richtext ol { padding-left: 1.2rem; }
.richtext li { margin-bottom: .35rem; }
.richtext table { width: 100%; border-collapse: collapse; font-size: .92rem; }
.richtext th, .richtext td { border: var(--line); padding: .5rem .65rem; text-align: left; }
.richtext a { color: var(--brand); text-decoration: underline; }

/* -- ticket conversation -------------------------------------------------- */
.msg {
  border: var(--line); border-radius: var(--radius);
  background: var(--surface); padding: 1rem 1.1rem; margin-bottom: .75rem;
}
.msg--staff  { border-left: 3px solid var(--brand); }
.msg--system { border-left: 3px solid var(--mist-deep); background: var(--paper); }
.msg--note   { border-left: 3px solid var(--gold); background: var(--gold-wash); }
.msg-head {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: var(--gap-sm); flex-wrap: wrap; margin-bottom: .5rem;
}
.msg-body { margin: 0; white-space: pre-wrap; }
.msg time { font-family: var(--mono); font-size: .74rem; color: var(--ink-faint); }

.tag {
  display: inline-flex; align-items: center; gap: .3rem;
  font-family: var(--mono); font-size: .66rem; letter-spacing: .08em;
  text-transform: uppercase; padding: .15rem .45rem; border-radius: 2px;
  background: var(--mist); color: var(--ink-soft);
}
.tag--brand { background: var(--brand); color: #fff; }
.tag--gold { background: var(--gold); color: var(--brand-deep); }
.tag--clay { background: var(--clay); color: #fff; }

.file-list {
  list-style: none; display: flex; flex-wrap: wrap; gap: .4rem;
  margin: .75rem 0 0; padding: .75rem 0 0; border-top: var(--line);
}

/* -- basket rows ---------------------------------------------------------- */
/* Each control in a basket row is its own form -- one quantity, one removal --
   so the grid children are forms rather than the widgets themselves. On a narrow
   screen they are placed explicitly, because the template's own rule targets the
   widgets and would otherwise leave the row in source order. */
@media (max-width: 680px) {
  .cart-row > *:nth-child(1) { grid-row: 1; grid-column: 1; }
  .cart-row > *:nth-child(2) { grid-row: 1; grid-column: 2; }
  .cart-row > *:nth-child(5) { grid-row: 1; grid-column: 3; align-self: start; }
  .cart-row > *:nth-child(3) { grid-row: 2; grid-column: 2; }
  .cart-row > *:nth-child(4) { grid-row: 2; grid-column: 3; align-self: center; }
}

/* -- the honeypot --------------------------------------------------------- */
/* Off-screen rather than display:none. Some bots skip anything the CSS hides,
   and this catches more of them. */
.honeypot { position: absolute; left: -9999px; top: auto; width: 1px; height: 1px; overflow: hidden; }

/* -- QR payment ----------------------------------------------------------- */
.qr-shot {
  display: block; margin: 1.25rem auto; padding: .75rem;
  background: #fff; border: var(--line); border-radius: var(--radius);
}

/* -- sign out sits in a form, because a GET sign-out is triggerable by an
      image tag on any page a member visits ------------------------------- */
.side-nav-out form { margin: 0; }
.side-nav-out button { font: inherit; font-size: .9rem; }

/* -- utilities ------------------------------------------------------------ */
/* A short, named set. The alternative is a style attribute per view, which is
   where a design system quietly stops being one. */
.stack > * + * { margin-top: var(--gap-sm); }
.stack-lg > * + * { margin-top: var(--gap); }
.actions { display: flex; flex-wrap: wrap; gap: .6rem; align-items: center; }
.actions--end { justify-content: flex-end; }
.actions--between { justify-content: space-between; }
.actions--stack { flex-direction: column; align-items: stretch; }
.grid-3 { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--gap); }
.grid-auto { display: grid; grid-template-columns: repeat(auto-fill, minmax(250px, 1fr)); gap: var(--gap); }
.muted { color: var(--ink-soft); }
.faint { color: var(--ink-faint); }
.small { font-size: .85rem; }
.tiny { font-size: .78rem; }
.mono { font-family: var(--mono); }
.nowrap { white-space: nowrap; }
.danger { color: var(--clay); }
.ok { color: var(--leaf); }
.center { text-align: center; }
.flush { margin: 0; }
.gap-top { margin-top: var(--gap); }
.gap-top-lg { margin-top: var(--gap-lg); }
.measure { max-width: 62ch; }
.full { width: 100%; }
.card-note { font-size: .85rem; color: var(--ink-soft); }

/* -- leadership profiles ---------------------------------------------------
   The About page and the Leadership page. Both draw from the Directors table
   and from the company copy in SiteSettings, so nothing here assumes a fixed
   number of people, a photograph, or that any optional field was filled in.

   No colour literal: every value below is one of the tokens declared in the
   :root block of storefront.css, so a rebrand still happens in one place.     */

.leaders { display: grid; gap: var(--gap-lg); }

.leader {
  display: grid;
  grid-template-columns: 190px 1fr;
  gap: var(--gap-lg);
  align-items: start;
  background: var(--surface);
  border: var(--line);
  border-radius: var(--radius-lg);
  padding: var(--gap-lg);
}

/* Fixed square, so a portrait shot at any aspect ratio crops to the same
   circle instead of stretching the row it sits in. */
.leader-portrait {
  width: 100%;
  aspect-ratio: 1;
  border-radius: 50%;
  overflow: hidden;
  background: var(--paper);
  border: 1px solid var(--mist-deep);
  display: grid;
  place-items: center;
}
.leader-portrait img { width: 100%; height: 100%; object-fit: cover; display: block; }

/* Initials, drawn when there is no photograph. This is deliberately not a
   silhouette icon: a generic avatar reads as "this person has no face", where
   initials read as "no photograph yet", which is what is actually true. */
.leader-initials {
  font-family: var(--display);
  font-size: 2.6rem;
  line-height: 1;
  color: var(--brand);
  letter-spacing: .02em;
}

.leader-name { margin: 0; font-size: 1.4rem; }
.leader-role {
  display: block;
  font-family: var(--mono);
  font-size: .78rem;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--gold-ink);
  margin-top: .35rem;
}
.leader-where { display: block; font-size: .88rem; color: var(--ink-faint); margin-top: .2rem; }
.leader-summary { margin: var(--gap-sm) 0 0; color: var(--ink); font-size: 1.02rem; }
.leader-bio { margin-top: var(--gap); }

/* The vision / mission pair on the About page. Two cards rather than three,
   so .value-grid's fixed three columns would leave a gap. */
.pledge-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: var(--gap); }
.pledge {
  background: var(--surface);
  border: var(--line);
  border-left: 3px solid var(--gold);
  border-radius: var(--radius);
  padding: 1.25rem 1.35rem 1.4rem;
}
.pledge h3 { font-size: 1.08rem; margin-bottom: .5rem; }
.pledge p { margin: 0; color: var(--ink-soft); }

@media (max-width: 760px) {
  .leader { grid-template-columns: 1fr; gap: var(--gap); }

  /* Capped, or the portrait becomes a full-width circle taller than the phone. */
  .leader-portrait { max-width: 160px; }

  .pledge-grid { grid-template-columns: 1fr; }
}

@media (max-width: 900px) {
  .grid-3 { grid-template-columns: 1fr; }
}

/* Show/hide password eye (password-toggle.js) */
.pw-wrap { position: relative; display: block; }
.pw-wrap > input { padding-right: 2.75rem; width: 100%; }
.pw-toggle {
  position: absolute; top: 0; right: 0; bottom: 0; width: 2.75rem;
  display: flex; align-items: center; justify-content: center;
  background: none; border: 0; padding: 0; cursor: pointer; color: #6b7280;
}
.pw-toggle:hover, .pw-toggle:focus-visible { color: var(--brand, #0e3a78); }
