/* Cloud-only visual layer, loaded AFTER the shared /style.css.
   Rule of the file: it may only ADD new selectors, all prefixed `sl-`. It never
   restyles a class style.css owns (.card, .chip, .table, .dim, .cap-badge, …) —
   that file is shared verbatim with the local UI through the served-path
   allowlist, and a rule here that fought it would break the other app.

   Color discipline: the chrome is achromatic. Every colored pixel is either
   DATA (the blue ordinal ramp) or STATUS (good/warn/crit). Bootstrap's dark
   variables carry the neutrals, so a theme change still carries.

   The blue ramp is validated for a dark surface: monotone lightness, visible
   step gaps, and the lightest step clears the surface it sits on. */

:root {
  --sl-b1: #184f95;
  --sl-b2: #2a78d6;
  --sl-b3: #5598e7;
  --sl-b4: #86b6ef;
  --sl-b0: #1b2432;            /* the "none" step of the heat ramp */
  --sl-data: #3987e5;

  --sl-warn: #fab219;
  --sl-crit: #d03b3b;

  --sl-mono: ui-monospace, "Cascadia Mono", "JetBrains Mono", Consolas, monospace;
}

/* ------------------------------- page header ------------------------------- */

/* Every page opens with the one sentence it exists to answer. The hero figure
   is the number a reader would repeat out loud; exactly one per view. */
.sl-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 1.5rem; flex-wrap: wrap; margin-bottom: 1.25rem; }
.sl-head h1 { font-size: 1.5rem; font-weight: 600; letter-spacing: -0.02em; margin: 0 0 .25rem; }
.sl-answer { font-size: 1.0625rem; line-height: 1.5; color: var(--bs-secondary-color); max-width: 62ch; margin: 0; text-wrap: pretty; }
.sl-answer b { color: var(--bs-emphasis-color); font-weight: 600; }
.sl-answer .sl-fig { font-size: 2.25rem; font-weight: 650; color: var(--bs-emphasis-color); letter-spacing: -0.03em; line-height: 1; margin-right: .125rem; }

.sl-crumb { font-size: .75rem; color: var(--bs-secondary-color); margin-bottom: .5rem; }

/* Section rhythm: a hairline rule and a mono eyebrow, not another card. */
.sl-sec { margin-top: 1.75rem; }
.sl-sec > .sl-sec-hd { display: flex; align-items: baseline; justify-content: space-between; gap: 1rem; border-bottom: 1px solid var(--bs-border-color); padding-bottom: .375rem; margin-bottom: .75rem; }
.sl-eyebrow { font-family: var(--sl-mono); font-size: .6875rem; font-weight: 600; text-transform: uppercase; letter-spacing: .1em; color: var(--bs-secondary-color); margin: 0; }

/* A caption that states a limit of the data above it. Never decorative: if it
   is on screen, something about the numbers is bounded. */
.sl-cap-note { font-size: .6875rem; color: var(--bs-secondary-color); margin-top: .5rem; display: flex; align-items: baseline; gap: .375rem; }
.sl-cap-note::before { content: ""; width: .75rem; height: 1px; background: var(--bs-border-color); flex: none; position: relative; top: -.25rem; }

/* ------------------------------- stat tiles -------------------------------- */

.sl-tiles { display: grid; grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr)); gap: .625rem; }
.sl-tile { background: var(--bs-card-bg); border: 1px solid var(--bs-card-border-color); border-radius: .375rem; padding: .75rem .875rem; display: flex; flex-direction: column; gap: .25rem; min-width: 0; }
.sl-tile-lab { font-family: var(--sl-mono); font-size: .625rem; letter-spacing: .09em; text-transform: uppercase; color: var(--bs-secondary-color); }
.sl-tile-lab .sl-q { border-bottom: 1px dotted var(--bs-secondary-color); cursor: help; }
.sl-tile-val { font-size: 1.625rem; font-weight: 620; letter-spacing: -0.02em; line-height: 1.1; color: var(--bs-emphasis-color); }
.sl-tile-val small { font-size: .8125rem; color: var(--bs-secondary-color); font-weight: 500; }
.sl-tile-sub { font-size: .75rem; color: var(--bs-secondary-color); }

.sl-delta { font-family: var(--sl-mono); font-size: .6875rem; }
.sl-delta.up { color: var(--bs-success-text-emphasis); }
.sl-delta.down { color: var(--bs-warning-text-emphasis); }

/* --------------------------------- stamps ---------------------------------- */

/* Badges as audit stamps, not game medals: every one states its earning rule on
   hover, and one of them is a DISCLOSURE (evidence integrity) rather than an
   award. A badge whose criteria you cannot inspect is an ad, not a credential. */
.sl-stamps { display: flex; gap: .5rem; flex-wrap: wrap; }
.sl-stamp { border: 1px solid var(--bs-border-color); border-radius: .25rem; padding: .375rem .6875rem .3125rem; display: flex; flex-direction: column; gap: .0625rem; background: var(--bs-card-bg); cursor: help; }
.sl-stamp b { font-family: var(--sl-mono); font-size: .625rem; font-weight: 700; letter-spacing: .09em; text-transform: uppercase; color: var(--bs-emphasis-color); white-space: nowrap; }
.sl-stamp span { font-family: var(--sl-mono); font-size: .5625rem; letter-spacing: .06em; text-transform: uppercase; color: var(--bs-secondary-color); white-space: nowrap; }
.sl-stamp.accent { border-color: rgba(85, 152, 231, .5); }
.sl-stamp.accent b { color: var(--sl-b4); }

/* --------------------------------- alerts ---------------------------------- */

/* Severity reads in the stripe, the glyph AND the word — never color alone. */
.sl-alerts { border: 1px solid var(--bs-border-color); border-radius: .375rem; overflow: hidden; }
.sl-alert { display: grid; grid-template-columns: 3px auto 1fr auto; align-items: center; gap: .75rem; background: var(--bs-card-bg); padding: .625rem .875rem .625rem 0; border-bottom: 1px solid var(--bs-border-color); }
.sl-alert:last-child { border-bottom: 0; }
.sl-alert .sl-stripe { width: 3px; align-self: stretch; min-height: 2rem; }
.sl-alert.crit .sl-stripe { background: var(--sl-crit); }
.sl-alert.warn .sl-stripe { background: var(--sl-warn); }
.sl-alert.info .sl-stripe { background: var(--bs-border-color); }
.sl-alert .sl-ico { width: 1.25rem; height: 1.25rem; border-radius: 50%; display: grid; place-items: center; font-family: var(--sl-mono); font-size: .75rem; font-weight: 700; margin-left: .6875rem; }
.sl-alert.crit .sl-ico { background: rgba(208, 59, 59, .16); color: var(--sl-crit); }
.sl-alert.warn .sl-ico { background: rgba(250, 178, 25, .14); color: var(--sl-warn); }
.sl-alert.info .sl-ico { background: var(--bs-tertiary-bg); color: var(--bs-secondary-color); }
.sl-alert .sl-alert-t { font-size: .8125rem; color: var(--bs-body-color); }
.sl-alert .sl-alert-d { font-size: .75rem; color: var(--bs-secondary-color); margin-top: .0625rem; }
.sl-alert .sl-sev { font-family: var(--sl-mono); font-size: .625rem; letter-spacing: .1em; text-transform: uppercase; margin-right: .375rem; }
.sl-alert.crit .sl-sev { color: var(--sl-crit); }
.sl-alert.warn .sl-sev { color: var(--sl-warn); }
.sl-alert.info .sl-sev { color: var(--bs-secondary-color); }

/* --------------------------------- charts ---------------------------------- */

/* Column chart: bars capped at 24px with 4px rounded caps, 2px gaps, hairline
   solid gridlines. Weekends take the darker ramp step. */
.sl-chartframe { position: relative; padding-left: 2.125rem; }
.sl-gridline { position: absolute; left: 2.125rem; right: 0; border-top: 1px solid var(--bs-border-color); }
.sl-gridline span { position: absolute; left: -2.125rem; top: -.5rem; width: 1.75rem; text-align: right; font-family: var(--sl-mono); font-size: .625rem; color: var(--bs-secondary-color); font-variant-numeric: tabular-nums; }
.sl-cols { display: flex; align-items: flex-end; gap: 2px; position: relative; }
.sl-cols .sl-col { flex: 1 1 0; min-width: 0; max-width: 24px; margin: 0 auto; display: flex; align-items: flex-end; height: 100%; }
.sl-cols .sl-bar { width: 100%; background: var(--sl-data); border-radius: 4px 4px 0 0; min-height: 2px; }
.sl-cols .sl-col:hover .sl-bar { background: var(--sl-b4); }
.sl-cols .sl-col.wk .sl-bar { background: var(--sl-b1); }
.sl-cols .sl-col.wk:hover .sl-bar { background: var(--sl-b2); }
.sl-xaxis { display: flex; justify-content: space-between; margin-top: .375rem; padding-left: 2.125rem; font-family: var(--sl-mono); font-size: .625rem; color: var(--bs-secondary-color); }

/* Day grid — sequential, one hue, light→dark by magnitude. */
.sl-grid { display: grid; grid-auto-flow: column; grid-template-rows: repeat(7, 11px); gap: 3px; }
.sl-grid i { width: 11px; height: 11px; border-radius: 2px; background: var(--sl-b0); display: block; }
.sl-grid i.h1 { background: var(--sl-b1); }
.sl-grid i.h2 { background: var(--sl-b2); }
.sl-grid i.h3 { background: var(--sl-b3); }
.sl-grid i.h4 { background: var(--sl-b4); }
.sl-heatkey { display: flex; align-items: center; gap: .3125rem; font-family: var(--sl-mono); font-size: .625rem; color: var(--bs-secondary-color); }
.sl-heatkey i { width: 11px; height: 11px; border-radius: 2px; display: block; }

/* Stacked distribution — 2px gaps in the surface color do the separating, so
   no segment needs a stroke (which would add ink that is not data). */
.sl-dist { display: flex; gap: 2px; height: 9px; }
.sl-dist i { display: block; height: 100%; border-radius: 1px; }
.sl-distleg { display: flex; gap: .875rem; flex-wrap: wrap; margin-top: .375rem; font-size: .6875rem; color: var(--bs-secondary-color); }
.sl-distleg span { display: inline-flex; align-items: center; gap: .3125rem; }
.sl-distleg b { color: var(--bs-body-color); font-weight: 550; font-variant-numeric: tabular-nums; }

/* Lifespan bar: where an entity sits inside the org's whole recorded window.
   A SPAN, never effort — sessions carry no duration and nothing here implies one. */
.sl-span { position: relative; height: 6px; background: var(--bs-tertiary-bg); border-radius: 3px; min-width: 5rem; }
.sl-span i { position: absolute; top: 0; height: 100%; background: var(--sl-b2); border-radius: 3px; display: block; }

/* Exercise timeline: one dot per DISTINCT PROJECT, placed in time.
   Filled = grounded, hollow = claimed. This is the capability's trajectory —
   it is what makes a stale skill visibly stale. */
.sl-dots { position: relative; height: 1rem; min-width: 8rem; }
.sl-dots::before { content: ""; position: absolute; left: 0; right: 0; top: 50%; border-top: 1px solid var(--bs-border-color); }
.sl-dots i { position: absolute; top: 50%; transform: translate(-50%, -50%); width: 9px; height: 9px; border-radius: 50%; box-shadow: 0 0 0 2px var(--bs-card-bg); cursor: help; }
.sl-dots i.g { background: var(--sl-b3); }
.sl-dots i.c { background: var(--bs-card-bg); border: 2px solid var(--sl-b1); }

.sl-meter { height: 6px; background: var(--sl-b1); border-radius: 3px; overflow: hidden; }
.sl-meter i { display: block; height: 100%; background: var(--sl-b3); border-radius: 3px; }

.sl-spark { display: block; }

/* Legend swatches — identity never rests on color alone, so every chart that
   uses the ramp names its steps in words too. */
.sl-legend { display: flex; gap: 1rem; flex-wrap: wrap; align-items: center; font-size: .6875rem; color: var(--bs-secondary-color); margin-top: .75rem; }
.sl-legend span { display: inline-flex; align-items: center; gap: .3125rem; }
.sl-sw { width: 9px; height: 9px; border-radius: 2px; display: inline-block; flex: none; }
.sl-sw.round { border-radius: 50%; }
.sl-sw.hollow { background: transparent; border: 2px solid var(--sl-b1); width: 8px; height: 8px; }

/* ---------------------------------- rows ----------------------------------- */

/* A list row that is a real link to a real page, not an accordion that hides a
   detail row inside the table it came from. */
.sl-rows { display: flex; flex-direction: column; }
.sl-row { display: grid; grid-template-columns: 1fr 12rem 9rem; gap: 1.125rem; align-items: center; padding: .75rem 0; border-bottom: 1px solid var(--bs-border-color); cursor: pointer; }
.sl-row:last-child { border-bottom: 0; }
.sl-row:hover { background: var(--bs-secondary-bg); }
.sl-row-nm { font-weight: 550; display: flex; align-items: center; gap: .5rem; flex-wrap: wrap; }
.sl-row-meta { font-size: .75rem; color: var(--bs-secondary-color); margin-top: .125rem; }
.sl-rank { font-family: var(--sl-mono); font-size: .8125rem; color: var(--bs-secondary-color); text-align: right; font-variant-numeric: tabular-nums; }

.sl-num { font-family: var(--sl-mono); font-variant-numeric: tabular-nums; text-align: right; }
.sl-mono { font-family: var(--sl-mono); }

/* Capability currency — pure date math on last-exercised, so a profile ages
   honestly instead of listing a skill nobody has touched in a year. */
.sl-cur { font-size: .6875rem; letter-spacing: .04em; padding: .0625rem .5rem; border-radius: 999px; border: 1px solid; white-space: nowrap; cursor: help; }
.sl-cur.cur { color: var(--sl-b4); border-color: rgba(85, 152, 231, .5); }
.sl-cur.rec { color: var(--bs-secondary-color); border-color: var(--bs-border-color); }
.sl-cur.dor { color: var(--bs-secondary-color); border-color: var(--bs-border-color); border-style: dotted; }

/* ------------------------------ inline editing ----------------------------- */

/* The one dialog pattern: a panel revealed in place, then a targeted re-render.
   Deliberately not a Bootstrap modal — a body-level backdrop does not survive
   the innerHTML re-render this architecture is built on. */
.sl-editor { margin-top: .625rem; padding: .75rem .875rem; background: var(--bs-secondary-bg); border: 1px solid var(--bs-border-color); border-radius: .375rem; display: flex; gap: .5rem; align-items: center; flex-wrap: wrap; }
.sl-editor .sl-err { color: var(--bs-danger-text-emphasis); font-size: .75rem; flex-basis: 100%; }
.sl-editor input[type="text"] { min-width: 15rem; }

/* --------------------------------- tooltip --------------------------------- */

#sl-tip { position: fixed; pointer-events: none; z-index: 1080; opacity: 0; transition: opacity .09s; background: var(--bs-tertiary-bg); border: 1px solid var(--bs-border-color); border-radius: .3125rem; padding: .375rem .5625rem; font-family: var(--sl-mono); font-size: .6875rem; color: var(--bs-body-color); box-shadow: 0 .375rem 1.25rem rgba(0, 0, 0, .5); max-width: 18rem; }
#sl-tip.on { opacity: 1; }
#sl-tip .tv { color: var(--bs-secondary-color); }

@media (prefers-reduced-motion: reduce) {
  #sl-tip { transition: none; }
}

@media (max-width: 720px) {
  .sl-row { grid-template-columns: 1fr !important; gap: .5rem; }
  .sl-answer { font-size: 1rem; }
}
