/* ==========================================================================
   Lispa · Design canon component utilities  (Round 2 of the port)
   --------------------------------------------------------------------------
   Opt-in component classes lifted from the canonical Lispa OS Therapist
   artifact (claude.ai/artifact/JeyXV8dQAu42dJ41BFFke2). This file is
   ADDITIVE — including it in a page never changes the appearance of
   anything already there. Adopt the classes progressively as pages get
   their taste pass.

   Naming: every class here is prefixed `.lb-c-` (lispa brand · canon)
   to distinguish from the existing `.lb-*` utilities in lispa-brand.css
   and the workspace/shell `.os-*` and `.hq-*` classes in
   lispa-os-shell.js. That means:

     - Round 1 tokens (already in lispa-brand.css) supply the palette
     - Round 2 classes here supply the shape / rhythm / typography
     - Round 3 per-page adoption composes them into the actual UI

   Load AFTER lispa-brand.css so canon tokens (--sage, --copper,
   --paper2, --stone-2, --lilac, etc.) are resolvable. Every value
   here reads through a token — no hard-coded hex. If a token you need
   is missing, add it to lispa-brand.css, do not inline a hex here.

   Rules for use:
     - Do not add a `.lb-c-*` class outside this file. Compose them
       inside per-page CSS with your own semantic names.
     - When the artifact shows two variants of the same thing (e.g.
       `.btn-primary` and `.btn-copper`), preserve both — they carry
       different intent (sage = the safe/system action; copper = the
       personal/attention action).
     - Motion sits in the shared shell (`.os-*` in lispa-os-shell.js).
       This file styles at rest; hovers are OK, keyframe animations
       are not.
     - Every component that carries text SHOULD state its `font-family`
       explicitly because pages that don't set body-font default to
       system-ui and the artifact's whole feel depends on Garamond.
   ========================================================================== */

/* ---- Ornament divider — hairlines with a single ✦ ------------------------
   Used between major sections of a boutique page (dashboard hero → today
   → this month → foot). NOT a decorative flourish — a rhythmic pause.
   Keep to at most 2 per screen or the effect flattens. */
.lb-c-ornament {
  display: flex;
  align-items: center;
  gap: 18px;
  color: var(--copper, var(--bronze));
  font-family: var(--font-serif);
  font-style: italic;
  font-size: 14px;
  padding: 10px 0;
  letter-spacing: 0.01em;
}
.lb-c-ornament::before,
.lb-c-ornament::after {
  content: "";
  height: 1px;
  flex: 1;
  background: var(--stone, var(--travertine));
  opacity: 0.7;
}
.lb-c-ornament .mark {
  color: var(--copper, var(--bronze));
  font-size: 10px;
  opacity: 0.8;
  font-style: normal;
}

/* ---- Card — near-square, 2px radius, single hairline border --------------
   The artifact's signature card shape. The customary CSS "soft rounded
   card" reads as software; Lispa's cards read as boutique-hotel invitation
   stationery. Do not raise the radius. */
.lb-c-card {
  background: var(--paper, var(--limestone-light));
  border: 1px solid var(--stone, var(--travertine));
  border-radius: 2px;
  padding: 22px;
  position: relative;
  overflow: hidden;
}
.lb-c-card-lg {
  padding: 28px;
}
.lb-c-card-flat {
  background: var(--paper2, #EEE9DF);
  border: 1px solid var(--stone, var(--travertine));
  border-radius: 2px;
  padding: 16px;
}

/* ---- Buttons — uppercase, letter-spaced serif; no shadow, no pill --------
   Two accent buttons carry different intent. Use the sage primary for
   "the system does this by default" — clocking in, saving, confirming.
   Use the copper for "you personally decide this now" — the single
   next-best-action, the recovery voucher, the escalation. Never both on
   the same card. */
.lb-c-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  min-height: 44px;
  padding: 0 22px;
  border-radius: 2px;
  font-family: var(--font-serif);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  transition: background .16s ease, color .16s ease, border-color .16s ease, transform .16s ease;
  border: 1px solid transparent;
  cursor: pointer;
  white-space: nowrap;
}
.lb-c-btn:active { transform: translateY(1px); }
.lb-c-btn:focus-visible { outline: 1px solid var(--copper, var(--bronze)); outline-offset: 3px; }

.lb-c-btn-primary {
  background: var(--sage, var(--olive));
  color: var(--paper, var(--limestone-light));
  border-color: var(--sage, var(--olive));
}
.lb-c-btn-primary:hover {
  background: var(--sage-deep, var(--olive-deep));
  border-color: var(--sage-deep, var(--olive-deep));
}
.lb-c-btn-copper {
  background: var(--copper, var(--bronze));
  color: #fff;
  border-color: var(--copper, var(--bronze));
}
.lb-c-btn-copper:hover {
  background: var(--bronze-deep, var(--bronze));
  border-color: var(--bronze-deep, var(--bronze));
}
.lb-c-btn-ghost {
  background: transparent;
  color: var(--copper, var(--bronze));
  border-color: transparent;
}
.lb-c-btn-ghost:hover { color: var(--sage-deep, var(--olive-deep)); }

.lb-c-btn-outline {
  border: 1px solid var(--stone, var(--travertine));
  background: transparent;
  color: var(--ink);
}
.lb-c-btn-outline:hover {
  border-color: var(--copper, var(--bronze));
  color: var(--copper, var(--bronze));
}
.lb-c-btn-lg { min-height: 52px; padding: 0 28px; font-size: 12px; }
.lb-c-btn-sm { min-height: 34px; padding: 0 14px; font-size: 10px; letter-spacing: 0.16em; }
.lb-c-btn-block { width: 100%; }

/* ---- Chip — italic serif label with a leading 3px coloured dot ----------
   Not a filled brick. The dot IS the affordance; the label is what it is
   about. Use for status indicators that shouldn't shout: "Active",
   "Confirmed", "En route". For statuses that must shout — e.g. incoming
   guest T-minus, in-relaxation — use .lb-c-chip-solid instead. */
.lb-c-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 2px 0 2px 10px;
  border-radius: 0;
  font-size: 12px;
  font-weight: 400;
  letter-spacing: 0;
  text-transform: none;
  background: transparent;
  color: var(--muted);
  border: 0;
  font-family: var(--font-serif);
  font-style: italic;
  position: relative;
}
.lb-c-chip::before {
  content: "";
  position: absolute;
  left: 0;
  top: 50%;
  width: 3px;
  height: 3px;
  border-radius: 50%;
  background: currentColor;
  transform: translateY(-50%);
  opacity: 0.6;
}
.lb-c-chip-sage    { color: var(--sage,   var(--olive)); }
.lb-c-chip-copper  { color: var(--copper, var(--bronze)); }
.lb-c-chip-lilac   { color: var(--lilac,  #777081); }
.lb-c-chip-warn    { color: var(--warn); }
.lb-c-chip-danger  { color: var(--bad); }
.lb-c-chip-ghost   { color: var(--muted); opacity: 0.7; }

.lb-c-chip-solid {
  padding: 5px 10px;
  border-radius: 2px;
  font-style: normal;
  font-size: 9.5px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--paper, var(--limestone-light));
  background: var(--copper, var(--bronze));
}
.lb-c-chip-solid::before { display: none; }
.lb-c-chip-solid-sage { background: var(--sage, var(--olive)); }

/* ---- Stat tile — the italic-serif number, the tiny uppercase label ------
   The canonical Lispa metric. Use for anything the human should *feel*
   (this month's earnings, streak days, guests seen). For pure counts
   without personal weight, use a bare number. */
.lb-c-stat {
  padding: 20px;
  background: var(--paper, var(--limestone-light));
  border: 1px solid var(--stone, var(--travertine));
  border-radius: 2px;
  position: relative;
}
.lb-c-stat .lb-c-stat-k {
  font-size: 9px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--muted);
  font-weight: 500;
}
.lb-c-stat .lb-c-stat-v {
  font-family: var(--font-serif);
  font-style: italic;
  font-weight: 400;
  font-size: 30px;
  margin-top: 6px;
  letter-spacing: -0.005em;
  line-height: 1;
  color: var(--ink);
}
.lb-c-stat .lb-c-stat-d {
  font-size: 11px;
  color: var(--sage, var(--olive));
  margin-top: 8px;
  display: flex;
  align-items: center;
  gap: 4px;
  font-family: var(--font-serif);
  font-style: italic;
}
.lb-c-stat .lb-c-stat-d.down { color: var(--bad); }

/* ---- Next-best-action card — copper-edge, single ✦, one action ----------
   The card that says: "of all the things you could do right now, THIS
   is the one only you can do." Never more than one per screen. Sits at
   the top-left of a page's fold. */
.lb-c-nba {
  background: var(--paper, var(--limestone-light));
  border: 1px solid var(--stone, var(--travertine));
  border-left: 3px solid var(--copper, var(--bronze));
  border-radius: 2px;
  padding: 22px 24px;
  position: relative;
  overflow: hidden;
}
.lb-c-nba::before {
  content: "✦";
  position: absolute;
  top: 16px;
  right: 20px;
  color: var(--copper, var(--bronze));
  font-family: var(--font-serif);
  font-style: italic;
  font-size: 20px;
}
.lb-c-nba .lb-c-nba-k {
  font-size: 9px;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  color: var(--copper, var(--bronze));
  font-weight: 500;
}
.lb-c-nba h3 {
  font-family: var(--font-serif);
  font-size: 24px;
  margin-top: 10px;
  padding-right: 28px;
  font-weight: 400;
  line-height: 1.15;
}
.lb-c-nba h3 em {
  color: var(--sage, var(--olive));
  font-style: italic;
}
.lb-c-nba p {
  color: var(--muted);
  font-size: 14px;
  margin-top: 10px;
  line-height: 1.55;
  font-style: italic;
}
.lb-c-nba-actions {
  margin-top: 18px;
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
}

/* ---- Sage-well clock card — the signature Lispa in-app surface ----------
   Sage-deep well with a soft radial glow; italic-serif large time; a
   breathing status dot. Use for the "you are here now" surface — clock
   in/out on the therapist portal, live-status header on ops. Never for
   a static number. */
.lb-c-clock {
  position: relative;
  background: var(--sage, var(--olive));
  color: var(--paper, var(--limestone-light));
  border-radius: 2px;
  padding: 26px 28px;
  overflow: hidden;
  box-shadow: var(--sh-drawer);
}
.lb-c-clock::before {
  content: "";
  position: absolute;
  inset: 0;
  background:
    radial-gradient(120% 90% at 20% 0%, rgba(216,198,166,.16), transparent 55%),
    radial-gradient(80% 80% at 100% 100%, rgba(169,124,69,.14), transparent 55%);
  pointer-events: none;
}
.lb-c-clock-status {
  position: relative;
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 10px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: rgba(255,255,255,.75);
}
.lb-c-clock-status .dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--sage-mint);
  box-shadow: 0 0 0 4px rgba(169,195,166,.22);
}
.lb-c-clock-time {
  font-family: var(--font-serif);
  font-style: italic;
  font-weight: 400;
  font-size: 58px;
  line-height: 1;
  margin-top: 18px;
  letter-spacing: -0.01em;
  font-variant-numeric: tabular-nums;
  position: relative;
}
.lb-c-clock-time small {
  font-size: 20px;
  opacity: 0.65;
  margin-left: 8px;
  font-style: normal;
}
.lb-c-clock-duration {
  color: rgba(255,255,255,.7);
  font-size: 12px;
  margin-top: 6px;
  font-style: italic;
}
.lb-c-clock-actions {
  display: flex;
  gap: 10px;
  margin-top: 20px;
  position: relative;
  z-index: 2;
}
/* State variations — driven by data-state on the clock element */
.lb-c-clock[data-state="inflight"] { background: var(--sage-deep, var(--olive-deep)); }
.lb-c-clock[data-state="break"]    { background: var(--lilac, #777081); }
.lb-c-clock[data-state="ended"]    { background: var(--stone, var(--travertine)); color: var(--ink); }
.lb-c-clock[data-state="ended"] .lb-c-clock-status,
.lb-c-clock[data-state="ended"] .lb-c-clock-duration { color: var(--muted); }
.lb-c-clock[data-state="ended"] .lb-c-clock-time     { color: var(--sage, var(--olive)); }

/* ---- Timeline — dot per event, state-coloured card + left-strip ---------
   The one component the artifact leans on for "here's how a day flows".
   Use for the therapist's Today, ops room-state ladder, guest's booked
   sequence. Every timeline is left-oriented; do NOT flip axis. */
.lb-c-tl {
  position: relative;
  padding-left: 28px;
}
.lb-c-tl::before {
  content: "";
  position: absolute;
  left: 10px;
  top: 8px;
  bottom: 8px;
  width: 1px;
  background: linear-gradient(180deg,
    var(--stone-2, #C9BFAE) 0%,
    var(--stone-2, #C9BFAE) 70%,
    transparent 100%);
}
.lb-c-tl-item {
  position: relative;
  padding-bottom: 18px;
}
.lb-c-tl-item:last-child { padding-bottom: 0; }
.lb-c-tl-dot {
  position: absolute;
  left: -24px;
  top: 6px;
  width: 12px;
  height: 12px;
  border-radius: 50%;
  background: var(--paper, var(--limestone-light));
  border: 2px solid var(--sage-deep, var(--olive-deep));
}
.lb-c-tl-item.now .lb-c-tl-dot {
  background: var(--copper, var(--bronze));
  border-color: var(--copper, var(--bronze));
  box-shadow: 0 0 0 4px rgba(169,124,69,.20);
}
.lb-c-tl-item.done .lb-c-tl-dot {
  background: var(--sage-deep, var(--olive-deep));
  border-color: var(--sage-deep, var(--olive-deep));
}
.lb-c-tl-item.break .lb-c-tl-dot {
  background: var(--lilac, #777081);
  border-color: var(--lilac, #777081);
}
.lb-c-tl-item.gap .lb-c-tl-dot {
  background: var(--paper, var(--limestone-light));
  border-color: var(--stone-2, #C9BFAE);
  border-style: dashed;
}
.lb-c-tl-time {
  font-size: 11px;
  color: var(--muted);
  letter-spacing: 0.08em;
  font-weight: 500;
  margin-bottom: 4px;
  font-family: var(--font-serif);
  font-style: italic;
}
.lb-c-tl-card {
  background: var(--paper, var(--limestone-light));
  border: 1px solid var(--stone, var(--travertine));
  border-radius: 2px;
  padding: 16px;
  transition: all .2s ease;
}
.lb-c-tl-item.now .lb-c-tl-card {
  border-color: var(--copper, var(--bronze));
  border-left: 3px solid var(--copper, var(--bronze));
}
.lb-c-tl-item.done .lb-c-tl-card {
  background: transparent;
  opacity: 0.65;
}
.lb-c-tl-item.break .lb-c-tl-card {
  background: rgba(119,112,129,.06);
  border-style: dashed;
}
.lb-c-tl-item.gap .lb-c-tl-card {
  background: transparent;
  border-style: dashed;
  padding: 8px 14px;
}

/* ---- Italic serif number — the "reading" number utility -----------------
   Alias of .num-italic in lispa-brand.css for consistency with the .lb-c-*
   family. Prefer .num-italic in new code; .lb-c-num is kept for pages that
   want to keep every canon primitive namespaced. */
.lb-c-num {
  font-family: var(--font-serif);
  font-style: italic;
  font-weight: 400;
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.005em;
}

/* ---- Editorial section eyebrow — for section headings ------------------- */
.lb-c-eyebrow {
  font-family: var(--font-serif);
  text-transform: uppercase;
  letter-spacing: 0.22em;
  font-size: 10px;
  color: var(--copper, var(--bronze));
  font-weight: 500;
}

/* ==========================================================================
   Round 3.5 — admin-surface primitives
   --------------------------------------------------------------------------
   The artifact is a therapist-facing specimen, so it has no vocabulary for
   the shapes an operator page needs: a KPI strip, a tab rail, a data table,
   a titled panel, a filter toolbar, a status label. These six are ported
   from the shapes that ALREADY recur across admin-home / admin-guests-hub /
   admin-operations / admin-delivery-hub / admin-inbox-hub / admin-person,
   canon-corrected on three axes:

     - radius drops to 2px everywhere (was 4/6/12/16px depending on page)
     - every type stack moves to EB Garamond (several used Inter)
     - colours read through tokens, never inline rgba/hex

   They are NOT new inventions — each one is the majority shape across the
   pages that already have it, so adoption is mostly a class rename.
   ========================================================================== */

/* ---- KPI strip — the 4-across metric row at the top of an operator page --
   The individual cell is just .lb-c-stat; this is only the grid that holds
   them, plus the three border states admin-operations uses to flag a metric
   that needs attention. Collapses 4 → 2 → 1 as the viewport narrows. */
.lb-c-kpis {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 12px;
}
@media (max-width: 820px) { .lb-c-kpis { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 480px) { .lb-c-kpis { grid-template-columns: 1fr; } }

.lb-c-stat-good { border-color: var(--sage, var(--olive)); }
.lb-c-stat-warn { border-color: var(--warn); }
.lb-c-stat-bad  { border-color: var(--bad); }

/* ---- Tab rail — underline-marked, never a pill or a filled segment -------
   The active marker is a 2px copper underline that sits ON the container's
   hairline (hence the -1px margin), so the selected tab reads as a piece of
   the page below rather than a button floating above it. */
.lb-c-tabs {
  display: flex;
  gap: 2px;
  border-bottom: 1px solid var(--stone, var(--travertine));
  overflow-x: auto;
  background: var(--limestone);
  padding-top: 6px;
}
.lb-c-tab {
  padding: 10px 16px;
  font-family: var(--font-serif);
  font-size: 11px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--muted);
  background: transparent;
  border: none;
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;
  white-space: nowrap;
  cursor: pointer;
  text-decoration: none;
  display: inline-flex;
  align-items: center;
  transition: color .15s ease, border-color .15s ease;
}
.lb-c-tab:hover { color: var(--sage, var(--olive)); }
.lb-c-tab-on {
  color: var(--sage, var(--olive));
  border-bottom-color: var(--copper, var(--bronze));
}
/* Rule between tab groups — "these belong to a different section". */
.lb-c-tab-divider {
  border-left: 1px solid var(--stone, var(--travertine));
  margin-left: 8px;
  padding-left: 16px;
}

/* ---- Data table — the operator's list view ------------------------------
   Header row is an eyebrow, not a heading: tiny, letter-spaced, uppercase,
   on the limestone shelf. Body rows separate with the soft hairline, and
   the last row drops its rule so the table ends on the wrapper's border
   rather than doubling it. */
.lb-c-tablewrap {
  overflow-x: auto;
  background: var(--paper);
  border: 1px solid var(--stone, var(--travertine));
  border-radius: 2px;
}
.lb-c-table {
  width: 100%;
  border-collapse: collapse;
  background: var(--paper);
  font-family: var(--font-serif);
  font-size: 13px;
}
.lb-c-table th {
  text-align: left;
  padding: 10px 12px;
  font-size: 10px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--muted);
  border-bottom: 1px solid var(--stone, var(--travertine));
  font-weight: 400;
  background: var(--limestone);
}
.lb-c-table td {
  padding: 10px 12px;
  border-bottom: 1px solid var(--wash-travertine-soft, var(--travertine));
  vertical-align: top;
}
.lb-c-table tr:last-child td { border-bottom: none; }
.lb-c-table b {
  font-weight: 400;
  font-variant-numeric: tabular-nums;
  color: var(--sage, var(--olive));
}
/* Money / count columns right-align and never wrap. */
.lb-c-table .amt {
  font-variant-numeric: tabular-nums;
  text-align: right;
  white-space: nowrap;
}

/* ---- Panel — a titled block of operator content -------------------------
   Distinct from .lb-c-card: a card holds one thing, a panel holds a titled
   SECTION with an optional right-hand link out. The title is an eyebrow so
   it never competes with the content's own headings. */
.lb-c-panel {
  background: var(--paper);
  border: 1px solid var(--stone, var(--travertine));
  border-radius: 2px;
  padding: 18px;
}
.lb-c-panel-head {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: 14px;
  margin-bottom: 20px;
  flex-wrap: wrap;
}
.lb-c-panel-title {
  font-family: var(--font-serif);
  font-size: 10px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--muted);
}
.lb-c-panel-link {
  font-family: var(--font-serif);
  font-size: 10px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--copper, var(--bronze));
  text-decoration: none;
}
.lb-c-panel-link:hover { color: var(--sage, var(--olive)); }
/* Standfirst under a panel title — italic serif, the explaining voice. */
.lb-c-panel-lede {
  font-family: var(--font-serif);
  font-style: italic;
  font-size: 13px;
  color: var(--muted);
  margin-bottom: 14px;
  line-height: 1.5;
}

/* ---- Toolbar — the filter / action row above a list ---------------------
   Inputs here are deliberately shorter than .hq-input (34px vs 44px): this
   is a row you scan past, not a form you fill in. Put the primary action in
   .lb-c-toolbar-end so it sits hard right regardless of how many filters
   wrapped onto the line. */
.lb-c-toolbar {
  display: flex;
  gap: 10px;
  flex-wrap: wrap;
  align-items: center;
}
.lb-c-toolbar-end {
  margin-left: auto;
  display: flex;
  gap: 8px;
  align-items: center;
}
.lb-c-toolbar label {
  font-family: var(--font-serif);
  font-size: 11px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--muted);
}
.lb-c-toolbar select,
.lb-c-toolbar input {
  padding: 6px 10px;
  border: 1px solid var(--stone, var(--travertine));
  border-radius: 2px;
  font-family: var(--font-serif);
  font-size: 13px;
  background: var(--paper);
  color: var(--ink);
  min-height: 34px;
}

/* ---- Status label — bordered, not dotted --------------------------------
   Deliberately NOT .lb-c-chip. A chip is a soft italic aside with a leading
   dot; a status is a hard state an operator acts on, so it gets a border and
   sits upright. Each modifier colours border AND text together so the label
   reads at a glance without needing to parse the word. */
.lb-c-status {
  display: inline-block;
  font-family: var(--font-serif);
  font-size: 10px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  padding: 3px 9px;
  border-radius: 2px;
  border: 1px solid var(--stone, var(--travertine));
  color: var(--muted);
  white-space: nowrap;
}
.lb-c-status-done { color: var(--sage, var(--olive));   border-color: var(--sage, var(--olive)); }
.lb-c-status-live { color: var(--green);                 border-color: var(--green); }
.lb-c-status-next { color: var(--copper, var(--bronze)); border-color: var(--copper, var(--bronze)); }
.lb-c-status-warn { color: var(--warn);                  border-color: var(--warn); }
.lb-c-status-bad  { color: var(--bad);                   border-color: var(--bad); }
.lb-c-status-off  { color: var(--muted); opacity: 0.7; }
