/* Fujitsu TMSP — Fujitsu PT - TMS Management Portal
   Base tokens (dark) + the themes: Windows Vista, Fujitsu Lounge (Light and
   Dark), Fujitsu View (Light and Dark), and Fujitsu TMSP 01, retired from
   tmsp_themes() on 2026-10-03 but still carried here (see that function).
   Every colour is a token on :root; each theme redefines the same tokens in
   its own :root[data-theme="<slug>"] blocks, then repaints the chrome in a
   structural section scoped to that selector.
*/

@import url('https://fonts.googleapis.com/css2?family=Open+Sans:wght@400;600;700&display=swap');

:root{
  --bg0:#04050a;
  --bg1:#070912;
  --panel: rgba(18,20,28,.86);
  --line: rgba(255,255,255,.10);

  --text:#eef1f7;
  --muted:#aab2bf;

  --red:#ff2b2b;
  --red2:#ff5a5a;

  --shadow: 0 0 48px rgba(255,43,43,.18);
  --shadow2: 0 0 90px rgba(255,43,43,.28);

  --radius: 22px;
  --font: ui-sans-serif, system-ui, -apple-system, Segoe UI, Roboto, Arial, sans-serif;
  --mono: 'JetBrains Mono', ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;

  /* ── Semantic tokens ─────────────────────────────────────────────────────
     Generated from the literals that already existed: in Crimson Hive each token
     is worth exactly the colour it replaced, so this theme changes nothing.
     The light themes redefine them in their :root[data-theme="<slug>"]
     blocks further down.

       --ov-NN     light overlay on the background (borders, separators, hover)
       --sink-NN   recessed background (inputs, terminal) — lightens in light themes
       --sh-NN     drop shadow — stays dark in light themes
       --red-NN    the accent, at various opacities
       --rc-*      the header reactor
     New colours must use these tokens; a literal only works in one theme. */
  --amber-40: rgba(255,230,0,0.4);
  --amber-45: rgba(255,230,0,0.45);
  --amber-90: rgba(255,230,0,0.9);
  --amber-100: rgba(255,230,0,1.0);
  --amber-b-25: rgba(255,220,0,0.25);
  --amber-b-65: rgba(255,220,0,0.65);
  --amber-bg-70: rgba(40,32,0,0.7);
  --amber-c-10: rgba(255,200,0,0.1);
  --amber-d-90: rgba(255,235,0,0.9);
  --amber-solid: #ffaa55;
  --black: #000000;
  --blue-btn-10: rgba(0,140,255,0.1);
  --blue-btn-12: rgba(0,140,255,0.12);
  --blue-btn-20: rgba(0,140,255,0.2);
  --blue-btn-22: rgba(0,140,255,0.22);
  --blue-btn-38: rgba(0,140,255,0.38);
  --blue-btn-40: rgba(0,140,255,0.4);
  --blue-btn2-18: rgba(0,160,255,0.18);
  --blue-btn2-22: rgba(0,160,255,0.22);
  --blue-btn2-40: rgba(0,160,255,0.4);
  --blue-btn2-65: rgba(0,160,255,0.65);
  --blue-btn3-28: rgba(0,180,255,0.28);
  --blue-btn3-35: rgba(0,180,255,0.35);
  --blue-btn4-95: rgba(0,200,255,0.95);
  --danger: #f87171;
  --danger-09: rgba(248,113,113,0.09);
  --danger-15: rgba(248,113,113,0.15);
  --danger-30: rgba(248,113,113,0.3);
  --deep-98: rgba(8,10,18,0.98);
  --deep-b-90: rgba(10,16,26,0.9);
  --deep-c-97: rgba(10,10,18,0.97);
  --deep-d-97: rgba(6,8,18,0.97);
  --deep-e-97: rgba(10,6,6,0.97);
  --deep-solid: #0a0c14;
  --deep-solid2: #06070c;
  --error-text: #ffd6d6;
  --green-btn-22: rgba(0,210,100,0.22);
  --green-btn-65: rgba(0,210,100,0.65);
  --green-btn2-28: rgba(0,230,110,0.28);
  --green-btn2-35: rgba(0,230,110,0.35);
  --green-btn3-22: rgba(0,190,90,0.22);
  --green-btn4-12: rgba(0,180,80,0.12);
  --green-btn5-95: rgba(0,255,120,0.95);
  --green-btn6-20: rgba(0,200,90,0.2);
  --grey-07: rgba(160,170,185,0.07);
  --grey-13: rgba(160,170,185,0.13);
  --grey-28: rgba(160,170,185,0.28);
  --grey-35: rgba(160,170,185,0.35);
  --grey-a: #555555;
  --grey-b: #666666;
  --grey-c: #444444;
  --info-07: rgba(96,165,250,0.07);
  --info-25: rgba(96,165,250,0.25);
  --info-b-08: rgba(80,170,255,0.08);
  --info-b-30: rgba(80,170,255,0.3);
  --info-b-solid: #50aaff;
  --info-c-12: rgba(100,200,255,0.12);
  --info-c-25: rgba(100,200,255,0.25);
  --info-c-solid: #60a5fa;
  --info-solid: #64c8ff;
  --label: #c8cfda;
  --muted-2: #6b7685;
  --muted-3: #444e5e;
  --muted-4: #999999;
  --ok-05: rgba(110,255,170,0.05);
  --ok-08: rgba(110,255,170,0.08);
  --ok-12: rgba(110,255,170,.12);
  --ok-20: rgba(110,255,170,0.2);
  --ok-25: rgba(110,255,170,0.25);
  --ok-30: rgba(110,255,170,0.3);
  --ok-40: rgba(110,255,170,0.4);
  --ok-b-12: rgba(74,222,128,0.12);
  --ok-b-25: rgba(74,222,128,0.25);
  --ok-b-solid: #4ade80;
  --ok-c-12: rgba(60,220,100,0.12);
  --ok-c-25: rgba(60,220,100,0.25);
  --ok-c-solid: #3cdc64;
  --ok-d-solid: #9fe7b6;
  --ok-solid: #6effaa;
  --option-bg: #0d0f16;
  --ov-01: rgba(255,255,255,0.01);
  --ov-02: rgba(255,255,255,0.02);
  --ov-03: rgba(255,255,255,0.03);
  --ov-04: rgba(255,255,255,0.04);
  --ov-05: rgba(255,255,255,0.05);
  --ov-06: rgba(255,255,255,0.06);
  --ov-07: rgba(255,255,255,0.07);
  --ov-08: rgba(255,255,255,0.08);
  --ov-09: rgba(255,255,255,0.09);
  --ov-10: rgba(255,255,255,0.1);
  --ov-12: rgba(255,255,255,0.12);
  --ov-15: rgba(255,255,255,0.15);
  --ov-25: rgba(255,255,255,0.25);
  --ov-35: rgba(255,255,255,0.35);
  --ov-45: rgba(255,255,255,0.45);
  --ov-50: rgba(255,255,255,0.5);
  --ov-85: rgba(255,255,255,0.85);
  --panel-solid: #0d0f18;
  --qv-up: #2962ff;
  --purple-10: rgba(160,80,255,0.1);
  --purple-25: rgba(160,80,255,0.25);
  --purple-solid: #b060ff;
  --rc-a-15: rgba(220,20,0,0.15);
  --rc-a-60: rgba(220,20,0,0.6);
  --rc-a-85: rgba(220,20,0,0.85);
  --rc-b-35: rgba(180,0,0,0.35);
  --rc-b-50: rgba(180,0,0,0.5);
  --rc-c-18: rgba(255,40,20,0.18);
  --rc-c-95: rgba(255,40,20,0.95);
  --rc-cold: #550000;
  --rc-d-12: rgba(255,80,40,0.12);
  --rc-d-70: rgba(255,80,40,0.7);
  --rc-e-90: rgba(255,60,20,0.9);
  --rc-f-50: rgba(255,30,10,0.5);
  --rc-g-100: rgba(255,80,30,1.0);
  --rc-h-80: rgba(220,30,0,0.8);
  --rc-hot: #ffccaa;
  --rc-mid: #ff3300;
  --red-03: rgba(255,43,43,0.03);
  --red-04: rgba(255,43,43,0.04);
  --red-05: rgba(255,43,43,0.05);
  --red-06: rgba(255,43,43,0.06);
  --red-07: rgba(255,43,43,0.07);
  --red-08: rgba(255,43,43,0.08);
  --red-10: rgba(255,43,43,0.1);
  --red-12: rgba(255,43,43,0.12);
  --red-14: rgba(255,43,43,0.14);
  --red-16: rgba(255,43,43,0.16);
  --red-18: rgba(255,43,43,0.18);
  --red-20: rgba(255,43,43,0.2);
  --red-22: rgba(255,43,43,0.22);
  --red-28: rgba(255,43,43,0.28);
  --red-30: rgba(255,43,43,0.3);
  --red-35: rgba(255,43,43,0.35);
  --red-40: rgba(255,43,43,0.4);
  --red-45: rgba(255,43,43,0.45);
  --red-55: rgba(255,43,43,0.55);
  --red-60: rgba(255,43,43,0.6);
  --red-70: rgba(255,43,43,0.7);
  --red-95: rgba(255,43,43,0.95);
  --red-b-10: rgba(255,60,60,0.1);
  --red-b-25: rgba(255,60,60,0.25);
  --red-b-50: rgba(255,60,60,0.5);
  --red-c-20: rgba(255,90,90,0.2);
  --red-c-35: rgba(255,90,90,0.35);
  --red-d-15: rgba(255,40,40,0.15);
  --red-dark-18: rgba(200,30,30,0.18);
  --red-dark-60: rgba(200,30,30,0.6);
  --red-dark2-35: rgba(180,30,30,0.35);
  --red-e-85: rgba(255,80,80,0.85);
  --sh-50: rgba(0,0,0,0.5);
  --sh-55: rgba(0,0,0,0.55);
  --sh-60: rgba(0,0,0,0.6);
  --sh-70: rgba(0,0,0,0.7);
  --sink-06: rgba(0,0,0,0.06);
  --sink-15: rgba(0,0,0,0.15);
  --sink-18: rgba(0,0,0,0.18);
  --sink-20: rgba(0,0,0,0.2);
  --sink-22: rgba(0,0,0,0.22);
  --sink-24: rgba(0,0,0,0.24);
  --sink-30: rgba(0,0,0,0.3);
  --sink-40: rgba(0,0,0,0.4);
  --success-text: #d9ffe9;
  --tag-text: #cfd6e0;
  --term-text: #d9d9d9;
  --text-b: #e8eaf0;
  --text-c: #c0c8d4;
  --text-d: #c0c8d6;
  --warn-07: rgba(250,204,21,0.07);
  --warn-12: rgba(250,204,21,0.12);
  --warn-25: rgba(250,204,21,0.25);
  --warn-b-08: rgba(255,200,50,0.08);
  --warn-b-10: rgba(255,200,50,0.1);
  --warn-b-25: rgba(255,200,50,0.25);
  --warn-b-30: rgba(255,200,50,0.3);
  --warn-b-solid: #ffc832;
  --warn-solid: #facc15;
  --white: #ffffff;

  /* Tokens for the colours that lived in style= attributes and PHP/JS helpers.
     Same rule: the value here is the literal they replaced. */
  --amber-c-20: rgba(255,200,0,.2);
  --amber-c-85: rgba(255,200,0,.85);
  --amber-f-solid: #fb923c;
  --green-btn-90: rgba(0,210,100,.9);
  --info-d-85: rgba(80,180,255,.85);
  --info-d-solid: #55aaff;
  --neutral-75: rgba(195,195,195,.75);
  --ok-e-85: rgba(0,220,100,.85);
  --ok-e-90: rgba(0,220,100,.9);
  --ok-e-solid: #22e07a;
  --purple-b-85: rgba(200,120,255,.85);
  --purple-c-solid: #a78bfa;
  --purple-d-solid: #c06fff;
  --red-15: rgba(255,43,43,.15);
  --red-25: rgba(255,43,43,.25);
  --red-b-85: rgba(255,60,60,.85);
  --red-e-90: rgba(255,80,80,.9);
  --red-e-95: rgba(255,80,80,.95);
  --red-f-solid: #ff4b4b;
  --sink-35: rgba(0,0,0,.35);
  --sink-75: rgba(0,0,0,.75);
  --teal-85: rgba(0,200,160,.85);
  --ok-c-70: rgba(60,220,100,.7);
  --red-b-70: rgba(255,60,60,.7);
  --blue-btn5-70: rgba(60,140,255,.7);
  --amber-e-70: rgba(255,180,30,.7);
  --purple-70: rgba(160,80,255,.7);
  --ok-deep-solid: #1a8c3a;
  --red-deep-solid: #8c1a1a;

  /* A translucent dark wash laid over a card's own surface — for the cards
     that should sit a shade below their neighbours (Manage Permissions'
     cards for the built-in items Home, Profile, Admin and Logout). Drawn as an inset box-shadow so every theme's card
     finish shows through it. Lighter in the light themes. */
  --card-tint-dark: rgba(0,0,0,.28);
}

*{ box-sizing:border-box; }
html, body{ height:100%; }
body{
  margin:0;
  font-family: var(--font);
  color: var(--text);
  background:
    radial-gradient(1000px 520px at 72% 18%, var(--red-20), transparent 58%),
    radial-gradient(820px 420px at 12% 86%, var(--red-10), transparent 62%),
    linear-gradient(180deg, var(--bg0), var(--bg1));
  overflow-x:hidden;
}

/* Light grid + scanlines */
body::before{
  content:"";
  position:fixed; inset:-60px;
  pointer-events:none;
  background:
    linear-gradient(to right, var(--ov-06) 1px, transparent 1px),
    linear-gradient(to bottom, var(--ov-06) 1px, transparent 1px);
  background-size: 64px 64px;
  opacity:.07;
  transform: skewY(-1.5deg);
  animation: tmsp-grid 18s linear infinite;
}
body::after{
  content:"";
  position:fixed; inset:-60px;
  pointer-events:none;
  background:
    repeating-linear-gradient(
      to bottom,
      var(--ov-05),
      var(--ov-05) 1px,
      transparent 2px,
      transparent 7px
    ),
    radial-gradient(760px 260px at 30% 12%, var(--red-16), transparent 62%),
    radial-gradient(980px 360px at 78% 84%, var(--red-12), transparent 62%);
  opacity:.24;
  filter: blur(.2px);
}

@keyframes tmsp-grid{
  0%{ background-position: 0 0, 0 0; }
  100%{ background-position: 240px 140px, 240px 140px; }
}
@media (prefers-reduced-motion: reduce){
  body::before{ animation:none; }
}

/* ---------- Helpers ---------- */
.tmsp-muted{
  color: var(--muted);
  font-size: 12px;
  letter-spacing: .12em;
  text-transform: uppercase;
}

/* A card title that needs to stand out from the plain .tmsp-muted ones
   nearby (several tables sharing one card, e.g. Phone Records in
   Datatables) — same soft-tint pairing as .tmsp-stat, bold instead of
   just letter-spaced. */
.tmsp-card-heading{
  display: inline-block;
  color: var(--text);
  background: var(--red-06);
  border: 1px solid var(--red-18);
  border-radius: 8px;
  padding: 6px 14px;
  font-size: 12px;
  font-weight: 800;
  letter-spacing: .12em;
  text-transform: uppercase;
}
/* ---------- Monthly Executive Reports: the slide deck ----------
   One card that pages through its slides. Every slide is in the DOM and all
   but one carry [hidden] — a deck of a few empty sections costs nothing to
   render, and the arrows then only swap a class. The bar keeps its height
   whatever the slide is called, and the dots say how long the deck is at a
   glance, which the counter says exactly. Tokens only, so it follows the
   seven themes like everything else. */
.tmsp-meg-deck{
  margin-top: 14px;
  border: 1px solid var(--ov-10);
  border-radius: 12px;
  overflow: hidden;
}
.tmsp-meg-deck-bar{
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 12px;
  background: var(--ov-04);
  border-bottom: 1px solid var(--ov-08);
}
.tmsp-meg-deck-title{
  flex: 1;
  text-align: center;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--text);
}
.tmsp-meg-deck-count{
  font-family: var(--mono);
  font-size: 11px;
}
.tmsp-meg-deck-nav{
  min-width: 32px;
  font-size: 16px;
  line-height: 1;
}
.tmsp-meg-deck-nav[disabled]{
  opacity: .35;
  cursor: default;
}
.tmsp-meg-slide{
  min-height: 260px;
  padding: 16px;
}
.tmsp-meg-deck-dots{
  display: flex;
  justify-content: center;
  gap: 7px;
  padding: 0 0 12px;
}
.tmsp-meg-deck-dot{
  width: 8px;
  height: 8px;
  padding: 0;
  border: 1px solid var(--ov-35);
  border-radius: 999px;
  background: transparent;
  cursor: pointer;
}
.tmsp-meg-deck-dot.is-current{
  background: var(--red);
  border-color: var(--red);
}

/* ---------- Monthly Executive Reports: the slide's components ----------
   Four pieces, used by every slide: the KPI card, the dial, the progress bar
   and the list card. Each one is drawn in whatever colour it is handed
   through --meg-accent, set inline where the component is used — so a figure
   that earns green for meeting its target and amber for missing it is one
   token swapped in PHP, and no rule here names a colour. The tints come from
   color-mix() over that same token; where it is not supported the card keeps
   the flat --ov-04 declared before it and nothing else changes. */
.tmsp-meg-ov{
  display: flex;
  flex-direction: column;
  gap: 26px;
}
.tmsp-meg-block-title{
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 0 0 12px;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--muted);
}
.tmsp-meg-block-title::after{
  content: "";
  flex: 1;
  height: 1px;
  background: var(--ov-10);
}
.tmsp-meg-block-note{
  font-size: 11px;
  letter-spacing: .04em;
  text-transform: none;
  color: var(--muted-3);
}
.tmsp-meg-row{
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
  align-items: start;      /* a short card stays short beside a tall dial */
  gap: 14px;
}
/* For a row of one or two cards that would otherwise stretch across the
   whole slide — a list of stores reads better in a column than in a band. */
.tmsp-meg-row-narrow{
  grid-template-columns: repeat(auto-fit, minmax(250px, 340px));
  justify-content: start;
}
.tmsp-meg-empty{ font-size: 12.5px; }

/* The card the KPIs and the dials sit in. The accent is a bar down its left
   edge and a wash over the whole face, both from the one token. */
.tmsp-meg-kpi,
.tmsp-meg-card{
  position: relative;
  padding: 16px 18px;
  border: 1px solid var(--ov-10);
  border-radius: 16px;
  background: var(--ov-04);
  background: color-mix(in srgb, var(--meg-accent) 9%, transparent);
  border-color: color-mix(in srgb, var(--meg-accent) 28%, transparent);
  overflow: hidden;
}
.tmsp-meg-kpi::before,
.tmsp-meg-card::before{
  content: "";
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  width: 3px;
  background: var(--meg-accent);
}
.tmsp-meg-kpi-label{
  margin-bottom: 8px;
  font-size: 10.5px;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--muted);
}
.tmsp-meg-kpi-value{
  font-size: clamp(1.5rem, 2.2vw, 2rem);
  font-weight: 900;
  line-height: 1;
  color: var(--meg-accent);
}
.tmsp-meg-foot{
  margin-top: 8px;
  font-size: 11.5px;
  color: var(--muted);
}
.tmsp-meg-foot strong{ color: var(--text); }
.tmsp-meg-pill{
  display: inline-block;
  margin-left: 6px;
  padding: 0 7px;
  border: 1px solid var(--meg-accent);
  border-radius: 999px;
  font-size: 10px;
  color: var(--meg-accent);
}

/* The sparkline: one bar per month of the span, the last one at full
   strength because that is the month being reported. */
.tmsp-meg-spark{
  display: block;
  width: 100%;
  height: 26px;
  margin-top: 12px;
}
.tmsp-meg-spark rect{
  fill: var(--meg-accent);
  opacity: .45;
}
.tmsp-meg-spark rect:last-of-type{ opacity: 1; }

/* The dial. Only the arc is rotated, so it starts at twelve o'clock while
   the figure in the middle stays upright; the notch is placed from the same
   twelve o'clock in PHP and needs no rotation of its own. */
.tmsp-meg-dial{
  display: flex;
  justify-content: center;
  padding: 6px 0 2px;
}
.tmsp-meg-dial svg{
  width: 136px;
  height: 136px;
}
.tmsp-meg-dial-track{
  fill: none;
  stroke: var(--ov-10);
  stroke-width: 11;
}
.tmsp-meg-dial-arc{
  fill: none;
  stroke: var(--meg-accent);
  stroke-width: 11;
  stroke-linecap: round;
  transform: rotate(-90deg);
  transform-origin: 60px 60px;
}
.tmsp-meg-dial-notch{
  stroke: var(--text);
  stroke-width: 2.5;
  opacity: .7;
}
.tmsp-meg-dial-value{
  fill: var(--meg-accent);
  font-size: 23px;
  font-weight: 900;
  text-anchor: middle;
}
.tmsp-meg-dial-caption{
  fill: var(--muted);
  font-size: 10px;
  letter-spacing: .06em;
  text-anchor: middle;
}

/* One row per project: name, how far it has got, the counts, the share. */
.tmsp-meg-bars{
  display: flex;
  flex-direction: column;
  gap: 9px;
}
.tmsp-meg-bar-row{
  display: grid;
  grid-template-columns: minmax(110px, 1.3fr) minmax(90px, 3fr) auto auto;
  align-items: center;
  gap: 12px;
}
.tmsp-meg-bar-name{
  overflow: hidden;
  font-size: 12.5px;
  color: var(--text);
  text-overflow: ellipsis;
  white-space: nowrap;
}
.tmsp-meg-bar{
  height: 10px;
  border-radius: 999px;
  background: var(--ov-08);
  overflow: hidden;
}
.tmsp-meg-bar-fill{
  height: 100%;
  border-radius: 999px;
  background: var(--meg-accent);
}
.tmsp-meg-bar-num{
  min-width: 96px;
  font-family: var(--mono);
  font-size: 11px;
  color: var(--muted);
  text-align: right;
}
.tmsp-meg-bar-pct{
  min-width: 58px;
  font-family: var(--mono);
  font-size: 12px;
  font-weight: 700;
  color: var(--meg-accent);
  text-align: right;
}

/* The stores that opened or closed, one card per status. */
.tmsp-meg-list{
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin: 10px 0 0;
  padding: 0;
  list-style: none;
}
.tmsp-meg-list li{
  display: flex;
  justify-content: space-between;
  gap: 10px;
  padding: 6px 10px;
  border-radius: 8px;
  background: var(--ov-04);
  font-size: 12.5px;
}
.tmsp-meg-list-when{
  font-family: var(--mono);
  font-size: 11px;
  color: var(--muted);
  white-space: nowrap;
}

/* Slide 2's four charts, two by two. The cards inside are the Legacy
   Reports ones and bring their own white-card chrome with them (see
   lidl-legacy.css); all this does is place them, and stop a grid column from
   being wider than its share — min-width:0 is load-bearing, because a canvas
   is a replaced element and would otherwise push its column open and take the
   row with it. One column below 1100px: at half of half a screen the 2:1
   charts lose their labels. */
.tmsp-meg-sem-grid{
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 16px;
}
.tmsp-meg-sem-cell{
  min-width: 0;
  display: flex;             /* the card fills the row's height, so a shorter */
}
.tmsp-meg-sem-cell > *{      /* one does not float above a taller neighbour   */
  flex: 1 1 auto;
  width: 100%;
}
/* Which months the charts ended up drawing, and the one copy button. */
.tmsp-meg-sem-bar{
  display: flex;
  justify-content: space-between;
  align-items: center;
  flex-wrap: wrap;
  gap: 10px;
  margin-bottom: 12px;
}
.tmsp-meg-sem-span{
  font-size: 13px;
  font-weight: 600;
  color: var(--legacy-ink);
}
.tmsp-meg-sem-span-note{
  font-size: 12px;
  font-weight: 400;
  color: var(--legacy-ink-muted);
}
@media (max-width: 1100px){
  .tmsp-meg-sem-grid{ grid-template-columns: minmax(0, 1fr); }
}

/* The fleet as one bar: what is out there against what is on the shelf. */
.tmsp-meg-split{
  display: flex;
  flex-direction: column;
  gap: 14px;
}
.tmsp-meg-split-bar{
  height: 16px;
  border-radius: 999px;
  overflow: hidden;
  background: var(--ov-08);
  background: color-mix(in srgb, var(--amber-solid) 55%, transparent);
}
.tmsp-meg-split-use{
  height: 100%;
  background: var(--info-solid);
}

@media (max-width: 760px){
  /* The counts move under the name rather than squeezing the bar to nothing. */
  .tmsp-meg-bar-row{ grid-template-columns: 1fr auto; }
  .tmsp-meg-bar{ grid-column: 1 / -1; order: 3; }
}

.tmsp-wrap{
  /* The user's Page Width (Profile), set on <html> by tmsp_theme_attr(); 95% by default. */
  width: var(--tmsp-wrap-width, 95%);
  margin: 0 auto;
  padding: 28px 0;   /* no side padding: the cards themselves span the width */
}
.tmsp-top{
  display:flex;
  justify-content:space-between;
  align-items:center;
  gap: 12px;
  margin-bottom: 16px;
}

.tmsp-title{
  margin:0;
  font-size: 28px;
  font-weight: 950;
  letter-spacing: .16em;
  text-transform: uppercase;
  text-shadow:
    0 0 12px var(--red-20),
    0 0 28px var(--red-12);
}

/* ---------- Card ---------- */
.tmsp-card{
  position:relative;
  border: 1px solid var(--ov-10);
  border-radius: var(--radius);
  background: var(--panel);
  box-shadow: var(--shadow2);
  backdrop-filter: blur(10px);
  padding: 24px;
  margin-bottom: 20px;
}

/* A card a shade darker than its neighbours (Manage Permissions). The wash
   is the first inset shadow so it sits over the surface and under the
   content; a theme that gives .tmsp-card its own shadow list restates this
   rule with its own lines added. */
.tmsp-perm-card{
  box-shadow: inset 0 0 0 100vmax var(--card-tint-dark), var(--shadow2);
}

/* HUD corners */
.tmsp-card::before,
.tmsp-card::after{
  content:"";
  position:absolute;
  width: 60px; height: 60px;
  border: 1px solid var(--red-55);
  opacity:.62;
  pointer-events:none;
}
.tmsp-card::before{
  left: 10px; top: 10px;
  border-right:none; border-bottom:none;
  border-top-left-radius: 14px;
}
.tmsp-card::after{
  right: 10px; bottom: 10px;
  border-left:none; border-top:none;
  border-bottom-right-radius: 14px;
}

.tmsp-glowbar{
  height: 2px;
  background: linear-gradient(90deg, transparent, var(--red-95), transparent);
  opacity:.62;
  margin: 10px 0 14px;
}

/* Sweep */
.tmsp-sweep{
  position:absolute;
  inset:-120px;
  background: linear-gradient(135deg, transparent 40%, var(--red-14) 50%, transparent 60%);
  transform: translateX(-60%);
  animation: tmsp-sweep 10s ease-in-out infinite;
  pointer-events:none;
  opacity:.35;
}
@keyframes tmsp-sweep{
  0%, 100%{ transform: translateX(-60%); }
  50%{ transform: translateX(30%); }
}
@media (prefers-reduced-motion: reduce){
  .tmsp-sweep{ animation:none; opacity:.20; }
}

/* ---------- Buttons ---------- */
.tmsp-btn{
  display:inline-block;
  padding: 8px 10px;
  border-radius: 10px;
  border: 1px solid var(--red-70);
  color:var(--white);
  text-decoration:none;
  letter-spacing: .12em;
  text-transform: uppercase;
  font-weight: 900;
  font-size: .85rem;
  cursor: pointer;
  font-family: var(--font);
  background:
    radial-gradient(80px 34px at 20% 20%, var(--red-c-35), transparent 60%),
    linear-gradient(180deg, var(--red-28), var(--sink-24));
  box-shadow:
    0 0 12px var(--red-22),
    0 0 30px var(--red-14);
  transition: transform .08s ease, box-shadow .12s ease, border-color .12s ease;
}
.tmsp-btn:hover{
  border-color: var(--red-95);
  box-shadow:
    0 0 15px var(--red-30),
    0 0 45px var(--red-18);
  transform: translateY(-1px);
}
.tmsp-btn:active{ transform: translateY(0); }
/* Inert button (e.g. up/down at the top/bottom of a list). :hover alone is not
   enough — without this a disabled button looks identical to an active one. */
.tmsp-btn:disabled,
.tmsp-btn:disabled:hover{
  opacity: .35;
  cursor: default;
  transform: none;
}
.tmsp-btn-block{
  display:block;
  width:100%;
  text-align:center;
}

/* Neutral/secondary button */
.tmsp-btn-ghost{
  background: var(--ov-04);
  border-color: var(--ov-15);
  box-shadow: none;
  color: var(--muted);
}
.tmsp-btn-ghost:hover{
  border-color: var(--ov-35);
  box-shadow: none;
  color: var(--text);
}

/* Blue button (secondary accent) */
.tmsp-btn-blue{
  border-color: var(--blue-btn2-65);
  background:
    radial-gradient(80px 34px at 20% 20%, var(--blue-btn3-28), transparent 60%),
    linear-gradient(180deg, var(--blue-btn-22), var(--sink-24));
  box-shadow:
    0 0 12px var(--blue-btn2-22),
    0 0 30px var(--blue-btn-12);
}
.tmsp-btn-blue:hover{
  border-color: var(--blue-btn4-95);
  box-shadow:
    0 0 15px var(--blue-btn3-35),
    0 0 45px var(--blue-btn-20);
}

.tmsp-btn-green{
  border-color: var(--green-btn-65);
  background:
    radial-gradient(80px 34px at 20% 20%, var(--green-btn2-28), transparent 60%),
    linear-gradient(180deg, var(--green-btn3-22), var(--sink-24));
  box-shadow:
    0 0 12px var(--green-btn-22),
    0 0 30px var(--green-btn4-12);
}
.tmsp-btn-green:hover{
  border-color: var(--green-btn5-95);
  box-shadow:
    0 0 15px var(--green-btn2-35),
    0 0 45px var(--green-btn6-20);
}

/* Danger button */
.tmsp-btn-danger{
  background:
    radial-gradient(80px 34px at 20% 20%, var(--red-c-20), transparent 60%),
    linear-gradient(180deg, var(--red-dark2-35), var(--sink-24));
  border-color: var(--red-dark-60);
  box-shadow: 0 0 10px var(--red-dark-18);
}
.tmsp-btn-danger:hover{
  border-color: var(--red-95);
  box-shadow: 0 0 18px var(--red-30);
}
/* Dark grey at rest, red on hover: a quiet secondary action (e.g. "+ Project"
   on a card header). Each theme paints it with its own neutrals and red below. */
.tmsp-btn-dark{
  background: linear-gradient(180deg, var(--ov-10), var(--sink-40));
  border-color: var(--ov-15);
  color: var(--text);
}
.tmsp-btn-dark:hover{
  background:
    radial-gradient(80px 34px at 20% 20%, var(--red-c-20), transparent 60%),
    linear-gradient(180deg, var(--red-dark2-35), var(--sink-24));
  border-color: var(--red-95);
  color: var(--text);
}

/* Small button */
.tmsp-btn-sm{
  padding: 5px 8px;
  font-size: .75rem;
  border-radius: 8px;
}

.tmsp-tag{
  display:inline-block;
  padding: 5px 10px;
  border-radius: 999px;
  border: 1px solid var(--ov-10);
  background: var(--sink-22);
  color:var(--tag-text);
  font-size: 11px;
  letter-spacing: .14em;
  text-transform: uppercase;
}

/* The pagehead's own pills (Impersonate, ADMINS, USER:, Theme) sit right next
   to the Admin/Profile/Logout .tmsp-btn buttons in the same toolbar and read
   as a mismatched, smaller row if left at the sitewide .tmsp-tag size used for
   small badges elsewhere (status tags, audit log results). Match .tmsp-btn's
   padding and font-size here only — the pill shape and weight stay as they are.
   every theme's own `:root[data-theme="x"] .tmsp-tag` block is (0,3,0)
   (:root counts as a class) and several of them (portal01, the default,
   among them) set their own padding/font-size — a plain (0,2,0) here loses
   to them regardless of position. `[data-theme][data-theme]` repeats the
   attribute on purpose, the same trick the FHD layer uses below, for
   (0,4,0): a clean, position-independent win over any one theme block. */
[data-theme][data-theme] .tmsp-pagehead-tools .tmsp-tag{
  padding: 8px 14px;
  font-size: .85rem;
}

.tmsp-tag-red{
  border-color: var(--red-40);
  background: var(--red-10);
  color: var(--red2);
}
.tmsp-tag-green{
  border-color: var(--ok-30);
  background: var(--ok-08);
  color: var(--ok-solid);
}
.tmsp-tag-yellow{
  border-color: var(--warn-b-30);
  background: var(--warn-b-08);
  color: var(--warn-b-solid);
}
.tmsp-tag-blue{
  border-color: var(--info-b-30);
  background: var(--info-b-08);
  color: var(--info-b-solid);
}

/* ---------- Inputs ---------- */
.tmsp-label{
  display:block;
  font-size: 12px;
  letter-spacing: .12em;
  text-transform: uppercase;
  color:var(--label);
  margin: 12px 0 6px;
}
.tmsp-input,
.tmsp-textarea,
select.tmsp-input{
  width: 100%;
  padding: 12px 12px;
  border-radius: 12px;
  border: 1px solid var(--ov-10);
  background: var(--sink-30);
  color: var(--text);
  font-family: var(--font);
  font-size: .9rem;
  outline: none;
}
.tmsp-textarea{ min-height: 140px; resize: vertical; }
select.tmsp-input option{ background: var(--option-bg); }

.tmsp-input:focus,
.tmsp-textarea:focus,
select.tmsp-input:focus{
  border-color: var(--red-70);
  box-shadow: 0 0 0 4px var(--red-14);
}

/* ---------- Terminal ---------- */
.tmsp-terminal{
  border-radius: 18px;
  border: 1px solid var(--ov-08);
  background: var(--sink-22);
  padding: 14px;
  font-family: var(--mono);
  font-size: 12.5px;
  line-height: 1.6;
  color:var(--term-text);
}

/* ---------- Messages ---------- */
.tmsp-error{
  border:1px solid var(--red-35);
  background: var(--red-10);
  color:var(--error-text);
  padding:10px 12px;
  border-radius: 12px;
  margin: 10px 0;
  font-size: 13px;
}
.tmsp-success{
  border:1px solid var(--ok-25);
  background: var(--ok-08);
  color:var(--success-text);
  padding:10px 12px;
  border-radius: 12px;
  margin: 10px 0;
  font-size: 13px;
}

/* ---------- Glitch title ---------- */
.tmsp-glitch{
  position:relative;
  display:inline-block;
  text-shadow: 0 0 16px var(--red-20);
}
.tmsp-glitch::before,
.tmsp-glitch::after{
  content: attr(data-text);
  position:absolute;
  left:0; top:0;
  width:100%;
  overflow:hidden;
  opacity:.22;
  pointer-events:none;
}
.tmsp-glitch::before{
  transform: translateX(1px);
  clip-path: inset(0 0 55% 0);
  animation: tmsp-glitch1 2.8s infinite linear;
}
.tmsp-glitch::after{
  transform: translateX(-1px);
  clip-path: inset(55% 0 0 0);
  animation: tmsp-glitch2 2.4s infinite linear;
}
@keyframes tmsp-glitch1{
  0%, 100%{ filter: blur(0); opacity:.18; }
  45%{ filter: blur(.25px); opacity:.26; }
  46%{ filter: blur(0); opacity:.10; transform: translateX(2px); }
  47%{ transform: translateX(1px); opacity:.22; }
}
@keyframes tmsp-glitch2{
  0%, 100%{ filter: blur(0); opacity:.16; }
  30%{ opacity:.24; }
  31%{ transform: translateX(-2px); opacity:.10; }
  32%{ transform: translateX(-1px); opacity:.18; }
}
@media (prefers-reduced-motion: reduce){
  .tmsp-glitch::before,
  .tmsp-glitch::after{ animation:none; opacity:.12; }
}

/* ---------- Nav ---------- */
.tmsp-nav{
  display:flex;
  align-items:center;
  justify-content:space-between;
  flex-wrap:wrap;
  gap: 8px;
  margin-bottom: 20px;
}
.tmsp-nav-left, .tmsp-nav-right{
  display:flex;
  align-items:center;
  gap: 6px;
  flex-wrap:wrap;
}

/* ---------- Help modal ----------
   A small "?" button next to a card's title opens a plain-language explanation of
   that card, aimed at someone with no trading or technical background. One modal
   shell is shared by every card on the page; each button just points it at a
   different hidden template via data-help-target. Tokens only, per the theme
   rules — a modal that only worked in one theme would be worse than no modal. */
.tmsp-help-btn{
  display:inline-flex;
  align-items:center;
  justify-content:center;
  width: 22px;
  height: 22px;
  margin-left: 8px;
  border-radius: 50%;
  border: 1px solid var(--ov-25);
  background: var(--ov-04);
  color: var(--muted);
  font-family: var(--mono);
  font-size: 12px;
  font-weight: 700;
  line-height: 1;
  cursor: pointer;
  vertical-align: middle;
  transition: color .15s ease, border-color .15s ease, background .15s ease;
}
.tmsp-help-btn:hover{
  color: var(--red2);
  border-color: var(--red-25);
  background: var(--red-08);
}
.tmsp-help-tpl{ display:none; }

/* ---------- Icon-only row action (Edit/Delete) ----------
   The standard for a data grid's row actions sitewide (src/partials/lidl-gss-grid.php
   today): a 28px square, the icon centred, the label moved to a native title=
   tooltip instead of sitting on the button. Built from the same tokens
   .tmsp-help-btn already uses, so it needs no theme CSS of its own. */
.tmsp-icon-btn{
  display:inline-flex;
  align-items:center;
  justify-content:center;
  width: 28px;
  height: 28px;
  padding: 0;
  border-radius: 7px;
  border: 1px solid var(--ov-15);
  background: var(--ov-04);
  color: var(--muted);
  cursor: pointer;
  flex: 0 0 auto;
  transition: color .15s ease, border-color .15s ease, background .15s ease;
}
.tmsp-icon-btn:hover{
  color: var(--text);
  border-color: var(--ov-35);
  background: var(--ov-08);
}
.tmsp-icon-btn-danger:hover{
  color: var(--red2);
  border-color: var(--red-25);
  background: var(--red-08);
}
.tmsp-icon{ display:block; }


.tmsp-modal{
  display:none;
  position: fixed;
  inset: 0;
  z-index: 1000;
  background: var(--sh-60);
  overflow-y: auto;
  padding: 6vh 16px;
}
.tmsp-modal.open{ display:block; }
.tmsp-modal-box{
  max-width: 560px;
  margin: 0 auto;
  background: var(--panel-solid);
  border: 1px solid var(--ov-15);
  border-radius: var(--radius);
  box-shadow: var(--shadow2);
  padding: 24px;
  position: relative;
}
/* A form with many fields (a wide data-grid row — 31 days, say) needs more
   than the 560px an explanation modal was sized for. */
.tmsp-modal-box.tmsp-modal-wide{ max-width: 960px; }

.tmsp-modal-close{
  position: absolute;
  top: 14px;
  right: 14px;
  width: 28px;
  height: 28px;
  border-radius: 50%;
  border: 1px solid var(--ov-15);
  background: var(--ov-04);
  color: var(--muted);
  font-size: 16px;
  line-height: 1;
  cursor: pointer;
}
.tmsp-modal-close:hover{ color: var(--red2); border-color: var(--red-25); }
.tmsp-modal-title{
  font-family: var(--mono);
  font-size: 1.05rem;
  font-weight: 700;
  letter-spacing: .02em;
  color: var(--text);
  margin: 0 32px 14px 0;
}
.tmsp-modal-body{
  color: var(--text);
  font-size: 14px;
  line-height: 1.7;
}
.tmsp-modal-body p{ margin: 0 0 12px; }
.tmsp-modal-body p:last-child{ margin-bottom: 0; }
.tmsp-modal-body strong{ color: var(--text); }
.tmsp-modal-body .tmsp-muted{ font-size: 12.5px; }

/* A small table of measurements inside an explanation modal — three or four
   rows of numbers that a paragraph would bury. Scrolls on its own so a narrow
   phone never widens the modal. */
.tmsp-modal-table{
  display: block;
  overflow-x: auto;
  width: 100%;
  margin: 0 0 12px;
  border-collapse: collapse;
  font-family: var(--mono);
  font-size: 12.5px;
  white-space: nowrap;
}
.tmsp-modal-table th,
.tmsp-modal-table td{
  padding: 5px 12px 5px 0;
  text-align: left;
  border-bottom: 1px solid var(--ov-08);
}
.tmsp-modal-table th{ color: var(--muted-2); font-weight: 600; }
.tmsp-modal-table tr:last-child td{ border-bottom: 0; }

/* ---------- Tabs (page sections) ----------
   Server-side tabs, in the same shape as admin.php's ?section= links — the state lives in the URL, so a tab is
   bookmarkable and survives a POST redirect. Tokens only: a literal here would be
   illegible in the light themes. */
.tmsp-tabs{
  display:flex;
  align-items:stretch;
  gap: 4px;
  flex-wrap:wrap;
  margin: 4px 0 18px;
  border-bottom: 1px solid var(--ov-08);
}
.tmsp-tab{
  display:inline-block;
  padding: 10px 16px;
  font-family: var(--mono);
  font-size: 12px;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--muted);
  text-decoration:none;
  border: 1px solid transparent;
  border-bottom: none;
  border-radius: 10px 10px 0 0;
  transition: color .15s ease, background .15s ease;
}
.tmsp-tab:hover{
  color: var(--text);
  background: var(--ov-03);
}
.tmsp-tab.is-current{
  color: var(--red2);
  background: var(--red-08);
  border-color: var(--red-25);
  box-shadow: inset 0 -2px 0 var(--red);
}
/* ── Sub tabs that belong to the right-hand group ───────────────────────────
   The bar is flex-wrap, so the slack goes to the FIRST right tab and carries
   everything after it to the far edge — and on a narrow screen it simply wraps
   instead of overlapping. Only the first one carries the class; lidl-gss.php
   latches it. */
.tmsp-tabs-sub .tmsp-tab.is-right-start{ margin-left: auto; }

/* ── Amber sub tab ──────────────────────────────────────────────────────────
   For a sub tab whose content comes from somewhere else — today the two that
   carry the ported LIDL legacy report. --amber-solid resolves in every theme
   (base, the shared light list, and the two Office blocks), so the accent needs
   no colour of its own. */
.tmsp-tab.is-amber{ color: var(--amber-solid); }
.tmsp-tab.is-amber:hover{ color: var(--amber-solid); background: var(--amber-c-10); }
.tmsp-tab.is-amber.is-current{
  color: var(--amber-solid);
  background: var(--amber-c-10);
  border-color: var(--amber-b-25);
  box-shadow: inset 0 -2px 0 var(--amber-solid);
}
/* The four themes that restyle .tmsp-tab.is-current win on specificity, so the
   accent has to be restated inside each — in that theme's own shape: Vista
   underlines from the top, Office with a thicker bar and no fill, the Portal
   pair keeps its lifted segment, and the Fujitsu pair drops its hot red fill
   (amber text on red is unreadable) for the same tint the base theme uses. */
:root[data-theme="vista"] .tmsp-tab.is-amber.is-current{
  color: var(--amber-solid);
  box-shadow: inset 0 2px 0 var(--amber-solid);
}
:root[data-theme^="office"] .tmsp-tab.is-amber.is-current{
  color: var(--amber-solid);
  box-shadow: inset 0 -3px 0 var(--amber-solid);
}
:root[data-theme^="portal01"] .tmsp-tab.is-amber.is-current{
  color: var(--amber-solid);
  box-shadow: inset 0 -2px 0 var(--amber-solid), var(--pt-shadow-soft);
}
:root[data-theme^="tmsp01"] .tmsp-tab.is-amber.is-current{
  color: var(--amber-solid);
  background: var(--amber-c-10);
  border-color: var(--amber-b-25);
  box-shadow: inset 0 -2px 0 var(--amber-solid);
  text-shadow: none;
}

/* Second level (dashboard.php ?tab=N&sub=…): the same tabs, one notch smaller
   and tighter to the row above, so the hierarchy reads at a glance. The
   themes' .tmsp-tab rules apply unchanged; only size and spacing differ. */
.tmsp-tabs-sub{
  margin: -8px 0 16px;
  gap: 2px;
}
.tmsp-tabs-sub .tmsp-tab{
  padding: 7px 13px;
  font-size: 11px;
}

/* ---------- Table ---------- */
.tmsp-table{
  width:100%;
  border-collapse:collapse;
  font-size: 13px;
}
.tmsp-table th{
  background: var(--red-08);
  color: var(--muted);
  font-size: 11px;
  letter-spacing: .14em;
  text-transform: uppercase;
  padding: 10px 12px;
  text-align: center;
  white-space: normal;
  line-height: 1.35;
  border-bottom: 1px solid var(--ov-06);
  font-weight: 600;
}
.tmsp-table td{
  padding: 10px 12px;
  border-bottom: 1px solid var(--ov-04);
  vertical-align: middle;
  text-align: center;
  white-space: nowrap;
}
.tmsp-table tr:last-child td{ border-bottom:none; }
.tmsp-table tr:hover td{ background: var(--ov-02); }

.tmsp-table-totals td{
  background: var(--red-14);
  font-weight: 700;
  border-top: 2px solid var(--red-35);
  border-bottom: none;
}
.tmsp-table tr.tmsp-table-totals:hover td{ background: var(--red-14); }
.tmsp-table-totals td:first-child{
  letter-spacing: .08em;
  text-transform: uppercase;
  font-size: 11px;
  color: var(--muted);
}

/* A table that has to fit its card instead of scrolling sideways. The three
   things that make a list outgrow the page are all here: cells that never
   wrap, group tags that are whole sentences, and a <select>, which is as wide
   as its longest option — ten group names of 90 characters each pushed the
   Operators list to four times the width of the card. Words themselves are
   never broken, so a one-word cell ("ACTIVE") still sets its column's width
   and reads as one word. Below roughly 900px the buttons and inputs cannot
   give any more, and the wrapper's overflow-x takes over again — a phone
   scrolls, a desktop does not. */
.tmsp-table-fit td,
.tmsp-table-fit th{ white-space: normal; }
.tmsp-table-fit .tmsp-inline-select{ max-width: 200px; }
.tmsp-table-fit .tmsp-input{ max-width: 100%; }

/* A list read as text rather than as figures: the cells line up on the left
   and sit in the middle of the row. .tmsp-table centres everything, which
   suits the numeric grids but not a list of names, tags and buttons — a
   left edge is what the eye follows down a column of words. The headers go
   with their columns. */
.tmsp-table-left th,
.tmsp-table-left td{
  text-align: left;
  vertical-align: middle;
}

/* Sortable + filterable list (driven by /assets/tmsp-table.js, see its header
   for the markup contract). Promoted from admin.php so every list page can
   use it. */
.tmsp-th-sort{ cursor:pointer; user-select:none; }
.tmsp-th-sort:hover{ color:var(--red2); }
.tmsp-th-sort[data-dir="asc"]::after { content:' ▲'; font-size:.65em; opacity:.6; }
.tmsp-th-sort[data-dir="desc"]::after{ content:' ▼'; font-size:.65em; opacity:.6; }
.tmsp-filter-row th{ padding:4px 6px !important; background:var(--sink-20); }
.tmsp-filter-row input{
  width:100%; background:var(--ov-04); border:1px solid var(--ov-10);
  border-radius:4px; padding:4px 8px; color:var(--text); font-size:.72rem;
  font-family:var(--mono); outline:none; box-sizing:border-box;
}
.tmsp-filter-row input:focus{ border-color:var(--red-40); }
.tmsp-filter-row input::placeholder{ color:var(--muted); opacity:.6; }

/* ---------- Stats grid ---------- */
.tmsp-stats{
  display:grid;
  grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
  gap: 16px;
  margin-bottom: 20px;
}
.tmsp-stat{
  background: var(--red-06);
  border: 1px solid var(--red-18);
  border-radius: 16px;
  padding: 18px 20px;
}
.tmsp-stat-label{
  font-size: 11px;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--muted);
  margin-bottom: 8px;
}
.tmsp-stat-value{
  font-size: 2rem;
  font-weight: 900;
  line-height: 1;
  color: var(--text);
}
.tmsp-stat-sub{
  font-size: 11px;
  color: var(--muted-3);
  letter-spacing: .1em;
  margin-top: 6px;
  text-transform: uppercase;
}

/* Pulse dot */
.tmsp-pulse{
  display:inline-block;
  width:7px; height:7px;
  border-radius:50%;
  background: var(--ok-solid);
  box-shadow: 0 0 6px var(--ok-solid);
  animation: tmsp-pulse 2s ease-in-out infinite;
  margin-right: 5px;
  vertical-align: middle;
}
@keyframes tmsp-pulse{
  0%,100%{ box-shadow: 0 0 4px var(--ok-solid); }
  50%{ box-shadow: 0 0 14px var(--ok-solid), 0 0 24px var(--ok-40); }
}

/* ---------- Row actions ---------- */
.tmsp-actions{
  display:flex;
  gap: 6px;
  flex-wrap:wrap;
  align-items:center;
}
.tmsp-inline-form{
  display:inline-flex;
  gap:5px;
  align-items:center;
}
.tmsp-inline-select{
  background: var(--sink-40);
  border: 1px solid var(--ov-10);
  border-radius: 7px;
  color: var(--text);
  font-size: .75rem;
  padding: 4px 6px;
  outline:none;
}
.tmsp-inline-select:focus{ border-color: var(--red-60); }
.tmsp-inline-select option{ background:var(--option-bg); }

/* ---------- Dropdown (nav) ---------- */
/* Consolidated from the 13 pages, where it was duplicated. Pure CSS: it opens
   on :hover and on :focus-within (keyboard), with no JavaScript. */
.tmsp-dropdown { position: relative; }

.tmsp-dropdown-menu {
  display: none;
  position: absolute;
  top: 100%;
  right: 0;
  min-width: 240px;
  background: var(--panel-solid);
  border: 1px solid var(--red-35);
  border-radius: 8px;
  padding-top: 6px;
  overflow: hidden;
  z-index: 100;
  box-shadow: 0 8px 32px var(--sh-60), 0 0 20px var(--red-08);
}

.tmsp-dropdown:focus-within .tmsp-dropdown-menu,
.tmsp-dropdown:hover .tmsp-dropdown-menu { display: block; }

/* Invisible bridge between the button and the menu, so the mouse does not lose :hover. */
.tmsp-dropdown-menu::before {
  content: "";
  position: absolute;
  top: -6px; left: 0; right: 0;
  height: 6px;
}

/* The items can be either links or buttons in a <form> (theme switching); they
   have to be visually indistinguishable. */
.tmsp-dropdown-menu a,
.tmsp-dropdown-menu button,
.tmsp-dropdown-menu .tmsp-dropdown-placeholder {
  display: block;
  width: 100%;
  text-align: left;
  padding: 10px 16px;
  font-size: .78rem;
  font-family: var(--mono);
  letter-spacing: .06em;
  color: var(--text);
  text-decoration: none;
  border: none;
  border-bottom: 1px solid var(--ov-05);
  background: none;
  cursor: pointer;
  transition: background .15s, color .15s;
}

.tmsp-dropdown-menu a:last-child,
.tmsp-dropdown-menu form:last-child button,
.tmsp-dropdown-menu .tmsp-dropdown-placeholder:last-child { border-bottom: none; }

.tmsp-dropdown-menu a:hover,
.tmsp-dropdown-menu button:hover {
  background: var(--red-10);
  color: var(--red2);
}

/* Active theme: marked with a ✓ added by CSS, so the button's text stays just
   the theme's name. */
.tmsp-dropdown-menu button.is-current { color: var(--red2); }
.tmsp-dropdown-menu button.is-current::after { content: ' ✓'; }

/* Placeholder item: same layout as the links, but not clickable (no exchange/page of its own yet). */
.tmsp-dropdown-menu .tmsp-dropdown-placeholder {
  color: var(--muted-2);
  cursor: default;
}
.tmsp-dropdown-menu .tmsp-dropdown-placeholder:hover {
  background: none;
  color: var(--muted-2);
}

/* Nested submenu (side flyout, opens on :hover/:focus-within, same pattern as the
   top dropdown) — for grouping items inside a dropdown. */
.tmsp-dropdown-submenu { position: relative; }

.tmsp-dropdown-submenu-label {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  width: 100%;
  text-align: left;
  padding: 10px 16px;
  font-size: .78rem;
  font-family: var(--mono);
  letter-spacing: .06em;
  color: var(--text);
  border-bottom: 1px solid var(--ov-05);
  cursor: default;
}
.tmsp-dropdown-submenu:last-child .tmsp-dropdown-submenu-label { border-bottom: none; }

.tmsp-dropdown-submenu:hover .tmsp-dropdown-submenu-label,
.tmsp-dropdown-submenu:focus-within .tmsp-dropdown-submenu-label {
  background: var(--red-10);
  color: var(--red2);
}

.tmsp-dropdown-submenu-flyout {
  display: none;
  position: absolute;
  top: -6px;
  left: 100%;
  min-width: 300px;
  background: var(--panel-solid);
  border: 1px solid var(--red-35);
  border-radius: 8px;
  padding-top: 6px;
  overflow: hidden;
  z-index: 101;
  box-shadow: 0 8px 32px var(--sh-60), 0 0 20px var(--red-08);
}
.tmsp-dropdown-submenu:hover .tmsp-dropdown-submenu-flyout,
.tmsp-dropdown-submenu:focus-within .tmsp-dropdown-submenu-flyout {
  display: block;
}

.tmsp-dropdown-submenu-flyout a {
  display: block;
  width: 100%;
  text-align: left;
  padding: 10px 16px;
  font-size: .78rem;
  font-family: var(--mono);
  letter-spacing: .06em;
  color: var(--text);
  text-decoration: none;
  border-bottom: 1px solid var(--ov-05);
  background: none;
  cursor: pointer;
  transition: background .15s, color .15s;
}
.tmsp-dropdown-submenu-flyout a:last-child { border-bottom: none; }
.tmsp-dropdown-submenu-flyout a:hover {
  background: var(--red-10);
  color: var(--red2);
}

/* .tmsp-dropdown-menu has overflow:hidden (to round the list's corners), which
   clips the submenu's flyout — and that needs to escape the box (left:100%).
   The overflow is only released when a submenu is actually open, so the rounded
   clipping is not lost the rest of the time. */
.tmsp-dropdown-menu:has(.tmsp-dropdown-submenu:hover),
.tmsp-dropdown-menu:has(.tmsp-dropdown-submenu:focus-within) {
  overflow: visible;
}

/* The same for a submenu nested inside a submenu (Projects Management →
   Jerónimo Martins → Pingo Doce): the flyout that holds it clips with
   overflow:hidden too, and its child flyout also escapes at left:100%. */
.tmsp-dropdown-submenu-flyout:has(.tmsp-dropdown-submenu:hover),
.tmsp-dropdown-submenu-flyout:has(.tmsp-dropdown-submenu:focus-within) {
  overflow: visible;
}

.tmsp-btn-dropdown::after {
  content: ' ▾';
  font-size: .7em;
  opacity: .7;
}

/* Theme selector: it lives in the header, next to the USER/ADMINS pills, so
   the trigger looks like a pill rather than a button. The menu it opens is the
   same .tmsp-dropdown-menu as the rest of the nav. */
.tmsp-theme-pick { display: inline-block; }

.tmsp-theme-pick > button.tmsp-tag {
  font-family: var(--font);
  font-weight: 400;
  line-height: inherit;
  cursor: pointer;
  transition: border-color .12s, color .12s;
}

.tmsp-theme-pick > button.tmsp-tag:hover {
  border-color: var(--red-40);
  color: var(--red2);
}

/* ---------- Header reactor ---------- */
/* Also consolidated from the 13 pages. */
.tmsp-reactor {
  position: relative;
  flex-shrink: 0;
  width: 52px; height: 52px;
}

/* The site logo in the orb's place (public/assets/fujitsu.svg). The wrapper
   keeps the .tmsp-reactor class because the themes key their header band on
   .tmsp-card:has(.tmsp-reactor); the rules below, at a higher specificity than
   any theme's .tmsp-reactor, strip the orb finish and let the image show. */
:root .tmsp-reactor.tmsp-reactor-logo,
:root[data-theme] .tmsp-reactor.tmsp-reactor-logo{
  display: flex;
  align-items: center;
  justify-content: center;
  background: none;
  border: 0;
  border-radius: 0;
  box-shadow: none;
  animation: none;
}
:root[data-theme] .tmsp-reactor.tmsp-reactor-logo::before,
:root[data-theme] .tmsp-reactor.tmsp-reactor-logo::after{ content: none; }
.tmsp-logo{
  display: block;
  width: 100%;
  height: 100%;
  object-fit: contain;
  filter: drop-shadow(0 1px 2px var(--sh-50));
}

.tmsp-reactor-ring {
  position: absolute; inset: 0;
  border-radius: 50%;
  border: 2px solid transparent;
}

.tmsp-reactor-ring:nth-child(1) {
  border-top-color: var(--rc-c-95);
  border-right-color: var(--rc-c-18);
  animation: qr-spin 2s linear infinite;
  box-shadow: 0 0 6px var(--rc-f-50);
}

.tmsp-reactor-ring:nth-child(2) {
  inset: 7px;
  border-bottom-color: var(--rc-a-85);
  border-left-color: var(--rc-a-15);
  animation: qr-spin 1.4s linear infinite reverse;
}

.tmsp-reactor-ring:nth-child(3) {
  inset: 14px;
  border-top-color: var(--rc-d-70);
  border-right-color: var(--rc-d-12);
  animation: qr-spin 3s linear infinite;
}

.tmsp-reactor-core {
  position: absolute; inset: 19px;
  border-radius: 50%;
  background: radial-gradient(circle, var(--rc-hot) 0%, var(--rc-mid) 40%, var(--rc-cold) 100%);
  box-shadow:
    0 0 6px 2px var(--rc-e-90),
    0 0 16px 5px var(--rc-a-60),
    0 0 32px 8px var(--rc-b-35);
  animation: qr-core 2s ease-in-out infinite;
}

@keyframes qr-spin { to { transform: rotate(360deg); } }

@keyframes qr-core {
  0%,100% { box-shadow: 0 0 6px 2px var(--rc-e-90), 0 0 16px 5px var(--rc-a-60), 0 0 32px 8px var(--rc-b-35); }
  50%      { box-shadow: 0 0 10px 4px var(--rc-g-100), 0 0 24px 8px var(--rc-h-80), 0 0 50px 14px var(--rc-b-50); }
}
/* ── Shared light-theme tokens (162) ──
   Windows Vista, Fujitsu TMSP 01 (Light), Fujitsu Lounge (Light) and
   Fujitsu View (Light) are light themes: each takes this block and then its own accent and chrome
   tokens below, and repaints the chrome in its structural section further
   down. A future light theme joins this selector list. */
:root[data-theme="vista"],
:root[data-theme="tmsp01"],
:root[data-theme^="portal01"],
:root[data-theme="office"]{
  /* ── Base ── */
  --bg0:#ffffff;
  --bg1:#f4f5f7;
  --panel:#ffffff;
  --line:rgba(0,0,0,.12);

  --text:#14161a;
  --muted:#5c6470;


  --shadow: 0 1px 3px rgba(0,0,0,.10);
  --shadow2: 0 6px 24px rgba(0,0,0,.10);

  /* ── Tokens ── */
  --amber-40: rgba(180,83,9,.6);
  --amber-45: rgba(180,83,9,.68);
  --amber-90: rgba(180,83,9,.9);
  --amber-100: rgba(180,83,9,1);
  --amber-b-25: rgba(180,83,9,.38);
  --amber-b-65: rgba(180,83,9,.65);
  --amber-bg-70: rgba(255,247,230,.7);
  --amber-c-10: rgba(180,83,9,.15);
  --amber-d-90: rgba(180,83,9,.9);
  --amber-solid: #b45309;
  --black: #000000;
  --blue-btn-10: rgba(29,78,216,.15);
  --blue-btn-12: rgba(29,78,216,.18);
  --blue-btn-20: rgba(29,78,216,.3);
  --blue-btn-22: rgba(29,78,216,.33);
  --blue-btn-38: rgba(29,78,216,.57);
  --blue-btn-40: rgba(29,78,216,.6);
  --blue-btn2-18: rgba(29,78,216,.27);
  --blue-btn2-22: rgba(29,78,216,.33);
  --blue-btn2-40: rgba(29,78,216,.6);
  --blue-btn2-65: rgba(29,78,216,.65);
  --blue-btn3-28: rgba(29,78,216,.42);
  --blue-btn3-35: rgba(29,78,216,.52);
  --blue-btn4-95: rgba(29,78,216,.95);
  --danger: #dc2626;
  --danger-09: rgba(220,38,38,.14);
  --danger-15: rgba(220,38,38,.22);
  --danger-30: rgba(220,38,38,.45);
  --deep-98: rgba(255,255,255,.98);
  --deep-b-90: rgba(255,255,255,.9);
  --deep-c-97: rgba(255,255,255,.97);
  --deep-d-97: rgba(255,255,255,.97);
  --deep-e-97: rgba(255,255,255,.97);
  --deep-solid: #ffffff;
  --deep-solid2: #f4f5f7;
  --error-text: #7f1d1d;
  --green-btn-22: rgba(21,128,61,.33);
  --green-btn-65: rgba(21,128,61,.65);
  --green-btn2-28: rgba(21,128,61,.42);
  --green-btn2-35: rgba(21,128,61,.52);
  --green-btn3-22: rgba(21,128,61,.33);
  --green-btn4-12: rgba(21,128,61,.18);
  --green-btn5-95: rgba(22,163,74,.95);
  --green-btn6-20: rgba(21,128,61,.3);
  --grey-07: rgba(90,98,110,.11);
  --grey-13: rgba(90,98,110,.2);
  --grey-28: rgba(90,98,110,.42);
  --grey-35: rgba(90,98,110,.52);
  --grey-a: #5a626e;
  --grey-b: #5a626e;
  --grey-c: #6a7280;
  --info-07: rgba(29,78,216,.11);
  --info-25: rgba(29,78,216,.38);
  --info-b-08: rgba(29,78,216,.12);
  --info-b-30: rgba(29,78,216,.45);
  --info-b-solid: #1d4ed8;
  --info-c-12: rgba(29,78,216,.18);
  --info-c-25: rgba(29,78,216,.38);
  --info-c-solid: #1d4ed8;
  --info-solid: #1d4ed8;
  --label: #3a4150;
  --muted-2: #6a7280;
  --muted-3: #707783;
  --muted-4: #6a7280;
  --ok-05: rgba(21,128,61,.08);
  --ok-08: rgba(21,128,61,.12);
  --ok-12: rgba(21,128,61,.18);
  --ok-20: rgba(21,128,61,.3);
  --ok-25: rgba(21,128,61,.38);
  --ok-30: rgba(21,128,61,.45);
  --ok-40: rgba(21,128,61,.6);
  --ok-b-12: rgba(22,163,74,.18);
  --ok-b-25: rgba(22,163,74,.38);
  --ok-b-solid: #15803d;
  --ok-c-12: rgba(22,163,74,.18);
  --ok-c-25: rgba(22,163,74,.38);
  --ok-c-solid: #15803d;
  --ok-d-solid: #15803d;
  --ok-solid: #15803d;
  --option-bg: #ffffff;
  --ov-01: rgba(0,0,0,.01);
  --ov-02: rgba(0,0,0,.02);
  --ov-03: rgba(0,0,0,.03);
  --ov-04: rgba(0,0,0,.04);
  --ov-05: rgba(0,0,0,.05);
  --ov-06: rgba(0,0,0,.06);
  --ov-07: rgba(0,0,0,.07);
  --ov-08: rgba(0,0,0,.08);
  --ov-09: rgba(0,0,0,.09);
  --ov-10: rgba(0,0,0,.1);
  --ov-12: rgba(0,0,0,.12);
  --ov-15: rgba(0,0,0,.15);
  --ov-25: rgba(0,0,0,.25);
  --ov-35: rgba(0,0,0,.35);
  --ov-45: rgba(0,0,0,.45);
  --ov-50: rgba(0,0,0,.5);
  --ov-85: rgba(0,0,0,.85);
  --panel-solid: #ffffff;
  --purple-10: rgba(126,34,206,.15);
  --purple-25: rgba(126,34,206,.38);
  --purple-solid: #7e22ce;
  --red-c-20: rgba(255,90,90,.3);
  --red-c-35: rgba(255,90,90,.52);
  --sh-50: rgba(0,0,0,.12);
  --sh-55: rgba(0,0,0,.14);
  --sh-60: rgba(0,0,0,.15);
  --sh-70: rgba(0,0,0,.17);
  --sink-06: rgba(0,0,0,.01);
  --sink-15: rgba(0,0,0,.03);
  --sink-18: rgba(0,0,0,.03);
  --sink-20: rgba(0,0,0,.04);
  --sink-22: rgba(0,0,0,.04);
  --sink-24: rgba(0,0,0,.04);
  --sink-30: rgba(0,0,0,.05);
  --sink-40: rgba(0,0,0,.06);
  --success-text: #14532d;
  --tag-text: #3a4150;
  --term-text: #2a2f38;
  --text-b: #14161a;
  --text-c: #3a4150;
  --text-d: #3a4150;
  --warn-07: rgba(180,83,9,.11);
  --warn-12: rgba(180,83,9,.18);
  --warn-25: rgba(180,83,9,.38);
  --warn-b-08: rgba(180,83,9,.12);
  --warn-b-10: rgba(180,83,9,.15);
  --warn-b-25: rgba(180,83,9,.38);
  --warn-b-30: rgba(180,83,9,.45);
  --warn-b-solid: #b45309;
  --warn-solid: #b45309;
  --white: #ffffff;

  /* Same, for the light themes. */
  --amber-c-20: rgba(180,83,9,.3);
  --amber-c-85: rgba(180,83,9,.85);
  --amber-f-solid: #b45309;
  --green-btn-90: rgba(21,128,61,.9);
  --info-d-85: rgba(29,78,216,.85);
  --info-d-solid: #1d4ed8;
  --neutral-75: rgba(58,65,76,.75);
  --ok-e-85: rgba(21,128,61,.85);
  --ok-e-90: rgba(21,128,61,.9);
  --ok-e-solid: #15803d;
  --purple-b-85: rgba(126,34,206,.85);
  --purple-c-solid: #7e22ce;
  --purple-d-solid: #7e22ce;
  --red-f-solid: #dc2626;
  --sink-35: rgba(0,0,0,.06);
  --sink-75: rgba(0,0,0,.06);
  --teal-85: rgba(13,120,110,.85);
  --ok-c-70: rgba(22,163,74,.7);
  --blue-btn5-70: rgba(29,78,216,.7);
  --amber-e-70: rgba(180,83,9,.7);
  --purple-70: rgba(126,34,206,.7);
  --ok-deep-solid: #14532d;
  --red-deep-solid: #7f1d1d;
  --card-tint-dark: rgba(0,0,0,.11);

  /* In Blue Quito the accent is already blue, so the "blue" family of the states
     and of the Hive button becomes turquoise: #1d4ed8 was indistinguishable from
     the accent and the button lost its job of standing out. These lines come
     after the common block and therefore beat it. */
  --blue-btn-10: rgba(14,116,144,.15);
  --blue-btn-12: rgba(14,116,144,.18);
  --blue-btn-20: rgba(14,116,144,.3);
  --blue-btn-22: rgba(14,116,144,.33);
  --blue-btn-38: rgba(14,116,144,.57);
  --blue-btn-40: rgba(14,116,144,.6);
  --blue-btn2-18: rgba(14,116,144,.27);
  --blue-btn2-22: rgba(14,116,144,.33);
  --blue-btn2-40: rgba(14,116,144,.6);
  --blue-btn2-65: rgba(14,116,144,.65);
  --blue-btn3-28: rgba(14,116,144,.42);
  --blue-btn3-35: rgba(14,116,144,.52);
  --blue-btn4-95: rgba(14,116,144,.95);
  --blue-btn5-70: rgba(14,116,144,.7);
  --info-07: rgba(14,116,144,.11);
  --info-25: rgba(14,116,144,.38);
  --info-b-08: rgba(14,116,144,.12);
  --info-b-30: rgba(14,116,144,.45);
  --info-b-solid: #0e7490;
  --info-c-12: rgba(14,116,144,.18);
  --info-c-25: rgba(14,116,144,.38);
  --info-c-solid: #0e7490;
  --info-d-85: rgba(14,116,144,.85);
  --info-d-solid: #0e7490;
  --info-solid: #0e7490;
}


/* Windows Vista accent: Aero's blue, rgb(26,140,216). Same token names and
   alpha ladder as the other light accents; the "-dark" variants and
   --rc-b/--rc-h use rgb(10,90,148). --red2 is #0a5a94 (6.9:1 on the near-white
   window body) so the accent-as-text states stay AA — #1a8cd8 itself is 3.4:1
   and is only ever a border, a fill or a glow. */
:root[data-theme="vista"]{
  --accent-glow: rgba(26,140,216,.05);
  --red: #1a8cd8;
  --red2: #0a5a94;
  --rc-a-15: rgba(26,140,216,.22);
  --rc-a-60: rgba(26,140,216,.6);
  --rc-a-85: rgba(26,140,216,.85);
  --rc-b-35: rgba(10,90,148,.52);
  --rc-b-50: rgba(10,90,148,.5);
  --rc-c-18: rgba(26,140,216,.27);
  --rc-c-95: rgba(26,140,216,.95);
  --rc-cold: #06334f;
  --rc-d-12: rgba(26,140,216,.18);
  --rc-d-70: rgba(26,140,216,.7);
  --rc-e-90: rgba(26,140,216,.9);
  --rc-f-50: rgba(26,140,216,.5);
  --rc-g-100: rgba(26,140,216,1);
  --rc-h-80: rgba(10,90,148,.8);
  --rc-hot: #a8dcff;
  --rc-mid: #1a8cd8;
  --red-03: rgba(26,140,216,.04);
  --red-04: rgba(26,140,216,.06);
  --red-05: rgba(26,140,216,.08);
  --red-06: rgba(26,140,216,.09);
  --red-07: rgba(26,140,216,.11);
  --red-08: rgba(26,140,216,.12);
  --red-10: rgba(26,140,216,.15);
  --red-12: rgba(26,140,216,.18);
  --red-14: rgba(26,140,216,.21);
  --red-16: rgba(26,140,216,.24);
  --red-18: rgba(26,140,216,.27);
  --red-20: rgba(26,140,216,.3);
  --red-22: rgba(26,140,216,.33);
  --red-28: rgba(26,140,216,.42);
  --red-30: rgba(26,140,216,.45);
  --red-35: rgba(26,140,216,.52);
  --red-40: rgba(26,140,216,.6);
  --red-45: rgba(26,140,216,.68);
  --red-55: rgba(26,140,216,.55);
  --red-60: rgba(26,140,216,.6);
  --red-70: rgba(26,140,216,.7);
  --red-95: rgba(26,140,216,.95);
  --red-b-10: rgba(26,140,216,.15);
  --red-b-25: rgba(26,140,216,.38);
  --red-b-50: rgba(26,140,216,.5);
  --red-d-15: rgba(26,140,216,.22);
  --red-dark-18: rgba(10,90,148,.27);
  --red-dark-60: rgba(10,90,148,.6);
  --red-dark2-35: rgba(10,90,148,.52);
  --red-e-85: rgba(26,140,216,.85);
  --red-15: rgba(26,140,216,.22);
  --red-25: rgba(26,140,216,.38);
  --red-b-85: rgba(26,140,216,.85);
  --red-e-90: rgba(26,140,216,.9);
  --red-e-95: rgba(26,140,216,.95);
  --red-b-70: rgba(26,140,216,.7);
}
:root[data-theme="vista"]{
  /* Segoe UI is the face Vista introduced and is present on every Windows
     client; Open Sans is the humanist stand-in everywhere else (normal
     metrics, so it drags in none of the correction layers VT323 once forced).
     Consolas arrived with Vista too and is the mono. No display font in
     --font: the title uses the same family a size up, as Vista's did. */
  --font: 'Segoe UI', 'Open Sans', Tahoma, Verdana, Arial, sans-serif;
  --mono: Consolas, 'DejaVu Sans Mono', 'Lucida Console', 'Courier New', ui-monospace, monospace;

  /* The desktop is the Aurora wallpaper, painted by body::before; both --bg
     tokens are the deep teal it fades to, so nothing can gradient between
     them. --panel is the window body: near-white and near-opaque, because the
     glass belongs to the FRAME, not to the paper you read text on. */
  --bg0: #06303f;
  --bg1: #06303f;
  --panel: rgba(246,249,252,.94);
  --panel-solid: #f6f9fc;
  --line: #c3d2df;

  /* Aero rounds controls at 3px and window corners at 8px (set per rule in
     the section). Windows cast a real drop shadow — the glass has depth. */
  --radius: 3px;
  --shadow: 0 1px 3px rgba(0,0,0,.25);
  --shadow2: 0 10px 30px rgba(0,0,0,.38);

  /* ── The Aero palette, for this theme's chrome only ──────────────────────
     Not the accent — that is still the --red-* family above. */

  /* Ink on the light window body. Same values as the shared light block, held
     as tokens here because the header card re-scopes --text/--muted to white
     and the menus inside it have to put them back. */
  --vi-ink:       #14161a;
  --vi-ink-muted: #5c6470;

  /* The glass. --vi-frame is the frame ring: translucent, so the blurred
     wallpaper is what you see through it. --vi-glass fills the header card,
     which is a window made entirely of glass. The two hairlines are Aero's
     signature: a bright one just inside the frame, a dark one just outside. */
  --vi-frame:      rgba(28,62,96,.42);
  --vi-frame-hot:  rgba(40,84,124,.46);
  --vi-glass:      rgba(10,34,56,.72);
  --vi-glass-2:    rgba(16,48,76,.55);
  --vi-inner-line: rgba(255,255,255,.70);
  --vi-outer-line: rgba(2,16,32,.55);
  --vi-blur:       blur(18px) saturate(150%);

  /* Text on glass, and the halo Vista drew behind it so it stayed legible
     over whatever the wallpaper was doing underneath. */
  --vi-on-glass:     #ffffff;
  --vi-on-glass-dim: rgba(255,255,255,.80);
  --vi-title-glow:   0 0 8px rgba(0,18,34,.95), 0 1px 2px rgba(0,0,0,.65);
  --vi-label-glow:   0 1px 2px rgba(0,0,0,.75), 0 0 6px rgba(0,20,38,.85);

  /* The gloss: a hard stop at the midline is what makes an Aero surface read
     as glass rather than as a gradient. */
  --vi-gloss:      linear-gradient(180deg, rgba(255,255,255,.30) 0, rgba(255,255,255,.10) 47%, rgba(255,255,255,.02) 47%, rgba(255,255,255,.10) 100%);
  --vi-gloss-line: rgba(255,255,255,.35);

  /* Push buttons, at rest / hover / pressed. The hover is the one everybody
     remembers: the face turns pale blue and the whole control glows. */
  --vi-btn-grad:      linear-gradient(180deg, #fdfefe 0, #f2f5f8 47%, #e2e9f0 47%, #eef3f8 100%);
  --vi-btn-grad-hot:  linear-gradient(180deg, #eaf6fd 0, #d9f0fc 47%, #bee6fd 47%, #d3eefb 100%);
  --vi-btn-grad-down: linear-gradient(180deg, #e5f4fc 0, #c4e5f6 47%, #98d1ef 47%, #b7e0f4 100%);
  --vi-btn-border:     #7c9dbd;
  --vi-btn-border-hot: #3c7fb1;
  --vi-btn-border-down:#2c628b;
  --vi-btn-hi:        rgba(255,255,255,.85);
  --vi-btn-down-ring: inset 0 2px 3px rgba(0,0,0,.18);
  --vi-glow:          rgba(90,180,255,.85);
  --vi-glow-soft:     rgba(90,180,255,.55);
  --vi-disabled:      #9aa8b4;
  --vi-disabled-edge: #c7d2dc;

  /* The same button, on glass. */
  --vi-glass-btn:      linear-gradient(180deg, rgba(255,255,255,.30) 0, rgba(255,255,255,.14) 47%, rgba(255,255,255,.05) 47%, rgba(255,255,255,.13) 100%);
  --vi-glass-btn-hot:  linear-gradient(180deg, rgba(255,255,255,.48) 0, rgba(255,255,255,.26) 47%, rgba(255,255,255,.14) 47%, rgba(255,255,255,.24) 100%);
  --vi-glass-btn-edge: rgba(255,255,255,.45);
  --vi-glass-btn-edge-hot: rgba(255,255,255,.85);

  /* Fields, selection, lists, separators. */
  --vi-field:      #ffffff;
  --vi-field-edge: #7c9dbd;
  --vi-field-ring: inset 0 1px 2px rgba(0,0,0,.10);
  --vi-focus-ring: 0 0 5px var(--vi-glow);
  --vi-sel:        linear-gradient(180deg, #f0f7ff 0, #d3e9fb 100%);
  --vi-sel-edge:   #7da2ce;
  --vi-row-hover:  #e8f2fd;
  --vi-head:       linear-gradient(180deg, #f9fbfd 0, #e9f0f7 100%);
  --vi-head-edge:  #b9c9d8;
  --vi-rule:       #e2e9f0;
  --vi-panel:      linear-gradient(180deg, rgba(255,255,255,.90) 0, rgba(232,240,248,.90) 100%);
  --vi-panel-edge: #c3d5e4;
  --vi-menu-edge:  #a3b8c9;
  --vi-menu-shadow: 0 6px 18px rgba(0,0,0,.30);
  --vi-tip:        linear-gradient(180deg, #ffffff 0, #eef4fa 100%);

  /* Title bars on a dialog, where there is no wallpaper behind to look
     through: the glass is faked with a solid gradient plus the gloss. */
  --vi-title-grad: linear-gradient(180deg, #2f739f 0, #1d5480 55%, #16405f 100%);

  /* The close button and the Start orb. */
  --vi-close-grad:     linear-gradient(180deg, #f4998a 0, #e2513a 47%, #c8290f 47%, #e05a3f 100%);
  --vi-close-grad-hot: linear-gradient(180deg, #ffb4a6 0, #f06550 47%, #dc3a1c 47%, #f0705a 100%);
  --vi-close-edge:     #7e1d0b;
  --vi-orb:        radial-gradient(circle at 50% 32%, #bfe6ff 0, #4aa8ea 34%, #1a72c0 66%, #0b3f74 100%);
  --vi-orb-edge:   rgba(255,255,255,.55);
  --vi-orb-ring:   rgba(120,200,255,.55);
  --vi-orb-gloss:  linear-gradient(180deg, rgba(255,255,255,.80) 0, rgba(255,255,255,.16) 46%, rgba(255,255,255,0) 62%);
}
/* ═══════════════════════════════════════════════════════════════════════════
   WINDOWS VISTA — structural section
   Everything here is scoped to :root[data-theme="vista"]. No rule may escape
   that, or it dirties the other eleven themes.

   Same architecture as Windows 3.11 and Windows XP: the theme takes the light
   themes' shared TOKENS (it is in that selector) but not their grouped
   structural rules, so the base dark chrome still applies until a rule below
   replaces it. This section covers every shared class the :root chrome
   styles, one by one, in the same order as those two sections.

   Reference: Aero, 2007 — the Aurora wallpaper, windows framed in blurred
   translucent glass, a light document body inside the frame, glossy buttons
   that glow blue when the pointer is over them, white fields with a blue
   focus glow, and the Start orb. Nothing moves.

   How the glass is built, because it is the one non-obvious thing here:
   `* { box-sizing: border-box }` is global (line 254), so a thick border
   costs nothing in layout width. A card gets `border: 6px solid <translucent>`
   plus `background-clip: padding-box`, so the card's own opaque background
   stops at the padding edge and the 6px ring stays see-through; the card's
   `backdrop-filter` blurs the wallpaper behind the whole border box, and that
   blur is what shows through the ring. That IS the Aero frame — not a picture
   of one. The two hairlines (an inset one at the padding edge, a spread one
   just outside the border box) are the bright and dark edges Aero drew.
   ═══════════════════════════════════════════════════════════════════════════ */

/* ── Desktop ────────────────────────────────────────────────────────────────
   The Aurora wallpaper, served from this site (/assets/vista.jpg — the CSP is
   default-src 'self', so it has to live here; bump ?v= when the file changes)
   on a fixed, viewport-sized layer at z-index:-1, with the deep teal it fades
   to underneath as the canvas and the fallback. It has to sit on body::before
   rather than on body's own background so that the cards' backdrop-filter has
   something to blur: a backdrop is what is PAINTED behind the element, and a
   fixed pseudo-element qualifies. The scanline layer and the card sweep go. */
:root[data-theme="vista"] body{
  background: var(--bg0);
}
:root[data-theme="vista"] body::before{
  content: "";
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  opacity: 1;
  transform: none;
  animation: none;
  filter: none;
  background:
    url('/assets/vista.jpg?v=1') center center / cover no-repeat,
    var(--bg0);
}
:root[data-theme="vista"] body::after{ display: none; }
:root[data-theme="vista"] .tmsp-sweep{ display: none; }

/* Text that sits directly on the desktop is a desktop-icon label: white with
   the halo Vista drew behind it, because the wallpaper underneath runs from
   deep teal to near-white and no flat colour survives both. */
:root[data-theme="vista"] .tmsp-wrap > .tmsp-muted{
  color: var(--vi-on-glass);
  text-shadow: var(--vi-label-glow);
}

/* ── Windows ────────────────────────────────────────────────────────────────
   A card is a window: a 6px glass frame around a near-white body, 8px
   corners, a real drop shadow. The HUD corners have no equivalent in Aero
   and go. */
:root[data-theme="vista"] .tmsp-card{
  border: 6px solid var(--vi-frame);
  border-radius: 8px;
  background: var(--panel);
  background-clip: padding-box;
  box-shadow:
    inset 0 0 0 1px var(--vi-inner-line),
    0 0 0 1px var(--vi-outer-line),
    var(--shadow2);
  backdrop-filter: var(--vi-blur);
  -webkit-backdrop-filter: var(--vi-blur);
}
:root[data-theme="vista"] .tmsp-card::before,
:root[data-theme="vista"] .tmsp-card::after{ display: none; }
:root[data-theme="vista"] .tmsp-perm-card{
  box-shadow:
    inset 0 0 0 1px var(--vi-inner-line),
    inset 0 0 0 100vmax var(--card-tint-dark),
    0 0 0 1px var(--vi-outer-line),
    var(--shadow2);
}

/* The header card is a window made entirely of glass: no light body, the
   wallpaper blurred right through it, everything on it in white. It holds
   only chrome — the title, the pills, the nav — so re-scoping the ink tokens
   here is safe and catches any page-local caption too, without naming its
   class. */
:root[data-theme="vista"] .tmsp-card:has(.tmsp-reactor){
  background: var(--vi-glass);
  background-clip: padding-box;
  border-color: var(--vi-frame-hot);
  --text:    var(--vi-on-glass);
  --text-b:  var(--vi-on-glass);
  --muted:   var(--vi-on-glass-dim);
  --muted-2: var(--vi-on-glass-dim);
  --muted-3: var(--vi-on-glass-dim);
  --muted-4: var(--vi-on-glass-dim);
  --label:   var(--vi-on-glass-dim);
}
/* The menus that open from that card are white panels and inherit those
   custom properties, so they are put back — otherwise the items are white on
   white. This is the cost of re-scoping tokens rather than classes, and it is
   one rule. */
:root[data-theme="vista"] .tmsp-card:has(.tmsp-reactor) .tmsp-dropdown-menu,
:root[data-theme="vista"] .tmsp-card:has(.tmsp-reactor) .tmsp-dropdown-submenu-flyout{
  --text:    var(--vi-ink);
  --text-b:  var(--vi-ink);
  --muted:   var(--vi-ink-muted);
  --muted-2: var(--vi-ink-muted);
  --muted-3: var(--vi-ink-muted);
  --muted-4: var(--vi-ink-muted);
  --label:   var(--vi-ink-muted);
}

/* The glow bar becomes the etched separator: a hairline over a white one on
   the light body, and a pair of translucent whites on the glass. */
:root[data-theme="vista"] .tmsp-glowbar{
  height: 2px;
  margin: 10px 0 14px;
  background: none;
  opacity: 1;
  border-top: 1px solid var(--vi-rule);
  border-bottom: 1px solid var(--vi-field);
}
:root[data-theme="vista"] .tmsp-card:has(.tmsp-reactor) .tmsp-glowbar{
  border-top-color: rgba(255,255,255,.22);
  border-bottom-color: rgba(255,255,255,.07);
}

/* ── Title bar ──────────────────────────────────────────────────────────────
   The same trick as the other two Windows themes: .tmsp-reactor appears once
   per page and the row holding it is .tmsp-pagehead on all 28 pages, so the
   row is pulled out to the inner edge of the frame (the card's 24px padding;
   the 6px border stays visible around it, which is where a title bar sits in
   Aero) and given the gloss. The phone layer pads the card at 14px and 12px,
   so the margin is restated at both tiers. */
:root[data-theme="vista"] .tmsp-card:has(.tmsp-reactor) .tmsp-pagehead{
  margin: -24px -24px 0;
  padding: 10px 12px;
  border-radius: 2px 2px 0 0;
  background: var(--vi-gloss), var(--vi-glass-2);
  box-shadow: inset 0 1px 0 var(--vi-gloss-line);
  color: var(--vi-on-glass);
}
@media (max-width: 820px){
  :root[data-theme="vista"] .tmsp-card:has(.tmsp-reactor) .tmsp-pagehead{ margin: -14px -14px 0; }
}
@media (max-width: 480px){
  :root[data-theme="vista"] .tmsp-card:has(.tmsp-reactor) .tmsp-pagehead{ margin: -12px -12px 0; }
}
:root[data-theme="vista"] .tmsp-card:has(.tmsp-reactor) .tmsp-pagehead .tmsp-title{
  color: var(--vi-on-glass);
  text-shadow: var(--vi-title-glow);
}
:root[data-theme="vista"] .tmsp-card:has(.tmsp-reactor) .tmsp-pagehead .tmsp-muted{
  color: var(--vi-on-glass-dim);
  text-shadow: var(--vi-label-glow);
}
/* The close button. .tmsp-pagehead is a flex row with justify-content:
   space-between from its inline style, so a ::after is a third flex item at
   the far right; the tools cluster takes margin-left:auto so it stays flush
   against it (auto margins win over justify-content). Aero's close was wide
   and glossy. Decoration only: no content text, pointer-events:none, and the
   x is two diagonal gradients. Hidden below 821px, where the row stacks. */
@media (min-width: 821px){
  :root[data-theme="vista"] .tmsp-card:has(.tmsp-reactor) .tmsp-pagehead .tmsp-pagehead-tools{
    margin-left: auto;
  }
  :root[data-theme="vista"] .tmsp-card:has(.tmsp-reactor) .tmsp-pagehead::after{
    content: "";
    flex: 0 0 34px;
    width: 34px;
    height: 21px;
    margin-top: 2px;
    border: 1px solid var(--vi-close-edge);
    border-radius: 3px;
    box-shadow: inset 0 1px 0 rgba(255,255,255,.45), 0 0 6px rgba(0,0,0,.35);
    background:
      linear-gradient(45deg, transparent calc(50% - 1px), var(--vi-on-glass) calc(50% - 1px), var(--vi-on-glass) calc(50% + 1px), transparent calc(50% + 1px)) center / 9px 9px no-repeat,
      linear-gradient(-45deg, transparent calc(50% - 1px), var(--vi-on-glass) calc(50% - 1px), var(--vi-on-glass) calc(50% + 1px), transparent calc(50% + 1px)) center / 9px 9px no-repeat,
      var(--vi-close-grad);
    pointer-events: none;
  }
}

/* ── Title ──────────────────────────────────────────────────────────────────
   Vista's title bars were the UI face at a larger size in regular weight and
   mixed case — not a display font, and not bold. That is the whole change. */
:root[data-theme="vista"] .tmsp-title{
  font-family: var(--font);
  font-weight: 400;
  font-size: 22px;
  letter-spacing: 0;
  text-transform: none;
  text-shadow: none;
  color: var(--text);
}
@media (max-width: 820px){
  :root[data-theme="vista"] .tmsp-title{ font-size: 19px; }
}
@media (max-width: 480px){
  :root[data-theme="vista"] .tmsp-title{ font-size: 17px; }
}
:root[data-theme="vista"] .tmsp-glitch{ text-shadow: none; }
:root[data-theme="vista"] .tmsp-glitch::before,
:root[data-theme="vista"] .tmsp-glitch::after{ display: none; }

/* ── The orb ────────────────────────────────────────────────────────────────
   The reactor is the one piece of shared chrome that was already round, so
   Vista is the theme that gets to keep it round: it becomes the Start orb.
   The three rings and the core are reused as the orb's layers rather than
   hidden — ring 1 is the bright rim, ring 2 the gloss across the top, ring 3
   is not needed, and the core is the highlight at the centre. Nothing spins. */
:root[data-theme="vista"] .tmsp-reactor{
  border-radius: 50%;
  background: var(--vi-orb);
  box-shadow:
    inset 0 0 0 1px var(--vi-orb-edge),
    0 0 10px var(--vi-orb-ring),
    0 2px 6px rgba(0,0,0,.45);
}
:root[data-theme="vista"] .tmsp-reactor-ring:nth-child(1){
  inset: 0;
  border: 1px solid var(--vi-orb-edge);
  border-radius: 50%;
  box-shadow: none;
  animation: none;
}
:root[data-theme="vista"] .tmsp-reactor-ring:nth-child(2){
  inset: 3px;
  border: none;
  border-radius: 50%;
  background: var(--vi-orb-gloss);
  animation: none;
}
:root[data-theme="vista"] .tmsp-reactor-ring:nth-child(3){ display: none; }
:root[data-theme="vista"] .tmsp-reactor-core{
  inset: 20px;
  border-radius: 50%;
  border: none;
  background: radial-gradient(circle, rgba(255,255,255,.95) 0, rgba(190,230,255,.35) 55%, transparent 70%);
  box-shadow: none;
  animation: none;
}

/* ── Buttons ────────────────────────────────────────────────────────────────
   The Aero push button: the two-tone gloss with its hard stop at the midline,
   a 1px blue-grey border, 3px corners, the UI face in mixed case at regular
   weight. Hover turns the face pale blue and lights the outer glow — the one
   thing everyone remembers about this interface. Pressed is the darker face
   with an inset shadow. Disabled is greyed, not faded. Aero had no coloured
   buttons, so the variants keep the face and differ by text colour; danger
   also takes a red border, because there the colour means "destructive
   action" and not the accent, as in the other eleven themes. */
:root[data-theme="vista"] .tmsp-btn{
  background: var(--vi-btn-grad);
  border: 1px solid var(--vi-btn-border);
  border-radius: 3px;
  box-shadow: inset 0 1px 0 var(--vi-btn-hi);
  color: var(--vi-ink);
  font-family: var(--font);
  font-weight: 400;
  font-size: 12.5px;
  letter-spacing: 0;
  text-transform: none;
  transition: box-shadow .15s ease, border-color .15s ease, background .15s ease;
}
:root[data-theme="vista"] .tmsp-btn:hover{
  background: var(--vi-btn-grad-hot);
  border-color: var(--vi-btn-border-hot);
  box-shadow: inset 0 1px 0 var(--vi-btn-hi), 0 0 6px var(--vi-glow);
  transform: none;
}
:root[data-theme="vista"] .tmsp-btn:active{
  background: var(--vi-btn-grad-down);
  border-color: var(--vi-btn-border-down);
  box-shadow: var(--vi-btn-down-ring);
  transform: none;
}
:root[data-theme="vista"] .tmsp-btn:focus-visible{
  outline: none;
  border-color: var(--vi-btn-border-hot);
  box-shadow: inset 0 1px 0 var(--vi-btn-hi), var(--vi-focus-ring);
}
:root[data-theme="vista"] .tmsp-btn:disabled,
:root[data-theme="vista"] .tmsp-btn:disabled:hover{
  opacity: 1;
  background: var(--vi-btn-grad);
  border-color: var(--vi-disabled-edge);
  box-shadow: none;
  color: var(--vi-disabled);
  transform: none;
}
:root[data-theme="vista"] .tmsp-btn-sm{ font-size: 11.5px; border-radius: 3px; }
:root[data-theme="vista"] .tmsp-btn-ghost{ color: var(--vi-ink-muted); }
:root[data-theme="vista"] .tmsp-btn-ghost:hover{ color: var(--vi-ink); }
:root[data-theme="vista"] .tmsp-btn-blue{ color: var(--red2); }
:root[data-theme="vista"] .tmsp-btn-blue:hover{ color: var(--red2); }
:root[data-theme="vista"] .tmsp-btn-green{ color: var(--ok-solid); }
:root[data-theme="vista"] .tmsp-btn-green:hover{ color: var(--ok-solid); }
:root[data-theme="vista"] .tmsp-btn-danger{ color: var(--danger); border-color: var(--danger-30); }
:root[data-theme="vista"] .tmsp-btn-danger:hover{ color: var(--danger); border-color: var(--danger); }
:root[data-theme="vista"] .tmsp-btn-dark{
  background: linear-gradient(180deg, var(--vi-ink-muted) 0, var(--vi-ink) 100%);
  border-color: var(--vi-ink);
  color: var(--vi-on-glass);
  text-shadow: 0 1px 1px rgba(0,0,0,.55);
}
:root[data-theme="vista"] .tmsp-btn-dark:hover{
  background: var(--vi-close-grad-hot);
  border-color: var(--vi-close-edge);
  color: var(--vi-on-glass);
}

/* The same button on the glass header: the face becomes translucent white so
   the wallpaper still reads through it, and the label turns white. */
:root[data-theme="vista"] .tmsp-card:has(.tmsp-reactor) .tmsp-btn,
:root[data-theme="vista"] .tmsp-card:has(.tmsp-reactor) .tmsp-tag,
:root[data-theme="vista"] .tmsp-card:has(.tmsp-reactor) .tmsp-nav-burger{
  background: var(--vi-glass-btn);
  border: 1px solid var(--vi-glass-btn-edge);
  border-radius: 3px;
  box-shadow: inset 0 1px 0 var(--vi-gloss-line);
  color: var(--vi-on-glass);
  text-shadow: 0 1px 1px rgba(0,0,0,.55);
}
:root[data-theme="vista"] .tmsp-card:has(.tmsp-reactor) .tmsp-btn:hover,
:root[data-theme="vista"] .tmsp-card:has(.tmsp-reactor) .tmsp-tag:hover,
:root[data-theme="vista"] .tmsp-card:has(.tmsp-reactor) .tmsp-nav-burger:hover{
  background: var(--vi-glass-btn-hot);
  border-color: var(--vi-glass-btn-edge-hot);
  box-shadow: inset 0 1px 0 var(--vi-gloss-line), 0 0 8px var(--vi-glow-soft);
  color: var(--vi-on-glass);
}
/* The red button on the glass header keeps its red: the Aero close-button
   gradient, so it reads as a real red control and not a tinted label. */
:root[data-theme="vista"] .tmsp-card:has(.tmsp-reactor) .tmsp-btn-danger{
  background: var(--vi-close-grad);
  border-color: var(--vi-close-edge);
  color: var(--vi-on-glass);
}
:root[data-theme="vista"] .tmsp-card:has(.tmsp-reactor) .tmsp-btn-danger:hover{
  background: var(--vi-close-grad-hot);
  border-color: var(--vi-close-edge);
  color: var(--vi-on-glass);
}
:root[data-theme="vista"] .tmsp-card:has(.tmsp-reactor) .tmsp-btn:active{
  background: var(--vi-glass-btn);
  box-shadow: var(--vi-btn-down-ring);
}
:root[data-theme="vista"] .tmsp-card:has(.tmsp-reactor) .tmsp-btn:disabled,
:root[data-theme="vista"] .tmsp-card:has(.tmsp-reactor) .tmsp-btn:disabled:hover{
  background: var(--vi-glass-btn);
  border-color: var(--vi-glass-btn-edge);
  box-shadow: none;
  color: var(--vi-on-glass-dim);
  opacity: .55;
}

/* ── Tags ───────────────────────────────────────────────────────────────────
   On the light body they are small glossy panels; on the glass they are
   handled by the rule above. The coloured variants keep their meaning through
   the state solids, which the shared light block already calibrated for a
   near-white surface. */
:root[data-theme="vista"] .tmsp-tag{
  background: var(--vi-panel);
  border: 1px solid var(--vi-panel-edge);
  border-radius: 3px;
  box-shadow: inset 0 1px 0 var(--vi-btn-hi);
  color: var(--tag-text);
}
:root[data-theme="vista"] .tmsp-tag-red{
  border-color: var(--danger-30);
  background: var(--danger-09);
  color: var(--danger);
}
:root[data-theme="vista"] .tmsp-tag-green{  color: var(--ok-solid); }
:root[data-theme="vista"] .tmsp-tag-yellow{ color: var(--warn-solid); }
:root[data-theme="vista"] .tmsp-tag-blue{   color: var(--info-b-solid); }

/* ── Fields ─────────────────────────────────────────────────────────────────
   White, the Aero blue-grey border, a hairline of shading at the top, and on
   focus the border goes blue and the control glows — the same glow as the
   buttons, which is what made the two feel like one system. */
:root[data-theme="vista"] .tmsp-input,
:root[data-theme="vista"] .tmsp-textarea,
:root[data-theme="vista"] select.tmsp-input,
:root[data-theme="vista"] .tmsp-inline-select{
  background: var(--vi-field);
  border: 1px solid var(--vi-field-edge);
  border-radius: 3px;
  box-shadow: var(--vi-field-ring);
  color: var(--text);
}
:root[data-theme="vista"] .tmsp-input:focus,
:root[data-theme="vista"] .tmsp-textarea:focus,
:root[data-theme="vista"] select.tmsp-input:focus,
:root[data-theme="vista"] .tmsp-inline-select:focus{
  border-color: var(--vi-btn-border-hot);
  box-shadow: var(--vi-field-ring), var(--vi-focus-ring);
}
:root[data-theme="vista"] .tmsp-terminal{
  background: var(--vi-field);
  border: 1px solid var(--vi-field-edge);
  border-radius: 3px;
  box-shadow: var(--vi-field-ring);
  color: var(--term-text);
}

/* ── Message boxes ──────────────────────────────────────────────────────────
   Small dialogs: the light panel with a border in the state colour. They also
   sit outside the cards on some pages (the flash), where an accent tint on
   the wallpaper would be unreadable, so the fill is opaque. */
:root[data-theme="vista"] .tmsp-error{
  background: var(--vi-panel);
  border: 1px solid var(--danger);
  border-radius: 4px;
  box-shadow: var(--shadow2);
}
:root[data-theme="vista"] .tmsp-success{
  background: var(--vi-panel);
  border: 1px solid var(--ok-solid);
  border-radius: 4px;
  box-shadow: var(--shadow2);
}

/* ── Tabs ───────────────────────────────────────────────────────────────────
   Glossy tabs on a hairline; the current one is white and carries the accent
   along its top edge. */
:root[data-theme="vista"] .tmsp-tabs{ border-bottom: 1px solid var(--vi-head-edge); }
:root[data-theme="vista"] .tmsp-tab{
  background: var(--vi-btn-grad);
  border: 1px solid var(--vi-btn-border);
  border-bottom: none;
  border-radius: 3px 3px 0 0;
  box-shadow: inset 0 1px 0 var(--vi-btn-hi);
  color: var(--vi-ink);
  font-family: var(--font);
  font-weight: 400;
  font-size: 12.5px;
  letter-spacing: 0;
  text-transform: none;
  transition: background .15s ease;
}
:root[data-theme="vista"] .tmsp-tabs-sub .tmsp-tab{ font-size: 11.5px; }
:root[data-theme="vista"] .tmsp-tab:hover{
  background: var(--vi-btn-grad-hot);
  border-color: var(--vi-btn-border-hot);
  color: var(--vi-ink);
}
:root[data-theme="vista"] .tmsp-tab.is-current{
  background: var(--vi-field);
  border-color: var(--vi-btn-border);
  box-shadow: inset 0 2px 0 var(--red);
  color: var(--vi-ink);
}

/* ── Tables ─────────────────────────────────────────────────────────────────
   A list view: a glossy header on a hairline, faint rules between rows, a
   light blue row hover. The hover is not the selection gradient on purpose —
   rows carry inline style="color:…" P&L colours, and the selection is kept
   for the states that really are selected. */
:root[data-theme="vista"] .tmsp-table th{
  background: var(--red-08);
  color: var(--muted);
  border-bottom: 1px solid var(--vi-head-edge);
}
:root[data-theme="vista"] .tmsp-table td{
  border-bottom: 1px solid var(--vi-rule);
}
:root[data-theme="vista"] .tmsp-table tr:hover td{
  background: var(--vi-row-hover);
}
:root[data-theme="vista"] .tmsp-table-totals td,
:root[data-theme="vista"] .tmsp-table tr.tmsp-table-totals:hover td{
  background: var(--vi-head);
  border-top: 1px solid var(--vi-head-edge);
  color: var(--text);
}

/* ── Stat tiles ─────────────────────────────────────────────────────────────
   The glossy panel Vista used for a group of readings. */
:root[data-theme="vista"] .tmsp-stat{
  background: var(--vi-panel);
  border: 1px solid var(--vi-panel-edge);
  border-radius: 4px;
  box-shadow: inset 0 1px 0 var(--vi-btn-hi);
}

/* ── Menus ──────────────────────────────────────────────────────────────────
   White panels with a hairline border and a soft shadow, the UI face instead
   of mono. Hover and the current theme are the Explorer selection: the pale
   blue gradient with a blue edge and dark text — drawn with an inset ring so
   nothing shifts by a pixel when it appears. The check mark on the current
   theme is inherited from the base rule. */
:root[data-theme="vista"] .tmsp-dropdown-menu,
:root[data-theme="vista"] .tmsp-dropdown-submenu-flyout{
  background: var(--vi-field);
  border: 1px solid var(--vi-menu-edge);
  border-radius: 3px;
  box-shadow: var(--vi-menu-shadow);
  padding-top: 3px;
}
:root[data-theme="vista"] .tmsp-dropdown-menu a,
:root[data-theme="vista"] .tmsp-dropdown-menu button,
:root[data-theme="vista"] .tmsp-dropdown-menu .tmsp-dropdown-placeholder,
:root[data-theme="vista"] .tmsp-dropdown-submenu-label,
:root[data-theme="vista"] .tmsp-dropdown-submenu-flyout a{
  font-family: var(--font);
  font-size: 12.5px;
  letter-spacing: 0;
  padding: 6px 24px 6px 16px;
  color: var(--text);
  border-bottom: none;
  transition: none;
}
:root[data-theme="vista"] .tmsp-dropdown-menu a:hover,
:root[data-theme="vista"] .tmsp-dropdown-menu button:hover,
:root[data-theme="vista"] .tmsp-dropdown-menu button.is-current,
:root[data-theme="vista"] .tmsp-dropdown-submenu:hover .tmsp-dropdown-submenu-label,
:root[data-theme="vista"] .tmsp-dropdown-submenu:focus-within .tmsp-dropdown-submenu-label,
:root[data-theme="vista"] .tmsp-dropdown-submenu-flyout a:hover{
  background: var(--vi-sel);
  box-shadow: inset 0 0 0 1px var(--vi-sel-edge);
  color: var(--vi-ink);
}
:root[data-theme="vista"] .tmsp-dropdown-menu .tmsp-dropdown-placeholder,
:root[data-theme="vista"] .tmsp-dropdown-menu .tmsp-dropdown-placeholder:hover{
  background: none;
  box-shadow: none;
  color: var(--vi-disabled);
}

/* ── Help button, modal, tooltip ────────────────────────────────────────────
   The "?" stays round and becomes a glossy button. The modal is a dialog
   window with the same glass frame as a card; its title becomes the title
   bar. There is no wallpaper behind a dialog that floats over the page, so
   that one band is a solid gradient with the gloss laid over it rather than
   real glass — the only place in this theme where the glass is painted. The
   close button precedes the title in the markup and is absolutely positioned,
   so it lands on the band. */
:root[data-theme="vista"] .tmsp-help-btn{
  background: var(--vi-btn-grad);
  border: 1px solid var(--vi-btn-border);
  box-shadow: inset 0 1px 0 var(--vi-btn-hi);
  color: var(--vi-ink);
  font-family: var(--font);
  transition: box-shadow .15s ease, border-color .15s ease;
}
:root[data-theme="vista"] .tmsp-help-btn:hover{
  background: var(--vi-btn-grad-hot);
  border-color: var(--vi-btn-border-hot);
  box-shadow: inset 0 1px 0 var(--vi-btn-hi), 0 0 6px var(--vi-glow);
  color: var(--vi-ink);
}
:root[data-theme="vista"] .tmsp-modal-box{
  border: 6px solid var(--vi-frame);
  border-radius: 8px;
  background: var(--panel-solid);
  background-clip: padding-box;
  box-shadow:
    inset 0 0 0 1px var(--vi-inner-line),
    0 0 0 1px var(--vi-outer-line),
    var(--shadow2);
  backdrop-filter: var(--vi-blur);
  -webkit-backdrop-filter: var(--vi-blur);
}
:root[data-theme="vista"] .tmsp-modal-title{
  margin: -24px -24px 14px;
  padding: 9px 46px 9px 12px;
  min-height: 24px;
  line-height: 24px;
  border-radius: 2px 2px 0 0;
  background: var(--vi-gloss), var(--vi-title-grad);
  box-shadow: inset 0 1px 0 var(--vi-gloss-line);
  color: var(--vi-on-glass);
  text-shadow: var(--vi-title-glow);
  font-family: var(--font);
  font-size: 13.5px;
  font-weight: 400;
  letter-spacing: 0;
}
:root[data-theme="vista"] .tmsp-modal-close{
  top: 10px;
  right: 10px;
  width: 34px;
  height: 21px;
  border-radius: 3px;
  border: 1px solid var(--vi-close-edge);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.45);
  background: var(--vi-close-grad);
  color: var(--vi-on-glass);
  font-family: var(--font);
  font-size: 14px;
  font-weight: 400;
  line-height: 1;
}
:root[data-theme="vista"] .tmsp-modal-close:hover{
  color: var(--vi-on-glass);
  border-color: var(--vi-close-edge);
  background: var(--vi-close-grad-hot);
}
:root[data-theme="vista"] .tmsp-tip{
  background: var(--vi-tip);
  border: 1px solid var(--vi-menu-edge);
  border-radius: 3px;
  box-shadow: var(--vi-menu-shadow);
  color: var(--vi-ink);
}

/* ── Engine stopped ─────────────────────────────────────────────────────────
   The liveness dot stays — it is a signal, not decoration — but it does not
   breathe. Nothing in this section animates and every base animation is
   switched off unconditionally above, so there is nothing left for a
   prefers-reduced-motion block to stop. */
:root[data-theme="vista"] .tmsp-pulse{
  animation: none;
}

/* ── One-off page corrections ───────────────────────────────────────────────
   Page-local classes that set a radius or an accent-tinted "selected" state,
   and the two families of tile that sit directly on the wallpaper instead of
   inside a card — those become small windows, light like the others, because
   their contents are page-coloured (green readings, inline P&L) and only a
   light surface keeps all of it legible. */
:root[data-theme="vista"] .view-tab{
  border-radius: 3px;
  background: var(--vi-btn-grad);
  border: 1px solid var(--vi-btn-border);
  box-shadow: inset 0 1px 0 var(--vi-btn-hi);
  color: var(--vi-ink);
}
:root[data-theme="vista"] .view-tab.active,
:root[data-theme="vista"] .hive-tab.active{
  background: var(--vi-btn-grad-down);
  border-color: var(--vi-btn-border-down);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.55);
  color: var(--vi-ink);
}
:root[data-theme="vista"] .dash-stat,
:root[data-theme="vista"] .stat-tile{
  background: var(--panel);
  border: 4px solid var(--vi-frame);
  border-radius: 6px;
  background-clip: padding-box;
  box-shadow:
    inset 0 0 0 1px var(--vi-inner-line),
    0 0 0 1px var(--vi-outer-line),
    var(--shadow2);
  backdrop-filter: var(--vi-blur);
  -webkit-backdrop-filter: var(--vi-blur);
}
/* The dashboard's centrepiece is the reactor scaled 7x with an animated HUD
   around it. Here the reactor is the orb, and an orb does carry being large —
   but 364px is a wallpaper, not an icon, so the scale drops to 3 and the HUD,
   the one thing on the page that still moved, is hidden. */
:root[data-theme="vista"] .dash-reactor{ --dash-reactor-scale: 3; }
:root[data-theme="vista"] .dash-hud,
:root[data-theme="vista"] .dash-corner{ display: none; }
/* The phone layer's burger lives inside the header card and is caught by the
   glass-button rule above; this is only its open state, which tmsp-responsive
   .css sets at id specificity. */
:root[data-theme="vista"] #tmsp-nav-toggle:checked ~ .tmsp-nav-burger{
  background: var(--vi-glass-btn-hot);
  border-color: var(--vi-glass-btn-edge-hot);
  box-shadow: var(--vi-btn-down-ring);
}


/* ═══════════════════════════════════════════════════════════════════════════
   Fujitsu TMSP 01 (retired) — tokens (Light and Dark)
   A glossy theme in Fujitsu's colours: the brand red, white, and a ladder of
   greys. Every surface has a finish — brushed steel for the canvas, linen for
   the cards, a hard-stop gloss on the header, the buttons and the tabs,
   chrome rings and bevels — and the finishes are all drawn with CSS
   gradients, so there is no image to serve.
   Two slugs share it: tmsp01 (Light) takes the shared light block above (it
   is in that selector list) and then the two blocks here; tmsp01dark (Dark)
   keeps the base dark tokens instead, takes the same two blocks, and then
   the "Dark" block after them, which repaints every finish on graphite. The
   selectors of this theme are written [data-theme^="tmsp01"] so both slugs
   get them; only the Dark block names tmsp01dark.
   ═══════════════════════════════════════════════════════════════════════════ */

/* Accent: Fujitsu red, rgb(230,0,18). Same token names and alpha ladder as
   the Vista accent; the "-dark" variants and --rc-b/--rc-h use rgb(184,0,14).
   --red2 is #b8000e (6.9:1 on white) for the accent-as-text states; #e60012
   itself is 4.8:1 and is used for fills, borders and large text. */
:root[data-theme^="tmsp01"]{
  --accent-glow: rgba(230,0,18,.06);
  --red: #e60012;
  --red2: #b8000e;
  --rc-a-15: rgba(230,0,18,.22);
  --rc-a-60: rgba(230,0,18,.6);
  --rc-a-85: rgba(230,0,18,.85);
  --rc-b-35: rgba(184,0,14,.52);
  --rc-b-50: rgba(184,0,14,.5);
  --rc-c-18: rgba(230,0,18,.27);
  --rc-c-95: rgba(230,0,18,.95);
  --rc-cold: #7a0009;
  --rc-d-12: rgba(230,0,18,.18);
  --rc-d-70: rgba(230,0,18,.7);
  --rc-e-90: rgba(230,0,18,.9);
  --rc-f-50: rgba(230,0,18,.5);
  --rc-g-100: rgba(230,0,18,1);
  --rc-h-80: rgba(184,0,14,.8);
  --rc-hot: #ffb3b8;
  --rc-mid: #e60012;
  --red-03: rgba(230,0,18,.04);
  --red-04: rgba(230,0,18,.06);
  --red-05: rgba(230,0,18,.08);
  --red-06: rgba(230,0,18,.09);
  --red-07: rgba(230,0,18,.11);
  --red-08: rgba(230,0,18,.12);
  --red-10: rgba(230,0,18,.15);
  --red-12: rgba(230,0,18,.18);
  --red-14: rgba(230,0,18,.21);
  --red-16: rgba(230,0,18,.24);
  --red-18: rgba(230,0,18,.27);
  --red-20: rgba(230,0,18,.3);
  --red-22: rgba(230,0,18,.33);
  --red-28: rgba(230,0,18,.42);
  --red-30: rgba(230,0,18,.45);
  --red-35: rgba(230,0,18,.52);
  --red-40: rgba(230,0,18,.6);
  --red-45: rgba(230,0,18,.68);
  --red-55: rgba(230,0,18,.55);
  --red-60: rgba(230,0,18,.6);
  --red-70: rgba(230,0,18,.7);
  --red-95: rgba(230,0,18,.95);
  --red-b-10: rgba(230,0,18,.15);
  --red-b-25: rgba(230,0,18,.38);
  --red-b-50: rgba(230,0,18,.5);
  --red-d-15: rgba(230,0,18,.22);
  --red-dark-18: rgba(184,0,14,.27);
  --red-dark-60: rgba(184,0,14,.6);
  --red-dark2-35: rgba(184,0,14,.52);
  --red-e-85: rgba(230,0,18,.85);
  --red-15: rgba(230,0,18,.22);
  --red-25: rgba(230,0,18,.38);
  --red-b-85: rgba(230,0,18,.85);
  --red-e-90: rgba(230,0,18,.9);
  --red-e-95: rgba(230,0,18,.95);
  --red-b-70: rgba(230,0,18,.7);

  /* The state red is the same red. */
  --danger: #c4000f;
  --danger-09: rgba(230,0,18,.08);
  --danger-15: rgba(230,0,18,.16);
  --danger-30: rgba(230,0,18,.45);
  --error-text: #7a0009;
  --red-f-solid: #c4000f;
  --red-deep-solid: #7a0009;
  --red-c-20: rgba(230,0,18,.2);
  --red-c-35: rgba(230,0,18,.35);

  /* The "blue"/info family is a graphite grey here — the palette is red,
     white and grey, and turquoise (the shared block's choice) is neither.
     These come after the shared block and therefore beat it. */
  --blue-btn-10: rgba(74,85,99,.15);
  --blue-btn-12: rgba(74,85,99,.18);
  --blue-btn-20: rgba(74,85,99,.3);
  --blue-btn-22: rgba(74,85,99,.33);
  --blue-btn-38: rgba(74,85,99,.57);
  --blue-btn-40: rgba(74,85,99,.6);
  --blue-btn2-18: rgba(74,85,99,.27);
  --blue-btn2-22: rgba(74,85,99,.33);
  --blue-btn2-40: rgba(74,85,99,.6);
  --blue-btn2-65: rgba(74,85,99,.65);
  --blue-btn3-28: rgba(74,85,99,.42);
  --blue-btn3-35: rgba(74,85,99,.52);
  --blue-btn4-95: rgba(74,85,99,.95);
  --blue-btn5-70: rgba(74,85,99,.7);
  --info-07: rgba(74,85,99,.11);
  --info-25: rgba(74,85,99,.38);
  --info-b-08: rgba(74,85,99,.12);
  --info-b-30: rgba(74,85,99,.45);
  --info-b-solid: #4a5563;
  --info-c-12: rgba(74,85,99,.18);
  --info-c-25: rgba(74,85,99,.38);
  --info-c-solid: #4a5563;
  --info-d-85: rgba(74,85,99,.85);
  --info-d-solid: #4a5563;
  --info-solid: #4a5563;
}
:root[data-theme^="tmsp01"]{
  --font: 'Segoe UI', 'Open Sans', Roboto, Helvetica, Arial, sans-serif;
  --mono: Consolas, 'JetBrains Mono', 'DejaVu Sans Mono', ui-monospace, monospace;

  /* The canvas is brushed steel (painted by body); both --bg tokens are its
     base grey so nothing can gradient between them. --panel is the card
     face, white. */
  --bg0: #dfe3e8;
  --bg1: #dfe3e8;
  --panel: #ffffff;
  --panel-solid: #ffffff;
  --line: #b9c1cb;

  --radius: 10px;
  --shadow: 0 1px 2px rgba(0,0,0,.14);
  --shadow2: 0 2px 4px rgba(0,0,0,.10), 0 12px 32px rgba(20,30,45,.18);

  /* ── The Fujitsu palette, for this theme's chrome only ────────────────────
     Not the accent — that is still the --red-* family above. */

  /* Brand red at three depths, and the highlight it takes under gloss. */
  --fj-red:       #e60012;
  --fj-red-deep:  #b8000e;
  --fj-red-ink:   #7a0009;
  --fj-red-hot:   #ff5a63;

  /* Greys, light to dark. */
  --fj-white:     #ffffff;
  --fj-silver-1:  #f6f7f9;
  --fj-silver-2:  #e9ecf0;
  --fj-silver-3:  #d5dae1;
  --fj-silver-4:  #b9c1cb;
  --fj-steel:     #8f99a5;
  --fj-graphite:  #3b444f;
  --fj-graphite-deep: #232a33;
  --fj-ink:       #1c2128;
  --fj-ink-muted: #5c6470;
  --fj-disabled:  #a3acb6;

  /* Text on the red header and on graphite. */
  --fj-on-dark:     #ffffff;
  --fj-on-dark-dim: rgba(255,255,255,.78);
  --fj-title-glow:  0 1px 0 rgba(255,255,255,.30), 0 2px 6px rgba(0,0,0,.35);
  --fj-label-glow:  0 1px 2px rgba(0,0,0,.45);
  --fj-emboss:      0 1px 0 rgba(255,255,255,.85);

  /* ── Finishes ─────────────────────────────────────────────────────────────
     The gloss: a hard stop at the midline is what makes a surface read as
     glass rather than as a gradient. */
  --fj-gloss: linear-gradient(180deg, rgba(255,255,255,.42) 0, rgba(255,255,255,.14) 48%, rgba(255,255,255,0) 48%, rgba(255,255,255,.08) 100%);
  --fj-gloss-line: rgba(255,255,255,.55);

  /* Brushed steel: fine horizontal streaks over a grey ramp, with a broad
     sheen across the top of the viewport. */
  --fj-canvas:
    radial-gradient(1400px 520px at 50% -8%, rgba(255,255,255,.85) 0, rgba(255,255,255,0) 70%),
    repeating-linear-gradient(180deg, rgba(255,255,255,.55) 0 1px, rgba(255,255,255,0) 1px 2px, rgba(0,0,0,.03) 2px 3px),
    linear-gradient(180deg, #e8ebef 0, #d6dbe1 100%);

  /* Linen: two faint diagonal weaves over a white gloss. The card face. */
  --fj-card:
    repeating-linear-gradient(45deg, rgba(0,0,0,.022) 0 1px, rgba(0,0,0,0) 1px 4px),
    repeating-linear-gradient(-45deg, rgba(0,0,0,.022) 0 1px, rgba(0,0,0,0) 1px 4px),
    linear-gradient(180deg, #ffffff 0, #fbfcfd 46%, #f1f4f7 46%, #f8fafc 100%);
  --fj-card-edge:   #c2c9d2;
  --fj-card-inner:  rgba(255,255,255,.95);

  /* The header: a sober brushed-silver band — gloss, then a fine diagonal
     pinstripe, then a white-to-silver ramp — with a thin red rule along its
     bottom edge as the only colour. */
  --fj-header:
    linear-gradient(180deg, rgba(255,255,255,.55) 0, rgba(255,255,255,.20) 48%, rgba(255,255,255,0) 48%, rgba(255,255,255,.12) 100%),
    repeating-linear-gradient(135deg, rgba(0,0,0,.028) 0 2px, rgba(0,0,0,0) 2px 7px),
    linear-gradient(180deg, #fbfcfd 0, #eaedf1 52%, #d9dee4 100%);
  --fj-header-edge:  #aeb7c2;
  --fj-header-shadow: 0 2px 4px rgba(0,0,0,.10), 0 12px 32px rgba(20,30,45,.16);
  --fj-header-line:      rgba(255,255,255,.85);
  --fj-header-line-soft: rgba(0,0,0,.14);

  /* Chrome: the bevelled silver band under the header and the ring round
     the orb. */
  --fj-chrome: linear-gradient(180deg, #ffffff 0, #d9dee5 45%, #aeb7c2 50%, #cfd5dc 100%);
  --fj-chrome-edge: #7f8996;

  /* Graphite, brushed: the terminal and the totals row. */
  --fj-graphite-panel:
    repeating-linear-gradient(180deg, rgba(255,255,255,.05) 0 1px, rgba(255,255,255,0) 1px 3px),
    linear-gradient(180deg, #454f5b 0, #2e3640 100%);
  --fj-graphite-edge: #1a2027;

  /* Push buttons: silver chrome at rest, glossy red under the pointer,
     pressed dark. Ghost is a flatter silver, danger a deep red at rest. */
  --fj-btn:       linear-gradient(180deg, #ffffff 0, #f1f3f6 48%, #dfe4ea 48%, #eef1f4 100%);
  --fj-btn-edge:  #9aa4b0;
  --fj-btn-hi:    rgba(255,255,255,.95);
  --fj-btn-shadow: 0 1px 2px rgba(0,0,0,.18);
  --fj-btn-hot:   linear-gradient(180deg, #ff6b74 0, #f21f2b 48%, #d20010 48%, #ea0f1c 100%);
  --fj-btn-hot-edge: #9c000c;
  --fj-btn-hot-hi: rgba(255,255,255,.45);
  --fj-btn-hot-glow: 0 0 10px rgba(230,0,18,.45);
  --fj-btn-down:  linear-gradient(180deg, #b3000d 0, #c8000f 100%);
  --fj-btn-down-ring: inset 0 2px 4px rgba(0,0,0,.35);
  --fj-btn-ghost: linear-gradient(180deg, #fbfcfd 0, #eef1f4 48%, #e3e7ec 48%, #eef1f4 100%);
  --fj-btn-ghost-edge: #b9c1cb;
  --fj-btn-graphite: linear-gradient(180deg, #6b7683 0, #4a5563 48%, #353d47 48%, #434c57 100%);
  --fj-btn-graphite-edge: #1f252c;
  --fj-btn-danger: linear-gradient(180deg, #e0303b 0, #c4000f 48%, #a4000c 48%, #b8000e 100%);
  --fj-btn-danger-edge: #6e0008;
  --fj-btn-disabled: var(--fj-silver-2);
  --fj-btn-disabled-edge: var(--fj-silver-3);
  --fj-focus-ring: 0 0 0 3px rgba(230,0,18,.28);
  /* The 1px highlight along the top of cards and menus. */
  --fj-bevel: var(--fj-white);

  /* Fields, selection, lists, separators. */
  --fj-field:       #ffffff;
  --fj-field-edge:  #a9b2bd;
  --fj-field-ring:  inset 0 2px 3px rgba(0,0,0,.10);
  --fj-row-hover:   #f1f4f7;
  --fj-head:        linear-gradient(180deg, #fbfcfd 0, #eef1f4 48%, #e2e6eb 48%, #eaeef2 100%);
  --fj-head-edge:   #b9c1cb;
  --fj-rule:        #e1e6ec;
  --fj-panel:       linear-gradient(180deg, #ffffff 0, #f4f6f8 100%);
  --fj-panel-edge:  #c9d0d8;
  --fj-menu-edge:   #8f99a5;
  --fj-menu-shadow: 0 12px 32px rgba(0,0,0,.28);
  --fj-sel:         linear-gradient(180deg, #ff5a63 0, #e60012 50%, #cc0010 50%, #e0101c 100%);
  --fj-sel-edge:    #9c000c;

  /* The orb: a glossy red sphere. */
  --fj-orb:        radial-gradient(circle at 50% 30%, #ffb3b8 0, #ff2a36 30%, #c9000f 66%, #6e0008 100%);
  --fj-orb-ring:   rgba(255,255,255,.65);
  --fj-orb-glow:   rgba(230,0,18,.55);
  --fj-orb-gloss:  linear-gradient(180deg, rgba(255,255,255,.85) 0, rgba(255,255,255,.18) 46%, rgba(255,255,255,0) 60%);

  /* The glow bar: a thin glossy red rule. */
  --fj-bar: linear-gradient(180deg, #ff6b74 0, #e60012 50%, #c4000f 50%, #e0101c 100%);
  --fj-bar-glow: 0 1px 4px rgba(230,0,18,.45);

  /* The close control on a modal. */
  --fj-close:     linear-gradient(180deg, #ff6b74 0, #f21f2b 48%, #d20010 48%, #ea0f1c 100%);
  --fj-close-hot: linear-gradient(180deg, #ff8f96 0, #ff3540 48%, #e60012 48%, #ff2a36 100%);
  --fj-close-edge: #7e0009;
}

/* ── Fujitsu TMSP 01 (Dark, retired) ─────────────────────────────────────────────────
   Same chrome, same red, on graphite instead of silver. The base :root
   (dark) tokens supply text, overlays and state colours; this block redoes
   what the two blocks above set for white surfaces, and every --fj-* finish.
   Same specificity as the blocks above and later in the file, so it wins. */
:root[data-theme="tmsp01dark"]{
  /* Canvas and cards. */
  --bg0: #1a1e24;
  --bg1: #1a1e24;
  --panel: #242a32;
  --panel-solid: #242a32;
  --line: #3a424c;
  --shadow: 0 1px 2px rgba(0,0,0,.5);
  --shadow2: 0 2px 4px rgba(0,0,0,.4), 0 12px 32px rgba(0,0,0,.55);

  /* The accent as text needs to be lighter on graphite. */
  --red2: #ff5a63;
  --danger: #ff5a63;
  --error-text: #ffb3b8;
  --red-f-solid: #ff5a63;
  --red-deep-solid: #ffb3b8;
  --info-b-solid: #aab4c0;
  --info-c-solid: #aab4c0;
  --info-d-solid: #aab4c0;
  --info-solid: #aab4c0;

  /* Brand red, unchanged. The deep variant is only ever a text colour (tab
     hover, green button) and reads badly on graphite, so here it is a vivid
     red; the ink variant is lightened for text too. */
  --fj-red-deep:  #ff3b47;
  --fj-red-ink:   #ff8f96;

  /* Greys: the ladder flips — text is light, surfaces are dark. */
  --fj-silver-1:  #2b323b;
  --fj-silver-2:  #e9ecf0;
  --fj-silver-3:  #3a424c;
  --fj-silver-4:  #46505b;
  --fj-steel:     #6b7683;
  --fj-graphite:  #cfd6de;
  --fj-graphite-deep: #0f1317;
  --fj-ink:       #e6e9ee;
  --fj-ink-muted: #9aa4b0;
  --fj-disabled:  #5c6470;

  --fj-title-glow:  0 1px 0 rgba(0,0,0,.6), 0 2px 6px rgba(0,0,0,.5);
  --fj-label-glow:  0 1px 2px rgba(0,0,0,.6);
  --fj-emboss:      0 1px 0 rgba(0,0,0,.7);

  /* Finishes: the same hard-stop gloss, dimmed. */
  --fj-gloss: linear-gradient(180deg, rgba(255,255,255,.14) 0, rgba(255,255,255,.05) 48%, rgba(255,255,255,0) 48%, rgba(255,255,255,.03) 100%);
  --fj-gloss-line: rgba(255,255,255,.18);
  --fj-bevel: rgba(255,255,255,.14);

  --fj-canvas:
    radial-gradient(1400px 520px at 50% -8%, rgba(255,255,255,.10) 0, rgba(255,255,255,0) 70%),
    repeating-linear-gradient(180deg, rgba(255,255,255,.04) 0 1px, rgba(255,255,255,0) 1px 2px, rgba(0,0,0,.12) 2px 3px),
    linear-gradient(180deg, #262c34 0, #171b20 100%);

  --fj-card:
    repeating-linear-gradient(45deg, rgba(255,255,255,.02) 0 1px, rgba(255,255,255,0) 1px 4px),
    repeating-linear-gradient(-45deg, rgba(255,255,255,.02) 0 1px, rgba(255,255,255,0) 1px 4px),
    linear-gradient(180deg, #2b323a 0, #282e36 46%, #21262d 46%, #252b32 100%);
  --fj-card-edge:   #0f1317;
  --fj-card-inner:  rgba(255,255,255,.06);

  --fj-header:
    linear-gradient(180deg, rgba(255,255,255,.12) 0, rgba(255,255,255,.05) 48%, rgba(255,255,255,0) 48%, rgba(255,255,255,.03) 100%),
    repeating-linear-gradient(135deg, rgba(255,255,255,.03) 0 2px, rgba(255,255,255,0) 2px 7px),
    linear-gradient(180deg, #353c46 0, #282e36 52%, #1f242b 100%);
  --fj-header-edge:  #0f1317;
  --fj-header-shadow: 0 2px 4px rgba(0,0,0,.4), 0 12px 32px rgba(0,0,0,.5);
  --fj-header-line:      rgba(255,255,255,.14);
  --fj-header-line-soft: rgba(0,0,0,.5);

  --fj-chrome: linear-gradient(180deg, #5a6572 0, #3a434d 45%, #232a33 50%, #333b45 100%);
  --fj-chrome-edge: #0f1317;

  --fj-graphite-panel:
    repeating-linear-gradient(180deg, rgba(255,255,255,.04) 0 1px, rgba(255,255,255,0) 1px 3px),
    linear-gradient(180deg, #1b2027 0, #11151a 100%);
  --fj-graphite-edge: #0a0d10;

  /* Push buttons: dark chrome at rest, the same glossy red under the pointer. */
  --fj-btn:       linear-gradient(180deg, #4d5762 0, #3f4852 48%, #313941 48%, #38404a 100%);
  --fj-btn-edge:  #161a1f;
  --fj-btn-hi:    rgba(255,255,255,.16);
  --fj-btn-shadow: 0 1px 2px rgba(0,0,0,.5);
  --fj-btn-ghost: linear-gradient(180deg, #363e47 0, #2f363e 48%, #272d34 48%, #2d343c 100%);
  --fj-btn-ghost-edge: #161a1f;
  --fj-btn-graphite: linear-gradient(180deg, #5a6572 0, #3f4852 48%, #2b323a 48%, #353d47 100%);
  --fj-btn-graphite-edge: #0f1317;
  --fj-btn-disabled: #2a3038;
  --fj-btn-disabled-edge: #3a424c;

  /* Fields, selection, lists, separators. */
  --fj-field:       #161a1f;
  --fj-field-edge:  #3a424c;
  --fj-field-ring:  inset 0 2px 3px rgba(0,0,0,.45);
  --fj-row-hover:   #2c333b;
  --fj-head:        linear-gradient(180deg, #3a434d 0, #2f3740 48%, #262c34 48%, #2b323a 100%);
  --fj-head-edge:   #161a1f;
  --fj-rule:        #323a43;
  --fj-panel:       linear-gradient(180deg, #2b323a 0, #232930 100%);
  --fj-panel-edge:  #0f1317;
  --fj-menu-edge:   #46505b;
  --fj-menu-shadow: 0 12px 32px rgba(0,0,0,.6);
  --fj-orb-ring:    rgba(255,255,255,.35);
}

/* ═══════════════════════════════════════════════════════════════════════════
   Fujitsu TMSP 01 (retired) — structural section
   Everything here is scoped to :root[data-theme^="tmsp01"]. No rule may
   escape that, or it dirties the other themes.

   Same architecture as Windows Vista: the theme takes the light themes' shared
   TOKENS but not any grouped structural rules, so the base dark chrome still
   applies until a rule below replaces it. This section covers every shared
   class the :root chrome styles, one by one, in the same order as Vista's.

   Reference: Fujitsu's red on white and the glossy hardware finishes of its
   product line — brushed steel, linen-textured panels, chrome bevels, a
   brushed-silver header on a red rule, silver push buttons that turn
   lacquer-red under the pointer. The red is an accent, never a field.
   Nothing moves apart from the liveness dot.
   ═══════════════════════════════════════════════════════════════════════════ */

/* ── Canvas ─────────────────────────────────────────────────────────────────
   Brushed steel, painted directly on body. The base's animated grid layer
   (body::before) becomes a fixed glossy red strip along the top edge; the
   scanline layer and the card sweep go. */
:root[data-theme^="tmsp01"] body{
  background: var(--fj-canvas);
  background-attachment: fixed;
}
:root[data-theme^="tmsp01"] body::before{
  content: "";
  position: fixed;
  inset: 0 0 auto 0;
  height: 7px;
  z-index: 20;
  pointer-events: none;
  opacity: 1;
  transform: none;
  animation: none;
  filter: none;
  background: var(--fj-bar);
  background-size: auto;
  box-shadow: var(--fj-bar-glow);
}
:root[data-theme^="tmsp01"] body::after{ display: none; }
:root[data-theme^="tmsp01"] .tmsp-sweep{ display: none; }

/* Text that sits directly on the steel is embossed. */
:root[data-theme^="tmsp01"] .tmsp-wrap > .tmsp-muted{
  color: var(--fj-ink-muted);
  text-shadow: var(--fj-emboss);
}

/* ── Cards ──────────────────────────────────────────────────────────────────
   Linen-textured white with a gloss across the top half, a silver edge, a
   white inner highlight and a real drop shadow. The HUD corners go. */
:root[data-theme^="tmsp01"] .tmsp-card{
  border: 1px solid var(--fj-card-edge);
  border-radius: 10px;
  background: var(--fj-card);
  box-shadow: inset 0 1px 0 var(--fj-card-inner), var(--shadow2);
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
}
:root[data-theme^="tmsp01"] .tmsp-card::before,
:root[data-theme^="tmsp01"] .tmsp-card::after{ display: none; }
:root[data-theme^="tmsp01"] .tmsp-perm-card{
  box-shadow:
    inset 0 1px 0 var(--fj-card-inner),
    inset 0 0 0 100vmax var(--card-tint-dark),
    var(--shadow2);
}

/* The header card is brushed silver with a pinstripe under the gloss and a
   thin red rule along its bottom edge. Its ink is the same graphite as the
   rest of the page, so nothing is re-scoped; the controls on it are the
   same chrome buttons as everywhere else. */
:root[data-theme^="tmsp01"] .tmsp-card:has(.tmsp-reactor){
  background: var(--fj-header);
  border-color: var(--fj-header-edge);
  border-bottom: 3px solid var(--fj-red);
  box-shadow: inset 0 1px 0 var(--fj-gloss-line), var(--fj-header-shadow);
}

/* The glow bar is a thin lacquered red rule with its own gloss; on the
   header it is an etched line instead, so the band stays quiet. */
:root[data-theme^="tmsp01"] .tmsp-glowbar{
  height: 4px;
  margin: 10px 0 16px;
  opacity: 1;
  border-radius: 2px;
  background: var(--fj-bar);
  box-shadow: var(--fj-bar-glow);
}
:root[data-theme^="tmsp01"] .tmsp-card:has(.tmsp-reactor) .tmsp-glowbar{
  height: 2px;
  background: none;
  box-shadow: none;
  border-top: 1px solid var(--fj-header-line-soft);
  border-bottom: 1px solid var(--fj-header-line);
}

/* ── Title ──────────────────────────────────────────────────────────────────
   Bold and mixed case, embossed graphite everywhere. */
:root[data-theme^="tmsp01"] .tmsp-title{
  font-family: var(--font);
  font-weight: 700;
  font-size: 22px;
  letter-spacing: -.01em;
  text-transform: none;
  text-shadow: var(--fj-emboss);
  color: var(--fj-graphite);
}
:root[data-theme^="tmsp01"] .tmsp-card:has(.tmsp-reactor) .tmsp-muted{
  text-shadow: var(--fj-emboss);
}
@media (max-width: 820px){
  :root[data-theme^="tmsp01"] .tmsp-title{ font-size: 19px; letter-spacing: -.01em; }
}
@media (max-width: 480px){
  :root[data-theme^="tmsp01"] .tmsp-title{ font-size: 17px; }
}
:root[data-theme^="tmsp01"] .tmsp-glitch{ text-shadow: inherit; }
:root[data-theme^="tmsp01"] .tmsp-glitch::before,
:root[data-theme^="tmsp01"] .tmsp-glitch::after{ display: none; }

/* ── The orb ────────────────────────────────────────────────────────────────
   The reactor is already round, so it becomes a glossy red sphere in a
   chrome ring. Ring 1 is the chrome, ring 2 the gloss across the top, ring 3
   is not needed, and the core is the specular highlight. Nothing spins. */
:root[data-theme^="tmsp01"] .tmsp-reactor{
  border-radius: 50%;
  background: var(--fj-orb);
  box-shadow:
    inset 0 0 0 1px var(--fj-orb-ring),
    0 0 12px var(--fj-orb-glow),
    0 3px 6px var(--sh-50);
}
:root[data-theme^="tmsp01"] .tmsp-reactor-ring:nth-child(1){
  inset: -4px;
  border: 3px solid transparent;
  border-radius: 50%;
  background: var(--fj-chrome) border-box;
  -webkit-mask: linear-gradient(var(--black) 0 0) padding-box, linear-gradient(var(--black) 0 0);
  -webkit-mask-composite: xor;
  mask: linear-gradient(var(--black) 0 0) padding-box, linear-gradient(var(--black) 0 0);
  mask-composite: exclude;
  box-shadow: none;
  animation: none;
}
:root[data-theme^="tmsp01"] .tmsp-reactor-ring:nth-child(2){
  inset: 3px;
  border: none;
  border-radius: 50%;
  background: var(--fj-orb-gloss);
  animation: none;
}
:root[data-theme^="tmsp01"] .tmsp-reactor-ring:nth-child(3){ display: none; }
:root[data-theme^="tmsp01"] .tmsp-reactor-core{
  inset: 21px;
  border-radius: 50%;
  border: none;
  background: radial-gradient(circle, var(--fj-white) 0, var(--fj-orb-ring) 45%, transparent 70%);
  box-shadow: none;
  animation: none;
}

/* ── Buttons ────────────────────────────────────────────────────────────────
   Silver chrome push buttons: the two-tone gloss with its hard stop at the
   midline, a grey edge, a white highlight along the top, 6px corners, mixed
   case at semibold. Under the pointer the face turns lacquer red with white
   text and a red glow; pressed is dark red with an inset shadow. Disabled is
   greyed, not faded. Variants: ghost is a flatter silver, "blue" is
   graphite, green is the same silver with a red label (there is no green in
   this palette), danger is deep red at rest. */
:root[data-theme^="tmsp01"] .tmsp-btn{
  background: var(--fj-btn);
  border: 1px solid var(--fj-btn-edge);
  border-radius: 6px;
  box-shadow: inset 0 1px 0 var(--fj-btn-hi), var(--fj-btn-shadow);
  color: var(--fj-ink);
  font-family: var(--font);
  font-weight: 600;
  font-size: 13px;
  letter-spacing: 0;
  text-transform: none;
  text-shadow: var(--fj-emboss);
  transition: background .15s ease, color .15s ease, border-color .15s ease, box-shadow .15s ease;
}
:root[data-theme^="tmsp01"] .tmsp-btn:hover{
  background: var(--fj-btn-hot);
  border-color: var(--fj-btn-hot-edge);
  box-shadow: inset 0 1px 0 var(--fj-btn-hot-hi), var(--fj-btn-hot-glow);
  color: var(--fj-on-dark);
  text-shadow: var(--fj-label-glow);
  transform: none;
}
:root[data-theme^="tmsp01"] .tmsp-btn:active{
  background: var(--fj-btn-down);
  border-color: var(--fj-btn-hot-edge);
  box-shadow: var(--fj-btn-down-ring);
  color: var(--fj-on-dark);
  transform: none;
}
:root[data-theme^="tmsp01"] .tmsp-btn:focus-visible{
  outline: none;
  box-shadow: inset 0 1px 0 var(--fj-btn-hi), var(--fj-focus-ring);
}
:root[data-theme^="tmsp01"] .tmsp-btn:disabled,
:root[data-theme^="tmsp01"] .tmsp-btn:disabled:hover{
  opacity: 1;
  background: var(--fj-btn-disabled);
  border-color: var(--fj-btn-disabled-edge);
  box-shadow: none;
  color: var(--fj-disabled);
  text-shadow: none;
  transform: none;
}
:root[data-theme^="tmsp01"] .tmsp-btn-sm{ font-size: 12px; border-radius: 5px; }
:root[data-theme^="tmsp01"] .tmsp-btn-ghost{
  background: var(--fj-btn-ghost);
  border-color: var(--fj-btn-ghost-edge);
  box-shadow: inset 0 1px 0 var(--fj-btn-hi);
  color: var(--fj-ink-muted);
}
:root[data-theme^="tmsp01"] .tmsp-btn-ghost:hover{
  background: var(--fj-btn);
  border-color: var(--fj-btn-edge);
  box-shadow: inset 0 1px 0 var(--fj-btn-hi), var(--fj-btn-shadow);
  color: var(--fj-ink);
  text-shadow: var(--fj-emboss);
}
:root[data-theme^="tmsp01"] .tmsp-btn-blue{
  background: var(--fj-btn-graphite);
  border-color: var(--fj-btn-graphite-edge);
  box-shadow: inset 0 1px 0 var(--fj-btn-hot-hi), var(--fj-btn-shadow);
  color: var(--fj-on-dark);
  text-shadow: var(--fj-label-glow);
}
:root[data-theme^="tmsp01"] .tmsp-btn-blue:hover{
  background: var(--fj-btn-hot);
  border-color: var(--fj-btn-hot-edge);
}
:root[data-theme^="tmsp01"] .tmsp-btn-green{ color: var(--fj-red-deep); }
:root[data-theme^="tmsp01"] .tmsp-btn-green:hover{ color: var(--fj-on-dark); }
:root[data-theme^="tmsp01"] .tmsp-btn-danger{
  background: var(--fj-btn-danger);
  border-color: var(--fj-btn-danger-edge);
  box-shadow: inset 0 1px 0 var(--fj-btn-hot-hi), var(--fj-btn-shadow);
  color: var(--fj-on-dark);
  text-shadow: var(--fj-label-glow);
}
:root[data-theme^="tmsp01"] .tmsp-btn-danger:hover{
  background: var(--fj-btn-hot);
  border-color: var(--fj-btn-hot-edge);
  box-shadow: inset 0 1px 0 var(--fj-btn-hot-hi), var(--fj-btn-hot-glow);
}
:root[data-theme^="tmsp01"] .tmsp-btn-dark{
  background: var(--fj-graphite-panel);
  border-color: var(--fj-graphite-edge);
  box-shadow: inset 0 1px 0 var(--ov-15), var(--fj-btn-shadow);
  color: var(--fj-on-dark);
  text-shadow: var(--fj-label-glow);
}
:root[data-theme^="tmsp01"] .tmsp-btn-dark:hover{
  background: var(--fj-btn-hot);
  border-color: var(--fj-btn-hot-edge);
  box-shadow: inset 0 1px 0 var(--fj-btn-hot-hi), var(--fj-btn-hot-glow);
  color: var(--fj-on-dark);
}

/* ── Tags ───────────────────────────────────────────────────────────────────
   On the card face they are small chrome pills. The red variant is lacquer;
   the green and yellow ones keep their state tints from the shared light
   block, since there they mean a state and not the brand. */
:root[data-theme^="tmsp01"] .tmsp-tag{
  background: var(--fj-btn);
  border: 1px solid var(--fj-btn-edge);
  border-radius: 999px;
  box-shadow: inset 0 1px 0 var(--fj-btn-hi), var(--fj-btn-shadow);
  color: var(--fj-ink-muted);
  font-weight: 600;
  text-shadow: var(--fj-emboss);
}
:root[data-theme^="tmsp01"] .tmsp-tag-red{
  background: var(--fj-btn-hot);
  border-color: var(--fj-btn-hot-edge);
  box-shadow: inset 0 1px 0 var(--fj-btn-hot-hi), var(--fj-btn-shadow);
  color: var(--fj-on-dark);
  text-shadow: var(--fj-label-glow);
}
:root[data-theme^="tmsp01"] .tmsp-tag-green{  color: var(--ok-solid);      text-shadow: none; }
:root[data-theme^="tmsp01"] .tmsp-tag-yellow{ color: var(--warn-b-solid);  text-shadow: none; }
:root[data-theme^="tmsp01"] .tmsp-tag-blue{   color: var(--fj-graphite);   text-shadow: none; }

/* ── Fields ─────────────────────────────────────────────────────────────────
   White with a recessed inner shadow and a grey edge; on focus the edge goes
   red and the field takes a red ring. */
:root[data-theme^="tmsp01"] .tmsp-input,
:root[data-theme^="tmsp01"] .tmsp-textarea,
:root[data-theme^="tmsp01"] select.tmsp-input,
:root[data-theme^="tmsp01"] .tmsp-inline-select{
  background: var(--fj-field);
  border: 1px solid var(--fj-field-edge);
  border-radius: 6px;
  box-shadow: var(--fj-field-ring);
  color: var(--text);
}
:root[data-theme^="tmsp01"] .tmsp-input:focus,
:root[data-theme^="tmsp01"] .tmsp-textarea:focus,
:root[data-theme^="tmsp01"] select.tmsp-input:focus,
:root[data-theme^="tmsp01"] .tmsp-inline-select:focus{
  border-color: var(--fj-red);
  box-shadow: var(--fj-field-ring), var(--fj-focus-ring);
}
/* The terminal is brushed graphite with light text. */
:root[data-theme^="tmsp01"] .tmsp-terminal{
  background: var(--fj-graphite-panel);
  border: 1px solid var(--fj-graphite-edge);
  border-radius: 8px;
  box-shadow: inset 0 1px 0 var(--ov-15), var(--shadow);
  color: var(--fj-silver-2);
  --muted: var(--fj-on-dark-dim);
  --text:  var(--fj-white);
}

/* ── Messages ───────────────────────────────────────────────────────────────
   Glossy panels with a 4px bar in the state colour along the left edge. */
:root[data-theme^="tmsp01"] .tmsp-error{
  background: var(--fj-panel);
  border: 1px solid var(--danger-30);
  border-left: 4px solid var(--fj-red);
  border-radius: 8px;
  box-shadow: inset 0 1px 0 var(--fj-bevel), var(--shadow);
  color: var(--error-text);
}
:root[data-theme^="tmsp01"] .tmsp-success{
  background: var(--fj-panel);
  border: 1px solid var(--ok-30);
  border-left: 4px solid var(--ok-solid);
  border-radius: 8px;
  box-shadow: inset 0 1px 0 var(--fj-bevel), var(--shadow);
  color: var(--success-text);
}

/* ── Tabs ───────────────────────────────────────────────────────────────────
   Chrome tabs on a hairline; the current one is lacquer red with white
   text and sits on the rule. */
:root[data-theme^="tmsp01"] .tmsp-tabs{ border-bottom: 1px solid var(--fj-head-edge); gap: 4px; }
:root[data-theme^="tmsp01"] .tmsp-tab{
  margin-bottom: -1px;
  background: var(--fj-btn);
  border: 1px solid var(--fj-btn-edge);
  border-bottom: none;
  border-radius: 6px 6px 0 0;
  box-shadow: inset 0 1px 0 var(--fj-btn-hi);
  color: var(--fj-ink);
  font-family: var(--font);
  font-weight: 600;
  font-size: 13px;
  letter-spacing: 0;
  text-transform: none;
  text-shadow: var(--fj-emboss);
  transition: background .15s ease, color .15s ease;
}
:root[data-theme^="tmsp01"] .tmsp-tabs-sub .tmsp-tab{ font-size: 12px; }
:root[data-theme^="tmsp01"] .tmsp-tab:hover{
  background: var(--fj-btn-ghost);
  color: var(--fj-red-deep);
}
:root[data-theme^="tmsp01"] .tmsp-tab.is-current{
  background: var(--fj-btn-hot);
  border-color: var(--fj-btn-hot-edge);
  box-shadow: inset 0 1px 0 var(--fj-btn-hot-hi), var(--fj-btn-hot-glow);
  color: var(--fj-on-dark);
  text-shadow: var(--fj-label-glow);
}

/* ── Tables ─────────────────────────────────────────────────────────────────
   A chrome header on a red rule, hairlines between rows, a silver row hover,
   totals on brushed graphite. */
:root[data-theme^="tmsp01"] .tmsp-table th{
  background: var(--red-08);
  color: var(--fj-graphite);
  border-bottom: 2px solid var(--fj-red);
  text-shadow: var(--fj-emboss);
}
:root[data-theme^="tmsp01"] .tmsp-table td{
  border-bottom: 1px solid var(--fj-rule);
}
:root[data-theme^="tmsp01"] .tmsp-table tr:hover td{
  background: var(--fj-row-hover);
}
:root[data-theme^="tmsp01"] .tmsp-table-totals td,
:root[data-theme^="tmsp01"] .tmsp-table tr.tmsp-table-totals:hover td{
  background: var(--fj-graphite-panel);
  border-top: 2px solid var(--fj-red);
  color: var(--fj-white);
}
:root[data-theme^="tmsp01"] .tmsp-table-totals td:first-child{ color: var(--fj-on-dark-dim); }

/* ── Stat tiles ─────────────────────────────────────────────────────────────
   Glossy silver panels with a red top edge. */
:root[data-theme^="tmsp01"] .tmsp-stat{
  background: var(--fj-panel);
  border: 1px solid var(--fj-panel-edge);
  border-top: 3px solid var(--fj-red);
  border-radius: 8px;
  box-shadow: inset 0 1px 0 var(--fj-bevel), var(--shadow);
}

/* ── Menus ──────────────────────────────────────────────────────────────────
   White glossy panels with a grey edge and a deep shadow, the UI face
   instead of mono. Hover and the current theme are the lacquer-red
   selection bar with white text, drawn with an inset ring so nothing
   shifts. The check mark on the current theme is inherited. */
:root[data-theme^="tmsp01"] .tmsp-dropdown-menu,
:root[data-theme^="tmsp01"] .tmsp-dropdown-submenu-flyout{
  background: var(--fj-panel);
  border: 1px solid var(--fj-menu-edge);
  border-radius: 6px;
  box-shadow: inset 0 1px 0 var(--fj-bevel), var(--fj-menu-shadow);
  padding-top: 4px;
}
:root[data-theme^="tmsp01"] .tmsp-dropdown-menu a,
:root[data-theme^="tmsp01"] .tmsp-dropdown-menu button,
:root[data-theme^="tmsp01"] .tmsp-dropdown-menu .tmsp-dropdown-placeholder,
:root[data-theme^="tmsp01"] .tmsp-dropdown-submenu-label,
:root[data-theme^="tmsp01"] .tmsp-dropdown-submenu-flyout a{
  font-family: var(--font);
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0;
  padding: 8px 20px 8px 16px;
  color: var(--text);
  border-bottom: none;
  transition: none;
}
:root[data-theme^="tmsp01"] .tmsp-dropdown-menu a:hover,
:root[data-theme^="tmsp01"] .tmsp-dropdown-menu button:hover,
:root[data-theme^="tmsp01"] .tmsp-dropdown-menu button.is-current,
:root[data-theme^="tmsp01"] .tmsp-dropdown-submenu:hover .tmsp-dropdown-submenu-label,
:root[data-theme^="tmsp01"] .tmsp-dropdown-submenu:focus-within .tmsp-dropdown-submenu-label,
:root[data-theme^="tmsp01"] .tmsp-dropdown-submenu-flyout a:hover{
  background: var(--fj-sel);
  box-shadow: inset 0 0 0 1px var(--fj-sel-edge), inset 0 1px 0 var(--fj-btn-hot-hi);
  color: var(--fj-on-dark);
  text-shadow: var(--fj-label-glow);
}
:root[data-theme^="tmsp01"] .tmsp-dropdown-menu .tmsp-dropdown-placeholder,
:root[data-theme^="tmsp01"] .tmsp-dropdown-menu .tmsp-dropdown-placeholder:hover{
  background: none;
  box-shadow: none;
  color: var(--fj-disabled);
  text-shadow: none;
}

/* ── Help button, modal, tooltip ────────────────────────────────────────────
   The "?" is a small chrome button. The modal is a glossy white card with a
   brushed-silver title band on a red rule; its close control is a glossy
   red button. */
:root[data-theme^="tmsp01"] .tmsp-help-btn{
  background: var(--fj-btn);
  border: 1px solid var(--fj-btn-edge);
  box-shadow: inset 0 1px 0 var(--fj-btn-hi), var(--fj-btn-shadow);
  color: var(--fj-ink);
  font-family: var(--font);
  transition: background .15s ease, color .15s ease;
}
:root[data-theme^="tmsp01"] .tmsp-help-btn:hover{
  background: var(--fj-btn-hot);
  border-color: var(--fj-btn-hot-edge);
  color: var(--fj-on-dark);
}
:root[data-theme^="tmsp01"] .tmsp-modal-box{
  border: 1px solid var(--fj-card-edge);
  border-radius: 10px;
  background: var(--fj-card);
  box-shadow: inset 0 1px 0 var(--fj-card-inner), var(--fj-menu-shadow);
}
:root[data-theme^="tmsp01"] .tmsp-modal-title{
  margin: -24px -24px 14px;
  padding: 10px 50px 10px 16px;
  min-height: 24px;
  line-height: 24px;
  border-radius: 9px 9px 0 0;
  border-bottom: 3px solid var(--fj-red);
  background: var(--fj-header);
  box-shadow: inset 0 1px 0 var(--fj-gloss-line);
  color: var(--fj-graphite);
  text-shadow: var(--fj-emboss);
  font-family: var(--font);
  font-size: 15px;
  font-weight: 700;
  letter-spacing: 0;
}
:root[data-theme^="tmsp01"] .tmsp-modal-close{
  top: 10px;
  right: 12px;
  width: 30px;
  height: 24px;
  border-radius: 5px;
  border: 1px solid var(--fj-close-edge);
  box-shadow: inset 0 1px 0 var(--fj-btn-hot-hi), var(--fj-btn-shadow);
  background: var(--fj-close);
  color: var(--fj-on-dark);
  font-family: var(--font);
  font-size: 15px;
  font-weight: 700;
  line-height: 1;
  text-shadow: var(--fj-label-glow);
}
:root[data-theme^="tmsp01"] .tmsp-modal-close:hover{
  color: var(--fj-on-dark);
  border-color: var(--fj-close-edge);
  background: var(--fj-close-hot);
}
:root[data-theme^="tmsp01"] .tmsp-tip{
  background: var(--fj-panel);
  border: 1px solid var(--fj-menu-edge);
  border-radius: 6px;
  box-shadow: inset 0 1px 0 var(--fj-bevel), var(--fj-menu-shadow);
  color: var(--fj-ink);
}

/* ── Sign-in ────────────────────────────────────────────────────────────────
   login.php styles its own button as a solid accent block; the chrome button
   above would beat it on specificity, so the lacquer face is restated here.
   Only visible if this theme ever becomes the default. */
:root[data-theme^="tmsp01"] body.tmsp-login .tmsp-btn{
  background: var(--fj-btn-hot);
  border-color: var(--fj-btn-hot-edge);
  box-shadow: inset 0 1px 0 var(--fj-btn-hot-hi), var(--fj-btn-shadow);
  color: var(--fj-on-dark);
  text-shadow: var(--fj-label-glow);
}
:root[data-theme^="tmsp01"] body.tmsp-login .tmsp-btn:hover{
  background: var(--fj-btn-down);
}

/* ── Liveness dot ───────────────────────────────────────────────────────────
   The one thing that still moves: it is a signal, and it stays, as a small
   glossy red lamp that breathes. */
:root[data-theme^="tmsp01"] .tmsp-pulse{
  background: var(--fj-orb);
  box-shadow: 0 0 6px var(--fj-orb-glow);
  animation: tmsp-pulse-tmsp01 2s ease-in-out infinite;
}
@keyframes tmsp-pulse-tmsp01{
  0%,100%{ box-shadow: 0 0 4px var(--fj-orb-glow); }
  50%{ box-shadow: 0 0 12px var(--fj-orb-glow), 0 0 20px var(--rc-a-15); }
}
@media (prefers-reduced-motion: reduce){
  :root[data-theme^="tmsp01"] .tmsp-pulse{ animation: none; }
}

/* ── Phone layer ────────────────────────────────────────────────────────────
   The burger is a chrome button like the rest; its open state is lacquer
   red, restated at id specificity because tmsp-responsive.css sets it so. */
:root[data-theme^="tmsp01"] .tmsp-nav-burger{
  background: var(--fj-btn);
  border: 1px solid var(--fj-btn-edge);
  border-radius: 6px;
  box-shadow: inset 0 1px 0 var(--fj-btn-hi), var(--fj-btn-shadow);
  color: var(--fj-ink);
  text-shadow: var(--fj-emboss);
}
:root[data-theme^="tmsp01"] #tmsp-nav-toggle:checked ~ .tmsp-nav-burger{
  background: var(--fj-btn-hot);
  border-color: var(--fj-btn-hot-edge);
  box-shadow: var(--fj-btn-down-ring);
  color: var(--fj-on-dark);
  text-shadow: var(--fj-label-glow);
}


/* ═══════════════════════════════════════════════════════════════════════════
   Fujitsu View — tokens (Light and Dark)
   A flat theme in the language of Microsoft 365 / Fluent 2: Segoe UI, 4px
   controls on 8px cards, hairline borders, soft layered shadows, no
   textures and no gloss. The one field of colour is the app title bar —
   Microsoft 365 blue on the header card and on the status bar — which is
   what "Colorful" means in Office's own theme picker.
   Two slugs share it: office (Colorful) takes the shared light block above
   (it is in that selector list) and then the two blocks here; officedark
   (Dark) keeps the base dark tokens instead, takes the same two blocks, and
   then the "Dark" block after them, which repaints every --of-* surface on
   Fluent's dark neutrals (the Office Black theme with the blue bar kept, as
   the new Outlook does). The selectors of this theme are written
   [data-theme^="office"] so both slugs get them; only the Dark block names
   officedark.
   Every value is from the Fluent 2 brand ramp (brand-80 #0f6cbd …) and the
   neutral ramp (#242424, #424242, #616161, #d1d1d1, #e0e0e0, #f0f0f0 …).
   ═══════════════════════════════════════════════════════════════════════════ */

/* Accent: Microsoft 365 blue, rgb(15,108,189) — Fluent brand-80. Same token
   names and alpha ladder as the other accents; the "-dark" variants and
   --rc-b/--rc-h use brand-50, rgb(14,71,117). --red2 is brand-70 #115ea3
   (6.3:1 on white) for the accent-as-text states. */
:root[data-theme^="office"]{
  --accent-glow: rgba(15,108,189,.06);
  --red: #0f6cbd;
  --red2: #115ea3;
  --rc-a-15: rgba(15,108,189,.22);
  --rc-a-60: rgba(15,108,189,.6);
  --rc-a-85: rgba(15,108,189,.85);
  --rc-b-35: rgba(14,71,117,.52);
  --rc-b-50: rgba(14,71,117,.5);
  --rc-c-18: rgba(15,108,189,.27);
  --rc-c-95: rgba(15,108,189,.95);
  --rc-cold: #0c3b5e;
  --rc-d-12: rgba(15,108,189,.18);
  --rc-d-70: rgba(15,108,189,.7);
  --rc-e-90: rgba(15,108,189,.9);
  --rc-f-50: rgba(15,108,189,.5);
  --rc-g-100: rgba(15,108,189,1);
  --rc-h-80: rgba(14,71,117,.8);
  --rc-hot: #b4d6fa;
  --rc-mid: #0f6cbd;
  --red-03: rgba(15,108,189,.04);
  --red-04: rgba(15,108,189,.06);
  --red-05: rgba(15,108,189,.08);
  --red-06: rgba(15,108,189,.09);
  --red-07: rgba(15,108,189,.11);
  --red-08: rgba(15,108,189,.12);
  --red-10: rgba(15,108,189,.15);
  --red-12: rgba(15,108,189,.18);
  --red-14: rgba(15,108,189,.21);
  --red-16: rgba(15,108,189,.24);
  --red-18: rgba(15,108,189,.27);
  --red-20: rgba(15,108,189,.3);
  --red-22: rgba(15,108,189,.33);
  --red-28: rgba(15,108,189,.42);
  --red-30: rgba(15,108,189,.45);
  --red-35: rgba(15,108,189,.52);
  --red-40: rgba(15,108,189,.6);
  --red-45: rgba(15,108,189,.68);
  --red-55: rgba(15,108,189,.55);
  --red-60: rgba(15,108,189,.6);
  --red-70: rgba(15,108,189,.7);
  --red-95: rgba(15,108,189,.95);
  --red-b-10: rgba(15,108,189,.15);
  --red-b-25: rgba(15,108,189,.38);
  --red-b-50: rgba(15,108,189,.5);
  --red-d-15: rgba(15,108,189,.22);
  --red-dark-18: rgba(14,71,117,.27);
  --red-dark-60: rgba(14,71,117,.6);
  --red-dark2-35: rgba(14,71,117,.52);
  --red-e-85: rgba(15,108,189,.85);
  --red-15: rgba(15,108,189,.22);
  --red-25: rgba(15,108,189,.38);
  --red-b-85: rgba(15,108,189,.85);
  --red-e-90: rgba(15,108,189,.9);
  --red-e-95: rgba(15,108,189,.95);
  --red-b-70: rgba(15,108,189,.7);
  --red-c-20: rgba(15,108,189,.2);
  --red-c-35: rgba(15,108,189,.35);

  /* The state red is Fluent's danger red, rgb(197,15,31). */
  --danger: #c50f1f;
  --danger-09: rgba(197,15,31,.08);
  --danger-15: rgba(197,15,31,.16);
  --danger-30: rgba(197,15,31,.45);
  --error-text: #b10e1c;
  --red-f-solid: #c50f1f;
  --red-deep-solid: #960b18;

  /* The "blue"/info family is the brand blue: in Office an informational
     tint is the same blue as everything else. These come after the shared
     block and therefore beat it. */
  --blue-btn-10: rgba(15,108,189,.15);
  --blue-btn-12: rgba(15,108,189,.18);
  --blue-btn-20: rgba(15,108,189,.3);
  --blue-btn-22: rgba(15,108,189,.33);
  --blue-btn-38: rgba(15,108,189,.57);
  --blue-btn-40: rgba(15,108,189,.6);
  --blue-btn2-18: rgba(15,108,189,.27);
  --blue-btn2-22: rgba(15,108,189,.33);
  --blue-btn2-40: rgba(15,108,189,.6);
  --blue-btn2-65: rgba(15,108,189,.65);
  --blue-btn3-28: rgba(15,108,189,.42);
  --blue-btn3-35: rgba(15,108,189,.52);
  --blue-btn4-95: rgba(15,108,189,.95);
  --blue-btn5-70: rgba(15,108,189,.7);
  --info-07: rgba(15,108,189,.11);
  --info-25: rgba(15,108,189,.38);
  --info-b-08: rgba(15,108,189,.12);
  --info-b-30: rgba(15,108,189,.45);
  --info-b-solid: #115ea3;
  --info-c-12: rgba(15,108,189,.18);
  --info-c-25: rgba(15,108,189,.38);
  --info-c-solid: #115ea3;
  --info-d-85: rgba(15,108,189,.85);
  --info-d-solid: #115ea3;
  --info-solid: #115ea3;

  /* Fluent's green and orange for the state tints. */
  --ok-solid: #107c10;
  --ok-b-solid: #107c10;
  --ok-c-solid: #107c10;
  --ok-d-solid: #0e700e;
  --success-text: #0e700e;
  --warn-b-solid: #bc4b09;
  --warn-solid: #bc4b09;
  --amber-solid: #bc4b09;
}
:root[data-theme^="office"]{
  --font: 'Segoe UI', 'Segoe UI Web (West European)', 'Open Sans', -apple-system, system-ui, Roboto, 'Helvetica Neue', Arial, sans-serif;
  --mono: 'Cascadia Mono', Consolas, 'JetBrains Mono', 'DejaVu Sans Mono', ui-monospace, monospace;

  /* The canvas is Office's flat app grey; both --bg tokens are it so nothing
     can gradient between them. --panel is the card face, white. */
  --bg0: #f0f0f0;
  --bg1: #f0f0f0;
  --panel: #ffffff;
  --panel-solid: #ffffff;
  --line: #e0e0e0;
  --option-bg: #ffffff;

  /* Fluent shadow2 for cards, shadow8 for raised ones. */
  --radius: 8px;
  --shadow: 0 0 2px rgba(0,0,0,.12), 0 1px 2px rgba(0,0,0,.14);
  --shadow2: 0 0 2px rgba(0,0,0,.12), 0 4px 8px rgba(0,0,0,.14);
  --card-tint-dark: rgba(0,0,0,.06);

  /* ── The Fluent palette, for this theme's chrome only ─────────────────────
     Not the accent — that is still the --red-* family above. */

  /* Brand: the fill (buttons, the title bar), its hover and pressed steps,
     the same blue as text and as a line, and the pale tint behind a selected
     row or item. */
  --of-brand:         #0f6cbd;
  --of-brand-hover:   #115ea3;
  --of-brand-pressed: #0e4775;
  --of-brand-text:    #115ea3;
  --of-brand-line:    #0f6cbd;
  --of-brand-tint:    #ebf3fc;
  --of-brand-tint-edge: #b4d6fa;

  /* The title bar and the status bar: the one field of colour. */
  --of-titlebar:      #0f6cbd;
  --of-titlebar-edge: #0e4775;
  --of-on-brand:      #ffffff;
  --of-on-brand-dim:  rgba(255,255,255,.80);
  --of-on-brand-fill: rgba(255,255,255,.14);
  --of-on-brand-fill-hot: rgba(255,255,255,.24);
  --of-on-brand-edge: rgba(255,255,255,.38);
  --of-on-brand-edge-hot: rgba(255,255,255,.70);

  /* Neutrals: surfaces light to dark, then ink dark to light. */
  --of-bg-1:      #ffffff;
  --of-bg-2:      #fafafa;
  --of-bg-3:      #f5f5f5;
  --of-hover:     #f5f5f5;
  --of-pressed:   #e0e0e0;
  --of-selected:  #ebebeb;
  --of-stroke-1:  #d1d1d1;
  --of-stroke-2:  #e0e0e0;
  --of-stroke-strong: #616161;
  --of-ink:       #242424;
  --of-ink-2:     #424242;
  --of-ink-3:     #616161;
  --of-disabled:  #bdbdbd;
  --of-disabled-bg:   #f0f0f0;
  --of-disabled-edge: #e0e0e0;
  /* The halo behind the one line of text that sits on the wallpaper rather
     than on a card: light here, dark on the dark theme. */
  --of-label-halo: rgba(255,255,255,.85);

  /* Push buttons: Fluent's secondary (white, hairline) and the dark-grey
     one that turns red under the pointer. */
  --of-btn:            #ffffff;
  --of-btn-edge:       #d1d1d1;
  --of-btn-hover:      #f5f5f5;
  --of-btn-hover-edge: #c7c7c7;
  --of-btn-pressed:    #e0e0e0;
  --of-neutral-dark:      #424242;
  --of-neutral-dark-edge: #383838;
  --of-focus-ring: 0 0 0 2px var(--of-bg-1), 0 0 0 4px var(--of-brand-line);

  /* States: the danger fill and its text/tint/edge trio, the same for
     success and warning; Excel's green for the green button's label. */
  --of-danger:         #c50f1f;
  --of-danger-hover:   #b10e1c;
  --of-danger-pressed: #960b18;
  --of-danger-text:    #b10e1c;
  --of-danger-tint:    #fdf3f4;
  --of-danger-edge:    #eeacb2;
  --of-success-text:   #0e700e;
  --of-success-tint:   #f1faf1;
  --of-success-edge:   #9fd89f;
  --of-warn-text:      #bc4b09;
  --of-warn-tint:      #fff9f5;
  --of-warn-edge:      #fdcfb4;
  --of-green-text:     #107c41;
  --of-presence:       #13a10e;

  /* Fields: white, a hairline, and the darker line along the bottom that
     Fluent gives every text field. */
  --of-field:            #ffffff;
  --of-field-edge:       #d1d1d1;
  --of-field-hover-edge: #c7c7c7;
  --of-field-line:       #616161;

  /* Tags (badges), the terminal, menus and dialogs. */
  --of-tag-bg:   #f0f0f0;
  --of-tag-edge: #e0e0e0;
  --of-tag-text: #424242;
  --of-terminal:      #f5f5f5;
  --of-terminal-edge: #e0e0e0;
  --of-terminal-text: #242424;
  --of-menu-shadow:   0 0 2px rgba(0,0,0,.12), 0 8px 16px rgba(0,0,0,.14);
  --of-dialog-shadow: 0 0 8px rgba(0,0,0,.20), 0 32px 64px rgba(0,0,0,.24);
  --of-scrim: rgba(0,0,0,.40);
}

:root[data-theme^="portal01"]{
  --accent-glow: rgba(230,0,18,.05);
  --red: #e60012;
  --red2: #b8000e;
  --rc-a-15: rgba(230,0,18,.22);
  --rc-a-60: rgba(230,0,18,.6);
  --rc-a-85: rgba(230,0,18,.85);
  --rc-b-35: rgba(184,0,14,.52);
  --rc-b-50: rgba(184,0,14,.5);
  --rc-c-18: rgba(230,0,18,.27);
  --rc-c-95: rgba(230,0,18,.95);
  --rc-cold: #4a0006;
  --rc-d-12: rgba(230,0,18,.18);
  --rc-d-70: rgba(230,0,18,.7);
  --rc-e-90: rgba(230,0,18,.9);
  --rc-f-50: rgba(230,0,18,.5);
  --rc-g-100: rgba(230,0,18,1);
  --rc-h-80: rgba(184,0,14,.8);
  --rc-hot: #ffb3b8;
  --rc-mid: #e60012;
  --red-03: rgba(230,0,18,.04);
  --red-04: rgba(230,0,18,.06);
  --red-05: rgba(230,0,18,.08);
  --red-06: rgba(230,0,18,.09);
  --red-07: rgba(230,0,18,.11);
  --red-08: rgba(230,0,18,.12);
  --red-10: rgba(230,0,18,.15);
  --red-12: rgba(230,0,18,.18);
  --red-14: rgba(230,0,18,.21);
  --red-16: rgba(230,0,18,.24);
  --red-18: rgba(230,0,18,.27);
  --red-20: rgba(230,0,18,.3);
  --red-22: rgba(230,0,18,.33);
  --red-28: rgba(230,0,18,.42);
  --red-30: rgba(230,0,18,.45);
  --red-35: rgba(230,0,18,.52);
  --red-40: rgba(230,0,18,.6);
  --red-45: rgba(230,0,18,.68);
  --red-55: rgba(230,0,18,.55);
  --red-60: rgba(230,0,18,.6);
  --red-70: rgba(230,0,18,.7);
  --red-95: rgba(230,0,18,.95);
  --red-b-10: rgba(230,0,18,.15);
  --red-b-25: rgba(230,0,18,.38);
  --red-b-50: rgba(230,0,18,.5);
  --red-d-15: rgba(230,0,18,.22);
  --red-dark-18: rgba(184,0,14,.27);
  --red-dark-60: rgba(184,0,14,.6);
  --red-dark2-35: rgba(184,0,14,.52);
  --red-e-85: rgba(230,0,18,.85);
  --red-15: rgba(230,0,18,.22);
  --red-25: rgba(230,0,18,.38);
  --red-b-85: rgba(230,0,18,.85);
  --red-e-90: rgba(230,0,18,.9);
  --red-e-95: rgba(230,0,18,.95);
  --red-b-70: rgba(230,0,18,.7);
}

:root[data-theme^="portal01"]{
  /* San Francisco is the system face on Apple hardware and is reached through
     -apple-system; Inter is the metric-compatible stand-in everywhere else.
     No display font: the title is the same family a size up, as the system's
     own window titles are. */
  --font: -apple-system, BlinkMacSystemFont, 'SF Pro Text', 'SF Pro Display', Inter, 'Helvetica Neue', Helvetica, Arial, sans-serif;
  --mono: 'SF Mono', ui-monospace, Menlo, Monaco, 'Cascadia Mono', 'DejaVu Sans Mono', monospace;

  /* The desktop is the login wallpaper, painted by body::before. Both --bg
     tokens are the warm off-white the photograph fades to at its edges, so
     nothing can gradient between them and the fallback is never a flash of
     the base's near-black. */
  --bg0: #e8e6e2;
  --bg1: #e8e6e2;

  /* The surfaces. Glass is the whole idea: a pane is mostly the wallpaper
     seen through frost, so --panel is deliberately translucent and the blur
     lives on the rules below. --panel-solid is the opaque counterpart for the
     places a backdrop cannot work — a menu that overflows its stacking
     context, a cell the user may colour. */
  --panel: rgba(255,255,255,.62);
  --panel-solid: #fbfbfd;
  --line: rgba(0,0,0,.08);

  --text: #1d1d1f;
  --muted: #6e6e73;
  --muted-2: #6e6e73;
  --muted-3: #86868b;
  --muted-4: #86868b;
  --label: #3a3a3c;

  /* Continuous-looking corners: 12px on controls, 18px on windows (set per
     rule below). Panes cast one soft, wide shadow — depth comes from the
     blur and the shadow, never from a border. */
  --radius: 12px;
  --shadow:  0 1px 2px rgba(0,0,0,.06);
  --shadow2: 0 18px 50px rgba(0,0,0,.16);

  /* ── Glass finishes ──
     Every frosted surface on this theme comes from these, so a new pane
     inherits the same recipe instead of inventing its own blur. */
  --pt-glass:        rgba(255,255,255,.62);
  --pt-glass-thick:  rgba(255,255,255,.78);
  --pt-glass-thin:   rgba(255,255,255,.44);
  --pt-blur:         saturate(180%) blur(30px);
  --pt-blur-light:   saturate(180%) blur(18px);
  --pt-hairline:     rgba(0,0,0,.08);
  --pt-highlight:    rgba(255,255,255,.7);
  --pt-shadow:       0 18px 50px rgba(0,0,0,.16);
  --pt-shadow-soft:  0 6px 18px rgba(0,0,0,.10);
  --pt-fill:         rgba(120,120,128,.12);
  --pt-fill-strong:  rgba(120,120,128,.20);
  --pt-sep:          rgba(60,60,67,.14);
  --pt-on-accent:    #ffffff;
  --pt-accent-hover: #ff1a2e;
  --pt-accent-press: #b8000e;
  --pt-red:          #e60012;
  --pt-red-press:    #b8000e;
  --pt-green:        #34c759;
  --pt-amber:        #ff9f0a;
  /* The veil over the wallpaper, and the halo behind text that sits on it.
     Transparent here — the photograph is already light. */
  --pt-wall-scrim:   rgba(0,0,0,0);
  /* Its own value, not --pt-highlight: dark ink on a wallpaper with dark
     greens in it needs a solid white behind each letter, not a sheen. */
  --pt-label-halo:   rgba(255,255,255,.95);
}

/* ═══════════════════════════════════════════════════════════════════════════
   FUJITSU LOUNGE (LIGHT) — structural
   The block above sets TOKENS but not any grouped structural rules, so the
   base dark chrome still applies until a rule below replaces it. This section
   covers every shared class the :root chrome styles, one by one, in the same
   order as Vista's and Fujitsu's.

   Reference: the glass of a current macOS desktop. A window is a pane of
   frost over the wallpaper — the blur and a hairline do the work a border and
   a gradient used to do. The accent is Fujitsu red, not the system's blue:
   this is a Fujitsu portal wearing that glass. Green and amber appear only
   where a state demands them. Nothing moves apart from the liveness dot.
   ═══════════════════════════════════════════════════════════════════════════ */

/* ── Desktop ────────────────────────────────────────────────────────────────
   The theme's own wallpaper, served from this site (/assets/lounge-bg.jpg —
   the CSP is default-src 'self'; bump ?v= when the file changes) on a fixed,
   viewport-sized layer at z-index:-1, with --bg0 underneath as the canvas and
   the fallback. It is not the login page's: that one has its own, painted on
   body itself in login.php's scoped <style>, and the two are free to differ. It has to sit on body::before rather than on body's own
   background so that the panes' backdrop-filter has something to blur: a
   backdrop is what is PAINTED behind the element, and a fixed pseudo-element
   qualifies. The scanline layer and the card sweep go. */
:root[data-theme^="portal01"] body{
  background: var(--bg0);
}
:root[data-theme^="portal01"] body::before{
  content: "";
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  opacity: 1;
  transform: none;
  animation: none;
  filter: none;
  background:
    linear-gradient(var(--pt-wall-scrim), var(--pt-wall-scrim)),
    url('/assets/lounge-bg.jpg?v=1') center center / cover no-repeat,
    var(--bg0);
}
:root[data-theme^="portal01"] body::after{ display: none; }
:root[data-theme^="portal01"] .tmsp-sweep{ display: none; }

/* Text that sits directly on the wallpaper, not on a pane: the photograph is
   bright, so it takes the ink colour and a white halo rather than --muted. */
:root[data-theme^="portal01"] .tmsp-wrap > .tmsp-muted{
  color: var(--text);
  /* Two layers: a tight drop and a wider glow. One was not enough once the
     wallpaper had dark greens and bright sky in the same line of text. */
  text-shadow: 0 1px 2px var(--pt-label-halo), 0 0 7px var(--pt-label-halo);
}

/* ── Windows ────────────────────────────────────────────────────────────────
   A card is a pane of glass: frost, a hairline, an inner top highlight and
   one soft shadow. The HUD corners have no equivalent here and go. */
:root[data-theme^="portal01"] .tmsp-card{
  background: var(--pt-glass);
  -webkit-backdrop-filter: var(--pt-blur);
  backdrop-filter: var(--pt-blur);
  border: 1px solid var(--pt-hairline);
  border-radius: 18px;
  box-shadow: var(--pt-shadow), inset 0 1px 0 var(--pt-highlight);
}
:root[data-theme^="portal01"] .tmsp-card::before,
:root[data-theme^="portal01"] .tmsp-card::after{ display: none; }
:root[data-theme^="portal01"] .tmsp-perm-card{
  background: var(--pt-glass-thin);
  -webkit-backdrop-filter: var(--pt-blur-light);
  backdrop-filter: var(--pt-blur-light);
  border: 1px solid var(--pt-hairline);
  border-radius: 14px;
  box-shadow: var(--pt-shadow-soft);
}

/* ── Toolbar ────────────────────────────────────────────────────────────────
   The header card's .tmsp-pagehead is the window's toolbar: pulled out to the
   pane's edge, a touch more opaque than the body below it, separated by a
   hairline instead of a rule. The -24px has to match .tmsp-card's padding, and
   the bottom margin repeats it so the nav sits centred in the band below rather
   than hard against the toolbar — the card's own bottom padding is all that
   holds it up from below. The FHD layer restates both for the 28px/32px tier. */
:root[data-theme^="portal01"] .tmsp-card:has(.tmsp-reactor) .tmsp-pagehead{
  margin: -24px -24px 24px;
  padding: 14px 24px;
  background: var(--pt-glass-thick);
  border-bottom: 1px solid var(--pt-sep);
  border-radius: 17px 17px 0 0;
}
:root[data-theme^="portal01"] .tmsp-card:has(.tmsp-reactor) .tmsp-glowbar{
  display: none;
}
:root[data-theme^="portal01"] .tmsp-glowbar{
  height: 1px;
  background: var(--pt-sep);
  opacity: 1;
  box-shadow: none;
}

/* ── Title ──────────────────────────────────────────────────────────────────
   A window title: the body face a size up, tight, no glow and no glitch. */
:root[data-theme^="portal01"] .tmsp-title{
  font-family: var(--font);
  font-weight: 600;
  letter-spacing: -.02em;
  color: var(--text);
  text-shadow: none;
}
:root[data-theme^="portal01"] .tmsp-glitch{ text-shadow: none; }
:root[data-theme^="portal01"] .tmsp-glitch::before,
:root[data-theme^="portal01"] .tmsp-glitch::after{ display: none; }

/* The reactor keeps only its core as the liveness dot — the rings are the
   one piece of the base chrome with no place on a desktop. */
:root[data-theme^="portal01"] .tmsp-reactor{
  background: none;
  box-shadow: none;
  filter: none;
}
:root[data-theme^="portal01"] .tmsp-reactor-ring:nth-child(1),
:root[data-theme^="portal01"] .tmsp-reactor-ring:nth-child(2),
:root[data-theme^="portal01"] .tmsp-reactor-ring:nth-child(3){ display: none; }
:root[data-theme^="portal01"] .tmsp-reactor-core{
  background: var(--red);
  box-shadow: 0 0 0 3px var(--red-10);
  animation: none;
}

/* ── Buttons ────────────────────────────────────────────────────────────────
   The system's two weights: a filled accent button for the action a view is
   about, and a plain glass button for everything else. Flat fills, no gloss,
   no glow; the press is a darker fill, not a transform. Destructive shares the
   accent's red, as it does on the Fujitsu themes — one red per theme. */
:root[data-theme^="portal01"] .tmsp-btn{
  font-family: var(--font);
  font-weight: 500;
  font-size: .82rem;
  letter-spacing: 0;
  text-transform: none;
  padding: 7px 14px;
  border-radius: 999px;
  color: var(--text);
  background: var(--pt-fill);
  border: 1px solid transparent;
  box-shadow: none;
  text-shadow: none;
}
:root[data-theme^="portal01"] .tmsp-btn:hover{
  background: var(--pt-fill-strong);
  color: var(--text);
  box-shadow: none;
}
:root[data-theme^="portal01"] .tmsp-btn:active{
  background: var(--pt-fill-strong);
  transform: none;
}
:root[data-theme^="portal01"] .tmsp-btn:focus-visible{
  outline: none;
  box-shadow: 0 0 0 3px var(--red-30);
}
:root[data-theme^="portal01"] .tmsp-btn:disabled,
:root[data-theme^="portal01"] .tmsp-btn:disabled:hover{
  background: var(--pt-fill);
  color: var(--muted-3);
  box-shadow: none;
}
:root[data-theme^="portal01"] .tmsp-btn-sm{ padding: 4px 10px; font-size: .76rem; }

:root[data-theme^="portal01"] .tmsp-btn-ghost{
  background: transparent;
  border-color: var(--pt-hairline);
  color: var(--text);
}
:root[data-theme^="portal01"] .tmsp-btn-ghost:hover{ background: var(--pt-fill); }

:root[data-theme^="portal01"] .tmsp-btn-dark,
:root[data-theme^="portal01"] .tmsp-btn-blue{
  background: var(--red);
  border-color: transparent;
  color: var(--pt-on-accent);
}
:root[data-theme^="portal01"] .tmsp-btn-dark:hover,
:root[data-theme^="portal01"] .tmsp-btn-blue:hover{
  background: var(--pt-accent-hover);
  color: var(--pt-on-accent);
}
:root[data-theme^="portal01"] .tmsp-btn-danger{
  background: var(--pt-red);
  border-color: transparent;
  color: var(--pt-on-accent);
}
:root[data-theme^="portal01"] .tmsp-btn-danger:hover{ background: var(--pt-red-press); color: var(--pt-on-accent); }
:root[data-theme^="portal01"] .tmsp-btn-green{
  background: var(--pt-green);
  border-color: transparent;
  color: var(--pt-on-accent);
}
:root[data-theme^="portal01"] .tmsp-btn-green:hover{ background: var(--pt-green); color: var(--pt-on-accent); }

/* The toolbar's own buttons sit on thicker glass, so they take the thin fill
   to stay legible against it. */
:root[data-theme^="portal01"] .tmsp-card:has(.tmsp-reactor) .tmsp-btn{
  background: var(--pt-fill);
  color: var(--text);
}
:root[data-theme^="portal01"] .tmsp-card:has(.tmsp-reactor) .tmsp-btn:hover{ background: var(--pt-fill-strong); }
:root[data-theme^="portal01"] .tmsp-card:has(.tmsp-reactor) .tmsp-btn-danger{ background: var(--pt-red); color: var(--pt-on-accent); }
:root[data-theme^="portal01"] .tmsp-card:has(.tmsp-reactor) .tmsp-btn-danger:hover{ background: var(--pt-red-press); }

/* ── Fields ─────────────────────────────────────────────────────────────────
   A field is a recessed white well with a hairline; focus is the accent ring
   the system draws, never a glow. */
:root[data-theme^="portal01"] .tmsp-input,
:root[data-theme^="portal01"] .tmsp-textarea,
:root[data-theme^="portal01"] select.tmsp-input,
:root[data-theme^="portal01"] .tmsp-inline-select{
  background: var(--panel-solid);
  border: 1px solid var(--pt-hairline);
  border-radius: 10px;
  color: var(--text);
  box-shadow: none;
}
:root[data-theme^="portal01"] .tmsp-input:focus,
:root[data-theme^="portal01"] .tmsp-textarea:focus,
:root[data-theme^="portal01"] select.tmsp-input:focus,
:root[data-theme^="portal01"] .tmsp-inline-select:focus{
  border-color: var(--red);
  box-shadow: 0 0 0 3px var(--red-25);
  outline: none;
}

/* ── Menus ──────────────────────────────────────────────────────────────────
   A menu is the same frost as a window, one step thicker, with rounded items
   that take the accent as a highlight the way the system's do. */
:root[data-theme^="portal01"] .tmsp-dropdown-menu,
:root[data-theme^="portal01"] .tmsp-dropdown-submenu-flyout,
:root[data-theme^="portal01"] .tmsp-card:has(.tmsp-reactor) .tmsp-dropdown-menu,
:root[data-theme^="portal01"] .tmsp-card:has(.tmsp-reactor) .tmsp-dropdown-submenu-flyout{
  background: var(--pt-glass-thick);
  -webkit-backdrop-filter: var(--pt-blur);
  backdrop-filter: var(--pt-blur);
  border: 1px solid var(--pt-hairline);
  border-radius: 12px;
  box-shadow: var(--pt-shadow);
  padding: 5px;
}
:root[data-theme^="portal01"] .tmsp-dropdown-menu a,
:root[data-theme^="portal01"] .tmsp-dropdown-menu button,
:root[data-theme^="portal01"] .tmsp-dropdown-menu .tmsp-dropdown-placeholder,
:root[data-theme^="portal01"] .tmsp-dropdown-submenu-flyout a,
:root[data-theme^="portal01"] .tmsp-dropdown-submenu-label{
  font-family: var(--font);
  font-size: .82rem;
  letter-spacing: 0;
  text-transform: none;
  color: var(--text);
  border-bottom: none;
  border-radius: 8px;
  padding: 7px 10px;
}
:root[data-theme^="portal01"] .tmsp-dropdown-menu a:hover,
:root[data-theme^="portal01"] .tmsp-dropdown-menu button:hover,
:root[data-theme^="portal01"] .tmsp-dropdown-submenu-flyout a:hover,
:root[data-theme^="portal01"] .tmsp-dropdown-submenu:hover .tmsp-dropdown-submenu-label,
:root[data-theme^="portal01"] .tmsp-dropdown-submenu:focus-within .tmsp-dropdown-submenu-label{
  background: var(--red);
  color: var(--pt-on-accent);
}
:root[data-theme^="portal01"] .tmsp-dropdown-menu button.is-current{
  background: var(--pt-fill);
  color: var(--text);
}
:root[data-theme^="portal01"] .tmsp-dropdown-menu .tmsp-dropdown-placeholder:hover{
  background: none;
  color: var(--muted);
}

/* ── Tabs ───────────────────────────────────────────────────────────────────
   A segmented control: a recessed track with the selected segment lifted out
   of it on white, the way the system draws a tab bar. */
:root[data-theme^="portal01"] .tmsp-tabs{
  gap: 2px;
  padding: 3px;
  border-bottom: none;
  border-radius: 10px;
  background: var(--pt-fill);
}
:root[data-theme^="portal01"] .tmsp-tab{
  font-family: var(--font);
  font-size: .82rem;
  letter-spacing: 0;
  text-transform: none;
  color: var(--muted);
  border: none;
  border-radius: 8px;
  padding: 6px 14px;
  background: none;
}
:root[data-theme^="portal01"] .tmsp-tab:hover{ color: var(--text); background: none; }
:root[data-theme^="portal01"] .tmsp-tab.is-current{
  color: var(--text);
  background: var(--panel-solid);
  box-shadow: var(--pt-shadow-soft);
}
:root[data-theme^="portal01"] .tmsp-tabs-sub .tmsp-tab{ font-size: .78rem; padding: 5px 11px; }

/* ── Tags ───────────────────────────────────────────────────────────────────
   Flat, rounded status chips — the system's badges, not the base's glowing
   capsules. */
:root[data-theme^="portal01"] .tmsp-tag{
  font-family: var(--font);
  font-size: .7rem;
  font-weight: 500;
  letter-spacing: 0;
  text-transform: none;
  border-radius: 999px;
  padding: 4px 10px;
  color: var(--text);
  background: var(--pt-fill);
  border: 1px solid transparent;
  box-shadow: none;
  text-shadow: none;
}
:root[data-theme^="portal01"] .tmsp-tag-red{    background: var(--pt-red);   color: var(--pt-on-accent); }
:root[data-theme^="portal01"] .tmsp-tag-green{  background: var(--pt-green); color: var(--pt-on-accent); }
:root[data-theme^="portal01"] .tmsp-tag-yellow{ background: var(--pt-amber); color: var(--pt-on-accent); }
:root[data-theme^="portal01"] .tmsp-tag-blue{   background: var(--red);      color: var(--pt-on-accent); }
:root[data-theme^="portal01"] .tmsp-card:has(.tmsp-reactor) .tmsp-tag{
  background: var(--pt-fill);
  color: var(--text);
}
:root[data-theme^="portal01"] .tmsp-card:has(.tmsp-reactor) .tmsp-tag-red{ background: var(--pt-red); color: var(--pt-on-accent); }

/* ── Lists ──────────────────────────────────────────────────────────────────
   A table is a system list: hairline separators, a quiet header, a tinted row
   under the pointer. No rules, no zebra. */
:root[data-theme^="portal01"] .tmsp-table th{
  font-family: var(--font);
  font-size: .72rem;
  font-weight: 600;
  letter-spacing: 0;
  text-transform: none;
  color: var(--muted);
  background: var(--red-08);
  border-bottom: 1px solid var(--pt-sep);
}
:root[data-theme^="portal01"] .tmsp-table td{
  border-bottom: 1px solid var(--pt-sep);
  color: var(--text);
}
:root[data-theme^="portal01"] .tmsp-table tr:hover td{ background: var(--pt-fill); }
:root[data-theme^="portal01"] .tmsp-table-totals td,
:root[data-theme^="portal01"] .tmsp-table tr.tmsp-table-totals:hover td{
  background: var(--pt-fill);
  color: var(--text);
}

/* ── Sheets ─────────────────────────────────────────────────────────────────
   A modal is a sheet: the same frost, a larger radius, a deeper shadow. */
:root[data-theme^="portal01"] .tmsp-modal-box{
  background: var(--pt-glass-thick);
  -webkit-backdrop-filter: var(--pt-blur);
  backdrop-filter: var(--pt-blur);
  border: 1px solid var(--pt-hairline);
  border-radius: 18px;
  box-shadow: var(--pt-shadow);
}
:root[data-theme^="portal01"] .tmsp-modal-title{
  font-family: var(--font);
  font-weight: 600;
  letter-spacing: -.01em;
  text-transform: none;
  color: var(--text);
}
:root[data-theme^="portal01"] .tmsp-modal-close{ color: var(--muted); }
:root[data-theme^="portal01"] .tmsp-modal-close:hover{ color: var(--text); background: var(--pt-fill); }

/* ── Notices, panels, stats ────────────────────────────────────────────────
   A flash sits on the wallpaper, not inside a pane, so a tint alone would be
   unreadable over a photograph: it gets the same frost as a window, with the
   state's hue on the leading edge. */
:root[data-theme^="portal01"] .tmsp-success,
:root[data-theme^="portal01"] .tmsp-error,
:root[data-theme^="portal01"] .tmsp-tip{
  background: var(--pt-glass-thick);
  -webkit-backdrop-filter: var(--pt-blur);
  backdrop-filter: var(--pt-blur);
  border: 1px solid var(--pt-hairline);
  border-radius: 12px;
  box-shadow: var(--pt-shadow-soft);
  color: var(--text);
}
:root[data-theme^="portal01"] .tmsp-success{ border-left: 3px solid var(--pt-green); }
:root[data-theme^="portal01"] .tmsp-error{   border-left: 3px solid var(--pt-red); }
:root[data-theme^="portal01"] .tmsp-tip{     border-left: 3px solid var(--red); color: var(--muted); }
:root[data-theme^="portal01"] .tmsp-terminal{
  background: var(--pt-fill);
  border: 1px solid var(--pt-hairline);
  border-radius: 12px;
  color: var(--text);
  box-shadow: none;
}
:root[data-theme^="portal01"] .tmsp-stat{
  background: var(--pt-glass-thin);
  -webkit-backdrop-filter: var(--pt-blur-light);
  backdrop-filter: var(--pt-blur-light);
  border: 1px solid var(--pt-hairline);
  border-radius: 14px;
  box-shadow: none;
}
:root[data-theme^="portal01"] .tmsp-help-btn{
  background: var(--pt-fill);
  border-color: transparent;
  color: var(--muted);
}
:root[data-theme^="portal01"] .tmsp-help-btn:hover{ background: var(--pt-fill-strong); color: var(--text); }

/* ── Burger ─────────────────────────────────────────────────────────────────
   The phone menu's toggle, matching the toolbar's buttons. */
:root[data-theme^="portal01"] .tmsp-card:has(.tmsp-reactor) .tmsp-nav-burger{
  background: var(--pt-fill);
  border-color: transparent;
  color: var(--text);
}
:root[data-theme^="portal01"] .tmsp-card:has(.tmsp-reactor) .tmsp-nav-burger:hover{ background: var(--pt-fill-strong); }
:root[data-theme^="portal01"] #tmsp-nav-toggle:checked ~ .tmsp-nav-burger{
  background: var(--red);
  color: var(--pt-on-accent);
}

/* ── Fujitsu Lounge (Dark) ───────────────────────────────────────────────────
   The same glass, the same system blue, on a night desktop instead of a lit
   one. The base :root (dark) tokens supply the overlays and state colours;
   this block redoes what the two blocks above set for light surfaces, and
   every --pt-* finish. Token-only: the structural section above is written
   :root[data-theme^="portal01"] and serves both slugs, so a rule added there
   needs no counterpart here — but a new --pt-* token needs a dark value.
   Same specificity as the blocks above and later in the file, so it wins. */
:root[data-theme="portal01dark"]{
  /* Canvas and panes. The wallpaper is the same photograph, unveiled — the
     dark theme is dark chrome over the lit room, not a darkened room. */
  --bg0: #1c1c1e;
  --bg1: #1c1c1e;
  --panel: rgba(44,44,46,.62);
  --panel-solid: #2c2c2e;
  --line: rgba(255,255,255,.12);
  --shadow:  0 1px 2px rgba(0,0,0,.5);
  --shadow2: 0 18px 50px rgba(0,0,0,.55);

  /* Ink: the ladder flips — text is light, surfaces are dark. */
  --text: #f5f5f7;
  --muted: #aeaeb2;
  --muted-2: #aeaeb2;
  --muted-3: #8e8e93;
  --muted-4: #8e8e93;
  --label: #d1d1d6;

  /* The accent as TEXT needs to be lighter on graphite; as a FILL the brand
     red is unchanged, which is why --red stays as it is above. */
  --red2: #ff6b72;
  --danger: #ff6b72;
  --error-text: #ffb3ae;

  /* ── Glass finishes, repainted ──
     Dark glass is a dark pane with a faint white hairline on top, not a
     white pane turned down: the highlight is what makes it read as glass. */
  --pt-glass:        rgba(44,44,46,.62);
  --pt-glass-thick:  rgba(44,44,46,.82);
  --pt-glass-thin:   rgba(44,44,46,.44);
  --pt-hairline:     rgba(255,255,255,.12);
  --pt-highlight:    rgba(255,255,255,.10);
  --pt-shadow:       0 18px 50px rgba(0,0,0,.55);
  --pt-shadow-soft:  0 6px 18px rgba(0,0,0,.40);
  --pt-fill:         rgba(120,120,128,.24);
  --pt-fill-strong:  rgba(120,120,128,.36);
  --pt-sep:          rgba(255,255,255,.12);
  --pt-on-accent:    #ffffff;
  --pt-accent-hover: #ff3b47;
  --pt-accent-press: #e60012;
  --pt-red:          #ff3b47;
  --pt-red-press:    #ff6b72;
  --pt-green:        #30d158;
  --pt-amber:        #ffd60a;

  /* No veil: the wallpaper is the same photograph, shown as it is in the
     light theme. A dark halo keeps the light text that sits on it legible
     over the bright parts of the picture. */
  --pt-wall-scrim:   rgba(0,0,0,0);
  --pt-label-halo:   rgba(0,0,0,.55);
}

/* ── Fujitsu View (Dark) ───────────────────────────────────────────────
   The same chrome on Fluent's dark neutrals, the blue bar kept (as the new
   Outlook's dark mode keeps it). The base :root (dark) tokens supply the
   overlays and shadows; this block redoes what the two blocks above set for
   white surfaces, every --of-* value, and the accent ladder, which moves up
   to brand-100 so the blue still reads on dark grey. Same specificity as the
   blocks above and later in the file, so it wins. */
:root[data-theme="officedark"]{
  /* Canvas, cards, ink. */
  --bg0: #1f1f1f;
  --bg1: #1f1f1f;
  --panel: #292929;
  --panel-solid: #292929;
  --line: #3d3d3d;
  --option-bg: #292929;
  --text: #ffffff;
  --text-b: #ffffff;
  --text-c: #d6d6d6;
  --text-d: #d6d6d6;
  --muted: #adadad;
  --muted-2: #adadad;
  --muted-3: #999999;
  --muted-4: #adadad;
  --label: #d6d6d6;
  --tag-text: #d6d6d6;
  --term-text: #d6d6d6;
  --shadow: 0 0 2px rgba(0,0,0,.24), 0 1px 2px rgba(0,0,0,.28);
  --shadow2: 0 0 2px rgba(0,0,0,.24), 0 4px 8px rgba(0,0,0,.28);
  --card-tint-dark: rgba(0,0,0,.28);

  /* Accent: brand-100, rgb(71,158,245); the "-dark" variants use brand-60,
     rgb(15,84,140). --red2 is brand-110 #62abf5 (6.6:1 on the card). */
  --accent-glow: rgba(71,158,245,.08);
  --red: #479ef5;
  --red2: #62abf5;
  --rc-a-15: rgba(71,158,245,.22);
  --rc-a-60: rgba(71,158,245,.6);
  --rc-a-85: rgba(71,158,245,.85);
  --rc-b-35: rgba(15,84,140,.52);
  --rc-b-50: rgba(15,84,140,.5);
  --rc-c-18: rgba(71,158,245,.27);
  --rc-c-95: rgba(71,158,245,.95);
  --rc-cold: #0f548c;
  --rc-d-12: rgba(71,158,245,.18);
  --rc-d-70: rgba(71,158,245,.7);
  --rc-e-90: rgba(71,158,245,.9);
  --rc-f-50: rgba(71,158,245,.5);
  --rc-g-100: rgba(71,158,245,1);
  --rc-h-80: rgba(15,84,140,.8);
  --rc-hot: #cfe4fa;
  --rc-mid: #479ef5;
  --red-03: rgba(71,158,245,.04);
  --red-04: rgba(71,158,245,.06);
  --red-05: rgba(71,158,245,.08);
  --red-06: rgba(71,158,245,.09);
  --red-07: rgba(71,158,245,.11);
  --red-08: rgba(71,158,245,.12);
  --red-10: rgba(71,158,245,.15);
  --red-12: rgba(71,158,245,.18);
  --red-14: rgba(71,158,245,.21);
  --red-16: rgba(71,158,245,.24);
  --red-18: rgba(71,158,245,.27);
  --red-20: rgba(71,158,245,.3);
  --red-22: rgba(71,158,245,.33);
  --red-28: rgba(71,158,245,.42);
  --red-30: rgba(71,158,245,.45);
  --red-35: rgba(71,158,245,.52);
  --red-40: rgba(71,158,245,.6);
  --red-45: rgba(71,158,245,.68);
  --red-55: rgba(71,158,245,.55);
  --red-60: rgba(71,158,245,.6);
  --red-70: rgba(71,158,245,.7);
  --red-95: rgba(71,158,245,.95);
  --red-b-10: rgba(71,158,245,.15);
  --red-b-25: rgba(71,158,245,.38);
  --red-b-50: rgba(71,158,245,.5);
  --red-d-15: rgba(71,158,245,.22);
  --red-dark-18: rgba(15,84,140,.27);
  --red-dark-60: rgba(15,84,140,.6);
  --red-dark2-35: rgba(15,84,140,.52);
  --red-e-85: rgba(71,158,245,.85);
  --red-15: rgba(71,158,245,.22);
  --red-25: rgba(71,158,245,.38);
  --red-b-85: rgba(71,158,245,.85);
  --red-e-90: rgba(71,158,245,.9);
  --red-e-95: rgba(71,158,245,.95);
  --red-b-70: rgba(71,158,245,.7);
  --red-c-20: rgba(71,158,245,.2);
  --red-c-35: rgba(71,158,245,.35);

  /* States as text on dark grey: Fluent's dark-theme foregrounds. */
  --danger: #e37d80;
  --danger-09: rgba(227,125,128,.10);
  --danger-15: rgba(227,125,128,.18);
  --danger-30: rgba(227,125,128,.45);
  --error-text: #e37d80;
  --red-f-solid: #e37d80;
  --red-deep-solid: #f1bbbc;
  --info-07: rgba(71,158,245,.11);
  --info-25: rgba(71,158,245,.38);
  --info-b-08: rgba(71,158,245,.12);
  --info-b-30: rgba(71,158,245,.45);
  --info-b-solid: #62abf5;
  --info-c-12: rgba(71,158,245,.18);
  --info-c-25: rgba(71,158,245,.38);
  --info-c-solid: #62abf5;
  --info-d-85: rgba(71,158,245,.85);
  --info-d-solid: #62abf5;
  --info-solid: #62abf5;
  --ok-solid: #54b054;
  --ok-b-solid: #54b054;
  --ok-c-solid: #54b054;
  --ok-d-solid: #9fd89f;
  --success-text: #54b054;
  --warn-b-solid: #faa06b;
  --warn-solid: #faa06b;
  --amber-solid: #faa06b;

  /* Brand: the fill drops to brand-70 so white text stays readable; text
     and lines rise to brand-110/100. */
  --of-brand:         #115ea3;
  --of-brand-hover:   #0f6cbd;
  --of-brand-pressed: #0e4775;
  --of-brand-text:    #62abf5;
  --of-brand-line:    #479ef5;
  --of-brand-tint:    #082338;
  --of-brand-tint-edge: #0e4775;

  --of-titlebar:      #0f548c;
  --of-titlebar-edge: #0a2e4a;
  --of-on-brand-fill: rgba(255,255,255,.10);
  --of-on-brand-fill-hot: rgba(255,255,255,.18);
  --of-on-brand-edge: rgba(255,255,255,.28);
  --of-on-brand-edge-hot: rgba(255,255,255,.60);

  /* Neutrals: the ladder flips — surfaces dark, ink light. */
  --of-bg-1:      #292929;
  --of-bg-2:      #1f1f1f;
  --of-bg-3:      #242424;
  --of-hover:     #3d3d3d;
  --of-pressed:   #2b2b2b;
  --of-selected:  #383838;
  --of-stroke-1:  #666666;
  --of-stroke-2:  #3d3d3d;
  --of-stroke-strong: #adadad;
  --of-ink:       #ffffff;
  --of-ink-2:     #d6d6d6;
  --of-ink-3:     #adadad;
  --of-disabled:  #5c5c5c;
  --of-disabled-bg:   #141414;
  --of-disabled-edge: #3d3d3d;
  --of-label-halo: rgba(0,0,0,.55);

  --of-btn:            #292929;
  --of-btn-edge:       #666666;
  --of-btn-hover:      #3d3d3d;
  --of-btn-hover-edge: #757575;
  --of-btn-pressed:    #2b2b2b;
  --of-neutral-dark:      #424242;
  --of-neutral-dark-edge: #525252;

  --of-danger-text:    #e37d80;
  --of-danger-tint:    #3f1011;
  --of-danger-edge:    #6e0811;
  --of-success-text:   #54b054;
  --of-success-tint:   #052505;
  --of-success-edge:   #0e700e;
  --of-warn-text:      #faa06b;
  --of-warn-tint:      #4a1e04;
  --of-warn-edge:      #8a3707;
  --of-green-text:     #54b054;
  --of-presence:       #6ccb5f;

  --of-field:            #292929;
  --of-field-edge:       #666666;
  --of-field-hover-edge: #757575;
  --of-field-line:       #adadad;

  --of-tag-bg:   #333333;
  --of-tag-edge: #525252;
  --of-tag-text: #d6d6d6;
  --of-terminal:      #141414;
  --of-terminal-edge: #3d3d3d;
  --of-terminal-text: #d6d6d6;
  --of-menu-shadow:   0 0 2px rgba(0,0,0,.24), 0 8px 16px rgba(0,0,0,.28);
  --of-dialog-shadow: 0 0 8px rgba(0,0,0,.40), 0 32px 64px rgba(0,0,0,.48);
  --of-scrim: rgba(0,0,0,.60);
}

/* ═══════════════════════════════════════════════════════════════════════════
   Fujitsu View — structural section
   Everything here is scoped to :root[data-theme^="office"]. No rule may
   escape that, or it dirties the other themes.

   Same architecture as the other themes: the theme takes the light themes'
   shared TOKENS but not any grouped structural rules, so the base dark chrome
   still applies until a rule below replaces it. This section covers every
   shared class the :root chrome styles, one by one, in the same order as
   Fujitsu TMSP 01's.

   Reference: Microsoft 365 in its Colorful theme — a blue title bar over a
   white ribbon, flat white cards on a grey canvas, Fluent 2 controls (4px
   corners, hairline borders, the darker bottom line on a text field, a
   brand underline on the selected tab), mixed-case Segoe UI everywhere.
   Nothing glows and nothing moves apart from the presence dot.
   ═══════════════════════════════════════════════════════════════════════════ */

/* ── Canvas ─────────────────────────────────────────────────────────────────
   Flat app grey. The base's animated grid, the scanline layer and the card
   sweep all go. */
/* ── Desktop ────────────────────────────────────────────────────────────────
   A Fujitsu Teams wallpaper behind the Fluent chrome (2026-10-03, by
   request), served from this site — the CSP is default-src 'self'; bump the
   ?v= when the file changes. Same mechanics as the two TMS Portal themes: a
   fixed, viewport-sized layer at z-index -1 with --bg0 underneath it as the
   canvas and the fallback, and the shared grid and scanline layers off. The
   cards here are opaque Fluent surfaces, not glass, so what shows is a frame
   of photograph around them rather than a wash through them.
   Not on the login page: that one paints its own wallpaper on body itself
   (see login.php's scoped <style>). */
:root[data-theme^="office"] body{ background: var(--bg0); }
:root[data-theme^="office"] body:not(.tmsp-login)::before{
  content: "";
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  opacity: 1;
  transform: none;
  animation: none;
  filter: none;
  background:
    url('/assets/office-bg.jpg?v=2') center center / cover no-repeat,
    var(--bg0);
}
:root[data-theme^="office"] body.tmsp-login::before,
:root[data-theme^="office"] body::after{ display: none; }

/* Text that sits on the photograph instead of on a card — the line under the
   title — takes the ink colour and a halo, the way the TMS Portal themes do
   it, because a Fluent caption grey disappears into a sky. */
:root[data-theme^="office"] .tmsp-wrap > .tmsp-muted{
  color: var(--text);
  text-shadow: 0 1px 2px var(--of-label-halo);
}
:root[data-theme^="office"] .tmsp-sweep{ display: none; }

/* Captions and labels are Fluent captions: mixed case, no tracking. */
:root[data-theme^="office"] .tmsp-muted{
  letter-spacing: 0;
  text-transform: none;
  font-size: 12.5px;
  color: var(--of-ink-3);
}
:root[data-theme^="office"] .tmsp-label{
  letter-spacing: 0;
  text-transform: none;
  font-size: 12.5px;
  font-weight: 600;
  color: var(--of-ink-2);
}

/* ── Cards ──────────────────────────────────────────────────────────────────
   White, a hairline, 8px corners, Fluent's layered shadow. The HUD corners go. */
:root[data-theme^="office"] .tmsp-card{
  border: 1px solid var(--of-stroke-2);
  border-radius: 8px;
  background: var(--of-bg-1);
  box-shadow: var(--shadow2);
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
}
:root[data-theme^="office"] .tmsp-card::before,
:root[data-theme^="office"] .tmsp-card::after{ display: none; }
:root[data-theme^="office"] .tmsp-perm-card{
  box-shadow: inset 0 0 0 100vmax var(--card-tint-dark), var(--shadow2);
}

/* ── Title bar ──────────────────────────────────────────────────────────────
   The header card is the app window: its first row (.tmsp-pagehead, the one
   that holds .tmsp-reactor) is pulled out to the card edge and painted
   Microsoft 365 blue with white ink, the way the Colorful theme paints an
   Office title bar; the nav under it is the ribbon, on white. The ink tokens
   are re-scoped on the bar so the caption and the pills follow without
   naming their classes; the theme menu that opens from it is a white panel
   and puts them back. The phone layer pads the card at 14px and 12px and
   rounds it at 16px, so the margin and the corner are restated at both
   tiers; the FHD layer restates the margin for its 28px/32px padding. */
:root[data-theme^="office"] .tmsp-card:has(.tmsp-reactor) .tmsp-pagehead{
  margin: -24px -24px 0;
  padding: 12px 24px;
  border-radius: 7px 7px 0 0;
  background: var(--of-titlebar);
  border-bottom: 1px solid var(--of-titlebar-edge);
  color: var(--of-on-brand);
  --text:    var(--of-on-brand);
  --text-b:  var(--of-on-brand);
  --muted:   var(--of-on-brand-dim);
  --muted-2: var(--of-on-brand-dim);
  --muted-3: var(--of-on-brand-dim);
  --muted-4: var(--of-on-brand-dim);
  --label:   var(--of-on-brand-dim);
}
@media (max-width: 820px){
  :root[data-theme^="office"] .tmsp-card:has(.tmsp-reactor) .tmsp-pagehead{ margin: -14px -14px 0; padding: 10px 14px; border-radius: 15px 15px 0 0; }
}
@media (max-width: 480px){
  :root[data-theme^="office"] .tmsp-card:has(.tmsp-reactor) .tmsp-pagehead{ margin: -12px -12px 0; padding: 10px 12px; }
}
:root[data-theme^="office"] .tmsp-card:has(.tmsp-reactor) .tmsp-pagehead .tmsp-dropdown-menu,
:root[data-theme^="office"] .tmsp-card:has(.tmsp-reactor) .tmsp-pagehead .tmsp-dropdown-submenu-flyout{
  --text:    var(--of-ink);
  --text-b:  var(--of-ink);
  --muted:   var(--of-ink-3);
  --muted-2: var(--of-ink-3);
  --muted-3: var(--of-ink-3);
  --muted-4: var(--of-ink-3);
  --label:   var(--of-ink-2);
}
:root[data-theme^="office"] .tmsp-card:has(.tmsp-reactor) .tmsp-pagehead .tmsp-title{ color: var(--of-on-brand); }
:root[data-theme^="office"] .tmsp-card:has(.tmsp-reactor) .tmsp-pagehead .tmsp-muted{ color: var(--of-on-brand-dim); }
:root[data-theme^="office"] .tmsp-card:has(.tmsp-reactor) .tmsp-pagehead .tmsp-logo{ filter: drop-shadow(0 1px 2px rgba(0,0,0,.35)); }

/* The pills and any plain button on the bar are translucent white. The red
   and dark-grey buttons keep their own fills. */
:root[data-theme^="office"] .tmsp-card:has(.tmsp-reactor) .tmsp-pagehead .tmsp-tag,
:root[data-theme^="office"] .tmsp-card:has(.tmsp-reactor) .tmsp-pagehead .tmsp-btn:not(.tmsp-btn-danger):not(.tmsp-btn-dark):not(.tmsp-btn-blue){
  background: var(--of-on-brand-fill);
  border-color: var(--of-on-brand-edge);
  color: var(--of-on-brand);
}
:root[data-theme^="office"] .tmsp-card:has(.tmsp-reactor) .tmsp-pagehead .tmsp-tag:hover,
:root[data-theme^="office"] .tmsp-card:has(.tmsp-reactor) .tmsp-pagehead .tmsp-theme-pick > button.tmsp-tag:hover,
:root[data-theme^="office"] .tmsp-card:has(.tmsp-reactor) .tmsp-pagehead .tmsp-btn:not(.tmsp-btn-danger):not(.tmsp-btn-dark):not(.tmsp-btn-blue):hover{
  background: var(--of-on-brand-fill-hot);
  border-color: var(--of-on-brand-edge-hot);
  color: var(--of-on-brand);
}

/* The header card itself is the ribbon: white, no accent. */
:root[data-theme^="office"] .tmsp-card:has(.tmsp-reactor){
  background: var(--of-bg-1);
  border-color: var(--of-stroke-2);
}

/* The glow bar is a hairline; on the header it is not needed (the title
   bar's own edge is the separator), so it only keeps the spacing. */
:root[data-theme^="office"] .tmsp-glowbar{
  height: 1px;
  margin: 10px 0 14px;
  opacity: 1;
  background: var(--of-stroke-2);
}
:root[data-theme^="office"] .tmsp-card:has(.tmsp-reactor) .tmsp-glowbar{
  height: 0;
  margin: 0 0 12px;
  background: none;
}

/* ── Title ──────────────────────────────────────────────────────────────────
   Semibold, mixed case, no shadow. */
:root[data-theme^="office"] .tmsp-title{
  font-family: var(--font);
  font-weight: 600;
  font-size: 20px;
  letter-spacing: -.01em;
  text-transform: none;
  text-shadow: none;
  color: var(--of-ink);
}
@media (max-width: 820px){
  :root[data-theme^="office"] .tmsp-title{ font-size: 18px; letter-spacing: -.01em; }
}
@media (max-width: 480px){
  :root[data-theme^="office"] .tmsp-title{ font-size: 16px; }
}
:root[data-theme^="office"] .tmsp-glitch{ text-shadow: none; }
:root[data-theme^="office"] .tmsp-glitch::before,
:root[data-theme^="office"] .tmsp-glitch::after{ display: none; }

/* ── The orb ────────────────────────────────────────────────────────────────
   Only seen where a page has no logo: a flat brand disc with a white dot,
   like an app icon. Nothing spins. */
:root[data-theme^="office"] .tmsp-reactor{
  border-radius: 8px;
  background: var(--of-brand);
  box-shadow: var(--shadow);
}
:root[data-theme^="office"] .tmsp-reactor-ring{ display: none; }
:root[data-theme^="office"] .tmsp-reactor-core{
  inset: 18px;
  border-radius: 50%;
  background: var(--of-on-brand);
  box-shadow: none;
  animation: none;
}

/* ── Buttons ────────────────────────────────────────────────────────────────
   Fluent's secondary button: white, a hairline, 4px corners, semibold mixed
   case, a grey wash under the pointer and a darker one pressed; the focus
   ring is a brand outline with a white gap. Disabled is greyed, not faded.
   Variants: ghost is the subtle (transparent) button, "blue" is the primary
   (brand fill, white text), green is the secondary with Excel's green label,
   danger is the red fill, and the dark-grey one turns red under the pointer
   as the product asks. */
:root[data-theme^="office"] .tmsp-btn{
  background: var(--of-btn);
  border: 1px solid var(--of-btn-edge);
  border-radius: 4px;
  box-shadow: none;
  color: var(--of-ink);
  font-family: var(--font);
  font-weight: 600;
  font-size: 13px;
  letter-spacing: 0;
  text-transform: none;
  text-shadow: none;
  transition: background .1s ease, color .1s ease, border-color .1s ease;
}
:root[data-theme^="office"] .tmsp-btn:hover{
  background: var(--of-btn-hover);
  border-color: var(--of-btn-hover-edge);
  box-shadow: none;
  color: var(--of-ink);
  transform: none;
}
:root[data-theme^="office"] .tmsp-btn:active{
  background: var(--of-btn-pressed);
  border-color: var(--of-btn-hover-edge);
  color: var(--of-ink);
  transform: none;
}
:root[data-theme^="office"] .tmsp-btn:focus-visible{
  outline: none;
  box-shadow: var(--of-focus-ring);
}
:root[data-theme^="office"] .tmsp-btn:disabled,
:root[data-theme^="office"] .tmsp-btn:disabled:hover{
  opacity: 1;
  background: var(--of-disabled-bg);
  border-color: var(--of-disabled-edge);
  box-shadow: none;
  color: var(--of-disabled);
  transform: none;
}
:root[data-theme^="office"] .tmsp-btn-sm{ font-size: 12px; border-radius: 4px; }
:root[data-theme^="office"] .tmsp-btn-ghost{
  background: transparent;
  border-color: transparent;
  color: var(--of-ink-2);
}
:root[data-theme^="office"] .tmsp-btn-ghost:hover{
  background: var(--of-hover);
  border-color: transparent;
  color: var(--of-ink);
}
:root[data-theme^="office"] .tmsp-btn-blue{
  background: var(--of-brand);
  border-color: var(--of-brand);
  color: var(--of-on-brand);
}
:root[data-theme^="office"] .tmsp-btn-blue:hover{
  background: var(--of-brand-hover);
  border-color: var(--of-brand-hover);
  color: var(--of-on-brand);
}
:root[data-theme^="office"] .tmsp-btn-blue:active{
  background: var(--of-brand-pressed);
  border-color: var(--of-brand-pressed);
  color: var(--of-on-brand);
}
:root[data-theme^="office"] .tmsp-btn-green{ color: var(--of-green-text); }
:root[data-theme^="office"] .tmsp-btn-green:hover{
  background: var(--of-success-tint);
  border-color: var(--of-success-edge);
  color: var(--of-success-text);
}
:root[data-theme^="office"] .tmsp-btn-danger{
  background: var(--of-danger);
  border-color: var(--of-danger);
  color: var(--of-on-brand);
}
:root[data-theme^="office"] .tmsp-btn-danger:hover{
  background: var(--of-danger-hover);
  border-color: var(--of-danger-hover);
  color: var(--of-on-brand);
}
:root[data-theme^="office"] .tmsp-btn-danger:active{
  background: var(--of-danger-pressed);
  border-color: var(--of-danger-pressed);
  color: var(--of-on-brand);
}
:root[data-theme^="office"] .tmsp-btn-dark{
  background: var(--of-neutral-dark);
  border-color: var(--of-neutral-dark-edge);
  color: var(--of-on-brand);
}
:root[data-theme^="office"] .tmsp-btn-dark:hover{
  background: var(--of-danger);
  border-color: var(--of-danger);
  color: var(--of-on-brand);
}
:root[data-theme^="office"] .tmsp-btn-dark:active{
  background: var(--of-danger-pressed);
  border-color: var(--of-danger-pressed);
  color: var(--of-on-brand);
}

/* ── Tags ───────────────────────────────────────────────────────────────────
   Fluent badges: small filled pills in mixed case; the coloured ones take
   the state tint with its edge and text. */
:root[data-theme^="office"] .tmsp-tag{
  background: var(--of-tag-bg);
  border: 1px solid var(--of-tag-edge);
  border-radius: 999px;
  color: var(--of-tag-text);
  font-family: var(--font);
  font-size: 11.5px;
  font-weight: 600;
  letter-spacing: 0;
  text-transform: none;
}
:root[data-theme^="office"] .tmsp-tag-red{    background: var(--of-danger-tint);  border-color: var(--of-danger-edge);  color: var(--of-danger-text); }
:root[data-theme^="office"] .tmsp-tag-green{  background: var(--of-success-tint); border-color: var(--of-success-edge); color: var(--of-success-text); }
:root[data-theme^="office"] .tmsp-tag-yellow{ background: var(--of-warn-tint);    border-color: var(--of-warn-edge);    color: var(--of-warn-text); }
:root[data-theme^="office"] .tmsp-tag-blue{   background: var(--of-brand-tint);   border-color: var(--of-brand-tint-edge); color: var(--of-brand-text); }
:root[data-theme^="office"] .tmsp-theme-pick > button.tmsp-tag:hover{
  border-color: var(--of-brand-line);
  color: var(--of-brand-text);
}

/* ── Fields ─────────────────────────────────────────────────────────────────
   White, a hairline with the darker bottom line, 4px corners; on focus the
   bottom line thickens to 2px of brand, drawn inset so nothing moves. */
:root[data-theme^="office"] .tmsp-input,
:root[data-theme^="office"] .tmsp-textarea,
:root[data-theme^="office"] select.tmsp-input,
:root[data-theme^="office"] .tmsp-inline-select{
  background: var(--of-field);
  border: 1px solid var(--of-field-edge);
  border-bottom-color: var(--of-field-line);
  border-radius: 4px;
  box-shadow: none;
  color: var(--text);
  font-family: var(--font);
}
:root[data-theme^="office"] .tmsp-input:hover,
:root[data-theme^="office"] .tmsp-textarea:hover,
:root[data-theme^="office"] select.tmsp-input:hover,
:root[data-theme^="office"] .tmsp-inline-select:hover{
  border-color: var(--of-field-hover-edge);
  border-bottom-color: var(--of-field-line);
}
:root[data-theme^="office"] .tmsp-input:focus,
:root[data-theme^="office"] .tmsp-textarea:focus,
:root[data-theme^="office"] select.tmsp-input:focus,
:root[data-theme^="office"] .tmsp-inline-select:focus{
  border-color: var(--of-field-edge);
  border-bottom-color: var(--of-brand-line);
  box-shadow: inset 0 -1px 0 var(--of-brand-line);
}
:root[data-theme^="office"] .tmsp-filter-row th{ background: var(--of-bg-3); }
:root[data-theme^="office"] .tmsp-filter-row input{
  background: var(--of-field);
  border: 1px solid var(--of-field-edge);
  border-radius: 4px;
  font-family: var(--font);
}
:root[data-theme^="office"] .tmsp-filter-row input:focus{ border-color: var(--of-brand-line); }
/* The terminal is a grey well with the mono face. */
:root[data-theme^="office"] .tmsp-terminal{
  background: var(--of-terminal);
  border: 1px solid var(--of-terminal-edge);
  border-radius: 4px;
  box-shadow: none;
  color: var(--of-terminal-text);
}

/* ── Messages ───────────────────────────────────────────────────────────────
   Fluent message bars: a tinted panel with a matching hairline. */
:root[data-theme^="office"] .tmsp-error{
  background: var(--of-danger-tint);
  border: 1px solid var(--of-danger-edge);
  border-radius: 4px;
  box-shadow: none;
  color: var(--of-danger-text);
}
:root[data-theme^="office"] .tmsp-success{
  background: var(--of-success-tint);
  border: 1px solid var(--of-success-edge);
  border-radius: 4px;
  box-shadow: none;
  color: var(--of-success-text);
}

/* ── Tabs ───────────────────────────────────────────────────────────────────
   A Fluent tab list on a hairline: plain labels, a grey wash under the
   pointer, and the current one in ink on a 3px brand underline. */
:root[data-theme^="office"] .tmsp-tabs{ border-bottom: 1px solid var(--of-stroke-2); gap: 2px; }
:root[data-theme^="office"] .tmsp-tab{
  margin-bottom: -1px;
  background: none;
  border: 1px solid transparent;
  border-bottom: none;
  border-radius: 4px 4px 0 0;
  box-shadow: none;
  color: var(--of-ink-2);
  font-family: var(--font);
  font-weight: 600;
  font-size: 13px;
  letter-spacing: 0;
  text-transform: none;
  text-shadow: none;
  transition: background .1s ease, color .1s ease;
}
:root[data-theme^="office"] .tmsp-tabs-sub .tmsp-tab{ font-size: 12px; }
:root[data-theme^="office"] .tmsp-tab:hover{
  background: var(--of-hover);
  color: var(--of-ink);
}
:root[data-theme^="office"] .tmsp-tab.is-current{
  background: none;
  border-color: transparent;
  box-shadow: inset 0 -3px 0 var(--of-brand-line);
  color: var(--of-ink);
}
:root[data-theme^="office"] .tmsp-tab.is-current:hover{ background: var(--of-hover); }

/* ── Tables ─────────────────────────────────────────────────────────────────
   A Fluent data grid: a quiet header row in mixed case, hairlines between
   rows, a grey row hover, totals on the selected grey. */
:root[data-theme^="office"] .tmsp-table th{
  background: var(--red-08);
  color: var(--of-ink-2);
  font-size: 12px;
  letter-spacing: 0;
  text-transform: none;
  border-bottom: 1px solid var(--of-stroke-1);
  text-shadow: none;
}
:root[data-theme^="office"] .tmsp-table td{
  border-bottom: 1px solid var(--of-stroke-2);
}
:root[data-theme^="office"] .tmsp-table tr:hover td{
  background: var(--of-hover);
}
:root[data-theme^="office"] .tmsp-table-totals td,
:root[data-theme^="office"] .tmsp-table tr.tmsp-table-totals:hover td{
  background: var(--of-selected);
  border-top: 2px solid var(--of-stroke-1);
  color: var(--of-ink);
}
:root[data-theme^="office"] .tmsp-table-totals td:first-child{
  color: var(--of-ink-3);
  letter-spacing: 0;
  text-transform: none;
  font-size: 12px;
}
:root[data-theme^="office"] .tmsp-th-sort:hover{ color: var(--of-brand-text); }

/* ── Stat tiles ─────────────────────────────────────────────────────────────
   White tiles with a brand strip along the top. */
:root[data-theme^="office"] .tmsp-stat{
  background: var(--of-bg-1);
  border: 1px solid var(--of-stroke-2);
  border-top: 3px solid var(--of-brand-line);
  border-radius: 8px;
  box-shadow: var(--shadow);
}
:root[data-theme^="office"] .tmsp-stat-label,
:root[data-theme^="office"] .tmsp-stat-sub{
  letter-spacing: 0;
  text-transform: none;
  font-size: 12px;
}

/* ── Menus ──────────────────────────────────────────────────────────────────
   Fluent menus: white panels with a hairline and a layered shadow, the UI
   face in regular weight, a grey wash under the pointer (the text does not
   change), the current theme in brand blue with its inherited check. */
:root[data-theme^="office"] .tmsp-dropdown-menu,
:root[data-theme^="office"] .tmsp-dropdown-submenu-flyout{
  background: var(--of-bg-1);
  border: 1px solid var(--of-stroke-2);
  border-radius: 4px;
  box-shadow: var(--of-menu-shadow);
  padding-top: 4px;
}
:root[data-theme^="office"] .tmsp-dropdown-menu a,
:root[data-theme^="office"] .tmsp-dropdown-menu button,
:root[data-theme^="office"] .tmsp-dropdown-menu .tmsp-dropdown-placeholder,
:root[data-theme^="office"] .tmsp-dropdown-submenu-label,
:root[data-theme^="office"] .tmsp-dropdown-submenu-flyout a{
  font-family: var(--font);
  font-size: 13px;
  font-weight: 400;
  letter-spacing: 0;
  padding: 8px 20px 8px 16px;
  color: var(--text);
  border-bottom: none;
  transition: none;
}
:root[data-theme^="office"] .tmsp-dropdown-menu a:hover,
:root[data-theme^="office"] .tmsp-dropdown-menu button:hover,
:root[data-theme^="office"] .tmsp-dropdown-submenu:hover .tmsp-dropdown-submenu-label,
:root[data-theme^="office"] .tmsp-dropdown-submenu:focus-within .tmsp-dropdown-submenu-label,
:root[data-theme^="office"] .tmsp-dropdown-submenu-flyout a:hover{
  background: var(--of-hover);
  color: var(--text);
}
:root[data-theme^="office"] .tmsp-dropdown-menu button.is-current,
:root[data-theme^="office"] .tmsp-dropdown-menu button.is-current:hover{
  color: var(--of-brand-text);
  font-weight: 600;
}
:root[data-theme^="office"] .tmsp-dropdown-menu .tmsp-dropdown-placeholder,
:root[data-theme^="office"] .tmsp-dropdown-menu .tmsp-dropdown-placeholder:hover{
  background: none;
  color: var(--of-disabled);
}

/* ── Help button, modal, tooltip ────────────────────────────────────────────
   The "?" is a small outlined button. The dialog is a white card with the
   Fluent dialog shadow behind a darker scrim; its title is plain semibold
   text and its close control a subtle square button. */
:root[data-theme^="office"] .tmsp-help-btn{
  background: transparent;
  border: 1px solid var(--of-stroke-1);
  color: var(--of-ink-3);
  font-family: var(--font);
}
:root[data-theme^="office"] .tmsp-help-btn:hover{
  background: var(--of-hover);
  border-color: var(--of-stroke-1);
  color: var(--of-brand-text);
}
:root[data-theme^="office"] .tmsp-modal{ background: var(--of-scrim); }
:root[data-theme^="office"] .tmsp-modal-box{
  border: 1px solid var(--of-stroke-2);
  border-radius: 8px;
  background: var(--of-bg-1);
  box-shadow: var(--of-dialog-shadow);
}
:root[data-theme^="office"] .tmsp-modal-title{
  font-family: var(--font);
  font-size: 18px;
  font-weight: 600;
  letter-spacing: 0;
  color: var(--of-ink);
}
:root[data-theme^="office"] .tmsp-modal-close{
  border-radius: 4px;
  border: 1px solid transparent;
  background: transparent;
  color: var(--of-ink-2);
  font-family: var(--font);
  font-size: 18px;
  line-height: 1;
}
:root[data-theme^="office"] .tmsp-modal-close:hover{
  background: var(--of-hover);
  border-color: transparent;
  color: var(--of-ink);
}
:root[data-theme^="office"] .tmsp-modal-table th,
:root[data-theme^="office"] .tmsp-modal-table td{ border-bottom: 1px solid var(--of-stroke-2); }
:root[data-theme^="office"] .tmsp-tip{
  background: var(--of-bg-1);
  border: 1px solid var(--of-stroke-2);
  border-radius: 4px;
  box-shadow: var(--of-menu-shadow);
  color: var(--of-ink);
}

/* ── Sign-in ────────────────────────────────────────────────────────────────
   login.php styles its own button as a solid accent block; the secondary
   button above would beat it on specificity, so the primary fill is
   restated here. Only visible if this theme ever becomes the default. */
:root[data-theme^="office"] body.tmsp-login .tmsp-btn{
  background: var(--of-brand);
  border-color: var(--of-brand);
  color: var(--of-on-brand);
}
:root[data-theme^="office"] body.tmsp-login .tmsp-btn:hover{
  background: var(--of-brand-hover);
  border-color: var(--of-brand-hover);
}

/* ── Presence dot ───────────────────────────────────────────────────────────
   The liveness dot is a Teams presence badge: green with a ring in the card
   colour; it breathes once every two seconds and that is all that moves. */
:root[data-theme^="office"] .tmsp-pulse{
  background: var(--of-presence);
  box-shadow: 0 0 0 2px var(--of-bg-1);
  animation: tmsp-pulse-office 2s ease-in-out infinite;
}
@keyframes tmsp-pulse-office{
  0%,100%{ box-shadow: 0 0 0 2px var(--of-bg-1); }
  50%{ box-shadow: 0 0 0 2px var(--of-bg-1), 0 0 0 4px var(--ok-b-25); }
}
@media (prefers-reduced-motion: reduce){
  :root[data-theme^="office"] .tmsp-pulse{ animation: none; }
}

/* ── Phone layer ────────────────────────────────────────────────────────────
   The burger is a secondary button like the rest; its open state is the
   primary fill, restated at id specificity because tmsp-responsive.css sets
   it so. */
:root[data-theme^="office"] .tmsp-nav-burger{
  background: var(--of-btn);
  border: 1px solid var(--of-btn-edge);
  border-radius: 4px;
  color: var(--of-ink);
  font-family: var(--font);
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0;
  text-transform: none;
}
:root[data-theme^="office"] #tmsp-nav-toggle:checked ~ .tmsp-nav-burger{
  background: var(--of-brand);
  border-color: var(--of-brand);
  color: var(--of-on-brand);
}


/* ── Rendered Markdown (tmsp_markdown(), the Welcome card's project notes) ─
   Reading measure and rhythm for prose inside a card; every colour a token,
   so it follows the theme. Code blocks take the terminal's recessed look. */
.tmsp-md{
  max-width: 100%;         /* the whole card width, never more: long code and paths wrap or scroll */
  min-width: 0;
  overflow-wrap: anywhere;
  font-size: 23.8px;       /* 2× the card's 14px, then −15%, by request; everything below scales with it */
  line-height: 1.55;
  color: var(--text);
}
/* Smaller screens: the same notes at a size the width can carry. */
@media (max-width: 1600px){ .tmsp-md{ font-size: 18.7px; } }
@media (max-width: 1100px){ .tmsp-md{ font-size: 15.3px; } }
@media (max-width: 700px){  .tmsp-md{ font-size: 12.8px; } }
.tmsp-md h1, .tmsp-md h2, .tmsp-md h3, .tmsp-md h4{
  margin: .8em 0 .3em;
  line-height: 1.25;
  color: var(--text);
}
.tmsp-md h1{ font-size: 1.45em; }
.tmsp-md h2{
  font-size: 1.2em;
  padding-bottom: .15em;
  border-bottom: 1px solid var(--line);
}
.tmsp-md h3{ font-size: 1.08em; }
.tmsp-md h4{ font-size: 1em; }
.tmsp-md > :first-child{ margin-top: 0; }
.tmsp-md p,
.tmsp-md li{ text-align: justify; hyphens: auto; }   /* prose only; headings and code stay ragged */
.tmsp-md p{ margin: 0 0 .4em; }
.tmsp-md ul{ margin: 0 0 .4em; padding-left: .8em; }
.tmsp-md ul ul{ margin: .15em 0 0; }
.tmsp-md li{ margin: .1em 0; }
.tmsp-md a{ color: var(--red2); }
.tmsp-md strong{ color: var(--text); }
.tmsp-md code{
  font-family: var(--mono);
  font-size: .86em;
  overflow-wrap: anywhere;
  padding: .05em .2em;
  border-radius: .2em;
  background: var(--sink-22);
  border: 1px solid var(--ov-08);
}
.tmsp-md pre{
  margin: 0 0 .5em;
  padding: .45em .55em;
  max-width: 100%;
  overflow-x: auto;          /* the directory tree scrolls sideways instead of widening the card */
  border-radius: .35em;
  background: var(--sink-22);
  border: 1px solid var(--ov-08);
  font-family: var(--mono);
  font-size: .86em;
  line-height: 1.45;
}
.tmsp-md pre code{ padding: 0; border: 0; background: none; font-size: inherit; }

/* ── System status footer (src/partials/footer.php) ─────────────────────────
   One fixed line at the bottom; the metrics scroll as a ticker. The track holds
   the group twice and slides to -50%, so the loop has no seam; the gap between
   the two groups equals the gap between items (padding-right on the group).
   The duration is set by /assets/tmsp-footer.js from the measured width so the
   speed is constant; 40s is the fallback before it runs. Hovering pauses it. */
body.tmsp-has-footer{ padding-bottom: 36px; }

.tmsp-footer{
  position: fixed;
  left: 0; right: 0; bottom: 0;
  z-index: 60;
  height: 30px;
  background: var(--panel);
  border-top: 1px solid var(--line);
  backdrop-filter: blur(10px);
  font-family: var(--mono);
  font-size: 12px;
  line-height: 30px;
  color: var(--muted);
}
.tmsp-ticker{
  height: 100%;
  overflow: hidden;
  white-space: nowrap;
}
.tmsp-ticker-track{
  display: inline-flex;
  height: 100%;
  will-change: transform;
  animation: tmsp-ticker var(--tmsp-ticker-duration, 40s) linear infinite;
}
.tmsp-ticker:hover .tmsp-ticker-track{ animation-play-state: paused; }
.tmsp-ticker-group{
  display: inline-flex;
  gap: 36px;
  padding-right: 36px;
  padding-left: 0;
}
.tmsp-ticker-item{
  display: inline-flex;
  align-items: center;
  gap: 8px;
}
.tmsp-ticker-label{
  color: var(--muted);
  font-size: 10.5px;
  letter-spacing: .14em;
  text-transform: uppercase;
}
.tmsp-ticker-value{ color: var(--text); }
.tmsp-ticker-item.is-ok     .tmsp-ticker-value{ color: var(--ok-solid); }
.tmsp-ticker-item.is-warn   .tmsp-ticker-value{ color: var(--amber-solid); }
.tmsp-ticker-item.is-danger .tmsp-ticker-value{ color: var(--danger); }

@keyframes tmsp-ticker{
  from{ transform: translateX(0); }
  to{   transform: translateX(-50%); }
}
/* No prefers-reduced-motion opt-out here, on purpose (2026-10-06, by request):
   with Windows' animation effects off the bar stood still and read as broken, so
   the ticker scrolls whatever the OS asks. Hovering still pauses it. */

/* Per theme: the bar takes the same finish as the terminal box, so on the
   light themes it reads as the dark status strip under a light page. */
:root[data-theme="vista"] .tmsp-footer{
  background: var(--vi-field);
  border-top: 1px solid var(--vi-field-edge);
  backdrop-filter: none;
}
:root[data-theme^="tmsp01"] .tmsp-footer{
  background: var(--fj-graphite-panel);
  border-top: 1px solid var(--fj-graphite-edge);
  box-shadow: inset 0 1px 0 var(--ov-15);
  backdrop-filter: none;
  --muted: var(--fj-on-dark-dim);
  --text:  var(--fj-white);
  /* The light theme's status solids are dark-on-white; on this graphite strip
     the ticker takes the base (dark theme) solids, which are made for it. */
  --ok-solid:    #6effaa;
  --amber-solid: #ffaa55;
  --danger:      #f87171;
}
/* Fujitsu View: the status bar is the same blue as the title bar, as
   Excel's and Word's are in the Colorful theme; same light solids on it. */
:root[data-theme^="office"] .tmsp-footer{
  background: var(--of-titlebar);
  border-top: 1px solid var(--of-titlebar-edge);
  backdrop-filter: none;
  font-family: var(--font);
  --muted: var(--of-on-brand-dim);
  --text:  var(--of-on-brand);
  --ok-solid:    #6ccb5f;
  --amber-solid: #ffaa55;
  --danger:      #ff8a8a;
}
:root[data-theme^="office"] .tmsp-ticker-label{ letter-spacing: .04em; text-transform: none; font-size: 11px; }


/* ═══════════════════════════════════════════════════════════════════════════
   LARGE SCREENS — 1920×1080 (FHD) and up
   Everything here lives inside one media query at 1600px, so a laptop or a
   phone parses this and applies nothing. The desktop chrome was sized for
   ~1400px: at 1920 the 95% wrap became an 1824px slab and 13px table text
   was small for a 24" panel at 100% scaling. This layer caps the width so
   the reading measure stays sane, and lifts type and spacing one notch.

   Theme-agnostic: no colours, no theme selectors except two — Windows Vista
   and Fujitsu View pull their title bar out to the card edge with a
   -24px margin that has to match the card padding, which grows here. The `[data-theme][data-theme]`
   selectors repeat the attribute on purpose: that makes them (0,3,0), a tie
   with the themes' own `:root[data-theme="x"] .class` rules, and being last
   in the file they win the tie. Without that the themes' px sizes would
   beat these. Add a theme and nothing here needs touching.
   ═══════════════════════════════════════════════════════════════════════════ */
@media (min-width: 1600px){

  /* ── Measure ─────────────────────────────────────────────────────────── */
  /* The page is 95% of the browser at every size above a phone (the base
     rule); this layer used to cap it at 1640px and no longer does — the
     site fills the screen, only type and spacing lift one notch here. */
  .tmsp-wrap{
    width: var(--tmsp-wrap-width, 95%);
    max-width: none;
    padding: 32px 0;
  }
  .tmsp-card{ padding: 28px 32px; }
  :root[data-theme="vista"] .tmsp-card:has(.tmsp-reactor) .tmsp-pagehead{ margin: -28px -32px 0; }
  :root[data-theme^="office"] .tmsp-card:has(.tmsp-reactor) .tmsp-pagehead{ margin: -28px -32px 0; padding: 12px 32px; }
  :root[data-theme^="portal01"] .tmsp-card:has(.tmsp-reactor) .tmsp-pagehead{ margin: -28px -32px 28px; padding: 16px 32px; }
  .tmsp-stats{
    grid-template-columns: repeat(auto-fill, minmax(230px, 1fr));
    gap: 20px;
  }
  .tmsp-stat{ padding: 20px 24px; }

  /* ── Type ────────────────────────────────────────────────────────────── */
  .tmsp-muted{ font-size: 12.5px; }
  .tmsp-label{ font-size: 12.5px; }
  .tmsp-title{ font-size: 30px; }
  :root[data-theme][data-theme] .tmsp-title{ font-size: 26px; }
  .tmsp-table{ font-size: 14px; }
  .tmsp-table th{ font-size: 12px; padding: 11px 14px; }
  .tmsp-table td{ padding: 11px 14px; }
  .tmsp-table-totals td:first-child{ font-size: 12px; }
  .tmsp-stat-label{ font-size: 12px; }
  .tmsp-stat-value{ font-size: 2.4rem; }
  .tmsp-stat-sub{ font-size: 12px; }
  .tmsp-tag{ font-size: 12px; padding: 6px 12px; }
  .tmsp-terminal{ font-size: 13.5px; padding: 16px; }
  .tmsp-error, .tmsp-success{ font-size: 14px; padding: 12px 14px; }
  .tmsp-modal-body{ font-size: 15px; }
  .tmsp-modal-box{ max-width: 640px; }

  /* Controls: the base sizes in rem, and the themes' px sizes. */
  .tmsp-btn{ font-size: .9rem; padding: 9px 14px; }
  .tmsp-btn-sm{ font-size: .8rem; padding: 6px 10px; }
  :root[data-theme][data-theme] .tmsp-btn{ font-size: 14px; }
  :root[data-theme][data-theme] .tmsp-btn-sm{ font-size: 12.5px; }
  .tmsp-input, .tmsp-textarea, select.tmsp-input{ font-size: .95rem; padding: 12px 14px; }
  .tmsp-inline-select{ font-size: .8rem; padding: 5px 8px; }
  .tmsp-tab{ font-size: 13px; padding: 11px 18px; }
  :root[data-theme][data-theme] .tmsp-tab{ font-size: 14px; }
  .tmsp-dropdown-menu{ min-width: 260px; }
  .tmsp-dropdown-submenu-flyout{ min-width: 320px; }
  .tmsp-dropdown-menu a,
  .tmsp-dropdown-menu button,
  .tmsp-dropdown-menu .tmsp-dropdown-placeholder,
  .tmsp-dropdown-submenu-label,
  .tmsp-dropdown-submenu-flyout a{ font-size: .85rem; padding: 11px 18px; }
  :root[data-theme][data-theme] .tmsp-dropdown-menu a,
  :root[data-theme][data-theme] .tmsp-dropdown-menu button,
  :root[data-theme][data-theme] .tmsp-dropdown-menu .tmsp-dropdown-placeholder,
  :root[data-theme][data-theme] .tmsp-dropdown-submenu-label,
  :root[data-theme][data-theme] .tmsp-dropdown-submenu-flyout a{ font-size: 14px; }
  .tmsp-help-btn{ width: 24px; height: 24px; font-size: 13px; }
  .tmsp-reactor{ width: 56px; height: 56px; }

  /* ── Sign-in ─────────────────────────────────────────────────────────── */
  /* login.php's inline <style> is linked after this file and sets these at
     (0,2,1), so the wrap is named too, for (0,3,1). */
  body.tmsp-login .tmsp-login-wrap{ max-width: 420px; }
  body.tmsp-login .tmsp-login-wrap .tmsp-card{ padding: 36px 32px; }
  body.tmsp-login .tmsp-login-wrap .tmsp-label{ font-size: 14px; }
  body.tmsp-login .tmsp-login-wrap .tmsp-input{ font-size: 1rem; padding: 12px 14px; }
  body.tmsp-login .tmsp-login-wrap .tmsp-btn{ font-size: 1rem; padding: 13px; }
}

/* ---------- Users Online (the pagehead pill) ---------- */
/* src/partials/users-online.php. The control is the ordinary .tmsp-dropdown —
   it opens on :hover and :focus-within and inherits every theme — so there is
   nothing here about opening it. What is here is only the inside of the menu:
   a header line, then one row per user, three columns (dot, name, how long
   ago). The rows are <div>s, not the menu's usual links and buttons, so none
   of the .tmsp-dropdown-menu a/button rules reaches them and they need their
   own padding. Colours are tokens, as everywhere; --ok-solid is the same
   green the status tags use. */

.tmsp-online-count {
  display: inline-block;
  min-width: 1.35em;
  margin-left: .4em;
  padding: 0 .35em;
  border-radius: 999px;
  background: var(--ok-08);
  border: 1px solid var(--ok-30);
  color: var(--ok-solid);
  text-align: center;
  font-variant-numeric: tabular-nums;
}

/* Wide enough for the longest name beside the longest duration the window can
   produce ("23 h 40 min ago" on a 24 h window); past that the name ellipses
   rather than pushing the time out of line. */
.tmsp-online-menu { min-width: 320px; }

.tmsp-online-head {
  padding: 8px 16px;
  font-family: var(--mono);
  font-size: .68rem;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--muted-2);
  border-bottom: 1px solid var(--ov-05);
}

.tmsp-online-row {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 9px 16px;
  font-family: var(--mono);
  font-size: .78rem;
  color: var(--text);
  border-bottom: 1px solid var(--ov-05);
}
.tmsp-online-row:last-child { border-bottom: none; }

/* The dot is the only thing that says "online" at a glance; it is sized in em
   so it follows the row's font, and it does not shrink when a long username
   pushes the row. */
.tmsp-online-dot {
  flex: 0 0 auto;
  width: .55em;
  height: .55em;
  border-radius: 50%;
  background: var(--ok-solid);
  box-shadow: 0 0 6px var(--ok-30);
}

.tmsp-online-name {
  flex: 1 1 auto;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.tmsp-online-you { color: var(--muted-2); }

/* Right column: the time never wraps and never moves, however long the name
   next to it is — the list is read down this column. */
.tmsp-online-ago {
  flex: 0 0 auto;
  color: var(--muted-2);
  font-size: .72rem;
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}

/* Windows Vista moves every menu off the mono face and onto the UI one, with
   its own metrics; its rules target the menu's links and buttons, which these
   rows are not. Same treatment here, or the Users Online list would be the one
   mono panel in that theme. */
:root[data-theme="vista"] .tmsp-online-head,
:root[data-theme="vista"] .tmsp-online-row {
  font-family: var(--font);
  letter-spacing: 0;
  border-bottom: none;
}
:root[data-theme="vista"] .tmsp-online-row {
  font-size: 12.5px;
  padding: 6px 16px;
}
:root[data-theme="vista"] .tmsp-online-ago { font-size: 11.5px; }

/* ---------- Monthly Service Reports (the legacy report fed from Datatables) ---------- */
/* src/partials/lidl-gss-monthly-service.php. Only the caption line above the
   report is styled here — the report itself is the legacy's own markup inside
   .tmsp-legacy-report (public/assets/lidl-legacy.css), and that markup is
   already one card per row at its own widths, so there is no layout to add.
   Same three rules as the slide-2 bar, under their own name so either page
   can change without the other noticing. */
.tmsp-msr-bar {
  display: flex;
  justify-content: space-between;
  align-items: center;
  flex-wrap: wrap;
  gap: 10px;
  margin-bottom: 12px;
}
.tmsp-msr-span {
  font-size: 13px;
  font-weight: 600;
  color: var(--legacy-ink);
}
.tmsp-msr-span-note {
  font-size: 12px;
  font-weight: 400;
  color: var(--legacy-ink-muted);
}

/* One size for every chart on the sheet (2026-10-03, by request: the value
   labels were cramped at the legacy's half-width cards). The ported markup
   sizes its cards inline — subcards at width:50%, the SLA and Tickets trends
   at calc(50% - 8px), the Trend/Nagios/Master shells at width:50%, the
   Verifone card at the full width — so these rules override inline styles
   (hence !important) and reach each card through what it contains. Every
   WHITE chart card (the div that holds the canvas) ends up --msr-chart-w wide
   and centred; the frames around it hug it (+52px: the .hive-card's 24px
   padding twice, its 1px border and 3px accent). Chart.js holds the aspect
   ratio, so equal width is equal height — the orchestrator sets the two
   charts that declare another ratio (2.5, 2.2) to 2 as well. The four donuts
   are left exactly as the legacy sized them, by request. Every :has() below
   is anchored with child combinators on purpose: a bare :has(#x) also
   matches the SECTION card around the chart, and shrinks the whole section.
   And none of them names the `canvas` TAG: the copy button photographs a
   clone in which every canvas has been swapped for an <img> carrying the
   canvas's id (lidl-gss-snap.js), and a rule written `:has(canvas#x)` stopped
   matching there — the card fell back to its inline 50%, and the picture came
   out squeezed sideways (2026-10-03). Ids and data attributes survive the
   swap; the tag does not. */
.tmsp-msr { --msr-chart-w: 1100px; }
.tmsp-msr [data-subcard-key]:not([data-subcard-key="incoming-abandoned-calls"]):not([data-subcard-key="ftf-rate"]) {
  width: min(calc(var(--msr-chart-w) + 52px), 100%) !important;
}
/* These two white cards carry a 2px border the others do not: +4px, so the
   canvas inside comes out the same. */
.tmsp-msr div:has(> div > #chart-sla-semester),
.tmsp-msr div:has(> div > #chart-slt-trend) {
  width: min(calc(var(--msr-chart-w) + 4px), 100%) !important;
  max-width: 100% !important;
}
.tmsp-msr .hive-card:has(> div > [data-sr-copy-card]):not(:has(> div > [data-sr-copy-card="ongoing-monitor"])):not(:has(> div > [data-sr-copy-card="vol-trend"])) {
  width: min(calc(var(--msr-chart-w) + 52px), 100%) !important;
}
/* The volume trend's capture block paints its own 16px frame and a 1px
   border around the white card (+34px). */
.tmsp-msr .hive-card:has(> div > [data-sr-copy-card="vol-trend"]) {
  width: min(calc(var(--msr-chart-w) + 86px), 100%) !important;
}
.tmsp-msr [data-sr-copy-card="ongoing-monitor"] {
  width: min(var(--msr-chart-w), 100%);
  margin: 0 auto;
}
