/* Angels — spatial design system.
 *
 * Built as a token system rather than a palette, because the last two attempts
 * failed by picking colours without fixing the causes of "flat and lifeless":
 * no consistent light source, no depth hierarchy, no type scale, and a slab
 * behind every paragraph.
 *
 * Three rules the whole thing obeys:
 *
 *   1. ONE LIGHT SOURCE, top-left. Every shadow falls the same way, every
 *      raised edge catches light on its top-left. Inconsistent lighting is what
 *      makes an interface read as flat no matter how good the colours are.
 *
 *   2. DE-BOXED. Text sits ON the field. Sections are separated by space,
 *      typography and a hairline that fades — not by a bordered slab. Elevation
 *      is reserved for things you can actually interact with, so depth means
 *      something instead of being decoration.
 *
 *   3. DEPTH IS EARNED. Four levels only: field (the page), surface (raised),
 *      float (interactive/hover), and lift (overlays). Anything else and depth
 *      stops reading as depth.
 */

/* ─── tokens: LIGHT IS THE DEFAULT ─────────────────────────────────────── */
/* Neythan, 30 Jul: whole platform in this style, light theme only for now.
   Light gets depth from layered surfaces and real shadow, not glow — glow on
   white reads as blur. The violet undertone keeps it the same product as dark.
   Both #sp and #ops carry the tokens so the legacy templates inherit them. */
#sp, #ops, #sp.light, #ops.light {
  --void:        #EDEAF6;
  --field:       #F7F5FC;
  --field-2:     #FFFFFF;
  --surface:     #FFFFFF;
  --surface-2:   #FBFAFF;
  --edge-light:  rgba(255,255,255,.92);   /* top-left catch light */
  --edge-dark:   rgba(60,45,120,.09);

  --ink:         #17123A;
  --ink-2:       #4A4270;
  --ink-3:       #6E6694;
  --ink-4:       #948CB5;

  --royal:       #5843E8;   /* royal blue-violet — the primary */
  --royal-lit:   #7461FF;
  --royal-deep:  #2E2196;
  --gold:        #A9812A;   /* accent, used sparingly */
  --good:        #14A278;
  --warn:        #C2770F;
  --bad:         #D64550;

  --hair:        rgba(60,45,120,.10);
  --hair-strong: rgba(60,45,120,.18);

  /* Shadow ramps. Multiple stacked shadows at increasing blur is what makes a
     surface look like it occupies space rather than having a drop-shadow. */
  --d-surface: 0 1px 1px rgba(40,30,90,.05), 0 3px 8px -3px rgba(40,30,90,.10);
  --d-float:   0 2px 4px rgba(40,30,90,.06), 0 10px 24px -8px rgba(40,30,90,.14),
               0 28px 56px -28px rgba(70,45,180,.18);
  --d-lift:    0 4px 8px rgba(40,30,90,.08), 0 20px 48px -14px rgba(40,30,90,.18),
               0 56px 100px -40px rgba(70,45,180,.22);
  --glow-royal: 0 0 0 1px rgba(88,67,232,.20), 0 8px 28px -10px rgba(88,67,232,.28);

  --r-sm: 8px; --r-md: 13px; --r-lg: 20px; --r-xl: 28px;

  --sans: "Inter", -apple-system, BlinkMacSystemFont, "SF Pro Text",
          "Segoe UI Variable Text", "Segoe UI", system-ui, sans-serif;
  --display: "Inter Display", -apple-system, BlinkMacSystemFont, "SF Pro Display",
             "Segoe UI Variable Display", "Segoe UI", system-ui, sans-serif;
  --mono: ui-monospace, "SF Mono", "Cascadia Mono", "JetBrains Mono", monospace;

  --ease: cubic-bezier(.22,.61,.36,1);
  --ease-out: cubic-bezier(.16,1,.3,1);
}

/* ─── tokens: dark (kept ready, not shipped — .dark opts in later) ─────── */
#sp.dark, #ops.dark {
  --void:        #08060F;
  --field:       #0E0A1E;
  --field-2:     #141029;
  --surface:     #1A1435;
  --surface-2:   #221A44;
  --edge-light:  rgba(190,175,255,.14);
  --edge-dark:   rgba(0,0,0,.5);

  --ink:         #F4F1FF;
  --ink-2:       #C3BAE6;
  --ink-3:       #8A7FB5;
  --ink-4:       #605780;

  --royal:       #6D5BFF;
  --royal-lit:   #8E7DFF;
  --royal-deep:  #3B2E9E;
  --gold:        #E3C169;
  --good:        #45D6A4;
  --warn:        #F0A94C;
  --bad:         #FF7A85;

  --hair:        rgba(160,145,220,.13);
  --hair-strong: rgba(160,145,220,.22);

  --d-surface: 0 1px 1px rgba(0,0,0,.30), 0 4px 10px -4px rgba(0,0,0,.45);
  --d-float:   0 2px 4px rgba(0,0,0,.28), 0 12px 28px -10px rgba(0,0,0,.60),
               0 32px 64px -32px rgba(70,45,180,.45);
  --d-lift:    0 4px 8px rgba(0,0,0,.32), 0 24px 56px -16px rgba(0,0,0,.70),
               0 64px 120px -48px rgba(70,45,180,.55);
  --glow-royal: 0 0 0 1px rgba(109,91,255,.30), 0 8px 32px -8px rgba(109,91,255,.45);
}

/* ─── the field ────────────────────────────────────────────────────────── */
*, *::before, *::after { box-sizing: border-box; }
html, body { margin: 0; }

#sp, #ops {
  min-height: 100vh;
  margin: 0;
  background: var(--field);
  color: var(--ink);
  font-family: var(--sans);
  font-size: 15px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  font-feature-settings: "cv11", "ss01";
  position: relative;
}

/* The WebGL ambient layer sits here — behind everything, never in the way.
   position is !important because the later `#ops > *` rule would otherwise
   flip it to relative, dropping a viewport-sized canvas INTO the page flow —
   which pushed the whole interface below the fold (the "empty first screen,
   nav at the bottom" bug, 30 Jul). */
#sp-field {
  position: fixed !important; inset: 0; z-index: 0;
  display: block;
  pointer-events: none;
  opacity: .5;                                /* light: a faint violet haze */
}
#sp.dark #sp-field, #ops.dark #sp-field { opacity: .85; }

/* A soft vignette so the field reads as depth rather than wallpaper. */
#sp::after, #ops::after {
  content: ""; position: fixed; inset: 0; z-index: 1; pointer-events: none;
  background:
    radial-gradient(120% 80% at 20% 0%, transparent 45%, rgba(80,65,150,.07) 100%),
    radial-gradient(80% 60% at 85% 100%, rgba(109,91,255,.07), transparent 60%);
}
#sp.dark::after, #ops.dark::after {
  background:
    radial-gradient(120% 80% at 20% 0%, transparent 40%, rgba(8,6,15,.55) 100%),
    radial-gradient(80% 60% at 85% 100%, rgba(59,46,158,.16), transparent 60%);
}

#sp > *:not(#sp-field), #ops > *:not(#sp-field) { position: relative; z-index: 2; }

/* ─── type scale ───────────────────────────────────────────────────────── */
/* Tight, confident display sizes; body stays comfortable. Negative tracking on
   large text is most of what separates "designed" from "default". */
.sp-h1 { font-family: var(--display); font-size: clamp(30px, 3.6vw, 46px);
         line-height: 1.04; letter-spacing: -.032em; font-weight: 620;
         margin: 0 0 10px; }
.sp-h2 { font-family: var(--display); font-size: clamp(21px, 2.1vw, 27px);
         line-height: 1.14; letter-spacing: -.021em; font-weight: 600;
         margin: 0 0 8px; }
.sp-h3 { font-size: 16px; font-weight: 590; letter-spacing: -.008em; margin: 0 0 4px; }
.sp-lede { font-size: clamp(15px, 1.35vw, 17.5px); line-height: 1.62;
           color: var(--ink-2); max-width: 68ch; margin: 0; font-weight: 380; }
.sp-body { color: var(--ink-2); max-width: 72ch; }
.sp-eyebrow { font-size: 11px; font-weight: 600; letter-spacing: .13em;
              text-transform: uppercase; color: var(--ink-4); margin: 0 0 12px; }
.sp-num { font-family: var(--display); font-variant-numeric: tabular-nums;
          letter-spacing: -.035em; font-weight: 630; line-height: .94; }
.sp-mono { font-family: var(--mono); font-size: .92em;
           font-variant-numeric: tabular-nums; }

/* ─── de-boxed sections ────────────────────────────────────────────────── */
/* A section is separated by space and a fading hairline. No slab, no border,
   no card. This is the single biggest change from the old look. */
.sp-section { padding: 34px 0 8px; position: relative; }
/* The first thing on a page starts AT THE TOP — no dead air before the header. */
.sp-section:first-child { padding-top: 10px !important; }
.sp-section + .sp-section { padding-top: 34px; }
.sp-section + .sp-section::before {
  content: ""; position: absolute; top: 0; left: 0; right: 0; height: 1px;
  background: linear-gradient(90deg, transparent, var(--hair) 12%,
              var(--hair) 62%, transparent);
}
.sp-section-head { display: flex; align-items: baseline; gap: 14px;
                   flex-wrap: wrap; margin-bottom: 20px; }
.sp-section-head .sp-h2 { margin: 0; }
.sp-section-head .sp-note { color: var(--ink-4); font-size: 13px; }
.sp-spacer { flex: 1; }

.sp-shell { max-width: 1360px; margin: 0 auto; padding: 0 clamp(20px, 3.5vw, 52px); }

/* ─── raised surfaces (only where you can act) ─────────────────────────── */
.sp-card {
  background: linear-gradient(160deg, var(--surface), var(--field-2));
  border-radius: var(--r-lg);
  box-shadow: var(--d-surface);
  border-top: 1px solid var(--edge-light);      /* the top-left catch light */
  border-left: 1px solid var(--edge-light);
  padding: 20px 22px;
  transition: transform .5s var(--ease-out), box-shadow .5s var(--ease-out);
}
a.sp-card, .sp-card.is-interactive { cursor: pointer; }
a.sp-card:hover, .sp-card.is-interactive:hover {
  transform: translateY(-3px);
  box-shadow: var(--d-float);
}

/* ─── metrics, de-boxed ───────────────────────────────────────────────── */
/* Numbers live on the field with a hairline between them, not in boxes. */
.sp-metrics { display: grid; gap: 0;
              grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); }
.sp-metric { padding: 4px 26px 4px 0; position: relative; }
.sp-metric + .sp-metric { padding-left: 26px; }
.sp-metric + .sp-metric::before {
  content: ""; position: absolute; left: 0; top: 8%; bottom: 8%; width: 1px;
  background: linear-gradient(180deg, transparent, var(--hair) 25%,
              var(--hair) 75%, transparent);
}
.sp-metric .v { font-family: var(--display); font-size: clamp(30px, 3.4vw, 42px);
                font-weight: 630; letter-spacing: -.038em; line-height: 1;
                font-variant-numeric: tabular-nums;
                background: linear-gradient(170deg, var(--ink), var(--ink-2));
                -webkit-background-clip: text; background-clip: text;
                -webkit-text-fill-color: transparent; }
.sp-metric .k { font-size: 12.5px; color: var(--ink-4); margin-top: 7px;
                letter-spacing: .012em; }
.sp-metric.is-good .v { background: linear-gradient(170deg, var(--good), var(--ink-2)); }
.sp-metric.is-warn .v { background: linear-gradient(170deg, var(--warn), var(--ink-2)); }
.sp-metric.is-bad  .v { background: linear-gradient(170deg, var(--bad),  var(--ink-2)); }
.sp-metric.is-good .v, .sp-metric.is-warn .v, .sp-metric.is-bad .v {
  -webkit-background-clip: text; background-clip: text;
  -webkit-text-fill-color: transparent; }

/* ─── rows, de-boxed ──────────────────────────────────────────────────── */
/* A list is hairlines and space, not a stack of bordered tiles. */
.sp-rows { display: flex; flex-direction: column; }
.sp-row {
  display: grid; grid-template-columns: auto 1fr auto; gap: 16px;
  align-items: start; padding: 15px 14px; border-radius: var(--r-md);
  text-decoration: none; color: inherit; position: relative;
  transition: background .32s var(--ease), transform .32s var(--ease);
}
.sp-row + .sp-row::before {
  content: ""; position: absolute; top: 0; left: 14px; right: 14px; height: 1px;
  background: var(--hair);
}
.sp-row:hover { background: var(--surface); transform: translateX(3px); }
.sp-row:hover::before, .sp-row:hover + .sp-row::before { opacity: 0; }
.sp-row .t { font-weight: 530; letter-spacing: -.004em; }
.sp-row .s { color: var(--ink-3); font-size: 13.2px; margin-top: 2px; }

/* ─── chips & pills ───────────────────────────────────────────────────── */
.sp-chip { display: inline-flex; align-items: center; gap: 6px;
           padding: 4px 11px; border-radius: 100px; font-size: 12px;
           font-weight: 520; letter-spacing: .004em;
           background: var(--surface-2); color: var(--ink-2);
           border: 1px solid var(--hair); white-space: nowrap; }
.sp-chip.is-good { color: var(--good); border-color: color-mix(in srgb, var(--good) 32%, transparent); }
.sp-chip.is-warn { color: var(--warn); border-color: color-mix(in srgb, var(--warn) 32%, transparent); }
.sp-chip.is-bad  { color: var(--bad);  border-color: color-mix(in srgb, var(--bad) 34%, transparent); }
.sp-chip.is-royal{ color: var(--royal-lit);
                   border-color: color-mix(in srgb, var(--royal) 40%, transparent);
                   background: color-mix(in srgb, var(--royal) 12%, transparent); }
.sp-dot { width: 6px; height: 6px; border-radius: 50%; background: currentColor;
          box-shadow: 0 0 10px currentColor; flex: none; }

/* ─── buttons ─────────────────────────────────────────────────────────── */
.sp-btn { display: inline-flex; align-items: center; gap: 8px;
          padding: 9px 17px; border-radius: 100px; font: inherit;
          font-size: 13.5px; font-weight: 540; cursor: pointer;
          text-decoration: none; color: var(--ink-2);
          background: var(--surface); border: 1px solid var(--hair);
          box-shadow: var(--d-surface);
          transition: transform .3s var(--ease-out), box-shadow .3s var(--ease-out),
                      color .3s var(--ease); }
.sp-btn:hover { color: var(--ink); transform: translateY(-1.5px);
                box-shadow: var(--d-float); }
.sp-btn.is-primary { color: #fff; border-color: transparent;
                     background: linear-gradient(150deg, var(--royal-lit), var(--royal-deep));
                     box-shadow: var(--glow-royal); }
.sp-btn.is-primary:hover { box-shadow: var(--glow-royal), var(--d-float); }

/* ─── nav ─────────────────────────────────────────────────────────────── */
/* Floating, not a slab across the top. */
.sp-nav { position: sticky; top: 0; z-index: 40;
          backdrop-filter: saturate(180%) blur(22px);
          -webkit-backdrop-filter: saturate(180%) blur(22px);
          background: color-mix(in srgb, var(--field) 72%, transparent);
          border-bottom: 1px solid var(--hair); }
.sp-nav-in { display: flex; align-items: center; gap: 2px;
             max-width: 1360px; margin: 0 auto;
             padding: 5px clamp(16px, 2.5vw, 40px);
             /* Neythan, 1 Aug 2026: wrap onto a second row rather than
                scrolling sideways — every destination visible at once */
             flex-wrap: wrap; row-gap: 0; }
.sp-brand { font-family: var(--display); font-weight: 640; letter-spacing: -.022em;
            font-size: 16px; color: var(--ink); text-decoration: none;
            margin-right: 18px; display: flex; align-items: center; gap: 9px; }
.sp-brand .mark { width: 26px; height: 26px; border-radius: 8px;
                  background: linear-gradient(150deg, var(--royal-lit), var(--royal-deep));
                  box-shadow: var(--glow-royal); display: grid; place-items: center;
                  font-size: 14px; }
.sp-nav a.item { padding: 6px 10px; border-radius: 100px; font-size: 12.8px;
                 font-weight: 500; color: var(--ink-3); text-decoration: none;
                 white-space: nowrap; flex: none;
                 transition: color .28s var(--ease), background .28s var(--ease); }
.sp-nav a.item:hover { color: var(--ink); background: var(--surface); }
.sp-nav a.item.on { color: var(--ink);
                    background: color-mix(in srgb, var(--royal) 16%, transparent);
                    box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--royal) 26%, transparent); }

/* ─── entrance motion ─────────────────────────────────────────────────── */
/* On state, not on scroll — the scrollbar stays yours. */
@keyframes sp-rise { from { opacity: 0; transform: translateY(14px); }
                     to   { opacity: 1; transform: none; } }
.sp-rise { animation: sp-rise .74s var(--ease-out) both; }
.sp-rise:nth-child(1) { animation-delay: .02s }
.sp-rise:nth-child(2) { animation-delay: .07s }
.sp-rise:nth-child(3) { animation-delay: .12s }
.sp-rise:nth-child(4) { animation-delay: .17s }
.sp-rise:nth-child(5) { animation-delay: .22s }
.sp-rise:nth-child(6) { animation-delay: .27s }

@media (prefers-reduced-motion: reduce) {
  .sp-rise { animation: none; }
  #sp-field { display: none; }
  * { transition-duration: .01ms !important; }
}

/* ─── grid helpers ────────────────────────────────────────────────────── */
.sp-grid { display: grid; gap: clamp(14px, 1.6vw, 22px); }
.sp-g2 { grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); }
.sp-g3 { grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); }
.sp-split { display: grid; grid-template-columns: 1.55fr 1fr;
            gap: clamp(20px, 3vw, 44px); align-items: start; }
@media (max-width: 1000px) { .sp-split { grid-template-columns: 1fr; } }

.sp-quiet { color: var(--ink-4); font-size: 13px; }
.sp-empty { color: var(--ink-4); padding: 22px 2px; font-size: 14px; }

/* ─── data as diagrams ─────────────────────────────────────────────────── */
/* Server-rendered SVG and CSS only — no chart library, nothing to load. */

/* Ring gauge: an SVG circle whose stroke length is the percentage. */
.sp-ring { position: relative; width: 120px; height: 120px; flex: none; }
.sp-ring svg { transform: rotate(-90deg); }
.sp-ring .track { fill: none; stroke: var(--hair-strong); stroke-width: 8; }
.sp-ring .val   { fill: none; stroke: url(#spRingGrad); stroke-width: 8;
                  stroke-linecap: round;
                  transition: stroke-dashoffset 1.2s var(--ease-out); }
.sp-ring .mid { position: absolute; inset: 0; display: grid; place-items: center;
                text-align: center; }
.sp-ring .mid .v { font-family: var(--display); font-size: 26px; font-weight: 640;
                   letter-spacing: -.03em; line-height: 1; }
.sp-ring .mid .k { font-size: 10.5px; color: var(--ink-4); margin-top: 3px;
                   letter-spacing: .06em; text-transform: uppercase; }

/* Bar chart: a flex row of columns. Height set inline as a percentage. */
.sp-bars { display: flex; align-items: flex-end; gap: 10px; height: 92px; }
.sp-bar { flex: 1; display: flex; flex-direction: column; align-items: center;
          gap: 7px; min-width: 0; height: 100%; justify-content: flex-end; }
.sp-bar .col { width: 100%; max-width: 34px; border-radius: 7px 7px 3px 3px;
               background: linear-gradient(180deg, var(--royal-lit), var(--royal));
               box-shadow: 0 4px 12px -4px color-mix(in srgb, var(--royal) 45%, transparent);
               min-height: 4px;
               transition: transform .3s var(--ease-out); }
.sp-bar:hover .col { transform: scaleY(1.03); transform-origin: bottom; }
.sp-bar.is-today .col { background: linear-gradient(180deg, var(--gold), #8a6a1e); }
.sp-bar.is-gap .col { background: linear-gradient(180deg, var(--bad),
                       color-mix(in srgb, var(--bad) 60%, #000 10%)); }
.sp-bar .l { font-size: 10.5px; color: var(--ink-4); letter-spacing: .04em; }
.sp-bar .n { font-size: 11.5px; font-weight: 600; color: var(--ink-2);
             font-variant-numeric: tabular-nums; }

/* Meter: a thin horizontal gauge for inline percentages. */
.sp-meter { height: 6px; border-radius: 100px; background: var(--hair);
            overflow: hidden; }
.sp-meter > i { display: block; height: 100%; border-radius: 100px;
                background: linear-gradient(90deg, var(--royal), var(--royal-lit)); }
.sp-meter.is-good > i { background: linear-gradient(90deg, var(--good), #35c893); }
.sp-meter.is-warn > i { background: linear-gradient(90deg, var(--warn), #e09a2f); }
.sp-meter.is-bad  > i { background: linear-gradient(90deg, var(--bad), #ef6a75); }

/* Delta chip: a number with direction, for "vs last week". */
.sp-delta { font-size: 12px; font-weight: 600; font-variant-numeric: tabular-nums; }
.sp-delta.up { color: var(--bad); }        /* more flags = worse, so up is red */
.sp-delta.down { color: var(--good); }

/* ─── the worklist table ───────────────────────────────────────────────── */
/* De-boxed: hairlines between rows, no cell borders, generous rhythm. */
.sp-table { width: 100%; border-collapse: collapse; }
.sp-table th { text-align: left; font-size: 11px; font-weight: 620;
               letter-spacing: .09em; text-transform: uppercase;
               color: var(--ink-4); padding: 6px 12px 10px;
               border-bottom: 1px solid var(--hair-strong); }
.sp-table td { padding: 13px 12px; border-bottom: 1px solid var(--hair);
               vertical-align: middle; }
.sp-table tr:last-child td { border-bottom: none; }
.sp-table tbody tr { transition: background .28s var(--ease); }
.sp-table tbody tr:hover { background: var(--surface); }
.sp-table .t { font-weight: 530; letter-spacing: -.004em; }
.sp-table .s { color: var(--ink-3); font-size: 13px; margin-top: 2px; }
.sp-table form { margin: 0; }

/* ─── needs a decision: two-up worklist ────────────────────────────────── */
/* Neythan, 31 Jul: two decisions per row, a line down the middle, and use
   the spare width either side of the canvas — half the rows, less scrolling. */
.sp-breakout { width: min(100vw - 56px, 1720px); position: relative;
               left: 50%; transform: translateX(-50%); }
.sp-decide-card { padding: 4px 8px 8px; }
.sp-decide-grid { --dcols: 118px minmax(0, 1fr) 150px 52px;
                  display: grid; grid-template-columns: 1fr 1fr;
                  position: relative; }
.sp-decide-grid::before {           /* the centre divider */
  content: ""; position: absolute; top: 0; bottom: 0; left: 50%;
  width: 1px; background: var(--hair-strong);
}
.sp-decide-head, .sp-decide-cell {
  display: grid; grid-template-columns: var(--dcols); gap: 14px;
  align-items: center; padding: 13px 16px;
}
.sp-decide-head { padding: 8px 16px 10px; font-size: 11px; font-weight: 620;
                  letter-spacing: .09em; text-transform: uppercase;
                  color: var(--ink-4);
                  border-bottom: 1px solid var(--hair-strong); }
.sp-decide-cell { border-bottom: 1px solid var(--hair);
                  transition: background .28s var(--ease); }
/* long kinds ("medicine not available") must wrap inside the type column,
   not run over the message text — chips are nowrap everywhere else */
.sp-decide-cell > span { min-width: 0; }
.sp-decide-cell .sp-chip { white-space: normal; line-height: 1.3;
                           padding-top: 3px; padding-bottom: 3px; }
.sp-decide-cell:hover { background: var(--surface); }
.sp-decide-cell .t { font-weight: 530; letter-spacing: -.004em;
                     font-size: 13.8px; }
.sp-decide-cell .s { color: var(--ink-3); font-size: 12.8px; margin-top: 2px; }
.sp-decide-cell form { margin: 0; }
/* last row loses its hairline: the last cell always; its left-hand partner
   only when the count is even (partner = second-to-last AND in the left col,
   i.e. an odd nth-child once the two header strips are counted) */
.sp-decide-cell:last-child,
.sp-decide-cell:nth-last-child(2):nth-child(odd) { border-bottom: none; }
@media (max-width: 980px) {
  .sp-decide-grid { grid-template-columns: 1fr; }
  .sp-decide-grid::before { display: none; }
  .sp-decide-head:nth-child(2) { display: none; }
  .sp-decide-grid .sp-decide-cell:nth-last-child(2) { border-bottom: 1px solid var(--hair); }
}
/* The Watch wears the same table: Type | Signal | Go | Done. A tick records
   who dealt with it (the audit trail) and suppresses it for a week — it
   returns if the data still says it. */
.sp-watch-grid { --dcols: 118px minmax(0, 1fr) 90px 52px; }

/* ─── the issues page (/ops/issues/) ───────────────────────────────────── */
/* All three surfaces in one place; the Act column holds ✓ done and
   ✕ not-an-issue (which opens the explain-why dialog). */
.sp-issues-grid { --dcols: 118px minmax(0, 1fr) 130px 96px; }
.iss-acts { display: flex; gap: 6px; align-items: center; }
.iss-acts form { margin: 0; }
.iss-acts .sp-btn { padding: 6px 11px; }
.ni-dialog { border: 0; border-radius: var(--r-lg); padding: 22px 24px;
             max-width: 520px; width: calc(100vw - 40px);
             background: linear-gradient(160deg, var(--surface), var(--field-2));
             box-shadow: var(--d-float); color: var(--ink); }
.ni-dialog::backdrop { background: rgba(28, 30, 48, .38);
                       backdrop-filter: blur(3px); }

/* ─── the signal journey page (/ops/signal/<fp>/) ──────────────────────── */
/* A deck row unpacks into its own staged page: finding → receipts → act.
   Nothing hits all at once — sp-rise staggers each layer in. */
.sig-evs { display: grid; gap: 12px; }
.sig-ev { display: flex; align-items: center; justify-content: space-between;
          gap: 16px; padding: 16px 20px; text-decoration: none; color: inherit; }
.sig-ev .t { display: block; font-weight: 530; font-size: 14.5px;
             letter-spacing: -.004em; }
.sig-ev .s { display: block; color: var(--ink-3); font-size: 13px; margin-top: 3px; }
.sig-ev .go { color: var(--royal, #5843E8); font-size: 13px; font-weight: 600;
              white-space: nowrap; }
.sig-acts { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; }
.sig-acts form { margin: 0; }
.sig-note { margin-top: 12px; padding: 12px 16px; border-radius: 8px;
            border-left: 3px solid color-mix(in srgb, var(--royal, #5843E8) 35%, transparent);
            background: var(--field-2); font-size: 14px; line-height: 1.65;
            color: var(--ink-2); font-style: italic; }
/* three-column deck tables: the row's text IS the journey — no generic Go.
   The Act column carries the explicit "Open" (the journey), ✓ done and
   ✕ not-an-issue, so the journey is never hidden behind a subtle link. */
.sp-3col { --dcols: 118px minmax(0, 1fr) 150px; }
.sp-3col-acts { --dcols: 118px minmax(0, 1fr) 210px; }
/* the journey button — deliberately the blue one on every issue row, so the
   way in is never a subtle text link (Neythan asked twice; that's the lesson) */
.sp-btn.is-open { color: var(--royal, #5843E8); font-weight: 620;
                  border-color: color-mix(in srgb, var(--royal, #5843E8) 42%, transparent);
                  background: color-mix(in srgb, var(--royal, #5843E8) 8%, transparent);
                  white-space: nowrap; }
.sp-btn.is-open:hover { color: #fff; background: var(--royal, #5843E8);
                        border-color: var(--royal, #5843E8); }
/* a deck row's text is the door into its journey */
.sig-link { color: inherit; text-decoration: none;
            border-bottom: 1px dashed color-mix(in srgb, var(--royal, #5843E8) 38%, transparent);
            transition: color .25s var(--ease), border-color .25s var(--ease); }
.sig-link:hover { color: var(--royal, #5843E8);
                  border-bottom-color: var(--royal, #5843E8); }

/* ─── the review document (/ops/review/<pk>/) ──────────────────────────── */
/* Rendered as the FINISHED document — white sheet, letterhead, numbered
   sections, and the signing space empty until a person approves. A faint
   diagonal watermark says "pending review" while it is a draft. */
.doc-sheet { position: relative; overflow: hidden; background: #fffefc;
             border-radius: 10px; box-shadow: var(--d-float);
             border-top: 1px solid var(--edge-light);
             border-left: 1px solid var(--edge-light);
             padding: clamp(28px, 5vw, 58px); }
.doc-watermark { position: absolute; inset: 0; display: flex; align-items: center;
                 justify-content: center; pointer-events: none;
                 transform: rotate(-24deg); font-size: clamp(48px, 9vw, 92px);
                 font-weight: 800; letter-spacing: .12em;
                 color: rgba(194, 119, 15, .07); white-space: nowrap; }
.doc-head { border-bottom: 2px solid #232a40; padding-bottom: 18px; margin-bottom: 26px; }
.doc-org { font-size: 12px; font-weight: 650; letter-spacing: .14em;
           text-transform: uppercase; color: var(--royal, #5843E8); }
.doc-title { font-family: Georgia, 'Iowan Old Style', serif; font-size: 30px;
             font-weight: 650; color: #1d2338; margin: 8px 0 10px;
             letter-spacing: -.01em; }
.doc-meta { display: flex; gap: 18px; flex-wrap: wrap; font-size: 13px;
            color: #4a5068; }
.doc-h { display: flex; align-items: baseline; gap: 10px;
         font-family: Georgia, 'Iowan Old Style', serif; font-size: 17.5px;
         font-weight: 650; color: #232a40; margin: 26px 0 10px; }
.doc-h .n { font-size: 12px; font-weight: 700; color: var(--royal, #5843E8);
            font-family: var(--font, ui-sans-serif); }
.doc-p { font-size: 14.5px; line-height: 1.7; color: #2b3248; margin: 8px 0; }
.doc-li { position: relative; padding-left: 20px; font-size: 14.5px;
          line-height: 1.65; color: #2b3248; margin: 5px 0; }
.doc-li::before { content: "–"; position: absolute; left: 4px; color: var(--royal, #5843E8); }
.doc-signblock { margin-top: 40px; padding-top: 22px; border-top: 1px solid rgba(35, 42, 64, .25); }
.doc-signlabel { font-size: 12px; font-weight: 650; letter-spacing: .1em;
                 text-transform: uppercase; color: #4a5068; margin-bottom: 22px; }
.doc-signrow { display: flex; gap: 28px; flex-wrap: wrap; }
.doc-signcell { flex: 1; min-width: 140px; }
.doc-signline { height: 40px; border-bottom: 1.4px solid #232a40;
                display: flex; align-items: flex-end; padding-bottom: 4px;
                font-size: 15px; color: #1d2338; }
.doc-signed { font-family: 'Segoe Script', 'Brush Script MT', Georgia, cursive;
              font-size: 21px; color: #2b3560; }
.doc-signkey { font-size: 11px; color: #6a7088; margin-top: 5px;
               letter-spacing: .05em; text-transform: uppercase; }
.doc-signnote { margin-top: 16px; font-size: 12.5px; color: #6a7088; }

/* ─── the messages notebook ────────────────────────────────────────────── */
/* Neythan, 31 Jul: messages as a diary — they appear on ruled lines and get
   ticked off like on a notebook. An open spread: left page = for me,
   right page = what I sent (watching it get ticked by others). */
.sp-spread {
  --nb-rule: 36px;                       /* the ruling; every line sits on it */
  position: relative; display: grid; grid-template-columns: 1fr 34px 1fr;
  border-radius: var(--r-lg);
  background: linear-gradient(174deg, #fffefa, #f9f5ea);
  box-shadow: var(--d-surface);
  border-top: 1px solid var(--edge-light);
  border-left: 1px solid var(--edge-light);
  overflow: hidden;
}
.nb-spine {                              /* the fold + stitching */
  background: linear-gradient(90deg, rgba(40, 42, 70, 0) 6%,
              rgba(40, 42, 70, .07) 44%, rgba(40, 42, 70, .13) 50%,
              rgba(40, 42, 70, .07) 56%, rgba(40, 42, 70, 0) 94%);
  position: relative;
}
.nb-spine::before {
  content: ""; position: absolute; top: 10px; bottom: 10px; left: 50%;
  border-left: 2px dashed rgba(90, 95, 130, .22);
}
.nb-page { position: relative; padding: 22px 22px 30px 62px; min-width: 0; }
.nb-page::before {                       /* the red margin rule */
  content: ""; position: absolute; top: 0; bottom: 0; left: 46px;
  width: 1.5px; background: rgba(214, 69, 80, .28);
}
.nb-page::after {                        /* punched holes down the bound edge */
  content: ""; position: absolute; top: 0; bottom: 0; width: 26px;
  background-image: radial-gradient(circle at 13px 18px,
      #edeade 5.5px, rgba(45, 48, 75, .16) 6px 7px, transparent 8px);
  background-size: 26px 108px; background-position: 0 34px;
  background-repeat: repeat-y;
}
.nb-page:first-child::after { left: 10px; }        /* left page: outer edge */
.nb-page:last-child::after { left: auto; right: 10px; }  /* right page: outer */
.nb-lines {                              /* the ruling itself */
  background-image: repeating-linear-gradient(to bottom,
      transparent 0, transparent calc(var(--nb-rule) - 1px),
      rgba(96, 118, 200, .20) calc(var(--nb-rule) - 1px),
      rgba(96, 118, 200, .20) var(--nb-rule));
  min-height: calc(var(--nb-rule) * 5);
}
.nb-title { font-family: Georgia, 'Iowan Old Style', 'Times New Roman', serif;
            font-style: italic; font-weight: 650; font-size: 16.5px;
            line-height: var(--nb-rule); color: #262d44;
            display: flex; align-items: baseline; gap: 10px; }
.nb-title .nb-count { font-family: inherit; font-size: 12.5px;
                      font-weight: 480; color: rgba(214, 69, 80, .75); }
.nb-line { position: relative; display: flex; gap: 9px;
           align-items: flex-start; min-height: var(--nb-rule); }
.nb-text { flex: 1; min-width: 0;
           font-family: Georgia, 'Iowan Old Style', 'Times New Roman', serif;
           font-style: italic; font-size: 14.6px; line-height: var(--nb-rule);
           color: #2b3248; letter-spacing: .002em; }
.nb-meta { font-family: inherit; font-size: 11.8px; color: rgba(75, 82, 108, .62);
           margin-left: 7px; white-space: nowrap; }
.nb-tag { display: inline-block; font-family: var(--font, ui-sans-serif, system-ui);
          font-style: normal; font-size: 9.5px; font-weight: 650;
          letter-spacing: .07em; text-transform: uppercase;
          padding: 1px 7px; border-radius: 100px; vertical-align: 2px;
          margin-right: 6px; color: var(--royal, #5843E8);
          border: 1px solid color-mix(in srgb, var(--royal, #5843E8) 30%, transparent); }
.nb-tag.is-office { color: #8a6d1f; border-color: rgba(194, 119, 15, .35); }
/* the tick lives in the margin, left of the red rule — like a real notebook */
.nb-line .nb-tickform { position: absolute; left: -46px;
                        top: calc((var(--nb-rule) - 23px) / 2); margin: 0; }
.nb-acts form { margin: 0; }
.nb-tick { width: 23px; height: 23px; border-radius: 50%;
           border: 1.6px solid rgba(88, 96, 128, .45); background: transparent;
           color: transparent; font-size: 13px; line-height: 1; cursor: pointer;
           display: inline-flex; align-items: center; justify-content: center;
           transition: all .25s var(--ease); }
.nb-tick:hover { border-color: var(--good); color: var(--good);
                 background: rgba(20, 162, 120, .09); transform: scale(1.08); }
.nb-done-mark { position: absolute; left: -46px;
                top: calc((var(--nb-rule) - 23px) / 2);
                width: 23px; height: 23px; border-radius: 50%;
                border: 1.6px solid var(--good); color: var(--good);
                background: rgba(20, 162, 120, .10); font-size: 13px;
                display: inline-flex; align-items: center; justify-content: center; }
.nb-line.is-done .nb-text { color: rgba(72, 80, 104, .42);
    text-decoration: line-through;
    text-decoration-color: rgba(80, 90, 120, .48);
    text-decoration-thickness: 1.4px; }
.nb-line.is-done .nb-tag { opacity: .45; }
.nb-line .nb-acts { display: flex; gap: 6px; align-items: center;
                    height: var(--nb-rule); flex: none; }
.nb-acts .sp-btn { padding: 4px 11px; font-size: 12px; }
.nb-wait { font-family: var(--font, ui-sans-serif, system-ui); font-style: normal;
           font-size: 11px; font-weight: 620; letter-spacing: .05em;
           text-transform: uppercase; color: #8a6d1f; flex: none;
           line-height: var(--nb-rule); }
.nb-blank { font-family: Georgia, serif; font-style: italic; font-size: 13.5px;
            line-height: var(--nb-rule); color: rgba(90, 96, 120, .45); }
@media (max-width: 1000px) {
  .sp-spread { grid-template-columns: 1fr; }
  .nb-spine { display: none; }
  .nb-page:last-child::after { left: 10px; right: auto; }
}

/* ─── the composer (journal / messages) ────────────────────────────────── */
.sp-composer { background: linear-gradient(160deg, var(--surface), var(--field-2));
               border-radius: var(--r-lg); box-shadow: var(--d-surface);
               border-top: 1px solid var(--edge-light);
               border-left: 1px solid var(--edge-light); padding: 16px 18px; }
.sp-composer textarea { width: 100%; border: 0; background: transparent;
                        color: var(--ink); font: inherit; font-size: 14.5px;
                        resize: vertical; min-height: 54px; outline: none; }
.sp-composer .row { display: flex; gap: 8px; flex-wrap: wrap; align-items: center;
                    margin-top: 10px; padding-top: 12px;
                    border-top: 1px solid var(--hair); }
.sp-composer select, .sp-composer input[type=date] {
  background: var(--surface-2); border: 1px solid var(--hair);
  border-radius: 100px; color: var(--ink-2); padding: 6px 12px;
  font: inherit; font-size: 12.5px; }
.sp-composer select:focus, .sp-composer input:focus { outline: none;
  border-color: color-mix(in srgb, var(--royal) 45%, transparent); }

.sp-navbadge { display: inline-grid; place-items: center; min-width: 18px;
               height: 18px; padding: 0 5px; border-radius: 100px;
               background: var(--bad); color: #fff; font-size: 10.5px;
               font-weight: 700; margin-left: 6px; }

/* ══════════════════════════════════════════════════════════════════════ */
/* BRIDGE — ops.css still loads underneath this file, because it styles    */
/* the long tail (tab bars, client profile sections, the rota grid, the    */
/* journal feed, timesheets) that the compat layer below does not repeat.  */
/* Its rules are written against ITS variable names; mapping those names   */
/* onto the spatial palette makes every old structure render in the new    */
/* light scheme. Removing ops.css without covering all of this was the     */
/* 30 Jul bug: half the platform fell back to unstyled links.              */
/* ══════════════════════════════════════════════════════════════════════ */
#ops, #ops.light {
  --bg:        var(--field);
  --bg2:       var(--field-2);
  --raise:     var(--surface-2);
  --ink-soft:  var(--ink-2);
  --ink-faint: var(--ink-3);
  --line:      var(--hair-strong);
  --line-soft: var(--hair);
  --accent:    var(--royal);
  --accent-ink: var(--royal-deep);
  --accent-soft: rgba(88,67,232,.10);
  --gold-soft:   rgba(169,129,42,.12);
  --violet:    var(--royal-lit);
  --blue:      var(--royal);
  --glow:      var(--d-surface);
  --lift:      var(--d-float);
  --serif:     var(--display);
}

/* ══════════════════════════════════════════════════════════════════════ */
/* LEGACY COMPATIBILITY — the 45 existing templates, restyled in place.    */
/* Same class names the old ops.css served, spoken in the new language, so */
/* every page inherits the system without being rewritten. Pages get       */
/* properly re-cut one at a time; this keeps the whole platform coherent   */
/* in the meantime.                                                        */
/* ══════════════════════════════════════════════════════════════════════ */

#ops .canvas { max-width: 1360px; margin: 0 auto;
               padding: 12px clamp(20px, 3.5vw, 52px) 90px; }

/* Page titles: removed 30 Jul, put BACK the same evening — "it looks better
   with them". Kept compact so the content still starts high. */
#ops h1.deck { font-family: var(--display); font-size: clamp(24px, 2.6vw, 34px);
               line-height: 1.06; letter-spacing: -.026em; font-weight: 620;
               margin: 4px 0 6px; }
#ops .deck-sub { font-size: 14.5px; line-height: 1.55; color: var(--ink-2);
                 max-width: 70ch; margin: 0 0 16px; font-weight: 380; }
#ops .deck-sub { font-size: 15.5px; line-height: 1.62; color: var(--ink-2);
                 max-width: 70ch; margin: 0 0 22px; font-weight: 380; }
#ops h2 { font-family: var(--display); letter-spacing: -.018em; font-weight: 600; }
#ops h3 { font-weight: 590; letter-spacing: -.008em; }
#ops a { color: var(--royal); }
#ops a:hover { color: var(--royal-lit); }
#ops .muted { color: var(--ink-3); }
#ops .empty { color: var(--ink-4); padding: 18px 2px; }

/* the agent bar: de-slabbed into a quiet strip under the title */
#ops .agentbar { display: flex; align-items: center; gap: 9px; flex-wrap: wrap;
                 background: transparent; border: 0; padding: 10px 0 14px;
                 border-bottom: 1px solid var(--hair); margin-bottom: 18px; }
#ops .agentbar .ai { font-size: 11px; font-weight: 620; letter-spacing: .1em;
                     text-transform: uppercase; color: var(--royal);
                     background: color-mix(in srgb, var(--royal) 10%, transparent);
                     border: 1px solid color-mix(in srgb, var(--royal) 22%, transparent);
                     border-radius: 100px; padding: 4px 11px; }
#ops .flag { display: inline-flex; align-items: center; gap: 6px;
             padding: 4px 11px; border-radius: 100px; font-size: 12.2px;
             font-weight: 520; background: var(--surface-2); color: var(--ink-2);
             border: 1px solid var(--hair); }
#ops .flag.good { color: var(--good);
                  border-color: color-mix(in srgb, var(--good) 30%, transparent); }
#ops .flag.warn { color: var(--warn);
                  border-color: color-mix(in srgb, var(--warn) 30%, transparent); }
#ops .flag.bad  { color: var(--bad);
                  border-color: color-mix(in srgb, var(--bad) 32%, transparent); }
#ops .spacer, #ops .sp { flex: 1; }

/* stats: de-boxed metrics with hairline dividers, not tiles */
#ops .stats { display: grid; gap: 0; margin: 16px 0 22px;
              grid-template-columns: repeat(auto-fit, minmax(130px, 1fr)); }
#ops .stat { background: transparent; border: 0; box-shadow: none;
             padding: 4px 22px 4px 0; position: relative; border-radius: 0; }
#ops .stat + .stat { padding-left: 22px; }
#ops .stat + .stat::before { content: ""; position: absolute; left: 0; top: 10%;
  bottom: 10%; width: 1px;
  background: linear-gradient(180deg, transparent, var(--hair) 25%,
              var(--hair) 75%, transparent); }
#ops .stat .n { font-family: var(--display); font-size: clamp(26px, 2.8vw, 36px);
                font-weight: 630; letter-spacing: -.036em; line-height: 1;
                font-variant-numeric: tabular-nums; color: var(--ink); }
#ops .stat .k { font-size: 12px; color: var(--ink-4); margin-top: 6px; }
#ops .stat.good .n { color: var(--good); }
#ops .stat.warn .n { color: var(--warn); }
#ops .stat.miss .n, #ops .stat.bad .n { color: var(--bad); }
#ops .stat.acc .n { color: var(--royal); }

/* panels: soft raised surfaces — one shadow language everywhere */
#ops .panel { background: linear-gradient(160deg, var(--surface), var(--field-2));
              border: 0; border-top: 1px solid var(--edge-light);
              border-left: 1px solid var(--edge-light);
              border-radius: var(--r-lg); box-shadow: var(--d-surface);
              padding: 18px 20px; }
#ops .phead { display: flex; align-items: center; gap: 10px; font-weight: 590;
              letter-spacing: -.006em; font-size: 15px; margin-bottom: 6px; }
#ops details.panel > summary { cursor: pointer; }

/* items: hairline rows, not bordered tiles */
#ops .item { display: grid; grid-template-columns: auto 1fr auto; gap: 14px;
             align-items: start; background: transparent; border: 0;
             border-radius: var(--r-md); padding: 12px 10px; position: relative;
             transition: background .3s var(--ease); }
#ops .item + .item::before { content: ""; position: absolute; top: 0; left: 10px;
  right: 10px; height: 1px; background: var(--hair); }
#ops .item:hover { background: var(--surface-2); }

/* chips */
#ops .cchip { display: inline-flex; align-items: center; padding: 4px 11px;
              border-radius: 100px; font-size: 11.8px; font-weight: 560;
              border: 1px solid var(--hair); background: var(--surface-2);
              color: var(--ink-2); white-space: nowrap; }
#ops .cchip.c-active { color: var(--good);
  border-color: color-mix(in srgb, var(--good) 30%, transparent);
  background: color-mix(in srgb, var(--good) 8%, transparent); }
#ops .cchip.c-on_hold { color: var(--warn);
  border-color: color-mix(in srgb, var(--warn) 30%, transparent);
  background: color-mix(in srgb, var(--warn) 8%, transparent); }
#ops .cchip.c-archived { color: var(--bad);
  border-color: color-mix(in srgb, var(--bad) 30%, transparent);
  background: color-mix(in srgb, var(--bad) 8%, transparent); }

/* buttons */
#ops .btn, #ops .tbtn, #ops .act {
  display: inline-flex; align-items: center; gap: 7px; padding: 8px 15px;
  border-radius: 100px; font: inherit; font-size: 13px; font-weight: 540;
  cursor: pointer; text-decoration: none; color: var(--ink-2);
  background: var(--surface); border: 1px solid var(--hair);
  box-shadow: var(--d-surface);
  transition: transform .28s var(--ease-out), box-shadow .28s var(--ease-out),
              color .28s var(--ease); }
#ops .btn:hover, #ops .tbtn:hover, #ops .act:hover {
  color: var(--ink); transform: translateY(-1.5px); box-shadow: var(--d-float); }
#ops .btn.primary, #ops .act.primary { color: #fff; border-color: transparent;
  background: linear-gradient(150deg, var(--royal-lit), var(--royal-deep));
  box-shadow: var(--glow-royal); }

/* week navigation strip */
#ops .weeknav { display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
                margin: 0 0 14px; }
#ops .weeknav .wk { font-family: var(--display); font-weight: 600;
                    letter-spacing: -.012em; }

/* messages */
#ops .msgs { margin: 0 0 14px; }
#ops .msg { background: color-mix(in srgb, var(--royal) 8%, var(--surface));
            border: 1px solid color-mix(in srgb, var(--royal) 22%, transparent);
            border-radius: var(--r-md); padding: 10px 14px; margin-bottom: 6px;
            font-size: 13.5px; }

/* tables */
#ops table { border-collapse: collapse; }
#ops th { color: var(--ink-4); font-weight: 560; font-size: 12px;
          letter-spacing: .04em; }
#ops td, #ops th { border-color: var(--hair); }

/* forms */
#ops input[type=text], #ops input[type=date], #ops input[type=time],
#ops input[type=email], #ops input[type=number], #ops input[type=password],
#ops select, #ops textarea {
  background: var(--surface-2); border: 1px solid var(--hair);
  border-radius: var(--r-sm); color: var(--ink); padding: 8px 11px;
  font: inherit; font-size: 13.5px; }
#ops input:focus, #ops select:focus, #ops textarea:focus { outline: none;
  border-color: color-mix(in srgb, var(--royal) 45%, transparent);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--royal) 12%, transparent); }

/* rostering chips keep their look but in the new light */
#ops .runchip { background: var(--surface-2); border: 1px solid var(--hair);
                color: var(--ink-2); }
#ops .runchip em { color: var(--royal); }
#ops .navbadge { display: inline-grid; place-items: center; min-width: 17px;
                 height: 17px; padding: 0 5px; border-radius: 100px;
                 background: var(--bad); color: #fff; font-size: 10px;
                 font-weight: 700; margin-left: 6px; }
