/* =============================================================
   landing.css — LangSyn makeover landing component family
   (Coherence Spec A3 — one .css per component family). This file is
   registered with the component gate and scanned by the colour gate, and it
   is synced across sites from a single source, since these are the shared
   surfaces the hub + every service sub-landing + the status panel reuse. So
   do not edit a site's copy: edit the source under web/brand/ and re-run the
   sync, or the next sync silently reverts you. Token-only: every color is
   var(--ls-*) — no raw literal.

   The gate and sync commands are deliberately not named here. This file is
   SERVED, so a comment in it is published, and our build tooling is not
   something a public surface names.
   The repo's own web gate runner runs them all and names them in its output.

   Provides:
     .ls-service-card   link-card: hub -> a service sub-landing
     .ls-health-badge   status pill (.is-up / .is-down / .is-unknown)
     .ls-status-board   the .net status-panel list of service rows
     .ls-proof          a derivation: premises, the rule line, the conclusion
   The hero + generic .ls-card skeleton already live in langsyn-theme.css.
   ============================================================= */

/* --- Service card (hub -> sub-landing) --------------------- */
.ls-service-card{
  display:flex;flex-direction:column;gap:.5rem;
  background:var(--ls-surface);border:1px solid var(--ls-border);
  border-radius:var(--ls-radius);padding:1.4rem;
  text-decoration:none;color:var(--ls-text);
  position:relative;overflow:hidden;
  transition:border-color var(--ls-dur) var(--ls-ease),
             transform var(--ls-dur) var(--ls-ease),
             background var(--ls-dur) var(--ls-ease);
}
.ls-service-card::before{content:'';position:absolute;top:0;left:0;right:0;height:2px;background:var(--ls-accent);opacity:.55}
.ls-service-card:hover{border-color:var(--ls-accent-border);transform:translateY(-2px);background:var(--ls-surface-2)}
.ls-service-card-name{font-family:var(--ls-font-mono);font-size:.95rem;font-weight:500;letter-spacing:.02em;color:var(--ls-text)}
.ls-service-card-host{font-family:var(--ls-font-mono);font-size:.72rem;color:var(--ls-text-faint)}
.ls-service-card-desc{font-size:.85rem;color:var(--ls-text-2);line-height:1.6;flex:1}
.ls-service-card-cta{font-family:var(--ls-font-mono);font-size:.72rem;letter-spacing:.04em;color:var(--ls-accent);margin-top:.4rem}
.ls-service-card:hover .ls-service-card-cta{color:var(--ls-accent-glow)}

/* --- Health badge (up / down / unknown) -------------------- */
/* A state in words, in the text face and in sentence case, with a dot in the
   state's colour: a label on the sheet, not a pill. The word carries the state
   by itself, so the colour is never the only signal. */
.ls-health-badge{display:inline-flex;align-items:center;gap:.5rem;white-space:nowrap;
  font-family:var(--ls-font-text);font-size:1rem;color:var(--ls-text-2)}
.ls-health-badge-dot{width:8px;height:8px;border-radius:50%;background:var(--ls-text-faint);flex-shrink:0}
.ls-health-badge.is-up{color:var(--ls-ok)}
.ls-health-badge.is-up .ls-health-badge-dot{background:var(--ls-ok)}
.ls-health-badge.is-down{color:var(--ls-danger)}
.ls-health-badge.is-down .ls-health-badge-dot{background:var(--ls-danger)}
.ls-health-badge.is-unknown{color:var(--ls-text-faint)}
.ls-health-badge.is-unknown .ls-health-badge-dot{background:var(--ls-text-faint)}

/* --- Status board (.net status panel) ---------------------- */
/* One line per service in the sheet's main column: its name, the host it
   answers at, and its state at the end of the line. Rows are separated by
   space, never by a line, and a row is a link to the service. */
.ls-status-board{display:flex;flex-direction:column;max-width:46rem}
.ls-status-row{display:grid;grid-template-columns:minmax(0,1fr) auto;align-items:baseline;gap:1rem;
  padding:.85rem 1rem;margin-inline:-1rem;border-radius:var(--ls-radius);
  text-decoration:none;color:var(--ls-text)}
.ls-status-row:hover{background:var(--ls-surface)}
.ls-status-row-main{display:flex;flex-wrap:wrap;align-items:baseline;column-gap:1.25rem;row-gap:.2rem;min-width:0}
.ls-status-row-name{font-family:var(--ls-font-text);font-size:1.17rem;font-weight:600;color:var(--ls-text)}
.ls-status-row-host{font-family:var(--ls-font-mono);font-size:.9rem;color:var(--ls-text-2)}
.ls-status-note{max-width:62ch;color:var(--ls-text-2);font-size:.95rem}

/* --- Derivation ------------------------------------------- */
/* Set the way a proof is written down: premises, a rule line meaning
   "therefore" with the rule's name at its end, then the conclusion. It is the
   only horizontal line on the site. Each statement's source note sits beneath
   it, so the rule name stays in view at any width. The line draws once on
   load, and the conclusion appears after it; reduced motion shows both at
   rest. Rows are placed automatically, so a proof may carry several premises. */
.ls-proof{margin:0;padding:1.9rem 0 .4rem;display:grid;grid-template-columns:max-content max-content;column-gap:1rem;align-items:end;overflow-x:auto;max-width:100%}
.ls-proof-ln{grid-column:1;display:flex;flex-direction:column;font-family:var(--ls-font-mono);font-size:1.06rem;line-height:1.45;white-space:nowrap;padding-inline:2px}
.ls-proof-src{color:var(--ls-text-faint);font-size:.82em}
.ls-proof .ls-derived{font-weight:600}
.ls-proof-bar{grid-column:1;height:2px;background:var(--ls-rule);margin-block:.75rem;transform-origin:left center;animation:ls-proof-draw .7s cubic-bezier(.3,.7,.2,1) .35s both}
.ls-proof-rule{grid-column:2;align-self:center;font-family:var(--ls-font-mono);color:var(--ls-text-2);white-space:nowrap;animation:ls-proof-appear .4s ease 1s both}
.ls-proof-concl{animation:ls-proof-appear .5s ease 1.05s both}
@keyframes ls-proof-draw{from{transform:scaleX(0)}to{transform:scaleX(1)}}
@keyframes ls-proof-appear{from{opacity:0}to{opacity:1}}
@media(prefers-reduced-motion:reduce){.ls-proof-bar,.ls-proof-rule,.ls-proof-concl{animation:none}}

/* --- Mobile ------------------------------------------------ */
/* On a phone the rule's name has no room beside the line: it ran past the right
   edge, where the figure scrolls but shows no sign that it does (the landing-page
   review of 2026-11-12, finding 10). It takes the row under the line, at the
   line's right end, so it is still the line's label and is in view. */
@media(max-width:480px){
  .ls-proof{grid-template-columns:max-content}
  .ls-proof-ln{font-size:.94rem}
  .ls-proof-rule{grid-column:1;justify-self:end;font-size:.86rem;margin-top:-.5rem;margin-bottom:.35rem}
}
