/* QCI v2 — Quitos Central Intelligence
   Palette: black + glowing red + greys
   Cinematic "secure terminal / HUD" aesthetic
*/

@import url('https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@300;400;500;700&display=swap');
@import url('https://fonts.googleapis.com/css2?family=VT323&display=swap');
@import url('https://fonts.googleapis.com/css2?family=Share+Tech+Mono&display=swap');
@import url('https://fonts.googleapis.com/css2?family=Pixelify+Sans:wght@400;700&display=swap');
@import url('https://fonts.googleapis.com/css2?family=Open+Sans:wght@400;600;700&display=swap');
/* Paper Site: Caveat (titles), Kalam (handwritten body), Courier Prime (typed figures) —
   one request for the three; the font files load only where the theme uses them. */
@import url('https://fonts.googleapis.com/css2?family=Caveat:wght@500;700&family=Kalam:wght@300;400;700&family=Courier+Prime:wght@400;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 the :root[data-theme="red_quito"] and
     :root[data-theme="blue_quito"] blocks at the end of this file.

       --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;
  /* The verdict wash on a KPI tile — deliberately weaker than --ok-08/--danger-09,
     which measured 4,24:1 for the tile's own label on MacOS 27's glass. */
  --verdict-ok-bg:  rgba(110,255,170,.07);
  --verdict-bad-bg: rgba(248,113,113,.08);
  --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;
}

*{ 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: qci-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 qci-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 ---------- */
.qci-muted{
  color: var(--muted);
  font-size: 12px;
  letter-spacing: .12em;
  text-transform: uppercase;
}
.qci-wrap{
  width: 95%;
  margin: 0 auto;
  padding: 28px;
}
.qci-top{
  display:flex;
  justify-content:space-between;
  align-items:center;
  gap: 12px;
  margin-bottom: 16px;
}

.qci-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 ---------- */
.qci-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;
}

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

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

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

/* ---------- Buttons ---------- */
.qci-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;
}
.qci-btn:hover{
  border-color: var(--red-95);
  box-shadow:
    0 0 15px var(--red-30),
    0 0 45px var(--red-18);
  transform: translateY(-1px);
}
.qci-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. */
.qci-btn:disabled,
.qci-btn:disabled:hover{
  opacity: .35;
  cursor: default;
  transform: none;
}
.qci-btn-block{
  display:block;
  width:100%;
  text-align:center;
}

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

/* Blue button (Quitos Hive) */
.qci-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);
}
.qci-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);
}

.qci-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);
}
.qci-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 */
.qci-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);
}
.qci-btn-danger:hover{
  border-color: var(--red-95);
  box-shadow: 0 0 18px var(--red-30);
}

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

.qci-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;
}
.qci-tag-red{
  border-color: var(--red-40);
  background: var(--red-10);
  color: var(--red2);
}
.qci-tag-green{
  border-color: var(--ok-30);
  background: var(--ok-08);
  color: var(--ok-solid);
}
.qci-tag-yellow{
  border-color: var(--warn-b-30);
  background: var(--warn-b-08);
  color: var(--warn-b-solid);
}
.qci-tag-blue{
  border-color: var(--info-b-30);
  background: var(--info-b-08);
  color: var(--info-b-solid);
}

/* A count on a topnav button (src/partials/topnav.php, $qciNavBadges) — today the
   CSOC's unacknowledged critical/high alerts. The --danger family, not the accent:
   it means "needs attention" in every theme, and it is defined in all of them. */
.qci-nav-badge{
  display:inline-block;
  min-width: 1.6em;
  margin-left: 6px;
  padding: 1px 6px;
  border-radius: 999px;
  border: 1px solid var(--danger-30);
  background: var(--danger-15);
  color: var(--danger);
  font-size: 10px;
  line-height: 1.5;
  letter-spacing: 0;
  text-align: center;
  vertical-align: 1px;
}

/* ---------- Inputs ---------- */
.qci-label{
  display:block;
  font-size: 12px;
  letter-spacing: .12em;
  text-transform: uppercase;
  color:var(--label);
  margin: 12px 0 6px;
}
.qci-input,
.qci-textarea,
select.qci-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;
}
.qci-textarea{ min-height: 140px; resize: vertical; }
select.qci-input option{ background: var(--option-bg); }

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

/* ---------- Terminal ---------- */
.qci-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 ---------- */
.qci-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;
}
.qci-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 ---------- */
.qci-glitch{
  position:relative;
  display:inline-block;
  text-shadow: 0 0 16px var(--red-20);
}
.qci-glitch::before,
.qci-glitch::after{
  content: attr(data-text);
  position:absolute;
  left:0; top:0;
  width:100%;
  overflow:hidden;
  opacity:.22;
  pointer-events:none;
}
.qci-glitch::before{
  transform: translateX(1px);
  clip-path: inset(0 0 55% 0);
  animation: qci-glitch1 2.8s infinite linear;
}
.qci-glitch::after{
  transform: translateX(-1px);
  clip-path: inset(55% 0 0 0);
  animation: qci-glitch2 2.4s infinite linear;
}
@keyframes qci-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 qci-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){
  .qci-glitch::before,
  .qci-glitch::after{ animation:none; opacity:.12; }
}

/* ---------- Nav ---------- */
.qci-nav{
  display:flex;
  align-items:center;
  justify-content:space-between;
  flex-wrap:wrap;
  gap: 8px;
  margin-bottom: 20px;
}
.qci-nav-left, .qci-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. */
.qci-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;
}
.qci-help-btn:hover{
  color: var(--red2);
  border-color: var(--red-25);
  background: var(--red-08);
}
.qci-help-tpl{ display:none; }

.qci-modal{
  display:none;
  position: fixed;
  inset: 0;
  z-index: 1000;
  background: var(--sh-60);
  overflow-y: auto;
  padding: 6vh 16px;
}
.qci-modal.open{ display:block; }
.qci-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;
}
.qci-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;
}
.qci-modal-close:hover{ color: var(--red2); border-color: var(--red-25); }
.qci-modal-title{
  font-family: var(--mono);
  font-size: 1.05rem;
  font-weight: 700;
  letter-spacing: .02em;
  color: var(--text);
  margin: 0 32px 14px 0;
}
.qci-modal-body{
  color: var(--text);
  font-size: 14px;
  line-height: 1.7;
}
.qci-modal-body p{ margin: 0 0 12px; }
.qci-modal-body p:last-child{ margin-bottom: 0; }
.qci-modal-body strong{ color: var(--text); }
.qci-modal-body .qci-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. */
.qci-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;
}
.qci-modal-table th,
.qci-modal-table td{
  padding: 5px 12px 5px 0;
  text-align: left;
  border-bottom: 1px solid var(--ov-08);
}
.qci-modal-table th{ color: var(--muted-2); font-weight: 600; }
.qci-modal-table tr:last-child td{ border-bottom: 0; }

/* ---------- Tabs (page sections) ----------
   Used by quitos_trading_strategies.php. 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. */
.qci-tabs{
  display:flex;
  align-items:stretch;
  gap: 4px;
  flex-wrap:wrap;
  margin: 4px 0 18px;
  border-bottom: 1px solid var(--ov-08);
}
.qci-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;
}
.qci-tab:hover{
  color: var(--text);
  background: var(--ov-03);
}
.qci-tab.is-current{
  color: var(--red2);
  background: var(--red-08);
  border-color: var(--red-25);
  box-shadow: inset 0 -2px 0 var(--red);
}

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

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

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

/* Pulse dot */
.qci-pulse{
  display:inline-block;
  width:7px; height:7px;
  border-radius:50%;
  background: var(--ok-solid);
  box-shadow: 0 0 6px var(--ok-solid);
  animation: qci-pulse 2s ease-in-out infinite;
  margin-right: 5px;
  vertical-align: middle;
}
@keyframes qci-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 ---------- */
.qci-actions{
  display:flex;
  gap: 6px;
  flex-wrap:wrap;
  align-items:center;
}
.qci-inline-form{
  display:inline-flex;
  gap:5px;
  align-items:center;
}
.qci-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;
}
.qci-inline-select:focus{ border-color: var(--red-60); }
.qci-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. */
.qci-dropdown { position: relative; }

.qci-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);
}

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

/* Invisible bridge between the button and the menu, so the mouse does not lose :hover. */
.qci-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. */
.qci-dropdown-menu a,
.qci-dropdown-menu button,
.qci-dropdown-menu .qci-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;
}

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

.qci-dropdown-menu a:hover,
.qci-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. */
.qci-dropdown-menu button.is-current { color: var(--red2); }
.qci-dropdown-menu button.is-current::after { content: ' ✓'; }

/* Placeholder item: same layout as the links, but not clickable (no exchange/page of its own yet). */
.qci-dropdown-menu .qci-dropdown-placeholder {
  color: var(--muted-2);
  cursor: default;
}
.qci-dropdown-menu .qci-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. */
.qci-dropdown-submenu { position: relative; }

.qci-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;
}
.qci-dropdown-submenu:last-child .qci-dropdown-submenu-label { border-bottom: none; }

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

.qci-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);
}
.qci-dropdown-submenu:hover .qci-dropdown-submenu-flyout,
.qci-dropdown-submenu:focus-within .qci-dropdown-submenu-flyout {
  display: block;
}

.qci-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;
}
.qci-dropdown-submenu-flyout a:last-child { border-bottom: none; }
.qci-dropdown-submenu-flyout a:hover {
  background: var(--red-10);
  color: var(--red2);
}

/* .qci-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. */
.qci-dropdown-menu:has(.qci-dropdown-submenu:hover),
.qci-dropdown-menu:has(.qci-dropdown-submenu:focus-within) {
  overflow: visible;
}

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

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

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

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

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

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

.qci-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);
}

.qci-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;
}

.qci-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;
}

.qci-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); }
}

/* ═══════════════════════════════════════════════════════════════════════════
   THEME — Crimson Indigo
   Crimson Hive with the accent in indigo instead of red.

   Unlike the three light themes, this one derives from :root — it inherits the
   black background, the grid, the scanlines, the glow and the whole HUD look.
   That is why it does NOT join the grouped light-theme selectors further down:
   it merely redefines the accent family (--red-*), the reactor (--rc-*) and the
   two shadows, which are the only red that exists in :root.

   Each token keeps exactly the Crimson Hive alpha; only the RGB triple changes,
   preserving each family's relative luminosity (-b lighter than the base, -dark
   darker, the reactor going from cold #1a0a55 to hot #d5ccff).

   --error-text follows the accent because .qci-error paints border and background
   with --red-35/--red-10: leaving it pink gave reddish text on indigo.
   .qci-btn-danger stays red, as in the other themes — there the colour means
   "destructive action", it is not the accent.
   ═══════════════════════════════════════════════════════════════════════════ */
:root[data-theme="crimson_indigo"]{
  --red:#6c5cff;
  --red2:#9a8cff;
  --shadow: 0 0 48px rgba(108,92,255,.18);
  --shadow2: 0 0 90px rgba(108,92,255,.28);
  --deep-e-97: rgba(6,6,14,0.97);
  --error-text: #dcd8ff;
  --rc-a-15: rgba(92,44,224,0.15);
  --rc-a-60: rgba(92,44,224,0.6);
  --rc-a-85: rgba(92,44,224,0.85);
  --rc-b-35: rgba(68,20,184,0.35);
  --rc-b-50: rgba(68,20,184,0.5);
  --rc-c-18: rgba(122,72,255,0.18);
  --rc-c-95: rgba(122,72,255,0.95);
  --rc-cold: #1a0a55;
  --rc-d-12: rgba(150,112,255,0.12);
  --rc-d-70: rgba(150,112,255,0.7);
  --rc-e-90: rgba(132,86,255,0.9);
  --rc-f-50: rgba(112,60,255,0.5);
  --rc-g-100: rgba(146,106,255,1.0);
  --rc-h-80: rgba(96,48,224,0.8);
  --rc-hot: #d5ccff;
  --rc-mid: #6633ff;
  --red-03: rgba(108,92,255,0.03);
  --red-04: rgba(108,92,255,0.04);
  --red-05: rgba(108,92,255,0.05);
  --red-06: rgba(108,92,255,0.06);
  --red-07: rgba(108,92,255,0.07);
  --red-08: rgba(108,92,255,0.08);
  --red-10: rgba(108,92,255,0.1);
  --red-12: rgba(108,92,255,0.12);
  --red-14: rgba(108,92,255,0.14);
  --red-16: rgba(108,92,255,0.16);
  --red-18: rgba(108,92,255,0.18);
  --red-20: rgba(108,92,255,0.2);
  --red-22: rgba(108,92,255,0.22);
  --red-28: rgba(108,92,255,0.28);
  --red-30: rgba(108,92,255,0.3);
  --red-35: rgba(108,92,255,0.35);
  --red-40: rgba(108,92,255,0.4);
  --red-45: rgba(108,92,255,0.45);
  --red-55: rgba(108,92,255,0.55);
  --red-60: rgba(108,92,255,0.6);
  --red-70: rgba(108,92,255,0.7);
  --red-95: rgba(108,92,255,0.95);
  --red-b-10: rgba(124,110,255,0.1);
  --red-b-25: rgba(124,110,255,0.25);
  --red-b-50: rgba(124,110,255,0.5);
  --red-c-20: rgba(150,138,255,0.2);
  --red-c-35: rgba(150,138,255,0.35);
  --red-d-15: rgba(105,88,255,0.15);
  --red-dark-18: rgba(86,70,205,0.18);
  --red-dark-60: rgba(86,70,205,0.6);
  --red-dark2-35: rgba(76,62,186,0.35);
  --red-e-85: rgba(142,130,255,0.85);
  --red-15: rgba(108,92,255,.15);
  --red-25: rgba(108,92,255,.25);
  --red-b-85: rgba(124,110,255,.85);
  --red-e-90: rgba(142,130,255,.9);
  --red-e-95: rgba(142,130,255,.95);
  --red-f-solid: #7d6cff;
  --red-b-70: rgba(124,110,255,.7);
  --red-deep-solid: #2e2a8c;
}

/* ═══════════════════════════════════════════════════════════════════════════
   THEME — Blueprint 1:1
   Technical drawing: cyan ink on navy paper.

   It is not a dark theme with the accent swapped, nor one of the light ones: it
   is a change of category. The site stops being a panel and becomes a drawing
   sheet — millimetre grid, dimension lines, registration marks, title block and
   compass.

   It lives in two parts, like the ZX Spectrum: this token block, and the
   structural section at the end of the file (all scoped to
   :root[data-theme="blueprint"]).

   Choices worth recording:

   - --panel is translucent AND the card's backdrop-filter is switched off, so the
     grid passes THROUGH the cards instead of being blurred behind them. That is
     what paper does: the grid is the paper, the drawing sits on top.
   - The state colours (--ok*, --warn*, --info*, --danger*) are NOT touched. They
     were already calibrated for a dark background and stay legible on the navy;
     there the colour means state, not accent.
   - --shadow/--shadow2 go to zero. Paper is flat — what separates is the hairline.
   - --font and --mono both become JetBrains Mono, which was already loaded and
     has normal metrics. It was deliberate not to repeat the VT323 trap, which by
     diverging in metrics forced three layers of size correction to catch the 1173
     inline style= attributes across the pages. The drafting font (Share Tech Mono)
     enters only in the titles, which are sized by classes from here.
     ZX Spectrum has followed the same rule since 2026-09-09: its body font is a
     normal-metric one and VT323 is title-only, so those three layers are gone.
   ═══════════════════════════════════════════════════════════════════════════ */
:root[data-theme="blueprint"]{
  /* ── Papel e tinta ── */
  --bg0:#0c2846;
  --bg1:#081e37;
  --panel: rgba(18,52,88,.55);
  --line: rgba(127,212,255,.28);

  --text:#dceeff;
  --muted:#8fb3d4;
  --muted-2:#6a8fb0;
  --muted-3:#4a6a88;
  --muted-4:#7fa0bd;
  --label:#a8c8e4;
  --term-text:#cfe6fb;
  --option-bg:#0c2846;

  /* Paper is flat: separation is done with the stroke, not with shadow. */
  --shadow: 0 0 0 0 transparent;
  --shadow2: 0 0 0 0 transparent;

  /* Squared off: the shared radius goes to zero. The 16 fixed radii on the classes
     are handled one by one in the structural section. */
  --radius: 0px;

  --font: 'JetBrains Mono', ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
  --mono: 'JetBrains Mono', ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;

  /* ── Accent, overlays and recessed backgrounds ──
     Generated from the :root literals: each token keeps exactly the Crimson Hive
     alpha, only the RGB triple changes. */
  --red:#7fd4ff;
  --red2:#9ee2ff;
  --deep-e-97: rgba(6,14,26,0.97);
  --error-text: #d6ecff;
  --ov-01: rgba(170,220,255,0.01);
  --ov-02: rgba(170,220,255,0.02);
  --ov-03: rgba(170,220,255,0.03);
  --ov-04: rgba(170,220,255,0.04);
  --ov-05: rgba(170,220,255,0.05);
  --ov-06: rgba(170,220,255,0.06);
  --ov-07: rgba(170,220,255,0.07);
  --ov-08: rgba(170,220,255,0.08);
  --ov-09: rgba(170,220,255,0.09);
  --ov-10: rgba(170,220,255,0.1);
  --ov-12: rgba(170,220,255,0.12);
  --ov-15: rgba(170,220,255,0.15);
  --ov-25: rgba(170,220,255,0.25);
  --ov-35: rgba(170,220,255,0.35);
  --ov-45: rgba(170,220,255,0.45);
  --ov-50: rgba(170,220,255,0.5);
  --ov-85: rgba(170,220,255,0.85);
  --rc-a-15: rgba(90,170,225,0.15);
  --rc-a-60: rgba(90,170,225,0.6);
  --rc-a-85: rgba(90,170,225,0.85);
  --rc-b-35: rgba(60,130,185,0.35);
  --rc-b-50: rgba(60,130,185,0.5);
  --rc-c-18: rgba(127,212,255,0.18);
  --rc-c-95: rgba(127,212,255,0.95);
  --rc-cold: #0d3b66;
  --rc-d-12: rgba(175,232,255,0.12);
  --rc-d-70: rgba(175,232,255,0.7);
  --rc-e-90: rgba(150,222,255,0.9);
  --rc-f-50: rgba(110,200,250,0.5);
  --rc-g-100: rgba(190,240,255,1.0);
  --rc-h-80: rgba(95,175,228,0.8);
  --rc-hot: #ffffff;
  --rc-mid: #7fd4ff;
  --red-03: rgba(127,212,255,0.03);
  --red-04: rgba(127,212,255,0.04);
  --red-05: rgba(127,212,255,0.05);
  --red-06: rgba(127,212,255,0.06);
  --red-07: rgba(127,212,255,0.07);
  --red-08: rgba(127,212,255,0.08);
  --red-10: rgba(127,212,255,0.1);
  --red-12: rgba(127,212,255,0.12);
  --red-14: rgba(127,212,255,0.14);
  --red-16: rgba(127,212,255,0.16);
  --red-18: rgba(127,212,255,0.18);
  --red-20: rgba(127,212,255,0.2);
  --red-22: rgba(127,212,255,0.22);
  --red-28: rgba(127,212,255,0.28);
  --red-30: rgba(127,212,255,0.3);
  --red-35: rgba(127,212,255,0.35);
  --red-40: rgba(127,212,255,0.4);
  --red-45: rgba(127,212,255,0.45);
  --red-55: rgba(127,212,255,0.55);
  --red-60: rgba(127,212,255,0.6);
  --red-70: rgba(127,212,255,0.7);
  --red-95: rgba(127,212,255,0.95);
  --red-b-10: rgba(158,226,255,0.1);
  --red-b-25: rgba(158,226,255,0.25);
  --red-b-50: rgba(158,226,255,0.5);
  --red-c-20: rgba(190,238,255,0.2);
  --red-c-35: rgba(190,238,255,0.35);
  --red-d-15: rgba(120,208,255,0.15);
  --red-dark-18: rgba(74,150,205,0.18);
  --red-dark-60: rgba(74,150,205,0.6);
  --red-dark2-35: rgba(62,128,180,0.35);
  --red-e-85: rgba(175,232,255,0.85);
  --sink-06: rgba(4,14,28,0.06);
  --sink-15: rgba(4,14,28,0.15);
  --sink-18: rgba(4,14,28,0.18);
  --sink-20: rgba(4,14,28,0.2);
  --sink-22: rgba(4,14,28,0.22);
  --sink-24: rgba(4,14,28,0.24);
  --sink-30: rgba(4,14,28,0.3);
  --sink-40: rgba(4,14,28,0.4);
  --red-15: rgba(127,212,255,.15);
  --red-25: rgba(127,212,255,.25);
  --red-b-85: rgba(158,226,255,.85);
  --red-e-90: rgba(175,232,255,.9);
  --red-e-95: rgba(175,232,255,.95);
  --red-f-solid: #8ddaff;
  --sink-35: rgba(4,14,28,.35);
  --sink-75: rgba(4,14,28,.75);
  --red-b-70: rgba(158,226,255,.7);
  --red-deep-solid: #1e5a8c;
}

/* ═══════════════════════════════════════════════════════════════════════════
   THEME — Aurora Hive
   Real frosted glass over drifting northern lights.

   It derives from :root like Crimson Indigo — inheriting the dark structure —
   but changes what makes the card: instead of a near-opaque panel with a token
   blur, it is real glass, and behind it passes light that moves.

   The accent is violet-magenta and NOT green, even though the aurora is. Green
   collides with --ok (which means "success") and cyan with Blueprint. What takes
   the emerald and the cyan are the ribbons in the background, in the structural
   section; the accent stays violet and is confused with no state at all.
   ═══════════════════════════════════════════════════════════════════════════ */
:root[data-theme="aurora_hive"]{
  /* ── Meia-noite ── */
  --bg0:#050914;
  --bg1:#070d1c;

  /* Glass. See the .tg-time-col note in the structural section: this value is
     translucent on purpose, and there is one place in the site that relied on it
     to cover content. */
  --panel: rgba(255,255,255,.055);
  --line: rgba(255,255,255,.14);

  /* Vidro pede canto mais mole. */
  --radius: 26px;

  /* The shadow stops being a neon halo and becomes a real drop, so the card lifts
     off the background instead of glowing. */
  --shadow: 0 8px 24px rgba(0,0,0,.35);
  --shadow2: 0 20px 60px rgba(0,0,0,.45);

  /* ── Accent ──
     Generated from the :root literals: each token keeps exactly the Crimson Hive
     alpha, only the RGB triple changes. */
  --red:#c084fc;
  --red2:#d8b4fe;
  --deep-e-97: rgba(8,6,16,0.97);
  --error-text: #f0e0ff;
  --rc-a-15: rgba(168,85,247,0.15);
  --rc-a-60: rgba(168,85,247,0.6);
  --rc-a-85: rgba(168,85,247,0.85);
  --rc-b-35: rgba(124,58,237,0.35);
  --rc-b-50: rgba(124,58,237,0.5);
  --rc-c-18: rgba(192,132,252,0.18);
  --rc-c-95: rgba(192,132,252,0.95);
  --rc-cold: #2e1065;
  --rc-d-12: rgba(216,180,254,0.12);
  --rc-d-70: rgba(216,180,254,0.7);
  --rc-e-90: rgba(200,150,253,0.9);
  --rc-f-50: rgba(180,110,250,0.5);
  --rc-g-100: rgba(232,121,249,1.0);
  --rc-h-80: rgba(160,80,240,0.8);
  --rc-hot: #f5d0fe;
  --rc-mid: #c084fc;
  --red-03: rgba(192,132,252,0.03);
  --red-04: rgba(192,132,252,0.04);
  --red-05: rgba(192,132,252,0.05);
  --red-06: rgba(192,132,252,0.06);
  --red-07: rgba(192,132,252,0.07);
  --red-08: rgba(192,132,252,0.08);
  --red-10: rgba(192,132,252,0.1);
  --red-12: rgba(192,132,252,0.12);
  --red-14: rgba(192,132,252,0.14);
  --red-16: rgba(192,132,252,0.16);
  --red-18: rgba(192,132,252,0.18);
  --red-20: rgba(192,132,252,0.2);
  --red-22: rgba(192,132,252,0.22);
  --red-28: rgba(192,132,252,0.28);
  --red-30: rgba(192,132,252,0.3);
  --red-35: rgba(192,132,252,0.35);
  --red-40: rgba(192,132,252,0.4);
  --red-45: rgba(192,132,252,0.45);
  --red-55: rgba(192,132,252,0.55);
  --red-60: rgba(192,132,252,0.6);
  --red-70: rgba(192,132,252,0.7);
  --red-95: rgba(192,132,252,0.95);
  --red-b-10: rgba(205,152,253,0.1);
  --red-b-25: rgba(205,152,253,0.25);
  --red-b-50: rgba(205,152,253,0.5);
  --red-c-20: rgba(218,178,254,0.2);
  --red-c-35: rgba(218,178,254,0.35);
  --red-d-15: rgba(188,126,252,0.15);
  --red-dark-18: rgba(150,95,205,0.18);
  --red-dark-60: rgba(150,95,205,0.6);
  --red-dark2-35: rgba(130,80,180,0.35);
  --red-e-85: rgba(212,165,253,0.85);
  --red-15: rgba(192,132,252,.15);
  --red-25: rgba(192,132,252,.25);
  --red-b-85: rgba(205,152,253,.85);
  --red-e-90: rgba(212,165,253,.9);
  --red-e-95: rgba(212,165,253,.95);
  --red-f-solid: #cba6fc;
  --red-b-70: rgba(205,152,253,.7);
  --red-deep-solid: #5b21b6;
}

/* ═══════════════════════════════════════════════════════════════════════════
   THEME — Outrun 1986
   Synthwave: banded sun, grid in perspective, chrome on the titles.

   It derives from :root. The accent is hot pink and cyan comes in as a second
   voice — in the grid lines and in the chromatic aberration on the titles, which
   here stops being a HUD defect and becomes exactly the effect the genre asks for.

   The --rc-* family (the reactor) was mapped to the sun's gradient, magenta to
   amber, instead of to the accent's pink: that is what makes the header reactor
   read as a small sun rather than a pink dot.
   ═══════════════════════════════════════════════════════════════════════════ */
:root[data-theme="outrun"]{
  /* ── Noite violeta ── */
  --bg0:#1a0b2e;
  --bg1:#0d0518;
  --panel: rgba(28,12,52,.78);
  --line: rgba(255,46,136,.22);

  --text:#f6eaff;
  --muted:#b39ad0;
  --muted-2:#8a70a8;

  --shadow: 0 0 48px rgba(255,46,136,.22);
  --shadow2: 0 0 90px rgba(255,46,136,.30);

  /* ── Accent ──
     Alphas untouched, only the RGB triple changes. */
  --red:#ff2e88;
  --red2:#ff6bb0;
  --deep-e-97: rgba(14,5,26,0.97);
  --error-text: #ffd9ec;
  --rc-a-15: rgba(236,72,153,0.15);
  --rc-a-60: rgba(236,72,153,0.6);
  --rc-a-85: rgba(236,72,153,0.85);
  --rc-b-35: rgba(157,23,110,0.35);
  --rc-b-50: rgba(157,23,110,0.5);
  --rc-c-18: rgba(255,46,136,0.18);
  --rc-c-95: rgba(255,46,136,0.95);
  --rc-cold: #3b0a5c;
  --rc-d-12: rgba(255,160,80,0.12);
  --rc-d-70: rgba(255,160,80,0.7);
  --rc-e-90: rgba(255,110,90,0.9);
  --rc-f-50: rgba(255,60,140,0.5);
  --rc-g-100: rgba(255,190,90,1.0);
  --rc-h-80: rgba(210,50,130,0.8);
  --rc-hot: #ffe9a8;
  --rc-mid: #ff2e88;
  --red-03: rgba(255,46,136,0.03);
  --red-04: rgba(255,46,136,0.04);
  --red-05: rgba(255,46,136,0.05);
  --red-06: rgba(255,46,136,0.06);
  --red-07: rgba(255,46,136,0.07);
  --red-08: rgba(255,46,136,0.08);
  --red-10: rgba(255,46,136,0.1);
  --red-12: rgba(255,46,136,0.12);
  --red-14: rgba(255,46,136,0.14);
  --red-16: rgba(255,46,136,0.16);
  --red-18: rgba(255,46,136,0.18);
  --red-20: rgba(255,46,136,0.2);
  --red-22: rgba(255,46,136,0.22);
  --red-28: rgba(255,46,136,0.28);
  --red-30: rgba(255,46,136,0.3);
  --red-35: rgba(255,46,136,0.35);
  --red-40: rgba(255,46,136,0.4);
  --red-45: rgba(255,46,136,0.45);
  --red-55: rgba(255,46,136,0.55);
  --red-60: rgba(255,46,136,0.6);
  --red-70: rgba(255,46,136,0.7);
  --red-95: rgba(255,46,136,0.95);
  --red-b-10: rgba(255,90,165,0.1);
  --red-b-25: rgba(255,90,165,0.25);
  --red-b-50: rgba(255,90,165,0.5);
  --red-c-20: rgba(255,130,190,0.2);
  --red-c-35: rgba(255,130,190,0.35);
  --red-d-15: rgba(255,40,132,0.15);
  --red-dark-18: rgba(200,30,105,0.18);
  --red-dark-60: rgba(200,30,105,0.6);
  --red-dark2-35: rgba(175,25,95,0.35);
  --red-e-85: rgba(255,110,178,0.85);
  --red-15: rgba(255,46,136,.15);
  --red-25: rgba(255,46,136,.25);
  --red-b-85: rgba(255,90,165,.85);
  --red-e-90: rgba(255,110,178,.9);
  --red-e-95: rgba(255,110,178,.95);
  --red-f-solid: #ff4d9c;
  --red-b-70: rgba(255,90,165,.7);
  --red-deep-solid: #7a1050;
}

/* ═══════════════════════════════════════════════════════════════════════════
   THEME — Iridium
   Near-black with holographic foil on the edges.

   This is the only one of the nine with a DELIBERATELY neutral accent. The
   --red-* family becomes pearl — cool greys — and the colour lives only in the
   animated foil on the borders. That restraint is what makes it distinct: a
   monochrome interface where the only coloured thing is the edge, and that edge
   is always changing.

   In compensation the --rc-* family (the reactor) takes the full iridescent
   palette: teal, indigo, magenta and amber. The reactor becomes the most colourful
   object on the page, which makes sense — it is the living piece of the header.
   ═══════════════════════════════════════════════════════════════════════════ */
:root[data-theme="iridium"]{
  /* ── Quase-preto ── */
  --bg0:#07070c;
  --bg1:#050508;

  /* More opaque than the other dark themes on purpose: the foil is painted in
     border-box behind the panel, and a transparent panel let the colour spill
     into the card instead of staying trapped on the edge. */
  --panel: rgba(16,16,24,.92);
  --line: rgba(255,255,255,.10);

  --shadow: 0 8px 24px rgba(0,0,0,.5);
  --shadow2: 0 20px 60px rgba(0,0,0,.6);

  /* ── Pearl accent ──
     Alphas untouched, only the RGB triple changes. */
  --red:#d5d8e8;
  --red2:#e2e5f2;
  --deep-e-97: rgba(6,6,10,0.97);
  --error-text: #e8eaf5;
  --rc-a-15: rgba(129,140,248,0.15);
  --rc-a-60: rgba(129,140,248,0.6);
  --rc-a-85: rgba(129,140,248,0.85);
  --rc-b-35: rgba(79,70,229,0.35);
  --rc-b-50: rgba(79,70,229,0.5);
  --rc-c-18: rgba(45,212,191,0.18);
  --rc-c-95: rgba(45,212,191,0.95);
  --rc-cold: #0b1220;
  --rc-d-12: rgba(232,121,249,0.12);
  --rc-d-70: rgba(232,121,249,0.7);
  --rc-e-90: rgba(251,191,36,0.9);
  --rc-f-50: rgba(129,140,248,0.5);
  --rc-g-100: rgba(244,114,182,1.0);
  --rc-h-80: rgba(45,212,191,0.8);
  --rc-hot: #f8fafc;
  --rc-mid: #818cf8;
  --red-03: rgba(213,216,232,0.03);
  --red-04: rgba(213,216,232,0.04);
  --red-05: rgba(213,216,232,0.05);
  --red-06: rgba(213,216,232,0.06);
  --red-07: rgba(213,216,232,0.07);
  --red-08: rgba(213,216,232,0.08);
  --red-10: rgba(213,216,232,0.1);
  --red-12: rgba(213,216,232,0.12);
  --red-14: rgba(213,216,232,0.14);
  --red-16: rgba(213,216,232,0.16);
  --red-18: rgba(213,216,232,0.18);
  --red-20: rgba(213,216,232,0.2);
  --red-22: rgba(213,216,232,0.22);
  --red-28: rgba(213,216,232,0.28);
  --red-30: rgba(213,216,232,0.3);
  --red-35: rgba(213,216,232,0.35);
  --red-40: rgba(213,216,232,0.4);
  --red-45: rgba(213,216,232,0.45);
  --red-55: rgba(213,216,232,0.55);
  --red-60: rgba(213,216,232,0.6);
  --red-70: rgba(213,216,232,0.7);
  --red-95: rgba(213,216,232,0.95);
  --red-b-10: rgba(226,229,242,0.1);
  --red-b-25: rgba(226,229,242,0.25);
  --red-b-50: rgba(226,229,242,0.5);
  --red-c-20: rgba(238,240,250,0.2);
  --red-c-35: rgba(238,240,250,0.35);
  --red-d-15: rgba(208,212,229,0.15);
  --red-dark-18: rgba(150,155,178,0.18);
  --red-dark-60: rgba(150,155,178,0.6);
  --red-dark2-35: rgba(128,133,158,0.35);
  --red-e-85: rgba(232,234,246,0.85);
  --red-15: rgba(213,216,232,.15);
  --red-25: rgba(213,216,232,.25);
  --red-b-85: rgba(226,229,242,.85);
  --red-e-90: rgba(232,234,246,.9);
  --red-e-95: rgba(232,234,246,.95);
  --red-f-solid: #dde0ee;
  --red-b-70: rgba(226,229,242,.7);
  --red-deep-solid: #4a4f66;
}

/* ═══════════════════════════════════════════════════════════════════════════
   THEME — MacOS 27 (Dark)
   The night half of the macOS pair: dark Liquid Glass over the dark version of
   the wallpaper. The light half, and the note on how the two share one
   structural section, are further down with the light themes.

   It derives from :root like Crimson Indigo and Aurora Hive — it inherits the
   dark state colours, which were calibrated for a dark surface — and redefines
   the accent family, the surfaces and the --mac-* chrome tokens. Everything
   that is not a token lives in the "MACOS 27" structural section at the end of
   the file, which both halves share.

   The accent is International Orange lifted to #ff6b35 — the one warm thing on
   an indigo wallpaper — which holds 6:1 on the dark glass; --red2, the
   accent-as-text, is #ff9466 (6.0:1 over the wallpaper's brightest region).
   Each token keeps exactly the Crimson Hive alpha; only the RGB triple changes.
   ═══════════════════════════════════════════════════════════════════════════ */
:root[data-theme="macos27_dark"]{
  --red:#ff6b35;
  --red2:#ff9466;
  --deep-e-97: rgba(14,8,6,0.97);
  --error-text: #ffe0d2;
  --rc-a-15: rgba(232,80,20,0.15);
  --rc-a-60: rgba(232,80,20,0.6);
  --rc-a-85: rgba(232,80,20,0.85);
  --rc-b-35: rgba(190,56,8,0.35);
  --rc-b-50: rgba(190,56,8,0.5);
  --rc-c-18: rgba(255,110,50,0.18);
  --rc-c-95: rgba(255,110,50,0.95);
  --rc-cold: #5a1c05;
  --rc-d-12: rgba(255,150,100,0.12);
  --rc-d-70: rgba(255,150,100,0.7);
  --rc-e-90: rgba(255,124,64,0.9);
  --rc-f-50: rgba(255,96,36,0.5);
  --rc-g-100: rgba(255,140,84,1.0);
  --rc-h-80: rgba(226,80,24,0.8);
  --rc-hot: #ffd9c2;
  --rc-mid: #ff6b35;
  --red-03: rgba(255,107,53,0.03);
  --red-04: rgba(255,107,53,0.04);
  --red-05: rgba(255,107,53,0.05);
  --red-06: rgba(255,107,53,0.06);
  --red-07: rgba(255,107,53,0.07);
  --red-08: rgba(255,107,53,0.08);
  --red-10: rgba(255,107,53,0.1);
  --red-12: rgba(255,107,53,0.12);
  --red-14: rgba(255,107,53,0.14);
  --red-16: rgba(255,107,53,0.16);
  --red-18: rgba(255,107,53,0.18);
  --red-20: rgba(255,107,53,0.2);
  --red-22: rgba(255,107,53,0.22);
  --red-28: rgba(255,107,53,0.28);
  --red-30: rgba(255,107,53,0.3);
  --red-35: rgba(255,107,53,0.35);
  --red-40: rgba(255,107,53,0.4);
  --red-45: rgba(255,107,53,0.45);
  --red-55: rgba(255,107,53,0.55);
  --red-60: rgba(255,107,53,0.6);
  --red-70: rgba(255,107,53,0.7);
  --red-95: rgba(255,107,53,0.95);
  --red-b-10: rgba(255,128,82,0.1);
  --red-b-25: rgba(255,128,82,0.25);
  --red-b-50: rgba(255,128,82,0.5);
  --red-c-20: rgba(255,156,118,0.2);
  --red-c-35: rgba(255,156,118,0.35);
  --red-d-15: rgba(255,100,45,0.15);
  --red-dark-18: rgba(212,80,34,0.18);
  --red-dark-60: rgba(212,80,34,0.6);
  --red-dark2-35: rgba(188,70,30,0.35);
  --red-e-85: rgba(255,142,100,0.85);
  --red-15: rgba(255,107,53,.15);
  --red-25: rgba(255,107,53,.25);
  --red-b-85: rgba(255,128,82,.85);
  --red-e-90: rgba(255,142,100,.9);
  --red-e-95: rgba(255,142,100,.95);
  --red-f-solid: #ff7d4d;
  --red-b-70: rgba(255,128,82,.7);
  --red-deep-solid: #8c3a1a;
}
:root[data-theme="macos27_dark"]{
  /* The desktop is the wallpaper, painted by body::before; both --bg tokens are
     its own deep indigo (the image averages #23263a), so nothing can gradient
     between them and the fallback is the right colour while the JPEG loads. */
  --bg0: #181a28;
  --bg1: #181a28;

  /* A window body: dark glass, translucent enough to take the wallpaper's
     colour through the blur and opaque enough that the light state colours
     keep their contrast. 80% and not lower: the wallpaper's brightest region
     is a mid blue, #6679a0, and over it the glass composites to #2c303d —
     where --danger is 4.7:1 (at 74% it was 4.4). --panel-solid is what a
     surface with nothing behind it uses (menus, the calendar's sticky column). */
  --panel: rgba(30,30,36,.80);
  --panel-solid: #232328;
  --line: rgba(255,255,255,.12);
  --text: #f5f5f7;
  --muted: #a9adb8;
  /* :root's --muted-2 (#6b7685) is 2.8:1 on that same composite — it was tuned
     for Crimson Hive's near-black. Lifted to 4.7:1; --muted-3, which :root
     keeps decorative, to 4.2:1. */
  --muted-2: #949caa;
  --muted-3: #8b93a1;
  --option-bg: #232328;

  /* Windows float: a hairline to separate glass from glass, and a real drop. */
  --shadow: 0 1px 2px rgba(0,0,0,.35), 0 2px 8px rgba(0,0,0,.25);
  --shadow2: 0 0 0 .5px rgba(0,0,0,.6), 0 18px 50px rgba(0,0,0,.45);

  /* ── The Liquid Glass palette, for this theme's chrome only ──────────────
     Same names as the light half; the structural section reads only these. */
  --mac-wall: url('/assets/macos27_dark.jpg?v=1');
  --mac-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 104 104'%3E%3Cdefs%3E%3ClinearGradient id='b' x1='0' y1='0' x2='1' y2='1'%3E%3Cstop offset='0' stop-color='%230c0c16'/%3E%3Cstop offset='1' stop-color='%231d1d33'/%3E%3C/linearGradient%3E%3ClinearGradient id='g0' x1='.2' y1='0' x2='.8' y2='1'%3E%3Cstop offset='0' stop-color='%2334345a'/%3E%3Cstop offset='1' stop-color='%2314141f'/%3E%3C/linearGradient%3E%3ClinearGradient id='g1' x1='.2' y1='0' x2='.8' y2='1'%3E%3Cstop offset='0' stop-color='%232a2c4e'/%3E%3Cstop offset='1' stop-color='%230d0d18'/%3E%3C/linearGradient%3E%3ClinearGradient id='g2' x1='.2' y1='0' x2='.8' y2='1'%3E%3Cstop offset='0' stop-color='%233f4a78'/%3E%3Cstop offset='1' stop-color='%2315182a'/%3E%3C/linearGradient%3E%3Cfilter id='s' x='-20%25' y='-20%25' width='140%25' height='140%25'%3E%3CfeGaussianBlur stdDeviation='3.2'/%3E%3C/filter%3E%3C/defs%3E%3Crect width='104' height='104' fill='url%28%23b%29'/%3E%3Cpath d='M-6 70 C22 66 30 34 50 22 C66 12 82 10 110 -4 L110 110 L-6 110Z' fill='%23000' opacity='.28' transform='translate%280 -3%29' filter='url%28%23s%29'/%3E%3Cpath d='M-6 70 C22 66 30 34 50 22 C66 12 82 10 110 -4 L110 110 L-6 110Z' fill='url%28%23g0%29'/%3E%3Cpath d='M-6 70 C22 66 30 34 50 22 C66 12 82 10 110 -4' fill='none' stroke='%238f92ea' stroke-opacity='.95' stroke-width='1.3'/%3E%3Cpath d='M-6 96 C26 92 40 66 58 52 C74 40 90 36 110 22 L110 110 L-6 110Z' fill='%23000' opacity='.28' transform='translate%280 -3%29' filter='url%28%23s%29'/%3E%3Cpath d='M-6 96 C26 92 40 66 58 52 C74 40 90 36 110 22 L110 110 L-6 110Z' fill='url%28%23g1%29'/%3E%3Cpath d='M-6 96 C26 92 40 66 58 52 C74 40 90 36 110 22' fill='none' stroke='%238f92ea' stroke-opacity='.95' stroke-width='1.3'/%3E%3Cpath d='M22 110 C34 92 52 84 70 76 C86 69 98 62 110 50 L110 110Z' fill='%23000' opacity='.28' transform='translate%280 -3%29' filter='url%28%23s%29'/%3E%3Cpath d='M22 110 C34 92 52 84 70 76 C86 69 98 62 110 50 L110 110Z' fill='url%28%23g2%29'/%3E%3Cpath d='M22 110 C34 92 52 84 70 76 C86 69 98 62 110 50' fill='none' stroke='%238f92ea' stroke-opacity='.95' stroke-width='1.3'/%3E%3C/svg%3E");

  /* 72%, not lower: --muted on it has to hold AA over the wallpaper's
     brightest blue (4.8:1; at 58% it was 4.0). */
  --mac-bar:        rgba(38,38,46,.72);
  --mac-blur:       blur(30px) saturate(170%);
  --mac-edge:       rgba(255,255,255,.14);
  --mac-edge-top:   rgba(255,255,255,.22);
  --mac-hair:       rgba(0,0,0,.55);

  --mac-ctl:        rgba(255,255,255,.10);
  --mac-ctl-hot:    rgba(255,255,255,.17);
  --mac-ctl-down:   rgba(255,255,255,.06);
  --mac-ctl-edge:   rgba(255,255,255,.10);
  --mac-ctl-shadow: inset 0 .5px 0 rgba(255,255,255,.18), 0 1px 2px rgba(0,0,0,.30);
  --mac-ctl-on:     rgba(255,255,255,.22);

  /* An accent-filled control. White on #cf4512 is 4.65:1. */
  --mac-fill:       #cf4512;
  --mac-fill-hot:   #dd4d17;
  --mac-fill-down:  #b93a0e;
  --mac-on-fill:    #ffffff;

  --mac-field:      rgba(0,0,0,.26);
  --mac-field-edge: rgba(255,255,255,.14);
  --mac-focus:      0 0 0 3.5px rgba(255,107,53,.40);
  --mac-well:       rgba(0,0,0,.22);
  /* See the light half: the segmented control is near-opaque, not glass. */
  --mac-seg:        #23232b;
  --mac-seg-edge:   rgba(255,255,255,.12);
  --mac-tile:       rgba(255,255,255,.06);
  --mac-head:       rgba(255,255,255,.05);
  --mac-rule:       rgba(255,255,255,.09);
  --mac-rule-strong:rgba(255,255,255,.18);
  --mac-row-hover:  rgba(255,255,255,.05);

  --mac-menu:        rgba(44,44,52,.97);
  --mac-menu-edge:   rgba(255,255,255,.14);
  --mac-menu-shadow: 0 0 0 .5px rgba(0,0,0,.7), 0 12px 38px rgba(0,0,0,.55);
  --mac-sheet:       rgba(36,36,42,.90);

  --mac-desk-ink:    #ffffff;
  --mac-desk-shadow: 0 1px 3px rgba(0,0,0,.75);
  --mac-disabled:    rgba(255,255,255,.30);
}


/* ═══════════════════════════════════════════════════════════════════════════
   THEME — IBM 3270
   A 3279 colour display on a black CRT: green phosphor for the body, the
   intensified white-green for what the terminal would have intensified, and
   the other 3270 colours kept for what they meant — red for errors, yellow for
   warnings, turquoise for information.

   It derives from :root like Crimson Indigo, Aurora Hive and MacOS 27 (Dark),
   and for once that is not only economy: the dark state colours are already
   the 3279 palette in everything but name (--ok a mint green, --amber a
   yellow, --info a cyan, --danger a red), so they are inherited rather than
   restated. What changes here is the accent family — the whole ladder in
   phosphor green — the surfaces, the overlays and the two faces.

   Three intensities, which is what the terminal had:
     · dim green    #1fae5a  (7.3:1)   protected text, captions
     · normal green #33e878  (12.9:1)  the body
     · intensified  #e8fff2  (20:1)    labels, table heads, what you must read
   The accent is #33ff66 (15.6:1), used where the other themes use their red.

   Everything that is not a token lives in the "IBM 3270 — structural section"
   further down.
   ═══════════════════════════════════════════════════════════════════════════ */
:root[data-theme="ibm3270"]{
  /* The screen is off until the phosphor lights it: flat black, no gradient,
     and a panel that is barely a tint — a card here is a framed region of the
     screen, not a pane of glass over a background. */
  --bg0:#000000;
  --bg1:#000000;
  --panel: rgba(0,26,12,.42);
  --panel-solid:#020a05;
  --option-bg:#02120a;
  --line: rgba(51,255,102,.22);

  /* Nothing on a CRT casts a shadow. What looks like one is the bloom. */
  --shadow: 0 0 22px rgba(51,255,102,.05);
  --shadow2: 0 0 34px rgba(51,255,102,.07);
  --radius: 0px;

  /* The faces are the two this file already loads — Share Tech Mono for
     Blueprint, VT323 for the ZX title — so the theme costs no extra request.
     IBM Plex Mono would be the authentic one and is deliberately NOT here: a
     sixth @import is paid by every page in every theme, and Share Tech Mono is
     a terminal face with normal metrics. VT323 stays exactly where the ZX
     theme learned it belongs — the title, never the 10-13px body. */
  --font: 'Share Tech Mono', ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
  --mono: 'Share Tech Mono', ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;

  /* Phosphor. --white is the intensified green too: it is the button text, and
     a pure white one would be the only non-phosphor thing on the screen. */
  --text:#33e878;
  --muted:#1fae5a;
  --muted-2:#178a47;
  --muted-3:#12793c;
  --muted-4:#1fae5a;
  --label:#e8fff2;
  --tag-text:#8fe8b4;
  --term-text:#33e878;
  --text-b:#e8fff2;
  --text-c:#8fe8b4;
  --text-d:#8fe8b4;
  --white:#e8fff2;

  /* CLAUDE.md says green is out as an accent because it collides with --ok, and
     it is right everywhere but here: this is the one theme where green is not a
     signal but the colour of the screen itself, so a green number no longer
     reads as "good" on its own. The 3270 answer to that is intensity, not hue —
     an intensified field is how the terminal said "look at this" — so the --ok
     solids, and only the solids, become the intensified white-green. The
     backgrounds and borders of the --ok ladder keep their alphas, and --danger
     (red), --warn (yellow) and --info (turquoise) are untouched: those three
     already ARE the 3279 palette and they still carry the meaning. */
  --ok-solid:#b6ffd2;
  --ok-b-solid:#b6ffd2;
  --ok-c-solid:#b6ffd2;
  --ok-d-solid:#d7ffe8;
  --ok-e-solid:#b6ffd2;

  /* The accent: intensified phosphor. Alphas untouched, only the RGB triple. */
  --red: #33ff66;
  --red2: #8cffb0;
  --red-03: rgba(51,255,102,0.03);
  --red-04: rgba(51,255,102,0.04);
  --red-05: rgba(51,255,102,0.05);
  --red-06: rgba(51,255,102,0.06);
  --red-07: rgba(51,255,102,0.07);
  --red-08: rgba(51,255,102,0.08);
  --red-10: rgba(51,255,102,0.1);
  --red-12: rgba(51,255,102,0.12);
  --red-14: rgba(51,255,102,0.14);
  --red-16: rgba(51,255,102,0.16);
  --red-18: rgba(51,255,102,0.18);
  --red-20: rgba(51,255,102,0.2);
  --red-22: rgba(51,255,102,0.22);
  --red-28: rgba(51,255,102,0.28);
  --red-30: rgba(51,255,102,0.3);
  --red-35: rgba(51,255,102,0.35);
  --red-40: rgba(51,255,102,0.4);
  --red-45: rgba(51,255,102,0.45);
  --red-55: rgba(51,255,102,0.55);
  --red-60: rgba(51,255,102,0.6);
  --red-70: rgba(51,255,102,0.7);
  --red-95: rgba(51,255,102,0.95);
  --red-b-10: rgba(140,255,176,0.1);
  --red-b-25: rgba(140,255,176,0.25);
  --red-b-50: rgba(140,255,176,0.5);
  --red-c-20: rgba(180,255,205,0.2);
  --red-c-35: rgba(180,255,205,0.35);
  --red-d-15: rgba(51,255,102,0.15);
  --red-dark-18: rgba(24,160,70,0.18);
  --red-dark-60: rgba(24,160,70,0.6);
  --red-dark2-35: rgba(18,130,56,0.35);
  --red-e-85: rgba(160,255,190,0.85);
  --red-15: rgba(51,255,102,.15);
  --red-25: rgba(51,255,102,.25);
  --red-b-85: rgba(140,255,176,.85);
  --red-e-90: rgba(160,255,190,.9);
  --red-e-95: rgba(160,255,190,.95);
  --red-f-solid: #5cff8f;
  --red-b-70: rgba(140,255,176,.7);
  --red-deep-solid: #0d7a33;

  /* The reactor, which this theme turns into the cursor. */
  --rc-a-15: rgba(51,255,102,0.15);
  --rc-a-60: rgba(51,255,102,0.6);
  --rc-a-85: rgba(51,255,102,0.85);
  --rc-b-35: rgba(0,180,80,0.35);
  --rc-b-50: rgba(0,180,80,0.5);
  --rc-c-18: rgba(140,255,176,0.18);
  --rc-c-95: rgba(140,255,176,0.95);
  --rc-cold: #00331a;
  --rc-d-12: rgba(90,255,140,0.12);
  --rc-d-70: rgba(90,255,140,0.7);
  --rc-e-90: rgba(51,255,102,0.9);
  --rc-f-50: rgba(51,255,102,0.5);
  --rc-g-100: rgba(160,255,190,1.0);
  --rc-h-80: rgba(0,200,90,0.8);
  --rc-hot: #ccffdd;
  --rc-mid: #00ff66;

  /* Overlays: on a terminal every hairline is phosphor, not white. */
  --ov-01: rgba(51,255,102,0.01);
  --ov-02: rgba(51,255,102,0.02);
  --ov-03: rgba(51,255,102,0.03);
  --ov-04: rgba(51,255,102,0.04);
  --ov-05: rgba(51,255,102,0.05);
  --ov-06: rgba(51,255,102,0.06);
  --ov-07: rgba(51,255,102,0.07);
  --ov-08: rgba(51,255,102,0.08);
  --ov-09: rgba(51,255,102,0.09);
  --ov-10: rgba(51,255,102,0.1);
  --ov-12: rgba(51,255,102,0.12);
  --ov-15: rgba(51,255,102,0.15);
  --ov-25: rgba(51,255,102,0.25);
  --ov-35: rgba(51,255,102,0.35);
  --ov-45: rgba(51,255,102,0.45);
  --ov-50: rgba(51,255,102,0.5);
  --ov-85: rgba(51,255,102,0.85);
  /* Shared with the Blue and Red variants: the structural section paints with
     these instead of literals (2026-09-21), so the three differ only here. */
  --i3270-rgb: 51,255,102;
  --i3270-hi: #e8fff2;
  --i3270-menu: #010803;
  --i3270-err: #ffb4b4;
}
/* ═══════════════════════════════════════════════════════════════════════════
   THEME — IBM 3270 (Blue) and IBM 3270 (Red)
   The same terminal on the 3279's other two guns. Token blocks only, generated
   from the green one role by role; the structural section is shared with the
   green theme ([data-theme^="ibm3270"]) and paints with the --i3270-* tokens.
   ═══════════════════════════════════════════════════════════════════════════ */
:root[data-theme="ibm3270_blue"]{
  /* Generated from the green block with the same roles: every colour was
     re-derived for this hue at a target contrast on black (i3270 palette,
     2026-09-21) — accent 8.5:1, body 9.5:1, captions 6:1, small print 4.6:1,
     intensified 18.5:1 — so the screen keeps its colour instead of the pastel
     an equal-luminance copy of the green gives. */
  --bg0:#000000;
  --bg1:#000000;
  --panel: rgba(0,9,31,.42);
  --panel-solid:#000511;
  --option-bg:#00091f;
  --line: rgba(123,163,255,.22);

  /* Nothing on a CRT casts a shadow. What looks like one is the bloom. */
  --shadow: 0 0 22px rgba(123,163,255,.05);
  --shadow2: 0 0 34px rgba(123,163,255,.07);
  --radius: 0px;

  /* The faces are the two this file already loads — Share Tech Mono for
     Blueprint, VT323 for the ZX title — so the theme costs no extra request.
     IBM Plex Mono would be the authentic one and is deliberately NOT here: a
     sixth @import is paid by every page in every theme, and Share Tech Mono is
     a terminal face with normal metrics. VT323 stays exactly where the ZX
     theme learned it belongs — the title, never the 10-13px body. */
  --font: 'Share Tech Mono', ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
  --mono: 'Share Tech Mono', ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;

  /* Phosphor. --white is the intensified blue too: it is the button text, and
     a pure white one would be the only non-phosphor thing on the screen. */
  --text:#8aadff;
  --muted:#5685f1;
  --muted-2:#366def;
  --muted-3:#2461ed;
  --muted-4:#5685f1;
  --label:#eaf1ff;
  --tag-text:#b0c8ff;
  --term-text:#8aadff;
  --text-b:#eaf1ff;
  --text-c:#b0c8ff;
  --text-d:#b0c8ff;
  --white:#eaf1ff;


  /* The accent: intensified phosphor. Alphas untouched, only the RGB triple. */
  --red: #7ba3ff;
  --red2: #aac3ff;
  --red-03: rgba(123,163,255,0.03);
  --red-04: rgba(123,163,255,0.04);
  --red-05: rgba(123,163,255,0.05);
  --red-06: rgba(123,163,255,0.06);
  --red-07: rgba(123,163,255,0.07);
  --red-08: rgba(123,163,255,0.08);
  --red-10: rgba(123,163,255,0.1);
  --red-12: rgba(123,163,255,0.12);
  --red-14: rgba(123,163,255,0.14);
  --red-16: rgba(123,163,255,0.16);
  --red-18: rgba(123,163,255,0.18);
  --red-20: rgba(123,163,255,0.2);
  --red-22: rgba(123,163,255,0.22);
  --red-28: rgba(123,163,255,0.28);
  --red-30: rgba(123,163,255,0.3);
  --red-35: rgba(123,163,255,0.35);
  --red-40: rgba(123,163,255,0.4);
  --red-45: rgba(123,163,255,0.45);
  --red-55: rgba(123,163,255,0.55);
  --red-60: rgba(123,163,255,0.6);
  --red-70: rgba(123,163,255,0.7);
  --red-95: rgba(123,163,255,0.95);
  --red-b-10: rgba(170,195,255,0.1);
  --red-b-25: rgba(170,195,255,0.25);
  --red-b-50: rgba(170,195,255,0.5);
  --red-c-20: rgba(176,200,255,0.2);
  --red-c-35: rgba(176,200,255,0.35);
  --red-d-15: rgba(123,163,255,0.15);
  --red-dark-18: rgba(86,133,241,0.18);
  --red-dark-60: rgba(86,133,241,0.6);
  --red-dark2-35: rgba(36,97,237,0.35);
  --red-e-85: rgba(170,195,255,0.85);
  --red-15: rgba(123,163,255,.15);
  --red-25: rgba(123,163,255,.25);
  --red-b-85: rgba(170,195,255,.85);
  --red-e-90: rgba(170,195,255,.9);
  --red-e-95: rgba(170,195,255,.95);
  --red-f-solid: #97b6ff;
  --red-b-70: rgba(170,195,255,.7);
  --red-deep-solid: #003ac3;

  /* The reactor, which this theme turns into the cursor. */
  --rc-a-15: rgba(123,163,255,0.15);
  --rc-a-60: rgba(123,163,255,0.6);
  --rc-a-85: rgba(123,163,255,0.85);
  --rc-b-35: rgba(86,133,241,0.35);
  --rc-b-50: rgba(86,133,241,0.5);
  --rc-c-18: rgba(170,195,255,0.18);
  --rc-c-95: rgba(170,195,255,0.95);
  --rc-cold: #001d61;
  --rc-d-12: rgba(151,182,255,0.12);
  --rc-d-70: rgba(151,182,255,0.7);
  --rc-e-90: rgba(123,163,255,0.9);
  --rc-f-50: rgba(123,163,255,0.5);
  --rc-g-100: rgba(170,195,255,1.0);
  --rc-h-80: rgba(123,163,255,0.8);
  --rc-hot: #d4e1ff;
  --rc-mid: #7ba3ff;

  /* Overlays: on a terminal every hairline is phosphor, not white. */
  --ov-01: rgba(123,163,255,0.01);
  --ov-02: rgba(123,163,255,0.02);
  --ov-03: rgba(123,163,255,0.03);
  --ov-04: rgba(123,163,255,0.04);
  --ov-05: rgba(123,163,255,0.05);
  --ov-06: rgba(123,163,255,0.06);
  --ov-07: rgba(123,163,255,0.07);
  --ov-08: rgba(123,163,255,0.08);
  --ov-09: rgba(123,163,255,0.09);
  --ov-10: rgba(123,163,255,0.1);
  --ov-12: rgba(123,163,255,0.12);
  --ov-15: rgba(123,163,255,0.15);
  --ov-25: rgba(123,163,255,0.25);
  --ov-35: rgba(123,163,255,0.35);
  --ov-45: rgba(123,163,255,0.45);
  --ov-50: rgba(123,163,255,0.5);
  --ov-85: rgba(123,163,255,0.85);
  /* Shared with the Blue and Red variants: the structural section paints with
     these instead of literals (2026-09-21), so the three differ only here. */
  --i3270-rgb: 123,163,255;
  --i3270-hi: #eaf1ff;
  --i3270-menu: #00030b;
  --i3270-err: #ffb4b4;

  /* Blue is the screen here, so the state that IS blue collides: --info. The
     3270 answer is the one the green theme uses for --ok — intensity, not hue —
     so the info solids become the intensified white-blue. --ok (green), --warn
     (yellow) and --danger (red) keep their colours and their meaning. */
  --info-solid: #d4e1ff;
  --info-b-solid: #d4e1ff;
  --info-c-solid: #d4e1ff;
}
:root[data-theme="ibm3270_red"]{
  /* Generated from the green block with the same roles: every colour was
     re-derived for this hue at a target contrast on black (i3270 palette,
     2026-09-21) — accent 8.5:1, body 9.5:1, captions 6:1, small print 4.6:1,
     intensified 18.5:1 — so the screen keeps its colour instead of the pastel
     an equal-luminance copy of the green gives. */
  --bg0:#000000;
  --bg1:#000000;
  --panel: rgba(30,1,0,.42);
  --panel-solid:#130100;
  --option-bg:#1e0100;
  --line: rgba(255,126,121,.22);

  /* Nothing on a CRT casts a shadow. What looks like one is the bloom. */
  --shadow: 0 0 22px rgba(255,126,121,.05);
  --shadow2: 0 0 34px rgba(255,126,121,.07);
  --radius: 0px;

  /* The faces are the two this file already loads — Share Tech Mono for
     Blueprint, VT323 for the ZX title — so the theme costs no extra request.
     IBM Plex Mono would be the authentic one and is deliberately NOT here: a
     sixth @import is paid by every page in every theme, and Share Tech Mono is
     a terminal face with normal metrics. VT323 stays exactly where the ZX
     theme learned it belongs — the title, never the 10-13px body. */
  --font: 'Share Tech Mono', ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
  --mono: 'Share Tech Mono', ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;

  /* Phosphor. --white is the intensified red too: it is the button text, and
     a pure white one would be the only non-phosphor thing on the screen. */
  --text:#ff8e8a;
  --muted:#f0514b;
  --muted-2:#e81a13;
  --muted-3:#d61811;
  --muted-4:#f0514b;
  --label:#ffecec;
  --tag-text:#ffb5b2;
  --term-text:#ff8e8a;
  --text-b:#ffecec;
  --text-c:#ffb5b2;
  --text-d:#ffb5b2;
  --white:#ffecec;


  /* The accent: intensified phosphor. Alphas untouched, only the RGB triple. */
  --red: #ff7e79;
  --red2: #ffafac;
  --red-03: rgba(255,126,121,0.03);
  --red-04: rgba(255,126,121,0.04);
  --red-05: rgba(255,126,121,0.05);
  --red-06: rgba(255,126,121,0.06);
  --red-07: rgba(255,126,121,0.07);
  --red-08: rgba(255,126,121,0.08);
  --red-10: rgba(255,126,121,0.1);
  --red-12: rgba(255,126,121,0.12);
  --red-14: rgba(255,126,121,0.14);
  --red-16: rgba(255,126,121,0.16);
  --red-18: rgba(255,126,121,0.18);
  --red-20: rgba(255,126,121,0.2);
  --red-22: rgba(255,126,121,0.22);
  --red-28: rgba(255,126,121,0.28);
  --red-30: rgba(255,126,121,0.3);
  --red-35: rgba(255,126,121,0.35);
  --red-40: rgba(255,126,121,0.4);
  --red-45: rgba(255,126,121,0.45);
  --red-55: rgba(255,126,121,0.55);
  --red-60: rgba(255,126,121,0.6);
  --red-70: rgba(255,126,121,0.7);
  --red-95: rgba(255,126,121,0.95);
  --red-b-10: rgba(255,175,172,0.1);
  --red-b-25: rgba(255,175,172,0.25);
  --red-b-50: rgba(255,175,172,0.5);
  --red-c-20: rgba(255,181,178,0.2);
  --red-c-35: rgba(255,181,178,0.35);
  --red-d-15: rgba(255,126,121,0.15);
  --red-dark-18: rgba(240,81,75,0.18);
  --red-dark-60: rgba(240,81,75,0.6);
  --red-dark2-35: rgba(214,24,17,0.35);
  --red-e-85: rgba(255,175,172,0.85);
  --red-15: rgba(255,126,121,.15);
  --red-25: rgba(255,126,121,.25);
  --red-b-85: rgba(255,175,172,.85);
  --red-e-90: rgba(255,175,172,.9);
  --red-e-95: rgba(255,175,172,.95);
  --red-f-solid: #ff9c99;
  --red-b-70: rgba(255,175,172,.7);
  --red-deep-solid: #9a0500;

  /* The reactor, which this theme turns into the cursor. */
  --rc-a-15: rgba(255,126,121,0.15);
  --rc-a-60: rgba(255,126,121,0.6);
  --rc-a-85: rgba(255,126,121,0.85);
  --rc-b-35: rgba(240,81,75,0.35);
  --rc-b-50: rgba(240,81,75,0.5);
  --rc-c-18: rgba(255,175,172,0.18);
  --rc-c-95: rgba(255,175,172,0.95);
  --rc-cold: #500300;
  --rc-d-12: rgba(255,156,153,0.12);
  --rc-d-70: rgba(255,156,153,0.7);
  --rc-e-90: rgba(255,126,121,0.9);
  --rc-f-50: rgba(255,126,121,0.5);
  --rc-g-100: rgba(255,175,172,1.0);
  --rc-h-80: rgba(255,126,121,0.8);
  --rc-hot: #ffd8d6;
  --rc-mid: #ff7e79;

  /* Overlays: on a terminal every hairline is phosphor, not white. */
  --ov-01: rgba(255,126,121,0.01);
  --ov-02: rgba(255,126,121,0.02);
  --ov-03: rgba(255,126,121,0.03);
  --ov-04: rgba(255,126,121,0.04);
  --ov-05: rgba(255,126,121,0.05);
  --ov-06: rgba(255,126,121,0.06);
  --ov-07: rgba(255,126,121,0.07);
  --ov-08: rgba(255,126,121,0.08);
  --ov-09: rgba(255,126,121,0.09);
  --ov-10: rgba(255,126,121,0.1);
  --ov-12: rgba(255,126,121,0.12);
  --ov-15: rgba(255,126,121,0.15);
  --ov-25: rgba(255,126,121,0.25);
  --ov-35: rgba(255,126,121,0.35);
  --ov-45: rgba(255,126,121,0.45);
  --ov-50: rgba(255,126,121,0.5);
  --ov-85: rgba(255,126,121,0.85);
  /* Shared with the Blue and Red variants: the structural section paints with
     these instead of literals (2026-09-21), so the three differ only here. */
  --i3270-rgb: 255,126,121;
  --i3270-hi: #ffecec;
  --i3270-menu: #0e0000;
  --i3270-err: #ffecec;

  /* Red is the screen here, so the state that IS red collides: --danger. As the
     green theme does for --ok, the danger solid becomes the intensified
     white-red, and .qci-error's text (--i3270-err) with it: an error reads as a
     lit field, not as more of the same red. --ok (green), --warn (yellow) and
     --info (turquoise) keep their colours and their meaning. */
  --danger: #ffd8d6;
  --error-text: #ffd8d6;
}
/* ═══════════════════════════════════════════════════════════════════════════
   THEME — Red Quito
   Light, in red / white / black / greys, after Fujitsu's look.

   It works by redefining the :root tokens. An attribute selector ([data-theme])
   has higher specificity than a class, so these rules beat those in the pages'
   <style> blocks regardless of load order — that is what allows theming the site
   without rewriting every one of them.

   The HUD effects are kept but heavily toned down, and in grey instead of red:
   on white, neon at full intensity smears and hurts legibility.
   ═══════════════════════════════════════════════════════════════════════════ */
:root[data-theme="red_quito"],
:root[data-theme="blue_quito"],
:root[data-theme="zx_spectrum"],
/* Windows 3.11 is in this selector for the TOKENS only: it does not join the
   grouped structural rules further down (those are the Fujitsu look) and
   repaints the chrome in its own section at the end of the file. */
:root[data-theme="win311"],
/* Windows XP likewise: the tokens only, its own structural section at the end. */
:root[data-theme="winxp"],
/* Windows Vista likewise: the tokens only, its own structural section at the
   end. Its window bodies are near-white, so the shared greys and state solids
   — which were calibrated for white — need no darkening here. */
:root[data-theme="vista"],
/* MacOS 27 (Light) likewise: the tokens only, and a structural
   section at the end that it shares with its dark half. Its window bodies are
   86% white, so the shared greys and state solids hold AA here too. */
:root[data-theme="macos27_light"],
/* Paper Site likewise: the tokens only, its own structural section at the end.
   It redefines the greys and state solids for its cream paper. */
:root[data-theme="paper_site"]{
  /* ── 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;

  /* Idem, para o tema claro. */
  --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;

  /* 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;
}

/* Each light theme's accent. It is the only thing that distinguishes them. */
:root[data-theme="red_quito"]{
  --accent-glow: rgba(230,0,39,.05);
  --red: #e60027;
  --red2: #b3001f;
  --rc-a-15: rgba(230,0,39,.22);
  --rc-a-60: rgba(230,0,39,.6);
  --rc-a-85: rgba(230,0,39,.85);
  --rc-b-35: rgba(179,0,31,.52);
  --rc-b-50: rgba(179,0,31,.5);
  --rc-c-18: rgba(230,0,39,.27);
  --rc-c-95: rgba(230,0,39,.95);
  --rc-cold: #8c0018;
  --rc-d-12: rgba(230,0,39,.18);
  --rc-d-70: rgba(230,0,39,.7);
  --rc-e-90: rgba(230,0,39,.9);
  --rc-f-50: rgba(230,0,39,.5);
  --rc-g-100: rgba(230,0,39,1);
  --rc-h-80: rgba(179,0,31,.8);
  --rc-hot: #ff6b6b;
  --rc-mid: #e60027;
  --red-03: rgba(230,0,39,.04);
  --red-04: rgba(230,0,39,.06);
  --red-05: rgba(230,0,39,.08);
  --red-06: rgba(230,0,39,.09);
  --red-07: rgba(230,0,39,.11);
  --red-08: rgba(230,0,39,.12);
  --red-10: rgba(230,0,39,.15);
  --red-12: rgba(230,0,39,.18);
  --red-14: rgba(230,0,39,.21);
  --red-16: rgba(230,0,39,.24);
  --red-18: rgba(230,0,39,.27);
  --red-20: rgba(230,0,39,.3);
  --red-22: rgba(230,0,39,.33);
  --red-28: rgba(230,0,39,.42);
  --red-30: rgba(230,0,39,.45);
  --red-35: rgba(230,0,39,.52);
  --red-40: rgba(230,0,39,.6);
  --red-45: rgba(230,0,39,.68);
  --red-55: rgba(230,0,39,.55);
  --red-60: rgba(230,0,39,.6);
  --red-70: rgba(230,0,39,.7);
  --red-95: rgba(230,0,39,.95);
  --red-b-10: rgba(230,0,39,.15);
  --red-b-25: rgba(230,0,39,.38);
  --red-b-50: rgba(230,0,39,.5);
  --red-d-15: rgba(230,0,39,.22);
  --red-dark-18: rgba(179,0,31,.27);
  --red-dark-60: rgba(179,0,31,.6);
  --red-dark2-35: rgba(179,0,31,.52);
  --red-e-85: rgba(230,0,39,.85);
  --red-15: rgba(230,0,39,.22);
  --red-25: rgba(230,0,39,.38);
  --red-b-85: rgba(230,0,39,.85);
  --red-e-90: rgba(230,0,39,.9);
  --red-e-95: rgba(230,0,39,.95);
  --red-b-70: rgba(230,0,39,.7);
}

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

/* ZX Spectrum 128K accent: the Spectrum's cyan, darkened to meet the AA contrast
   target (4.5:1) on white. --rc-hot keeps the "pure" bright cyan because it only
   appears in the reactor's glow, with no text on top. --font/--mono are a
   deliberate exception to the "new theme = colour tokens only" rule: this theme
   asks for a terminal font in the body text too — Share Tech Mono, not the pixel
   one. VT323 is title-only, for the reason written over the token block below. */
:root[data-theme="zx_spectrum"]{
  --accent-glow: rgba(6,122,145,.05);
  --red: #067a91;
  --red2: #045a6c;
  --rc-a-15: rgba(6,122,145,.22);
  --rc-a-60: rgba(6,122,145,.6);
  --rc-a-85: rgba(6,122,145,.85);
  --rc-b-35: rgba(4,90,108,.52);
  --rc-b-50: rgba(4,90,108,.5);
  --rc-c-18: rgba(6,122,145,.27);
  --rc-c-95: rgba(6,122,145,.95);
  --rc-cold: #023544;
  --rc-d-12: rgba(6,122,145,.18);
  --rc-d-70: rgba(6,122,145,.7);
  --rc-e-90: rgba(6,122,145,.9);
  --rc-f-50: rgba(6,122,145,.5);
  --rc-g-100: rgba(6,122,145,1);
  --rc-h-80: rgba(4,90,108,.8);
  --rc-hot: #00e5ff;
  --rc-mid: #067a91;
  --red-03: rgba(6,122,145,.04);
  --red-04: rgba(6,122,145,.06);
  --red-05: rgba(6,122,145,.08);
  --red-06: rgba(6,122,145,.09);
  --red-07: rgba(6,122,145,.11);
  --red-08: rgba(6,122,145,.12);
  --red-10: rgba(6,122,145,.15);
  --red-12: rgba(6,122,145,.18);
  --red-14: rgba(6,122,145,.21);
  --red-16: rgba(6,122,145,.24);
  --red-18: rgba(6,122,145,.27);
  --red-20: rgba(6,122,145,.3);
  --red-22: rgba(6,122,145,.33);
  --red-28: rgba(6,122,145,.42);
  --red-30: rgba(6,122,145,.45);
  --red-35: rgba(6,122,145,.52);
  --red-40: rgba(6,122,145,.6);
  --red-45: rgba(6,122,145,.68);
  --red-55: rgba(6,122,145,.55);
  --red-60: rgba(6,122,145,.6);
  --red-70: rgba(6,122,145,.7);
  --red-95: rgba(6,122,145,.95);
  --red-b-10: rgba(6,122,145,.15);
  --red-b-25: rgba(6,122,145,.38);
  --red-b-50: rgba(6,122,145,.5);
  --red-d-15: rgba(6,122,145,.22);
  --red-dark-18: rgba(4,90,108,.27);
  --red-dark-60: rgba(4,90,108,.6);
  --red-dark2-35: rgba(4,90,108,.52);
  --red-e-85: rgba(6,122,145,.85);
  --red-15: rgba(6,122,145,.22);
  --red-25: rgba(6,122,145,.38);
  --red-b-85: rgba(6,122,145,.85);
  --red-e-90: rgba(6,122,145,.9);
  --red-e-95: rgba(6,122,145,.95);
  --red-b-70: rgba(6,122,145,.7);
}
:root[data-theme="zx_spectrum"]{
  /* The body font is Share Tech Mono — a terminal face with normal metrics, and
     already loaded for Blueprint's titles, so it costs no request.

     It was VT323 until 2026-09-09, and VT323 in the body is what this theme has
     to keep away from: one weight, a low x-height, and at the 10-13px the dense
     pages use (card captions, table cells, .qci-label, .qci-tag) it is not
     readable. It also read so much smaller than every other font that the theme
     carried a 19px root plus twenty-four rules re-sizing classes and inline
     style= attributes, and a standing rule that a new px value on a page had to
     be added to that list by hand. All of it is gone, replaced by the zoom below.
     The pixel font stays where it is legible and where the reference image puts
     it — the title, see .qci-title in this theme's section below. */
  --font: 'Share Tech Mono', ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
  --mono: 'Share Tech Mono', ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;

  /* This theme runs 20% larger than the other eight, on the owner's request, and
     ONE declaration does it.

     A root font-size cannot: the pages carry 469 inline font-sizes in rem and 234
     in px, plus the px values in this file's own classes, so raising the root
     grows two thirds of the text and leaves the rest behind. Papering over that
     gap is exactly what the twenty-four deleted rules were, list of px values and
     all. zoom scales the whole rendering — every px, every rem, the paddings
     between them — so nothing here has to know what a page wrote inline, and a
     new page needs no entry anywhere.

     Checked before choosing it: media queries stay viewport-based, so the phone
     layer still switches at 820px and has no sideways overflow at 360-780px, and
     above 820px the horizontal overflow is the same .qci-sweep every theme has
     (2160 unzoomed vs 2164 zoomed at 1600px). The fixed rainbow strip still spans
     the full width. The signal charts are SVG (ts_chart.js) and scale cleanly.
     The cost is the few canvas charts (Chart.js, qai_orbit.js): they are resampled
     by the zoom rather than redrawn at its scale, so they are slightly softer in
     this theme. That is the whole trade, and it was worth it for the text. */
  zoom: 1.2;

  /* Grey background with the light cards on top, like the +3e's screen: the card
     separates from the background by contrast, not by shadow. --panel stays white. */
  --bg0: #cdcdcd;
  --bg1: #c0c0c0;
  /* The common block's text greys were calibrated for a WHITE background and drop
     to 3.8:1 on this grey. Darkened here to meet the project's AA target (4.5:1)
     in both places: 4.9:1 on the background, 7.9:1 in the card. */
  --muted:   #4c525d;
  --muted-2: #4c525d;
  --muted-3: #4c525d;
  --muted-4: #4c525d;

  /* The Spectrum's literal palette, only for this theme's decorations (top bar,
     header diagonals, selected highlight). They do not replace the accent — that
     is still the --red-* family. */
  --zx-red:    #ff0000;
  --zx-yellow: #ffff00;
  --zx-green:  #00ff00;
  --zx-cyan:   #00ffff;
  --zx-ink:    #000000;
  --zx-paper:  #ffffff;
  --zx-dim:    #b9c0c8;
  --zx-on-ink-10: rgba(255,255,255,.10);
  --zx-on-ink-25: rgba(255,255,255,.25);
}

/* Windows 3.11 accent: the active title-bar navy, rgb(0,0,128). Same token
   names and alpha ladder as the other light accents; the "-dark" variants and
   --rc-b/--rc-h use rgb(0,0,96). --rc-hot is a pale navy that only ever shows
   in the reactor's glow — and this theme hides the rings anyway. */
:root[data-theme="win311"]{
  --accent-glow: rgba(0,0,128,.05);
  --red: #000080;
  --red2: #000060;
  --rc-a-15: rgba(0,0,128,.22);
  --rc-a-60: rgba(0,0,128,.6);
  --rc-a-85: rgba(0,0,128,.85);
  --rc-b-35: rgba(0,0,96,.52);
  --rc-b-50: rgba(0,0,96,.5);
  --rc-c-18: rgba(0,0,128,.27);
  --rc-c-95: rgba(0,0,128,.95);
  --rc-cold: #000040;
  --rc-d-12: rgba(0,0,128,.18);
  --rc-d-70: rgba(0,0,128,.7);
  --rc-e-90: rgba(0,0,128,.9);
  --rc-f-50: rgba(0,0,128,.5);
  --rc-g-100: rgba(0,0,128,1);
  --rc-h-80: rgba(0,0,96,.8);
  --rc-hot: #8080ff;
  --rc-mid: #000080;
  --red-03: rgba(0,0,128,.04);
  --red-04: rgba(0,0,128,.06);
  --red-05: rgba(0,0,128,.08);
  --red-06: rgba(0,0,128,.09);
  --red-07: rgba(0,0,128,.11);
  --red-08: rgba(0,0,128,.12);
  --red-10: rgba(0,0,128,.15);
  --red-12: rgba(0,0,128,.18);
  --red-14: rgba(0,0,128,.21);
  --red-16: rgba(0,0,128,.24);
  --red-18: rgba(0,0,128,.27);
  --red-20: rgba(0,0,128,.3);
  --red-22: rgba(0,0,128,.33);
  --red-28: rgba(0,0,128,.42);
  --red-30: rgba(0,0,128,.45);
  --red-35: rgba(0,0,128,.52);
  --red-40: rgba(0,0,128,.6);
  --red-45: rgba(0,0,128,.68);
  --red-55: rgba(0,0,128,.55);
  --red-60: rgba(0,0,128,.6);
  --red-70: rgba(0,0,128,.7);
  --red-95: rgba(0,0,128,.95);
  --red-b-10: rgba(0,0,128,.15);
  --red-b-25: rgba(0,0,128,.38);
  --red-b-50: rgba(0,0,128,.5);
  --red-d-15: rgba(0,0,128,.22);
  --red-dark-18: rgba(0,0,96,.27);
  --red-dark-60: rgba(0,0,96,.6);
  --red-dark2-35: rgba(0,0,96,.52);
  --red-e-85: rgba(0,0,128,.85);
  --red-15: rgba(0,0,128,.22);
  --red-25: rgba(0,0,128,.38);
  --red-b-85: rgba(0,0,128,.85);
  --red-e-90: rgba(0,0,128,.9);
  --red-e-95: rgba(0,0,128,.95);
  --red-b-70: rgba(0,0,128,.7);
}
:root[data-theme="win311"]{
  /* System fonts only, no import: Tahoma is the Windows UI face, the rest is
     the fallback chain down to whatever the OS maps Arial to. Lucida Console
     goes first in --mono because Courier New's hairlines do not survive the
     12px the tabs, the menu items and .qci-terminal use. The pixel font
     (Pixelify Sans) is title-only — see .qci-title in this theme's section. */
  --font: Tahoma, 'MS Sans Serif', 'Microsoft Sans Serif', Verdana, Arial, sans-serif;
  --mono: 'Lucida Console', Consolas, 'Courier New', Courier, ui-monospace, monospace;

  /* The desktop is flat teal; the windows are the grey. Both --bg tokens are
     the same colour so nothing on any page can gradient between them. --panel
     is opaque, so family_calendar.php's sticky .tg-time-col needs nothing. */
  --bg0: #008080;
  --bg1: #008080;
  --panel: #c0c0c0;
  --panel-solid: #c0c0c0;
  --line: #808080;

  /* Nothing is round and nothing floats: the depth comes from the bevels. */
  --radius: 0px;
  --shadow: 0 0 0 0 transparent;
  --shadow2: 0 0 0 0 transparent;

  /* Text. The common block's greys were calibrated for white and drop to
     3.3:1 on #c0c0c0; #404040 is 5.7:1 on the grey and 10.4:1 in a white field. */
  --text: #000000;
  --text-b: #000000;
  --muted:   #404040;
  --muted-2: #404040;
  --muted-3: #404040;
  --muted-4: #404040;
  --label:   #404040;
  --grey-a:  #404040;
  --grey-b:  #404040;
  --grey-c:  #404040;
  --tag-text: #000000;
  --term-text: #000000;

  /* State colours used as TEXT: the common block's values (#15803d, #b45309,
     #0e7490, #dc2626, #7e22ce) are 2.6-3.8:1 on this grey. Same hue, darker,
     all >= 4.5:1 on #c0c0c0. The alpha variants (backgrounds, borders) stay. */
  --ok-solid:   #14532d;
  --ok-b-solid: #14532d;
  --ok-c-solid: #14532d;
  --ok-d-solid: #14532d;
  --ok-e-solid: #14532d;
  --warn-solid:   #7a3700;
  --warn-b-solid: #7a3700;
  --amber-solid:  #7a3700;
  --amber-f-solid: #7a3700;
  --info-solid:   #06505f;
  --info-b-solid: #06505f;
  --info-c-solid: #06505f;
  --info-d-solid: #06505f;
  --danger: #7f1d1d;
  --red-f-solid: #7f1d1d;
  --purple-solid:   #5b1a99;
  --purple-c-solid: #5b1a99;
  --purple-d-solid: #5b1a99;

  /* The Windows 3.1 palette, for this theme's chrome only. Not the accent —
     that is still the --red-* family above. */
  --w31-teal:    #008080;
  --w31-grey:    #c0c0c0;
  --w31-light:   #dfdfdf;
  --w31-dark:    #808080;
  --w31-black:   #000000;
  --w31-white:   #ffffff;
  --w31-navy:    #000080;
  --w31-on-navy: #ffffff;
  --w31-maroon:  #800000;
  --w31-green:   #004a00;

  /* The bevels. Every base class already has a 1px border, so the OUTER ring
     is the border (four colours: top right bottom left) and the INNER ring is
     one inset shadow — pixel for pixel the Windows 3.1 button, with no change
     to any box's size. Raised = light top-left / dark bottom-right; sunken the
     reverse; pressed = dark top-left and nothing else. */
  --w31-edge-raised:  var(--w31-white) var(--w31-black) var(--w31-black) var(--w31-white);
  --w31-raised:       inset -1px -1px 0 var(--w31-dark), inset 1px 1px 0 var(--w31-light);
  --w31-edge-sunken:  var(--w31-dark) var(--w31-white) var(--w31-white) var(--w31-dark);
  --w31-sunken:       inset 1px 1px 0 var(--w31-black), inset -1px -1px 0 var(--w31-light);
  --w31-edge-pressed: var(--w31-black) var(--w31-white) var(--w31-white) var(--w31-black);
  --w31-pressed:      inset 1px 1px 0 var(--w31-dark);
  /* A window: black outline (the border) with the raised ring inside it. */
  --w31-frame:        inset 1px 1px 0 var(--w31-white), inset -1px -1px 0 var(--w31-dark);
  /* A group box: one dark line with a white line offset to its bottom-right. */
  --w31-etched:       inset 1px 1px 0 var(--w31-white), 1px 1px 0 var(--w31-white);
  /* Menus and dialogs cast a hard 2px black shadow, no blur. */
  --w31-menu-shadow:  2px 2px 0 var(--w31-black);
  --w31-focus:        0 0 0 1px var(--w31-navy);
}

/* Windows XP accent: Luna's frame blue, rgb(0,84,227). Same token names and
   alpha ladder as the other light accents; the "-dark" variants and
   --rc-b/--rc-h use rgb(0,60,160). --red2 is #003cb4 (7.5:1 on the beige) so
   the accent-as-text states stay AA. --rc-hot only ever shows in the
   reactor's glow, which this theme hides. */
:root[data-theme="winxp"]{
  --accent-glow: rgba(0,84,227,.05);
  --red: #0054e3;
  --red2: #003cb4;
  --rc-a-15: rgba(0,84,227,.22);
  --rc-a-60: rgba(0,84,227,.6);
  --rc-a-85: rgba(0,84,227,.85);
  --rc-b-35: rgba(0,60,160,.52);
  --rc-b-50: rgba(0,60,160,.5);
  --rc-c-18: rgba(0,84,227,.27);
  --rc-c-95: rgba(0,84,227,.95);
  --rc-cold: #002a80;
  --rc-d-12: rgba(0,84,227,.18);
  --rc-d-70: rgba(0,84,227,.7);
  --rc-e-90: rgba(0,84,227,.9);
  --rc-f-50: rgba(0,84,227,.5);
  --rc-g-100: rgba(0,84,227,1);
  --rc-h-80: rgba(0,60,160,.8);
  --rc-hot: #9ec4ff;
  --rc-mid: #0054e3;
  --red-03: rgba(0,84,227,.04);
  --red-04: rgba(0,84,227,.06);
  --red-05: rgba(0,84,227,.08);
  --red-06: rgba(0,84,227,.09);
  --red-07: rgba(0,84,227,.11);
  --red-08: rgba(0,84,227,.12);
  --red-10: rgba(0,84,227,.15);
  --red-12: rgba(0,84,227,.18);
  --red-14: rgba(0,84,227,.21);
  --red-16: rgba(0,84,227,.24);
  --red-18: rgba(0,84,227,.27);
  --red-20: rgba(0,84,227,.3);
  --red-22: rgba(0,84,227,.33);
  --red-28: rgba(0,84,227,.42);
  --red-30: rgba(0,84,227,.45);
  --red-35: rgba(0,84,227,.52);
  --red-40: rgba(0,84,227,.6);
  --red-45: rgba(0,84,227,.68);
  --red-55: rgba(0,84,227,.55);
  --red-60: rgba(0,84,227,.6);
  --red-70: rgba(0,84,227,.7);
  --red-95: rgba(0,84,227,.95);
  --red-b-10: rgba(0,84,227,.15);
  --red-b-25: rgba(0,84,227,.38);
  --red-b-50: rgba(0,84,227,.5);
  --red-d-15: rgba(0,84,227,.22);
  --red-dark-18: rgba(0,60,160,.27);
  --red-dark-60: rgba(0,60,160,.6);
  --red-dark2-35: rgba(0,60,160,.52);
  --red-e-85: rgba(0,84,227,.85);
  --red-15: rgba(0,84,227,.22);
  --red-25: rgba(0,84,227,.38);
  --red-b-85: rgba(0,84,227,.85);
  --red-e-90: rgba(0,84,227,.9);
  --red-e-95: rgba(0,84,227,.95);
  --red-b-70: rgba(0,84,227,.7);
}
:root[data-theme="winxp"]{
  /* System fonts only, no import: Tahoma is XP's UI face. Lucida Console goes
     first in --mono for the same reason as in Windows 3.11 — Courier New's
     hairlines do not survive 12px. Trebuchet MS is title-only (see .qci-title
     in this theme's section); on Linux it falls back to Tahoma/DejaVu. */
  --font: Tahoma, Verdana, 'Segoe UI', Arial, sans-serif;
  --mono: 'Lucida Console', Consolas, 'Courier New', Courier, ui-monospace, monospace;

  /* The desktop is Bliss, painted by body::before; both --bg tokens are the
     sky's top so nothing on any page can gradient between them. The windows
     are XP's dialog beige, opaque (family_calendar.php's sticky column needs
     nothing). */
  --bg0: #2e6fd0;
  --bg1: #2e6fd0;
  --panel: #ece9d8;
  --panel-solid: #ece9d8;
  --line: #aca899;

  /* Luna is mildly rounded: 3px on controls, 8px on the top corners of a
     window (set per rule in the section). XP windows cast a short soft shadow. */
  --radius: 3px;
  --shadow: 0 1px 2px rgba(0,0,0,.18);
  --shadow2: 0 2px 8px rgba(0,0,0,.28);

  /* Text. The common block's greys were calibrated for white: --muted-2/-3/-4
     and --grey-c (#6a7280) drop to 4.0:1 on the beige. #4d4d4d is 6.9:1 on
     #ece9d8, 8.5:1 in a white field and 6.3:1 on the task-pane blue. */
  --text: #000000;
  --text-b: #000000;
  --muted:   #4d4d4d;
  --muted-2: #4d4d4d;
  --muted-3: #4d4d4d;
  --muted-4: #4d4d4d;
  --label:   #4d4d4d;
  --grey-a:  #4d4d4d;
  --grey-b:  #4d4d4d;
  --grey-c:  #4d4d4d;
  --tag-text: #000000;
  --term-text: #000000;

  /* State colours used as TEXT. On #ece9d8 the common block's #15803d,
     #b45309 and #dc2626 are 4.1, 4.1 and 4.0:1 — below AA. Same hue, darker:
     ok #166534 5.8, warn/amber #9a3412 6.0, danger #b91c1c 5.3 (4.9 on the
     task pane). --info-* (#1d4ed8, 5.5) and --purple-* (#7e22ce, 5.7) already
     pass and are left alone. The alpha variants (backgrounds, borders) stay. */
  --ok-solid:   #166534;
  --ok-b-solid: #166534;
  --ok-c-solid: #166534;
  --ok-d-solid: #166534;
  --ok-e-solid: #166534;
  --warn-solid:   #9a3412;
  --warn-b-solid: #9a3412;
  --amber-solid:  #9a3412;
  --amber-f-solid: #9a3412;
  --danger: #b91c1c;
  --red-f-solid: #b91c1c;

  /* ── The Luna palette, for this theme's chrome only ──────────────────────
     Not the accent — that is still the --red-* family above. */
  --xp-white:   #ffffff;
  --xp-black:   #000000;
  --xp-face:    #ece9d8;   /* dialog face */
  --xp-face-2:  #f1efe2;   /* list header, tags */
  --xp-face-3:  #f6f5ef;   /* tab hover */
  --xp-line:    #aca899;   /* separators, tag and menu borders */
  --xp-line-2:  #919b9c;   /* tab control and card edge */
  --xp-line-3:  #dedbcd;   /* rules between table rows */
  --xp-disabled: #aca899;  /* engraved disabled text */
  --xp-tip:     #ffffe1;   /* tooltip face */
  --xp-navy:    #0a246a;   /* "blue" button text, title shadow */
  --xp-green:   #2d6b16;   /* "green" button text */
  --xp-danger:  #b41e1e;   /* "danger" button text and border */

  /* Window frame and title bar (Luna Blue). The 2px highlight strip at the
     top carries no text; the title sits on #0053ee (white 6.0:1). */
  --xp-frame:        #0054e3;
  --xp-frame-edge:   #0831d9;
  --xp-window-frame: inset 0 0 0 3px var(--xp-frame);
  --xp-title-grad:   linear-gradient(180deg, #3d95ff 0 2px, #0997ff 2px 4px, #0053ee 9px, #0054e3 88%, #0040c0 100%);
  --xp-on-title:     #ffffff;
  --xp-title-shadow: #0a246a;

  /* Caption buttons (the USER / QCIADMINS / Theme pills on the band): blue,
     white inner border, dark outer ring; white is >= 4.7:1 on every stop. */
  --xp-cap-grad:       linear-gradient(180deg, #2a70da 0, #1c5cc1 55%, #174fae 100%);
  --xp-cap-grad-hover: linear-gradient(180deg, #2a70da 0, #245edb 50%, #1f5fd0 100%);
  --xp-cap-edge:       #0a3d8f;
  --xp-close-grad:       linear-gradient(180deg, #e35d3a 0, #d54b2b 50%, #c52d0f 100%);
  --xp-close-grad-hover: linear-gradient(180deg, #f07a5a 0, #e35d3a 50%, #d0391a 100%);
  --xp-close-edge:       #8e2a15;

  /* Push buttons: white-to-beige face, the #003c74 border, the orange hover
     ring (outer strong, inner faded), the pressed face, the blue focus ring. */
  --xp-btn-grad:      linear-gradient(180deg, #ffffff 0, #f4f3ee 50%, #ecebe5 100%);
  --xp-btn-pressed:   #e0dfd9;
  --xp-btn-border:    #003c74;
  --xp-btn-disabled-border: #c9c7ba;
  --xp-hover-1:       #f8b330;
  --xp-hover-2:       #ffc73c;
  --xp-hover-ring:    inset 0 0 0 1px var(--xp-hover-1), inset 0 0 0 2px var(--xp-hover-2);
  --xp-pressed-ring:  inset 1px 1px 2px rgba(0,0,0,.18);
  --xp-focus:         #3d76c4;
  --xp-focus-ring:    inset 0 0 0 2px var(--xp-focus);

  /* Fields, selection, lists, task pane, tabs, menus, tooltips. */
  --xp-field-edge:  #7f9db9;
  --xp-sel:         #316ac5;
  --xp-on-sel:      #ffffff;
  --xp-row-hover:   #e8f0fb;
  --xp-pane:        #d6dff7;
  --xp-pane-edge:   #7ba2e7;
  --xp-tab-hot:     #ffc73c;
  --xp-menu-shadow: 2px 2px 0 rgba(0,0,0,.4);
  --xp-label-shadow: 1px 1px 2px rgba(0,0,0,.85), 0 0 3px rgba(0,0,0,.6);

  /* The icon tile that replaces the reactor. */
  --xp-icon-grad:   linear-gradient(180deg, #3a8ae8 0, #1c5cc1 100%);
  --xp-icon-edge:   #0a3d8f;
  --xp-icon-shadow: 0 1px 2px rgba(0,0,0,.35);
  --xp-gloss:       rgba(255,255,255,.55);
  --xp-gloss-2:     rgba(255,255,255,.25);

  /* The sky, under the Bliss photograph: the canvas and the fallback. */
  --xp-sky-1:   #2e6fd0;
  --xp-sky-2:   #4d93e0;
  --xp-sky-3:   #9dd3f6;
}

/* 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%);
}

/* ═══════════════════════════════════════════════════════════════════════════
   THEME — MacOS 27 (Light)   +   the tokens both halves share

   macOS as of Liquid Glass: windows of frosted, light-bending glass over the
   wallpaper, capsule controls, the system face, and an accent the user picks.
   The wallpaper is an abstract render of folded paper — sand and slate by day,
   indigo by night — supplied by the site's owner (/assets/macos27_light.jpg,
   macos27_dark.jpg: 3840px JPEGs of about 260 KB, down from 22 MB PNGs). The
   accent is International Orange, which sits with the sand by day and is the
   one warm thing on the indigo by night.

   The Dock icon (--mac-icon) is original artwork, a data: URI SVG that echoes
   the wallpaper: three folded sheets with a lit edge, sand and slate by day,
   indigo by night. The CSP allows both: default-src 'self', img-src 'self' data:.
   (The theme first shipped as "Golden Gate", with a wallpaper and an icon of the
   bridge; both are gone, and git history has them.)

   TWO THEMES, ONE STRUCTURAL SECTION. macos27_light is in the shared light
   TOKEN selector above (like the three Windows themes: the tokens only);
   macos27_dark derives from :root and has its block with the dark themes. Both
   then define the same --mac-* chrome tokens, and the "MACOS 27" section at the
   end of the file is written once against :root[data-theme^="macos27"] and
   reads only those. A fix to the chrome lands in both halves; a colour that
   differs between day and night is a token, never a second rule.

   Accent: #f04a00 is 3.7:1 on white, so it is only ever a border, a fill or a
   glow; --red2, the accent-as-text, is #b5380f (5.9:1), and an accent-FILLED
   control uses --mac-fill #c8420f, on which white is 4.95:1. Same token names
   and alpha ladder as the other light accents. Orange sits between --warn
   (amber) and --danger (red); it is kept apart from both by never being used
   for a state — the tags and messages below are restated with the state
   tokens, as in Vista — and by --warn being pulled toward yellow-brown here
   (see the state colours in the block below).
   ═══════════════════════════════════════════════════════════════════════════ */
:root[data-theme="macos27_light"]{
  --accent-glow: rgba(240,74,0,.05);
  --red: #f04a00;
  --red2: #b5380f;
  --rc-a-15: rgba(240,74,0,.22);
  --rc-a-60: rgba(240,74,0,.6);
  --rc-a-85: rgba(240,74,0,.85);
  --rc-b-35: rgba(181,56,15,.52);
  --rc-b-50: rgba(181,56,15,.5);
  --rc-c-18: rgba(240,74,0,.27);
  --rc-c-95: rgba(240,74,0,.95);
  --rc-cold: #5a1c05;
  --rc-d-12: rgba(240,74,0,.18);
  --rc-d-70: rgba(240,74,0,.7);
  --rc-e-90: rgba(240,74,0,.9);
  --rc-f-50: rgba(240,74,0,.5);
  --rc-g-100: rgba(240,74,0,1);
  --rc-h-80: rgba(181,56,15,.8);
  --rc-hot: #ffd2b8;
  --rc-mid: #f04a00;
  --red-03: rgba(240,74,0,.04);
  --red-04: rgba(240,74,0,.06);
  --red-05: rgba(240,74,0,.08);
  --red-06: rgba(240,74,0,.09);
  --red-07: rgba(240,74,0,.11);
  --red-08: rgba(240,74,0,.12);
  --red-10: rgba(240,74,0,.15);
  --red-12: rgba(240,74,0,.18);
  --red-14: rgba(240,74,0,.21);
  --red-16: rgba(240,74,0,.24);
  --red-18: rgba(240,74,0,.27);
  --red-20: rgba(240,74,0,.3);
  --red-22: rgba(240,74,0,.33);
  --red-28: rgba(240,74,0,.42);
  --red-30: rgba(240,74,0,.45);
  --red-35: rgba(240,74,0,.52);
  --red-40: rgba(240,74,0,.6);
  --red-45: rgba(240,74,0,.68);
  --red-55: rgba(240,74,0,.55);
  --red-60: rgba(240,74,0,.6);
  --red-70: rgba(240,74,0,.7);
  --red-95: rgba(240,74,0,.95);
  --red-b-10: rgba(240,74,0,.15);
  --red-b-25: rgba(240,74,0,.38);
  --red-b-50: rgba(240,74,0,.5);
  --red-d-15: rgba(240,74,0,.22);
  --red-dark-18: rgba(181,56,15,.27);
  --red-dark-60: rgba(181,56,15,.6);
  --red-dark2-35: rgba(181,56,15,.52);
  --red-e-85: rgba(240,74,0,.85);
  --red-15: rgba(240,74,0,.22);
  --red-25: rgba(240,74,0,.38);
  --red-b-85: rgba(240,74,0,.85);
  --red-e-90: rgba(240,74,0,.9);
  --red-e-95: rgba(240,74,0,.95);
  --red-b-70: rgba(240,74,0,.7);
}
:root[data-theme="macos27_light"]{
  /* The desktop is the wallpaper, painted by body::before; both --bg tokens are
     its own warm grey (the image averages #988b83), so nothing can gradient
     between them and the fallback is the right colour while the JPEG loads. */
  --bg0: #a89c93;
  --bg1: #a89c93;

  /* A window body. 88% white: the blurred wallpaper still tints it — that is
     the glass. The wallpaper's darkest region is a deep slate, #312d42, and
     over it the glass composites to #e6e6e8; every figure below is measured
     against THAT, not against white. --panel-solid is for a surface with
     nothing behind it. */
  --panel: rgba(255,255,255,.88);
  --panel-solid: #f6f6f8;
  --line: rgba(0,0,0,.10);

  /* ── State colours and greys, darkened for glass ──────────────────────────
     The shared light block calibrated these for WHITE, with little to spare
     (--ok-solid 5.0:1, --danger 4.8:1): on #e6e6e8 they measured 4.0 and 3.9,
     and on a trading site the green and the red are the content. Same twenty
     tokens Windows XP darkens for its beige, for the same reason. Each holds
     4.8:1 or better on the composite. --warn goes to a yellow-brown rather
     than XP's red-brown on purpose: it has to stay apart from the orange
     accent-as-text (--red2 #b5380f, 4.8:1), which a red-brown would not. */
  --muted-2: #59606c;
  --muted-3: #59606c;
  --muted-4: #59606c;
  --grey-a: #59606c;
  --grey-b: #59606c;
  --grey-c: #59606c;
  --verdict-ok-bg:  rgba(21,128,61,.07);
  --verdict-bad-bg: rgba(220,38,38,.08);
  --ok-solid: #15713a;
  --ok-b-solid: #15713a;
  --ok-c-solid: #15713a;
  --ok-d-solid: #15713a;
  --ok-e-solid: #15713a;
  --warn-solid: #8a5300;
  --warn-b-solid: #8a5300;
  --amber-solid: #8a5300;
  --amber-f-solid: #8a5300;
  --danger: #c21f1f;

  /* Windows float: a hairline, and a wide soft drop. */
  --shadow: 0 1px 2px rgba(0,0,0,.08), 0 2px 8px rgba(0,0,0,.06);
  --shadow2: 0 0 0 .5px rgba(0,0,0,.14), 0 14px 44px rgba(20,30,50,.20);

  /* ── The Liquid Glass palette, for this theme's chrome only ──────────────
     Not the accent — that is still the --red-* family above. */
  --mac-wall: url('/assets/macos27_light.jpg?v=1');
  --mac-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 104 104'%3E%3Cdefs%3E%3ClinearGradient id='b' x1='0' y1='0' x2='1' y2='1'%3E%3Cstop offset='0' stop-color='%237a5c48'/%3E%3Cstop offset='1' stop-color='%23c9b7a2'/%3E%3C/linearGradient%3E%3ClinearGradient id='g0' x1='.2' y1='0' x2='.8' y2='1'%3E%3Cstop offset='0' stop-color='%23f3ece1'/%3E%3Cstop offset='1' stop-color='%23b79f86'/%3E%3C/linearGradient%3E%3ClinearGradient id='g1' x1='.2' y1='0' x2='.8' y2='1'%3E%3Cstop offset='0' stop-color='%238d93ad'/%3E%3Cstop offset='1' stop-color='%234b4963'/%3E%3C/linearGradient%3E%3ClinearGradient id='g2' x1='.2' y1='0' x2='.8' y2='1'%3E%3Cstop offset='0' stop-color='%23f4f1ec'/%3E%3Cstop offset='1' stop-color='%23aeb9c4'/%3E%3C/linearGradient%3E%3Cfilter id='s' x='-20%25' y='-20%25' width='140%25' height='140%25'%3E%3CfeGaussianBlur stdDeviation='3.2'/%3E%3C/filter%3E%3C/defs%3E%3Crect width='104' height='104' fill='url%28%23b%29'/%3E%3Cpath d='M-6 70 C22 66 30 34 50 22 C66 12 82 10 110 -4 L110 110 L-6 110Z' fill='%23000' opacity='.28' transform='translate%280 -3%29' filter='url%28%23s%29'/%3E%3Cpath d='M-6 70 C22 66 30 34 50 22 C66 12 82 10 110 -4 L110 110 L-6 110Z' fill='url%28%23g0%29'/%3E%3Cpath d='M-6 70 C22 66 30 34 50 22 C66 12 82 10 110 -4' fill='none' stroke='%23ffffff' stroke-opacity='.95' stroke-width='1.3'/%3E%3Cpath d='M-6 96 C26 92 40 66 58 52 C74 40 90 36 110 22 L110 110 L-6 110Z' fill='%23000' opacity='.28' transform='translate%280 -3%29' filter='url%28%23s%29'/%3E%3Cpath d='M-6 96 C26 92 40 66 58 52 C74 40 90 36 110 22 L110 110 L-6 110Z' fill='url%28%23g1%29'/%3E%3Cpath d='M-6 96 C26 92 40 66 58 52 C74 40 90 36 110 22' fill='none' stroke='%23ffffff' stroke-opacity='.95' stroke-width='1.3'/%3E%3Cpath d='M22 110 C34 92 52 84 70 76 C86 69 98 62 110 50 L110 110Z' fill='%23000' opacity='.28' transform='translate%280 -3%29' filter='url%28%23s%29'/%3E%3Cpath d='M22 110 C34 92 52 84 70 76 C86 69 98 62 110 50 L110 110Z' fill='url%28%23g2%29'/%3E%3Cpath d='M22 110 C34 92 52 84 70 76 C86 69 98 62 110 50' fill='none' stroke='%23ffffff' stroke-opacity='.95' stroke-width='1.3'/%3E%3C/svg%3E");

  /* --mac-bar is the header window: a toolbar, a touch more see-through than
     a document — only a touch: it holds the page's --muted captions, and at
     66% they measured 3.0:1 over the wallpaper's deep slate; at 86% it is
     4.6:1. --mac-edge is the bright rim glass has where it catches light,
     --mac-edge-top the stronger one along the top, --mac-hair the dark
     hairline just outside. */
  --mac-bar:        rgba(255,255,255,.86);
  --mac-blur:       blur(30px) saturate(180%);
  --mac-edge:       rgba(255,255,255,.70);
  --mac-edge-top:   rgba(255,255,255,.95);
  --mac-hair:       rgba(0,0,0,.10);

  /* Controls, at rest / hover / pressed, and "on" for a selected segment. */
  --mac-ctl:        rgba(255,255,255,.74);
  --mac-ctl-hot:    rgba(255,255,255,.98);
  --mac-ctl-down:   rgba(0,0,0,.09);
  --mac-ctl-edge:   rgba(0,0,0,.10);
  --mac-ctl-shadow: 0 .5px 1px rgba(0,0,0,.14), 0 1px 3px rgba(0,0,0,.08);
  --mac-ctl-on:     #ffffff;

  --mac-fill:       #c8420f;
  --mac-fill-hot:   #b93a0e;
  --mac-fill-down:  #a8330c;
  --mac-on-fill:    #ffffff;

  /* Fields, wells, lists, separators. */
  --mac-field:      rgba(255,255,255,.92);
  --mac-field-edge: rgba(0,0,0,.16);
  --mac-focus:      0 0 0 3.5px rgba(240,74,0,.32);
  --mac-well:       rgba(0,0,0,.05);
  /* The segmented control's track. OPAQUE, not glass, and that is the point:
     .qci-tabs is the one control in this theme that sits directly on the
     wallpaper — it is between the header card and the content card, inside no
     .qci-card at all — so its labels were compositing against the photograph.
     Measured before: 1,00:1 at worst, 85% of the row below AA. Translucency at
     96% was still not enough, because the track then takes the wallpaper's own
     colour and lands at 4,45:1 over the dark part. Opaque, --muted on it is
     4,94:1 wherever the row happens to be. Same reason --mac-menu is 97%. */
  --mac-seg:        #e9e9ee;
  --mac-seg-edge:   rgba(0,0,0,.10);
  --mac-tile:       rgba(255,255,255,.55);
  --mac-head:       rgba(0,0,0,.035);
  --mac-rule:       rgba(0,0,0,.08);
  --mac-rule-strong:rgba(0,0,0,.18);
  --mac-row-hover:  rgba(0,0,0,.035);

  /* Menus are near-opaque on purpose: they open from the header card, whose
     own backdrop-filter makes it their backdrop root, so a blur on the menu
     would see nothing of the page once it hangs outside that card. */
  --mac-menu:        rgba(246,246,248,.97);
  --mac-menu-edge:   rgba(0,0,0,.10);
  --mac-menu-shadow: 0 0 0 .5px rgba(0,0,0,.18), 0 12px 38px rgba(0,0,0,.26);
  --mac-sheet:       rgba(246,246,248,.92);

  /* Text that sits directly on the wallpaper, like a desktop icon's label. */
  --mac-desk-ink:    #ffffff;
  --mac-desk-shadow: 0 1px 3px rgba(0,20,40,.70);
  --mac-disabled:    rgba(0,0,0,.28);
}
/* What the two halves share that is not a colour: the system face, the corner,
   and the traffic lights (which are the same three colours by day and night). */
:root[data-theme^="macos27"]{
  /* -apple-system / BlinkMacSystemFont resolve to SF Pro on a Mac and are
     ignored everywhere else, where Open Sans — already loaded for Vista, with
     normal metrics — stands in. No display font: macOS titles are the UI face. */
  --font: -apple-system, BlinkMacSystemFont, 'SF Pro Text', 'SF Pro Display', 'Helvetica Neue', 'Open Sans', 'Segoe UI', Arial, sans-serif;
  --mono: 'SF Mono', ui-monospace, Menlo, Monaco, 'JetBrains Mono', Consolas, monospace;
  --radius: 18px;

  --mac-tl-close: #ff5f57;
  --mac-tl-close-edge: #e0443e;
  --mac-tl-min:   #febc2e;
  --mac-tl-min-edge:   #dea123;
  --mac-tl-zoom:  #28c840;
  --mac-tl-zoom-edge:  #1aab29;
}

/* ── Efeitos: mantidos, muito atenuados, a cinzento ──────────────────────── */
:root[data-theme="red_quito"] body,
:root[data-theme="blue_quito"] body,
:root[data-theme="zx_spectrum"] body{
  background:
    radial-gradient(1000px 520px at 72% 18%, var(--accent-glow), transparent 58%),
    radial-gradient(820px 420px at 12% 86%, rgba(0,0,0,.03), transparent 62%),
    linear-gradient(180deg, var(--bg0), var(--bg1));
}
:root[data-theme="red_quito"] body::before,
:root[data-theme="blue_quito"] body::before,
:root[data-theme="zx_spectrum"] body::before{
  background:
    linear-gradient(to right, rgba(0,0,0,.06) 1px, transparent 1px),
    linear-gradient(to bottom, rgba(0,0,0,.06) 1px, transparent 1px);
  opacity:.05;
}
:root[data-theme="red_quito"] body::after,
:root[data-theme="blue_quito"] body::after,
:root[data-theme="zx_spectrum"] body::after{
  background:
    repeating-linear-gradient(
      to bottom,
      rgba(0,0,0,.03),
      rgba(0,0,0,.03) 1px,
      transparent 2px,
      transparent 7px
    ),
    radial-gradient(760px 260px at 30% 12%, var(--red-03), transparent 62%),
    radial-gradient(980px 360px at 78% 84%, rgba(0,0,0,.02), transparent 62%);
  opacity:.5;
}
:root[data-theme="red_quito"] .qci-sweep,
:root[data-theme="blue_quito"] .qci-sweep,
:root[data-theme="zx_spectrum"] .qci-sweep{
  background: linear-gradient(135deg, transparent 40%, rgba(0,0,0,.04) 50%, transparent 60%);
  opacity:.5;
}
:root[data-theme="red_quito"] .qci-title,
:root[data-theme="blue_quito"] .qci-title,
:root[data-theme="zx_spectrum"] .qci-title{
  text-shadow: none;
}
:root[data-theme="red_quito"] .qci-glitch,
:root[data-theme="blue_quito"] .qci-glitch{ text-shadow: none; }
:root[data-theme="zx_spectrum"] .qci-glitch{ text-shadow: none; }
:root[data-theme="red_quito"] .qci-glitch::before,
:root[data-theme="blue_quito"] .qci-glitch::before,
:root[data-theme="zx_spectrum"] .qci-glitch::before,
:root[data-theme="red_quito"] .qci-glitch::after,
:root[data-theme="blue_quito"] .qci-glitch::after{ opacity:.06; }
:root[data-theme="zx_spectrum"] .qci-glitch::after{ opacity:.06; }
:root[data-theme="red_quito"] .qci-glowbar,
:root[data-theme="blue_quito"] .qci-glowbar,
:root[data-theme="zx_spectrum"] .qci-glowbar{
  background: linear-gradient(90deg, transparent, var(--red), transparent);
  opacity:.5;
}

/* Cantos HUD do card: discretos, a cinzento. */
:root[data-theme="red_quito"] .qci-card::before,
:root[data-theme="blue_quito"] .qci-card::before,
:root[data-theme="zx_spectrum"] .qci-card::before,
:root[data-theme="red_quito"] .qci-card::after,
:root[data-theme="blue_quito"] .qci-card::after,
:root[data-theme="zx_spectrum"] .qci-card::after{
  border-color: rgba(0,0,0,.14);
  opacity:.7;
}
:root[data-theme="red_quito"] .qci-card,
:root[data-theme="blue_quito"] .qci-card,
:root[data-theme="zx_spectrum"] .qci-card{
  border-color: var(--line);
  backdrop-filter: none;
}

/* ── Buttons: solid red. The dark theme's translucent gradient disappeared
      on white. ─────────────────────────────────────────────────────────────── */
:root[data-theme="red_quito"] .qci-btn,
:root[data-theme="blue_quito"] .qci-btn,
:root[data-theme="zx_spectrum"] .qci-btn{
  background: var(--red);
  border-color: var(--red);
  color:#ffffff;
  box-shadow: 0 1px 2px rgba(0,0,0,.12);
}
:root[data-theme="red_quito"] .qci-btn:hover,
:root[data-theme="blue_quito"] .qci-btn:hover,
:root[data-theme="zx_spectrum"] .qci-btn:hover{
  background: var(--red2);
  border-color: var(--red2);
  box-shadow: 0 2px 6px rgba(0,0,0,.16);
}
:root[data-theme="red_quito"] .qci-btn-ghost,
:root[data-theme="blue_quito"] .qci-btn-ghost,
:root[data-theme="zx_spectrum"] .qci-btn-ghost{
  background:#ffffff;
  border-color: rgba(0,0,0,.20);
  color: var(--muted);
  box-shadow:none;
}
:root[data-theme="red_quito"] .qci-btn-ghost:hover,
:root[data-theme="blue_quito"] .qci-btn-ghost:hover,
:root[data-theme="zx_spectrum"] .qci-btn-ghost:hover{
  background:#f4f5f7;
  border-color: rgba(0,0,0,.35);
  color: var(--text);
}
:root[data-theme="red_quito"] .qci-btn-blue,
:root[data-theme="blue_quito"] .qci-btn-blue,
:root[data-theme="zx_spectrum"] .qci-btn-blue{
  background:#1d4ed8; border-color:#1d4ed8; color:#ffffff;
}
:root[data-theme="red_quito"] .qci-btn-blue:hover,
:root[data-theme="blue_quito"] .qci-btn-blue:hover{ background:#1e40af; border-color:#1e40af; }
:root[data-theme="zx_spectrum"] .qci-btn-blue:hover{ background:#1e40af; border-color:#1e40af; }
:root[data-theme="red_quito"] .qci-btn-green,
:root[data-theme="blue_quito"] .qci-btn-green,
:root[data-theme="zx_spectrum"] .qci-btn-green{
  background:#15803d; border-color:#15803d; color:#ffffff;
}
:root[data-theme="red_quito"] .qci-btn-green:hover,
:root[data-theme="blue_quito"] .qci-btn-green:hover{ background:#166534; border-color:#166534; }
:root[data-theme="zx_spectrum"] .qci-btn-green:hover{ background:#166534; border-color:#166534; }
:root[data-theme="red_quito"] .qci-btn-danger,
:root[data-theme="blue_quito"] .qci-btn-danger,
:root[data-theme="zx_spectrum"] .qci-btn-danger{
  /* Red in both light themes on purpose: here the colour means "destructive
     action", it is not the theme's accent. */
  background:#b3001f; border-color:#b3001f; color:#ffffff;
}
:root[data-theme="red_quito"] .qci-btn-danger:hover,
:root[data-theme="blue_quito"] .qci-btn-danger:hover{ background:#8c0018; border-color:#8c0018; }
:root[data-theme="zx_spectrum"] .qci-btn-danger:hover{ background:#8c0018; border-color:#8c0018; }

/* ── Forms ───────────────────────────────────────────────────────────────── */
:root[data-theme="red_quito"] .qci-input,
:root[data-theme="blue_quito"] .qci-input,
:root[data-theme="zx_spectrum"] .qci-input,
:root[data-theme="red_quito"] .qci-textarea,
:root[data-theme="blue_quito"] .qci-textarea,
:root[data-theme="zx_spectrum"] .qci-textarea,
:root[data-theme="red_quito"] select.qci-input,
:root[data-theme="blue_quito"] select.qci-input,
:root[data-theme="zx_spectrum"] select.qci-input,
:root[data-theme="red_quito"] .qci-inline-select,
:root[data-theme="blue_quito"] .qci-inline-select,
:root[data-theme="zx_spectrum"] .qci-inline-select{
  background:#ffffff;
  border-color: rgba(0,0,0,.20);
  color: var(--text);
}
:root[data-theme="red_quito"] .qci-input:focus,
:root[data-theme="blue_quito"] .qci-input:focus,
:root[data-theme="zx_spectrum"] .qci-input:focus,
:root[data-theme="red_quito"] .qci-textarea:focus,
:root[data-theme="blue_quito"] .qci-textarea:focus,
:root[data-theme="zx_spectrum"] .qci-textarea:focus,
:root[data-theme="red_quito"] select.qci-input:focus,
:root[data-theme="blue_quito"] select.qci-input:focus,
:root[data-theme="zx_spectrum"] select.qci-input:focus{
  border-color: var(--red);
  box-shadow: 0 0 0 3px var(--red-10);
}
:root[data-theme="red_quito"] .qci-terminal,
:root[data-theme="blue_quito"] .qci-terminal,
:root[data-theme="zx_spectrum"] .qci-terminal{
  background:#f4f5f7;
  border-color: rgba(0,0,0,.12);
  color:#2a2f38;
}

/* ── Reactor: solid red, no neon halo ────────────────────────────────────── */
:root[data-theme="red_quito"] .qci-reactor-core,
:root[data-theme="blue_quito"] .qci-reactor-core,
:root[data-theme="zx_spectrum"] .qci-reactor-core{
  background: radial-gradient(circle, var(--rc-hot) 0%, var(--rc-mid) 45%, var(--rc-cold) 100%);
  box-shadow: 0 0 0 1px rgba(0,0,0,.06);
  animation: none;
}
:root[data-theme="red_quito"] .qci-reactor-ring:nth-child(1),
:root[data-theme="blue_quito"] .qci-reactor-ring:nth-child(1){ box-shadow:none; }
:root[data-theme="zx_spectrum"] .qci-reactor-ring:nth-child(1){ box-shadow:none; }

/* ── Menu do nav ─────────────────────────────────────────────────────────── */
:root[data-theme="red_quito"] .qci-dropdown-menu,
:root[data-theme="blue_quito"] .qci-dropdown-menu,
:root[data-theme="zx_spectrum"] .qci-dropdown-menu{
  background:#ffffff;
  border-color: rgba(0,0,0,.15);
  box-shadow: 0 8px 28px rgba(0,0,0,.14);
}

/* ── Tables and statistics ───────────────────────────────────────────────── */
:root[data-theme="red_quito"] .qci-table th,
:root[data-theme="blue_quito"] .qci-table th,
:root[data-theme="zx_spectrum"] .qci-table th{
  background: var(--red-04);
  color: var(--muted);
}
:root[data-theme="red_quito"] .qci-table tr:hover td,
:root[data-theme="blue_quito"] .qci-table tr:hover td{ background: rgba(0,0,0,.03); }
:root[data-theme="zx_spectrum"] .qci-table tr:hover td{ background: rgba(0,0,0,.03); }
:root[data-theme="red_quito"] .qci-stat,
:root[data-theme="blue_quito"] .qci-stat,
:root[data-theme="zx_spectrum"] .qci-stat{
  background:#ffffff;
  border-color: rgba(0,0,0,.12);
  box-shadow: 0 1px 3px rgba(0,0,0,.06);
}
:root[data-theme="red_quito"] .qci-tag,
:root[data-theme="blue_quito"] .qci-tag,
:root[data-theme="zx_spectrum"] .qci-tag{
  background:#f4f5f7;
  border-color: rgba(0,0,0,.14);
  color:#3a4150;
}

/* ── One-off page corrections ────────────────────────────────────────────── */
/* The calendar's active tab used white text over a red ink that is pale here; it
   becomes dark red. */
:root[data-theme="red_quito"] .view-tab.active,
:root[data-theme="blue_quito"] .view-tab.active,
:root[data-theme="zx_spectrum"] .view-tab.active{
  color: var(--red2);
  background: var(--red-05);
}

/* ═══════════════════════════════════════════════════════════════════════════
   ZX SPECTRUM 128K — visual identity
   ───────────────────────────────────────────────────────────────────────────
   Reference: the +3e's boot menu — black bar with the title in white pixel font
   on the left and the rainbow diagonals on the right, selected line in solid cyan
   with black text, light panel on a grey background.

   Everything here is pure CSS: there is no shared header in PHP (the 14 pages
   repeat the same block), but .qci-reactor appears exactly once per page, so
   .qci-card:has(.qci-reactor) identifies the header without touching any markup.
   ═══════════════════════════════════════════════════════════════════════════ */

/* ── Text: the pixel font, kept to the title ─────────────────────────────────
   The rest of the theme reads in Share Tech Mono at the same sizes as every
   other theme. VT323 stays here, on the one string big enough for it and the one
   the reference image is built around: the white title on the black header.

   font-weight 400 because VT323 ships a single weight — .qci-title asks for 950
   and the browser was synthesising it, which is part of what made it mush. The
   size is set here rather than inherited from the old 19px root, which is gone,
   and it is above the base 28px because VT323 still reads small. */
:root[data-theme="zx_spectrum"] .qci-title{
  font-family: 'VT323', var(--mono);
  font-weight: 400;
  font-size: 34px;
  letter-spacing: .16em;
}

/* ── Rainbow strip pinned to the top of the viewport ─────────────────────────
   .qci-wrap::before is the only free pseudo-element that exists on every page
   (body:: and .qci-card:: are already taken). */
:root[data-theme="zx_spectrum"] .qci-wrap::before{
  content:"";
  position: fixed;
  top:0; left:0; right:0;
  height: 4px;
  z-index: 9999;
  pointer-events: none;
  background: linear-gradient(90deg,
    var(--zx-red)    0 25%,
    var(--zx-yellow) 25% 50%,
    var(--zx-green)  50% 75%,
    var(--zx-cyan)   75% 100%);
}

/* ── Black header ───────────────────────────────────────────────────────────
   The header card only. The rest of the page stays light, as in the picture:
   black plastic on top, light screen below. */
:root[data-theme="zx_spectrum"] .qci-card:has(.qci-reactor){
  background: var(--zx-ink);
  border-color: var(--zx-ink);
  box-shadow: 0 2px 6px var(--sh-60);
}
/* The HUD corners do not read on black and the ::before becomes useless — both
   are switched off. */
:root[data-theme="zx_spectrum"] .qci-card:has(.qci-reactor)::before,
:root[data-theme="zx_spectrum"] .qci-card:has(.qci-reactor)::after{ display:none; }
/* The sweep is a grey wash designed for a light background. */
:root[data-theme="zx_spectrum"] .qci-card:has(.qci-reactor) .qci-sweep{ display:none; }

:root[data-theme="zx_spectrum"] .qci-card:has(.qci-reactor) .qci-title{
  color: var(--zx-paper);
}
:root[data-theme="zx_spectrum"] .qci-card:has(.qci-reactor) .qci-muted{
  color: var(--zx-dim);
}
:root[data-theme="zx_spectrum"] .qci-card:has(.qci-reactor) .qci-tag{
  background: var(--zx-on-ink-10);
  border-color: var(--zx-on-ink-25);
  color: var(--zx-paper);
}
/* Without this the ghost button — white with a dark border — becomes a white
   block on the black. */
:root[data-theme="zx_spectrum"] .qci-card:has(.qci-reactor) .qci-btn-ghost{
  background: transparent;
  border-color: var(--zx-on-ink-25);
  color: var(--zx-paper);
}
:root[data-theme="zx_spectrum"] .qci-card:has(.qci-reactor) .qci-btn-ghost:hover{
  background: var(--zx-on-ink-10);
  border-color: var(--zx-paper);
  color: var(--zx-paper);
}

/* ── Rainbow diagonals in the header ─────────────────────────────────────────
   They sit on the header's .qci-glowbar: an empty <div> made for decoration, so
   the stripes end up flush right of the black bar as in the picture. The card's
   ::after is not used because the top-right corner is where the tags and the
   "Theme" dropdown live — and an overflow:hidden on the card would clip the
   dropdown. */
:root[data-theme="zx_spectrum"] .qci-card:has(.qci-reactor) .qci-glowbar{
  position: relative;
  overflow: hidden;
  height: 20px;
  margin: 10px 0 14px;
  opacity: 1;
  background: none;
}
:root[data-theme="zx_spectrum"] .qci-card:has(.qci-reactor) .qci-glowbar::after{
  content:"";
  position:absolute;
  top:0; bottom:0; right:0;
  width: 208px;
  transform: skewX(-20deg);
  background: linear-gradient(90deg,
    var(--zx-red)    0 25%,
    var(--zx-yellow) 25% 50%,
    var(--zx-green)  50% 75%,
    var(--zx-cyan)   75% 100%);
}

/* ── "Selected" highlight: solid cyan with black text ───────────────────────
   Like the "Loader" line in the +3e's menu. These rules come after the light
   themes' block on purpose — that is how they beat them. */
:root[data-theme="zx_spectrum"] .qci-dropdown-menu button.is-current{
  background: var(--zx-cyan);
  color: var(--zx-ink);
}
:root[data-theme="zx_spectrum"] .view-tab.active{
  background: var(--zx-cyan);
  color: var(--zx-ink);
}
:root[data-theme="zx_spectrum"] .hive-tab.active{
  background: var(--zx-cyan);
  color: var(--zx-ink);
}
:root[data-theme="zx_spectrum"] .qci-table tr:hover td{
  background: var(--zx-cyan);
  color: var(--zx-ink);
}


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

   This section is what separates Blueprint from a colour swap: it converts the
   shared chrome into a technical drawing without touching any PHP. The hooks are
   all pseudo-elements that were free — see the table in CLAUDE.md.
   ═══════════════════════════════════════════════════════════════════════════ */

/* ── Papel ──────────────────────────────────────────────────────────────────
   The two red radial glows go: what remains is the paper gradient and nothing else. */
:root[data-theme="blueprint"] body{
  background: linear-gradient(180deg, var(--bg0), var(--bg1));
}

/* Millimetre grid. No skewY and no qci-grid animation: paper does not drift.
   Two levels — fine at 8px, strong at 80px — like real drawing paper. */
:root[data-theme="blueprint"] body::before{
  inset: 0;
  transform: none;
  animation: none;
  opacity: 1;
  background:
    linear-gradient(to right,  rgba(127,212,255,.15) 1px, transparent 1px),
    linear-gradient(to bottom, rgba(127,212,255,.15) 1px, transparent 1px),
    linear-gradient(to right,  rgba(127,212,255,.055) 1px, transparent 1px),
    linear-gradient(to bottom, rgba(127,212,255,.055) 1px, transparent 1px);
  background-size: 80px 80px, 80px 80px, 8px 8px, 8px 8px;
}

/* No scanlines and no washes: a vignette that gives the sheet its edges. */
:root[data-theme="blueprint"] body::after{
  inset: 0;
  opacity: 1;
  filter: none;
  background: radial-gradient(120% 90% at 50% 40%, transparent 55%, rgba(4,14,28,.6) 100%);
}

/* ── Sheet and title block ──────────────────────────────────────────────────
   Both .qci-wrap pseudos were free (the ZX uses ::before, but inside its own
   scope). Fixed to the viewport, not catching the mouse. */
:root[data-theme="blueprint"] .qci-wrap::before{
  content:"";
  position: fixed; inset: 10px;
  border: 1px solid var(--red-30);
  pointer-events: none;
  z-index: 9998;
}
:root[data-theme="blueprint"] .qci-wrap::after{
  content: "QCI · SCALE 1:1 · REV 02";
  position: fixed; right: 20px; bottom: 20px;
  padding: 6px 10px;
  border: 1px solid var(--red-30);
  background: var(--sink-75);
  font-family: 'Share Tech Mono', var(--mono);
  font-size: 11px;
  letter-spacing: .18em;
  color: var(--muted);
  pointer-events: none;
  z-index: 9998;
}
/* On a narrow screen the title block covered content — and mobile_monitor.php exists. */
@media (max-width: 900px){
  :root[data-theme="blueprint"] .qci-wrap::before,
  :root[data-theme="blueprint"] .qci-wrap::after{ display: none; }
}

/* ── Squared off ────────────────────────────────────────────────────────────
   The file's 16 fixed radii go to zero. Only .qci-pulse and the reactor's
   rings/core stay round: circles are legal in technical drawing. */
:root[data-theme="blueprint"] .qci-card,
:root[data-theme="blueprint"] .qci-btn,
:root[data-theme="blueprint"] .qci-btn-sm,
:root[data-theme="blueprint"] .qci-tag,
:root[data-theme="blueprint"] .qci-input,
:root[data-theme="blueprint"] .qci-textarea,
:root[data-theme="blueprint"] select.qci-input,
:root[data-theme="blueprint"] .qci-inline-select,
:root[data-theme="blueprint"] .qci-terminal,
:root[data-theme="blueprint"] .qci-error,
:root[data-theme="blueprint"] .qci-success,
:root[data-theme="blueprint"] .qci-stat,
:root[data-theme="blueprint"] .qci-dropdown-menu,
:root[data-theme="blueprint"] .qci-dropdown-submenu-flyout{
  border-radius: 0;
}

/* ── Card = drawing box ─────────────────────────────────────────────────────
   The backdrop-filter goes so the grid passes THROUGH the card instead of being
   blurred behind it: the grid is the paper, the drawing sits on top. */
:root[data-theme="blueprint"] .qci-card{
  border: 1px solid var(--line);
  background: var(--panel);
  backdrop-filter: none;
  box-shadow: none;
}

/* Cantos HUD em L → marcas de registo. Duas riscas cruzadas em vez de borda. */
:root[data-theme="blueprint"] .qci-card::before,
:root[data-theme="blueprint"] .qci-card::after{
  width: 16px; height: 16px;
  border: none;
  border-radius: 0;
  opacity: .8;
  background:
    linear-gradient(to right,  var(--red-55) 0 100%) center/100% 1px no-repeat,
    linear-gradient(to bottom, var(--red-55) 0 100%) center/1px 100% no-repeat;
}
:root[data-theme="blueprint"] .qci-card::before{ left: 8px; top: 8px; }
:root[data-theme="blueprint"] .qci-card::after{ right: 8px; bottom: 8px; }

/* ── Dimension line ─────────────────────────────────────────────────────────
   .qci-glowbar is an empty decorative <div> present in every card's header; the
   ZX theme already proved it can be repurposed. Here it stops being a glow bar
   and becomes a dimension line, with vertical terminators at both ends. */
:root[data-theme="blueprint"] .qci-glowbar{
  position: relative;
  height: 10px;
  opacity: 1;
  margin: 12px 0 16px;
  background: linear-gradient(to right, var(--red-45) 0 100%) 0 50%/100% 1px no-repeat;
}
:root[data-theme="blueprint"] .qci-glowbar::before,
:root[data-theme="blueprint"] .qci-glowbar::after{
  content:"";
  position: absolute; top: 0; bottom: 0;
  width: 1px;
  background: var(--red-70);
}
:root[data-theme="blueprint"] .qci-glowbar::before{ left: 0; }
:root[data-theme="blueprint"] .qci-glowbar::after{ right: 0; }

/* ── Title block ────────────────────────────────────────────────────────────
   There is no shared header in PHP (the pages repeat the block), but
   .qci-reactor appears exactly once per page — it is the sentinel the ZX theme
   already uses to identify the header without touching markup. */
:root[data-theme="blueprint"] .qci-card:has(.qci-reactor){
  border-width: 2px;
  border-color: var(--red-45);
}

:root[data-theme="blueprint"] .qci-title{
  font-family: 'Share Tech Mono', var(--mono);
  font-weight: 400;
  letter-spacing: .22em;
  text-shadow: none;
  color: var(--text);
}
/* Chromatic aberration does not exist in technical drawing. */
:root[data-theme="blueprint"] .qci-glitch{ text-shadow: none; }
:root[data-theme="blueprint"] .qci-glitch::before,
:root[data-theme="blueprint"] .qci-glitch::after{ display: none; }

/* ── Compass ────────────────────────────────────────────────────────────────
   The three rings stop being coloured arcs spinning at different speeds and
   become complete 1px circles: dashed / solid / dashed, the centre-line
   convention. Only the outer one keeps rotating, and slowly, like a compass arm. */
:root[data-theme="blueprint"] .qci-reactor{ overflow: visible; }
:root[data-theme="blueprint"] .qci-reactor-ring{
  border-width: 1px;
  border-color: var(--red-45);
  box-shadow: none;
}
:root[data-theme="blueprint"] .qci-reactor-ring:nth-child(1){
  border-style: dashed;
  animation: qr-spin 60s linear infinite;
}
:root[data-theme="blueprint"] .qci-reactor-ring:nth-child(2){
  border-style: solid;
  border-color: var(--red-70);
  animation: none;
}
:root[data-theme="blueprint"] .qci-reactor-ring:nth-child(3){
  border-style: dashed;
  animation: none;
}
:root[data-theme="blueprint"] .qci-reactor-core{
  inset: 22px;
  background: var(--red);
  box-shadow: none;
  animation: none;
}
/* Centre lines, extending outside the circle. Both .qci-reactor pseudos were
   free — the rings are real child elements. */
:root[data-theme="blueprint"] .qci-reactor::before,
:root[data-theme="blueprint"] .qci-reactor::after{
  content:"";
  position: absolute;
  background: var(--red-45);
  pointer-events: none;
}
:root[data-theme="blueprint"] .qci-reactor::before{
  left: -7px; right: -7px; top: 50%; height: 1px;
}
:root[data-theme="blueprint"] .qci-reactor::after{
  top: -7px; bottom: -7px; left: 50%; width: 1px;
}

/* ── Flat buttons ───────────────────────────────────────────────────────────
   No gradient, no glow, no lift on hover. .qci-btn-danger stays red, as in the
   other five themes: there the colour means "destructive action", it is not the
   accent. */
:root[data-theme="blueprint"] .qci-btn{
  background: var(--red-08);
  border: 1px solid var(--red-45);
  box-shadow: none;
  color: var(--text);
  font-family: var(--mono);
}
:root[data-theme="blueprint"] .qci-btn:hover{
  background: var(--red-16);
  border-color: var(--red-70);
  box-shadow: none;
  transform: none;
}
:root[data-theme="blueprint"] .qci-btn-ghost{
  background: transparent;
  border-color: var(--ov-25);
  box-shadow: none;
}
:root[data-theme="blueprint"] .qci-btn-ghost:hover{
  background: var(--ov-06);
  border-color: var(--ov-45);
  box-shadow: none;
}
:root[data-theme="blueprint"] .qci-btn-blue{
  background: var(--blue-btn-12);
  box-shadow: none;
}
:root[data-theme="blueprint"] .qci-btn-blue:hover{
  background: var(--blue-btn-20);
  box-shadow: none;
}
:root[data-theme="blueprint"] .qci-btn-green{
  background: var(--green-btn4-12);
  box-shadow: none;
}
:root[data-theme="blueprint"] .qci-btn-green:hover{
  background: var(--green-btn6-20);
  box-shadow: none;
}
:root[data-theme="blueprint"] .qci-btn-danger{
  background: var(--danger-15);
  box-shadow: none;
}
:root[data-theme="blueprint"] .qci-btn-danger:hover{
  background: var(--danger-30);
  box-shadow: none;
}

/* ── Fields ─────────────────────────────────────────────────────────────────
   The 4px focus ring becomes a 2px stroke: it is a form field on a sheet, not a
   HUD target. */
:root[data-theme="blueprint"] .qci-input,
:root[data-theme="blueprint"] .qci-textarea,
:root[data-theme="blueprint"] select.qci-input,
:root[data-theme="blueprint"] .qci-inline-select{
  border: 1px solid var(--line);
  background: var(--sink-30);
}
:root[data-theme="blueprint"] .qci-input:focus,
:root[data-theme="blueprint"] .qci-textarea:focus,
:root[data-theme="blueprint"] select.qci-input:focus,
:root[data-theme="blueprint"] .qci-inline-select:focus{
  border-color: var(--red-95);
  box-shadow: 0 0 0 2px var(--red-25);
}

/* ── Tables ─────────────────────────────────────────────────────────────────
   Where the theme pays off. Since --font became JetBrains Mono, the numbers align
   by column across the whole site without touching a single page. */
:root[data-theme="blueprint"] .qci-table th{
  background: var(--red-08);
  border-bottom: 1px solid var(--red-35);
  color: var(--muted);
}
:root[data-theme="blueprint"] .qci-table td{
  border-bottom: 1px solid var(--ov-08);
}
:root[data-theme="blueprint"] .qci-table tr:hover td{
  background: var(--red-07);
}

/* Tiles = caixas de chamada. */
:root[data-theme="blueprint"] .qci-stat{
  background: var(--red-04);
  border: 1px solid var(--line);
}

:root[data-theme="blueprint"] .qci-terminal{
  border: 1px solid var(--line);
  background: var(--sink-40);
}

/* ── Engine stopped ─────────────────────────────────────────────────────────
   Paper neither moves nor glows. The green dot stays — it is a liveness signal,
   not decoration — but it stops breathing. */
:root[data-theme="blueprint"] .qci-sweep{ display: none; }
:root[data-theme="blueprint"] .qci-pulse{
  animation: none;
  box-shadow: none;
}
@media (prefers-reduced-motion: reduce){
  :root[data-theme="blueprint"] .qci-reactor-ring:nth-child(1){ animation: none; }
}


/* ═══════════════════════════════════════════════════════════════════════════
   AURORA HIVE — structural section
   Everything scoped to :root[data-theme="aurora_hive"].

   Two ideas and nothing more: light moving behind, and glass in front.
   ═══════════════════════════════════════════════════════════════════════════ */

/* ── Aurora ribbons ─────────────────────────────────────────────────────────
   Two layers instead of one, drifting in opposite directions, so the ribbons
   CROSS rather than moving as a block — it is the crossing that reads as an
   aurora and not as "coloured blobs".

   filter: blur(90px) is expensive and was a deliberate choice: it gives the
   organic softening a smooth gradient cannot imitate. */
:root[data-theme="aurora_hive"] body::before{
  inset: -25%;
  opacity: .55;
  transform: none;
  animation: aurora-drift-a 64s ease-in-out infinite;
  filter: blur(90px);
  background:
    radial-gradient(38% 26% at 22% 28%, rgba(52,211,153,.85), transparent 70%),
    radial-gradient(32% 22% at 68% 18%, rgba(34,211,238,.75), transparent 72%),
    radial-gradient(42% 30% at 82% 62%, rgba(168,85,247,.70), transparent 70%);
  background-repeat: no-repeat;
}
:root[data-theme="aurora_hive"] .qci-wrap::before{
  content:"";
  position: fixed; inset: -25%;
  z-index: -1;
  pointer-events: none;
  opacity: .45;
  filter: blur(90px);
  animation: aurora-drift-b 81s ease-in-out infinite;
  background:
    radial-gradient(36% 24% at 72% 78%, rgba(232,121,249,.75), transparent 70%),
    radial-gradient(30% 20% at 28% 82%, rgba(34,211,238,.60), transparent 72%);
  background-repeat: no-repeat;
}

@keyframes aurora-drift-a{
  0%,100%{ transform: translate3d(0,0,0) rotate(0deg) scale(1); }
  33%    { transform: translate3d(6%,-4%,0) rotate(4deg) scale(1.12); }
  66%    { transform: translate3d(-5%,5%,0) rotate(-3deg) scale(1.05); }
}
@keyframes aurora-drift-b{
  0%,100%{ transform: translate3d(0,0,0) rotate(0deg) scale(1.08); }
  50%    { transform: translate3d(-7%,-6%,0) rotate(-6deg) scale(1); }
}

/* No scanlines: a vignette that closes the corners and gives the glass depth. */
:root[data-theme="aurora_hive"] body::after{
  inset: 0;
  opacity: 1;
  filter: none;
  background: radial-gradient(130% 100% at 50% 30%, transparent 45%, rgba(2,4,10,.75) 100%);
}

/* Body background without the red glows: the light now comes from the ribbons. */
:root[data-theme="aurora_hive"] body{
  background: linear-gradient(180deg, var(--bg0), var(--bg1));
}

/* ── Glass ──────────────────────────────────────────────────────────────────
   The blur goes from 10px to 24px and gains saturation: it is the saturate that
   makes the aurora "take" on the glass instead of passing through washed out. The
   specular edge (inset 0 1px 0) is what separates real glass from a transparent
   panel. */
:root[data-theme="aurora_hive"] .qci-card{
  background: var(--panel);
  border: 1px solid var(--ov-12);
  backdrop-filter: blur(24px) saturate(160%);
  -webkit-backdrop-filter: blur(24px) saturate(160%);
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,.20),
    inset 0 -1px 0 rgba(255,255,255,.05),
    0 20px 60px rgba(0,0,0,.45);
}

/* The HUD corners go. ::before becomes the specular highlight along the top — the
   light settling on the glass's upper edge; ::after is switched off. */
:root[data-theme="aurora_hive"] .qci-card::before{
  left: 0; top: 0;
  width: 100%; height: 40%;
  border: none;
  border-radius: var(--radius) var(--radius) 0 0;
  opacity: .5;
  background: linear-gradient(180deg, rgba(255,255,255,.10), transparent 100%);
}
:root[data-theme="aurora_hive"] .qci-card::after{ display: none; }

/* Reflexo a passar no vidro, em vez do sweep de HUD. */
:root[data-theme="aurora_hive"] .qci-sweep{
  opacity: .18;
  background: linear-gradient(135deg, transparent 42%, rgba(255,255,255,.5) 50%, transparent 58%);
}

/* ── Chrome ─────────────────────────────────────────────────────────────────
   On glass, Crimson Hive's neon smears. Everything that used to glow now settles
   onto the surface: light borders, light fills. */
:root[data-theme="aurora_hive"] .qci-title{
  text-shadow: 0 0 30px rgba(192,132,252,.45);
}
:root[data-theme="aurora_hive"] .qci-glowbar{
  height: 1px;
  opacity: .8;
  background: linear-gradient(90deg, transparent, var(--red-70), transparent);
}
:root[data-theme="aurora_hive"] .qci-btn{
  background: rgba(255,255,255,.07);
  border: 1px solid var(--ov-15);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.14);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
}
:root[data-theme="aurora_hive"] .qci-btn:hover{
  background: rgba(255,255,255,.13);
  border-color: var(--red-55);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.20), 0 0 24px var(--red-25);
}
:root[data-theme="aurora_hive"] .qci-stat{
  background: rgba(255,255,255,.045);
  border: 1px solid var(--ov-10);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.12);
}
:root[data-theme="aurora_hive"] .qci-terminal,
:root[data-theme="aurora_hive"] .qci-input,
:root[data-theme="aurora_hive"] .qci-textarea,
:root[data-theme="aurora_hive"] select.qci-input{
  background: rgba(0,0,0,.28);
  border: 1px solid var(--ov-10);
}
:root[data-theme="aurora_hive"] .qci-dropdown-menu{
  background: rgba(10,14,28,.72);
  backdrop-filter: blur(20px) saturate(150%);
  -webkit-backdrop-filter: blur(20px) saturate(150%);
}

/* The reactor's core becomes a drop of aurora: it keeps the pulse, loses the
   hardness of plasma. */
:root[data-theme="aurora_hive"] .qci-reactor-core{
  filter: blur(1px);
}

/* ── The one place that relied on an opaque --panel ──────────────────────────
   family_calendar.php's .tg-time-col is position:sticky and used var(--panel) to
   cover the events passing beneath it on horizontal scroll. With the panel at
   5.5% white it covered nothing. Here it gets a background of its own. If another
   sticky column appears on another page, it needs the same. */
:root[data-theme="aurora_hive"] .tg-time-col{
  background: #080e1c;
}

/* Continuous movement is the concept, but whoever asks for stillness must get it. */
@media (prefers-reduced-motion: reduce){
  :root[data-theme="aurora_hive"] body::before,
  :root[data-theme="aurora_hive"] .qci-wrap::before{ animation: none; }
}


/* ═══════════════════════════════════════════════════════════════════════════
   OUTRUN 1986 — structural section
   Everything scoped to :root[data-theme="outrun"].

   It introduces three things that did not exist in this file: perspective(),
   background-clip:text and mask-image. Each has an acceptable fallback — without
   perspective the grid stays flat, without mask it gets a hard edge, and
   -webkit-text-fill-color always comes alongside the normal color.
   ═══════════════════════════════════════════════════════════════════════════ */

:root[data-theme="outrun"] body{
  background: linear-gradient(180deg, #2a1150 0%, var(--bg0) 42%, var(--bg1) 100%);
}

/* ── The sun ────────────────────────────────────────────────────────────────
   body::before stops being a full-viewport overlay and becomes a disc: inset:auto
   plus its own measurements. The horizontal bands live in a second layer confined
   to the bottom 55% via background-size/position — that is how they cut only the
   lower part, as the genre demands, without needing an extra element. */
:root[data-theme="outrun"] body::before{
  inset: auto;
  top: -120px; left: 50%;
  width: 640px; height: 640px;
  margin-left: -320px;
  transform: none;
  animation: none;
  opacity: 1;
  border-radius: 50%;
  background:
    repeating-linear-gradient(to bottom,
      transparent 0 13px,
      rgba(13,5,24,.94) 13px 20px) bottom/100% 55% no-repeat,
    linear-gradient(180deg, #ffe9a8 0%, #ff9a3c 30%, #ff2e88 66%, #b026ff 100%);
  box-shadow: 0 0 180px 70px rgba(255,46,136,.28);
  -webkit-mask-image: linear-gradient(180deg, #000 62%, transparent 100%);
          mask-image: linear-gradient(180deg, #000 62%, transparent 100%);
}

/* Estrelas e vinheta, no lugar das scanlines. */
:root[data-theme="outrun"] body::after{
  inset: 0;
  opacity: 1;
  filter: none;
  background:
    radial-gradient(1.5px 1.5px at 12% 14%, rgba(255,255,255,.7), transparent 100%),
    radial-gradient(1.5px 1.5px at 32% 7%,  rgba(255,255,255,.5), transparent 100%),
    radial-gradient(1.5px 1.5px at 58% 12%, rgba(255,255,255,.6), transparent 100%),
    radial-gradient(1.5px 1.5px at 78% 6%,  rgba(255,255,255,.45), transparent 100%),
    radial-gradient(1.5px 1.5px at 88% 20%, rgba(255,255,255,.55), transparent 100%),
    radial-gradient(130% 100% at 50% 25%, transparent 50%, rgba(6,2,14,.8) 100%);
}

/* ── The grid ───────────────────────────────────────────────────────────────
   Fixed to the bottom of the screen, laid down by perspective()+rotateX. The
   negative left/right are so the vertical lines converge outside the viewport
   instead of ending in view. The mask fades the horizon.

   Only the horizontal lines need to run; animating both in Y is harmless because
   the vertical layer is invariant in Y. */
:root[data-theme="outrun"] .qci-wrap::after{
  content:"";
  position: fixed;
  left: -60%; right: -60%; bottom: -12vh;
  height: 64vh;
  z-index: -1;
  pointer-events: none;
  transform: perspective(300px) rotateX(74deg);
  transform-origin: 50% 100%;
  background:
    repeating-linear-gradient(to right,  rgba(0,229,255,.50) 0 2px, transparent 2px 84px),
    repeating-linear-gradient(to bottom, rgba(255,46,136,.50) 0 2px, transparent 2px 84px);
  animation: outrun-grid 2.4s linear infinite;
  -webkit-mask-image: linear-gradient(to bottom, transparent 0%, #000 30%);
          mask-image: linear-gradient(to bottom, transparent 0%, #000 30%);
}
@keyframes outrun-grid{
  to{ background-position: 0 84px, 0 84px; }
}

/* ── Chrome ─────────────────────────────────────────────────────────────────
   The gradient clipped to the text is the chrome. The hard break in the middle
   (grey at 50%, white at 58%) is what gives the horizon line reflected in the metal. */
:root[data-theme="outrun"] .qci-title{
  background: linear-gradient(180deg,
    #ffffff 0%, #e9d5ff 36%, #8b8fa3 50%, #ffffff 58%, #ff2e88 100%);
  -webkit-background-clip: text;
          background-clip: text;
  color: transparent;
  -webkit-text-fill-color: transparent;
  text-shadow: none;
  filter: drop-shadow(0 0 18px rgba(255,46,136,.5));
}

/* .qci-glitch's chromatic aberration is, in this theme, exactly the right effect —
   but the layers inherited the chrome's transparent fill and vanished. They get
   an explicit colour: cyan on one side, pink on the other. */
:root[data-theme="outrun"] .qci-glitch::before{
  background: none;
  color: #00e5ff;
  -webkit-text-fill-color: #00e5ff;
  filter: none;
  opacity: .55;
}
:root[data-theme="outrun"] .qci-glitch::after{
  background: none;
  color: #ff2e88;
  -webkit-text-fill-color: #ff2e88;
  filter: none;
  opacity: .55;
}

/* ── Neon ───────────────────────────────────────────────────────────────────
   Cards and buttons get a luminous outline instead of a fill. */
:root[data-theme="outrun"] .qci-card{
  border: 1px solid var(--red-40);
  box-shadow:
    0 0 0 1px rgba(0,229,255,.06),
    0 0 40px rgba(255,46,136,.18),
    0 20px 60px rgba(6,2,14,.55);
}
:root[data-theme="outrun"] .qci-card::before,
:root[data-theme="outrun"] .qci-card::after{
  border-color: var(--red-70);
  opacity: .8;
}
:root[data-theme="outrun"] .qci-glowbar{
  height: 2px;
  opacity: 1;
  background: linear-gradient(90deg, transparent, #00e5ff, var(--red), transparent);
  box-shadow: 0 0 12px var(--red-55);
}
:root[data-theme="outrun"] .qci-btn{
  border: 1px solid var(--red-70);
  background: linear-gradient(180deg, var(--red-28), rgba(28,12,52,.6));
  box-shadow: 0 0 14px var(--red-30), inset 0 0 12px rgba(255,46,136,.15);
}
:root[data-theme="outrun"] .qci-btn:hover{
  border-color: #00e5ff;
  box-shadow: 0 0 20px rgba(0,229,255,.45), inset 0 0 14px rgba(255,46,136,.25);
}
:root[data-theme="outrun"] .qci-stat{
  border: 1px solid var(--red-28);
  box-shadow: inset 0 0 30px rgba(255,46,136,.07);
}
:root[data-theme="outrun"] .qci-table th{
  color: #00e5ff;
}

@media (prefers-reduced-motion: reduce){
  :root[data-theme="outrun"] .qci-wrap::after{ animation: none; }
}


/* ═══════════════════════════════════════════════════════════════════════════
   IRIDIUM — structural section

   NOTE — the only rule in this file that is NOT scoped to a theme.
   @property is a top-level at-rule: it cannot live inside a selector, so the
   registration of --iri-angle is global. It is harmless because nothing else in
   the project uses that name, and without it the custom property does not
   interpolate (only registered properties animate) — the foil would sit still
   instead of rotating.

   Fallback: in a browser without @property, --iri-angle is an ordinary custom
   property, the conic-gradient renders at the initial value and the foil is
   STATIC. It degrades to "stationary iridescent border", not to a broken one.
   ═══════════════════════════════════════════════════════════════════════════ */
@property --iri-angle{
  syntax: "<angle>";
  initial-value: 0deg;
  inherits: false;
}
@keyframes iri-spin{ to{ --iri-angle: 360deg; } }

:root[data-theme="iridium"] body{
  background: linear-gradient(180deg, var(--bg0), var(--bg1));
}
/* No grid and no scanlines: the background is plain so the edge is the only thing
   that draws the eye. Only a breath of light remains at the top. */
:root[data-theme="iridium"] body::before{
  animation: none;
  opacity: .5;
  transform: none;
  inset: 0;
  background: radial-gradient(80% 50% at 50% 0%, rgba(129,140,248,.10), transparent 70%);
}
:root[data-theme="iridium"] body::after{
  inset: 0;
  opacity: 1;
  filter: none;
  background: radial-gradient(130% 100% at 50% 30%, transparent 55%, rgba(0,0,0,.8) 100%);
}

/* ── The foil ───────────────────────────────────────────────────────────────
   The two-box trick: the panel is painted in padding-box and the conic in
   border-box, so the gradient only shows in the border band. This is why the
   border has to be transparent and the panel opaque. */
:root[data-theme="iridium"] .qci-card{
  border: 2px solid transparent;
  background:
    linear-gradient(var(--panel), var(--panel)) padding-box,
    conic-gradient(from var(--iri-angle),
      #2dd4bf, #818cf8, #e879f9, #fbbf24, #2dd4bf) border-box;
  animation: iri-spin 12s linear infinite;
  box-shadow: 0 20px 60px rgba(0,0,0,.6);
}

/* The HUD corners go. ::before becomes the diagonal sheen that crosses the card
   when the mouse is on it — the "tilt of the foil". */
:root[data-theme="iridium"] .qci-card::before{
  left: 0; top: 0;
  width: 100%; height: 100%;
  border: none;
  border-radius: inherit;
  opacity: 0;
  transition: opacity .35s ease;
  background: linear-gradient(115deg,
    transparent 30%,
    rgba(255,255,255,.10) 44%,
    rgba(232,121,249,.16) 50%,
    rgba(45,212,191,.14) 56%,
    transparent 70%);
}
:root[data-theme="iridium"] .qci-card:hover::before{ opacity: 1; }
:root[data-theme="iridium"] .qci-card::after{ display: none; }

/* The sweep goes: with the foil rotating and the sheen on hover, a third
   animation per card only muddies things. */
:root[data-theme="iridium"] .qci-sweep{ display: none; }

/* Buttons with the same foil at a smaller scale. */
:root[data-theme="iridium"] .qci-btn{
  border: 1.5px solid transparent;
  background:
    linear-gradient(rgba(20,20,30,.94), rgba(20,20,30,.94)) padding-box,
    conic-gradient(from var(--iri-angle),
      #2dd4bf, #818cf8, #e879f9, #fbbf24, #2dd4bf) border-box;
  animation: iri-spin 12s linear infinite;
  box-shadow: none;
  color: var(--text);
}
:root[data-theme="iridium"] .qci-btn:hover{
  background:
    linear-gradient(rgba(32,32,46,.94), rgba(32,32,46,.94)) padding-box,
    conic-gradient(from var(--iri-angle),
      #2dd4bf, #818cf8, #e879f9, #fbbf24, #2dd4bf) border-box;
  animation-duration: 4s;
  box-shadow: 0 0 24px rgba(129,140,248,.25);
  transform: none;
}

/* ── Pearl ──────────────────────────────────────────────────────────────────
   Typography and chrome stay neutral. The title's shadow is the only licence: a
   very faint iridescent halo. */
:root[data-theme="iridium"] .qci-title{
  color: #eef0f8;
  text-shadow: 0 0 24px rgba(129,140,248,.35), 0 0 48px rgba(232,121,249,.18);
}
:root[data-theme="iridium"] .qci-glowbar{
  height: 1px;
  opacity: .9;
  background: linear-gradient(90deg,
    transparent, #2dd4bf, #818cf8, #e879f9, #fbbf24, transparent);
}
:root[data-theme="iridium"] .qci-stat{
  background: rgba(255,255,255,.025);
  border: 1px solid var(--ov-08);
}
:root[data-theme="iridium"] .qci-terminal,
:root[data-theme="iridium"] .qci-input,
:root[data-theme="iridium"] .qci-textarea,
:root[data-theme="iridium"] select.qci-input{
  background: rgba(0,0,0,.45);
  border: 1px solid var(--ov-08);
}

@media (prefers-reduced-motion: reduce){
  :root[data-theme="iridium"] .qci-card,
  :root[data-theme="iridium"] .qci-btn{ animation: none; }
}


/* ═══════════════════════════════════════════════════════════════════════════
   IBM 3270 — structural section
   Everything here is scoped to :root[data-theme^="ibm3270"] — the green theme
   and its Blue and Red variants share it. No rule may escape that. Colours come
   from the --i3270-* tokens of each theme's block, never from literals.

   The theme derives from :root, so the base dark chrome — the red HUD corners,
   the gradients, the spinning reactor — still applies until a rule below
   replaces it. The reference is an ISPF panel on a 3279: a black screen, a
   frame drawn in characters, fields that are either normal or intensified, a
   cursor that blinks, and the PF-key line at the bottom. Nothing is rounded,
   nothing is glass, and the only thing that moves is the scan.
   ═══════════════════════════════════════════════════════════════════════════ */

/* ── The screen ─────────────────────────────────────────────────────────────
   Flat black with a breath of phosphor at the top, where a CRT is brightest.
   The 64px grid goes; scanlines stay, because they are the whole point, and a
   single soft band rolls down the screen the way an unsynced CRT rolls. */
:root[data-theme^="ibm3270"] body{
  background: #000000;
}
:root[data-theme^="ibm3270"] body::before{
  inset: 0;
  transform: none;
  animation: none;
  opacity: 1;
  background:
    repeating-linear-gradient(
      to bottom,
      rgba(0,0,0,.42),
      rgba(0,0,0,.42) 1px,
      transparent 1px,
      transparent 3px
    ),
    radial-gradient(90% 55% at 50% 0%, rgba(var(--i3270-rgb),.07), transparent 72%);
}
:root[data-theme^="ibm3270"] body::after{
  inset: 0;
  opacity: 1;
  filter: none;
  background:
    linear-gradient(to bottom,
      transparent 0%, rgba(var(--i3270-rgb),.05) 45%, rgba(var(--i3270-rgb),.07) 50%,
      rgba(var(--i3270-rgb),.05) 55%, transparent 100%),
    radial-gradient(130% 100% at 50% 45%, transparent 52%, rgba(0,0,0,.75) 100%);
  background-size: 100% 220%, 100% 100%;
  background-repeat: no-repeat;
  animation: q3270-roll 7.5s linear infinite;
}
@keyframes q3270-roll{
  from{ background-position: 0 -120%, 0 0; }
  to  { background-position: 0  120%, 0 0; }
}

/* Selected text is the 3270 cursor: the field inverts. */
:root[data-theme^="ibm3270"] ::selection{
  background: var(--red);
  color: #000000;
}

/* ── Panels ─────────────────────────────────────────────────────────────────
   A card is a region of the screen boxed in phosphor, not a pane of glass: one
   hairline border, one inset hairline for the doubled rule an ISPF panel draws,
   no blur and no drop shadow. The HUD corners belong to another century. */
:root[data-theme^="ibm3270"] .qci-card{
  border: 1px solid var(--red-35);
  background: var(--panel);
  backdrop-filter: none;
  box-shadow: inset 0 0 0 1px rgba(var(--i3270-rgb),.06), var(--shadow);
}
:root[data-theme^="ibm3270"] .qci-card::before,
:root[data-theme^="ibm3270"] .qci-card::after{ display: none; }

/* The sweep is a property of the screen here, not of each panel: it rolls in
   body::after above, once, for everything. */
:root[data-theme^="ibm3270"] .qci-sweep{ display: none; }

/* ── Type ───────────────────────────────────────────────────────────────────
   The title is the panel name at the top of an ISPF screen, in the pixel
   terminal face, with the bloom a phosphor tube gives a bright glyph. */
:root[data-theme^="ibm3270"] .qci-title{
  font-family: 'VT323', var(--mono);
  font-weight: 400;
  font-size: 34px;
  letter-spacing: .10em;
  color: var(--i3270-hi);
  text-shadow: 0 0 10px rgba(var(--i3270-rgb),.55), 0 0 26px rgba(var(--i3270-rgb),.25);
}
@media (max-width: 820px){
  :root[data-theme^="ibm3270"] .qci-title{ font-size: 24px; }
}
/* The ghosting stays — a CRT does that — but tighter, and without the colour
   fringes, which belong to a badly converged monitor and not to this one. */
:root[data-theme^="ibm3270"] .qci-glitch{ text-shadow: 0 0 14px rgba(var(--i3270-rgb),.35); }

/* The separator an ISPF panel draws under its title: one solid rule, edge to
   edge, no fade. */
:root[data-theme^="ibm3270"] .qci-glowbar{
  height: 1px;
  opacity: 1;
  background: var(--red-45);
}

/* ── Fields ─────────────────────────────────────────────────────────────────
   A 3270 input field is a stretch of the screen you are allowed to type on:
   slightly lit, underscored, square. The caret is the cursor, in the phosphor. */
:root[data-theme^="ibm3270"] .qci-input,
:root[data-theme^="ibm3270"] .qci-textarea,
:root[data-theme^="ibm3270"] select.qci-input,
:root[data-theme^="ibm3270"] .qci-inline-select{
  border: none;
  border-bottom: 1px solid var(--red-40);
  border-radius: 0;
  background: rgba(var(--i3270-rgb),.06);
  color: var(--i3270-hi);
  caret-color: var(--red);
  font-family: var(--mono);
}
:root[data-theme^="ibm3270"] .qci-input:focus,
:root[data-theme^="ibm3270"] .qci-textarea:focus,
:root[data-theme^="ibm3270"] select.qci-input:focus,
:root[data-theme^="ibm3270"] .qci-inline-select:focus{
  border-bottom-color: var(--red);
  box-shadow: inset 0 -2px 0 0 rgba(var(--i3270-rgb),.35);
  background: rgba(var(--i3270-rgb),.10);
}
:root[data-theme^="ibm3270"] .qci-input::placeholder,
:root[data-theme^="ibm3270"] .qci-textarea::placeholder{ color: var(--muted-2); }

/* ── PF keys ────────────────────────────────────────────────────────────────
   Buttons are the function-key line: square, outlined, and on hover the field
   inverts — which is the only way a 3270 ever highlighted anything. */
:root[data-theme^="ibm3270"] .qci-btn{
  border-radius: 0;
  border: 1px solid var(--red-55);
  background: rgba(var(--i3270-rgb),.05);
  color: var(--i3270-hi);
  font-family: var(--mono);
  font-weight: 400;
  box-shadow: none;
}
:root[data-theme^="ibm3270"] .qci-btn:hover{
  background: var(--red);
  border-color: var(--red);
  color: #000000;
  box-shadow: 0 0 14px rgba(var(--i3270-rgb),.35);
  transform: none;
}
:root[data-theme^="ibm3270"] .qci-btn:active{ background: var(--red-70); }
:root[data-theme^="ibm3270"] .qci-btn-sm{ border-radius: 0; }
/* The coloured buttons keep their meaning — a 3279 had six colours and used
   them for exactly this — but lose the gradient and the glow. */
:root[data-theme^="ibm3270"] .qci-btn-ghost{ background: transparent; }
:root[data-theme^="ibm3270"] .qci-btn-danger:hover{ background: var(--danger); border-color: var(--danger); color: #000000; }
:root[data-theme^="ibm3270"] .qci-btn-green:hover{ background: var(--ok-solid); border-color: var(--ok-solid); color: #000000; }
:root[data-theme^="ibm3270"] .qci-btn-blue:hover{ background: var(--info-solid); border-color: var(--info-solid); color: #000000; }

/* ── Tags, tabs, the small chrome ───────────────────────────────────────────
   Square. A pill is an injection-moulded shape and there were none on a CRT. */
:root[data-theme^="ibm3270"] .qci-tag{
  border-radius: 0;
  border-color: var(--red-25);
  background: rgba(var(--i3270-rgb),.05);
  font-family: var(--mono);
}
:root[data-theme^="ibm3270"] .qci-help-btn{
  border-radius: 0;
  border-color: var(--red-25);
}
:root[data-theme^="ibm3270"] .qci-tab{ border-radius: 0; }
:root[data-theme^="ibm3270"] .qci-tab.is-current{
  background: var(--red);
  color: #000000;
}

/* ── Tables ─────────────────────────────────────────────────────────────────
   Column heads are intensified and underscored; the row under the pointer
   lights up rather than greying, because that is what a lit row does. */
:root[data-theme^="ibm3270"] .qci-table th{
  color: var(--i3270-hi);
  border-bottom: 1px solid var(--red-40);
  font-family: var(--mono);
}
:root[data-theme^="ibm3270"] .qci-table td{ border-bottom: 1px solid rgba(var(--i3270-rgb),.10); }
:root[data-theme^="ibm3270"] .qci-table tr:hover td{ background: rgba(var(--i3270-rgb),.07); }

/* ── Messages ───────────────────────────────────────────────────────────────
   The short message line of an ISPF panel. An error is RED on a 3270 — it is
   the one place the accent must not be used, because green there would read as
   "fine". Success keeps the phosphor. */
:root[data-theme^="ibm3270"] .qci-error{
  border-radius: 0;
  border-color: var(--danger-30);
  background: var(--danger-09);
  color: var(--i3270-err);
}
:root[data-theme^="ibm3270"] .qci-success{
  border-radius: 0;
}

/* ── Menus and modals ───────────────────────────────────────────────────────
   The action-bar pull-down: black, boxed in phosphor, inverting under the
   pointer. */
:root[data-theme^="ibm3270"] .qci-dropdown-menu,
:root[data-theme^="ibm3270"] .qci-dropdown-submenu-flyout{
  border-radius: 0;
  border: 1px solid var(--red-35);
  background: var(--i3270-menu);
  backdrop-filter: none;
}
:root[data-theme^="ibm3270"] .qci-dropdown-menu a:hover,
:root[data-theme^="ibm3270"] .qci-dropdown-menu button:hover,
:root[data-theme^="ibm3270"] .qci-dropdown-submenu-flyout a:hover{
  background: var(--red);
  color: #000000;
}
:root[data-theme^="ibm3270"] .qci-modal-box{
  border-radius: 0;
  border: 1px solid var(--red-35);
  background: var(--panel-solid);
}
:root[data-theme^="ibm3270"] .qci-modal-close{ border-radius: 0; }
:root[data-theme^="ibm3270"] .qci-terminal,
:root[data-theme^="ibm3270"] .qci-stat{
  border-radius: 0;
  background: rgba(var(--i3270-rgb),.04);
  border: 1px solid var(--red-20);
}

/* ── The cursor ─────────────────────────────────────────────────────────────
   The reactor is the one ornament with no 3270 equivalent, so it becomes the
   thing every terminal has instead: the block cursor, blinking at the rate the
   3270 blinked at. The three rings go. */
:root[data-theme^="ibm3270"] .qci-reactor-ring{ display: none; }
:root[data-theme^="ibm3270"] .qci-reactor-core{
  inset: 10px 16px;
  border-radius: 0;
  background: var(--red);
  box-shadow: 0 0 12px rgba(var(--i3270-rgb),.6), 0 0 28px rgba(var(--i3270-rgb),.3);
  animation: q3270-blink 1.06s steps(1, end) infinite;
}
@keyframes q3270-blink{
  0%, 49%   { opacity: 1; }
  50%, 100% { opacity: 0; }
}

/* ── The status line ────────────────────────────────────────────────────────
   Ornament, and labelled as one: the band a 3270 emulator puts above the
   screen. It says what the theme is and nothing more — no counter here
   pretends to be reading anything. .qci-wrap is on every page that loads this
   file, and ::before is free. */
:root[data-theme^="ibm3270"] .qci-wrap::before{
  /* The middle dots are literal: a \00b7 escape swallows the space after it,
     and the band came out as "QCI \00b73270 DISPLAY STATION". */
  content: "QCI · 3270 DISPLAY STATION · MODEL 2 · 24x80";
  display: block;
  margin: -14px 0 18px;
  padding: 3px 0;
  border-bottom: 1px solid var(--red-20);
  color: var(--muted);
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: .18em;
  text-transform: uppercase;
}

@media (prefers-reduced-motion: reduce){
  :root[data-theme^="ibm3270"] body::after{ animation: none; }
  :root[data-theme^="ibm3270"] .qci-reactor-core{ animation: none; opacity: 1; }
}

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

   The theme takes the light themes' shared TOKENS (it is in that selector) but
   not their grouped structural rules: those are the Fujitsu look. So the base
   dark chrome — glows, HUD corners, gradients, spinning reactor — still applies
   to this theme until a rule below replaces it. This section therefore covers
   every shared class the :root chrome styles, one by one.

   Reference: Program Manager on the default "Windows Default" scheme — teal
   desktop, grey windows with 3D bevels, navy title bar with white text, white
   sunken fields, white menus with a hard black shadow. Nothing rounded, nothing
   glowing, nothing moving. The bevels are the --w31-* tokens defined in the
   theme's token block; no literal is written here.
   ═══════════════════════════════════════════════════════════════════════════ */

/* ── Desktop ────────────────────────────────────────────────────────────────
   Flat teal. The grid, the scanlines and their qci-grid animation go entirely
   — display:none is cheaper than repainting them transparent. */
:root[data-theme="win311"] body{
  background: var(--w31-teal);
}
:root[data-theme="win311"] body::before,
:root[data-theme="win311"] body::after{
  display: none;
}
:root[data-theme="win311"] .qci-sweep{ display: none; }

/* Text that sits directly on the desktop (a caption outside any card): black
   is 4.4:1 on the teal, white is 4.8:1. */
:root[data-theme="win311"] .qci-wrap > .qci-muted{ color: var(--w31-white); }

/* ── Windows ────────────────────────────────────────────────────────────────
   A card is a window: black outline, raised ring inside it, no shadow, no
   blur. The HUD corners have no equivalent in Windows and go. */
:root[data-theme="win311"] .qci-card{
  border: 1px solid var(--w31-black);
  background: var(--panel);
  box-shadow: var(--w31-frame);
  backdrop-filter: none;
}
:root[data-theme="win311"] .qci-card::before,
:root[data-theme="win311"] .qci-card::after{ display: none; }

/* The glow bar becomes the etched separator every window has under its menu
   bar: a dark line with a white line below it. */
:root[data-theme="win311"] .qci-glowbar{
  height: 2px;
  margin: 10px 0 14px;
  background: none;
  opacity: 1;
  border-top: 1px solid var(--w31-dark);
  border-bottom: 1px solid var(--w31-white);
}

/* ── Title bar ──────────────────────────────────────────────────────────────
   There is no shared header in PHP, but .qci-reactor appears exactly once per
   page (the sentinel ZX and Blueprint already use) and on all 28 pages the row
   holding it is .qci-pagehead, whose inline style only sets the flex layout.
   So the row itself becomes the navy title bar: pulled out to 4px inside the
   card's border (the header card's padding is 24px on every page; 4px is
   Windows' sizing frame — a page that changes that padding breaks the band).
   The title, the reactor tile, the tags and the Theme dropdown are its
   children and sit on the navy without touching markup. The dropdown menu is
   position:absolute inside it and is not clipped — nothing here has
   overflow:hidden, and nothing may. */
:root[data-theme="win311"] .qci-card:has(.qci-reactor) .qci-pagehead{
  margin: -20px -20px 0;
  padding: 6px 8px;
  background: var(--w31-navy);
  color: var(--w31-on-navy);
  border-bottom: 1px solid var(--w31-black);
  /* Page-local captions on the band (crypto_dashboard.php's refresh badge)
     paint with the muted tokens; re-scoped here so they read on the navy. */
  --muted:   var(--w31-light);
  --muted-2: var(--w31-light);
  --muted-3: var(--w31-light);
  --muted-4: var(--w31-light);
  --label:   var(--w31-light);
}
/* The phone layer pads the card at 14px and 12px; the band keeps its 4px
   frame at both tiers. */
@media (max-width: 820px){
  :root[data-theme="win311"] .qci-card:has(.qci-reactor) .qci-pagehead{ margin: -10px -10px 0; }
}
@media (max-width: 480px){
  :root[data-theme="win311"] .qci-card:has(.qci-reactor) .qci-pagehead{ margin: -8px -8px 0; }
}
:root[data-theme="win311"] .qci-card:has(.qci-reactor) .qci-pagehead .qci-title{
  color: var(--w31-on-navy);
}
:root[data-theme="win311"] .qci-card:has(.qci-reactor) .qci-pagehead .qci-muted{
  color: var(--w31-light);
}
/* USER / QCIADMINS / Theme pills become the title bar's buttons: grey, raised,
   black text — including the red admin tag, which would vanish on navy. */
:root[data-theme="win311"] .qci-card:has(.qci-reactor) .qci-pagehead .qci-tag,
:root[data-theme="win311"] .qci-card:has(.qci-reactor) .qci-pagehead .qci-btn-ghost{
  background: var(--w31-grey);
  border: 1px solid;
  border-color: var(--w31-edge-raised);
  box-shadow: var(--w31-raised);
  color: var(--w31-black);
}
:root[data-theme="win311"] .qci-card:has(.qci-reactor) .qci-pagehead .qci-tag:hover,
:root[data-theme="win311"] .qci-card:has(.qci-reactor) .qci-pagehead .qci-btn-ghost:hover{
  background: var(--w31-light);
  border-color: var(--w31-edge-raised);
  color: var(--w31-black);
}

/* ── Title: the pixel font, kept to the title ───────────────────────────────
   Pixelify Sans ships 400-700, so 700 rather than the base 950 (which the
   browser would fake). Mixed case: Windows 3.1 title bars were bold mixed
   case, and uppercase in a pixel face at this size is wider than the header
   on the narrower pages. No glow — nothing in this theme glows. */
:root[data-theme="win311"] .qci-title{
  font-family: 'Pixelify Sans', var(--font);
  font-weight: 700;
  font-size: 26px;
  letter-spacing: .02em;
  text-transform: none;
  text-shadow: none;
  color: var(--text);
}
/* qci-responsive.css shrinks .qci-title to 19px at this width with a lower
   specificity than the rule above, so the phone size is restated here. */
@media (max-width: 820px){
  :root[data-theme="win311"] .qci-title{ font-size: 20px; }
}
/* No chromatic aberration in Windows 3.1. */
:root[data-theme="win311"] .qci-glitch{ text-shadow: none; }
:root[data-theme="win311"] .qci-glitch::before,
:root[data-theme="win311"] .qci-glitch::after{ display: none; }

/* ── Program Manager icon ───────────────────────────────────────────────────
   The reactor stops: no rings, no spin, no glow. The 52px box becomes a raised
   grey tile (it doubles as the title bar's system-menu box) and the core
   becomes a static icon of a window — navy title stripe over white, black
   outline. */
:root[data-theme="win311"] .qci-reactor{
  background: var(--w31-grey);
  border: 1px solid;
  border-color: var(--w31-edge-raised);
  box-shadow: var(--w31-raised);
}
:root[data-theme="win311"] .qci-reactor-ring{ display: none; }
:root[data-theme="win311"] .qci-reactor-core{
  inset: 13px;
  border-radius: 0;
  border: 1px solid var(--w31-black);
  background: linear-gradient(180deg, var(--w31-navy) 0 7px, var(--w31-white) 7px);
  box-shadow: 1px 1px 0 var(--w31-dark);
  animation: none;
}

/* ── Buttons ────────────────────────────────────────────────────────────────
   Grey, bevelled, bold mixed case in the UI font (Windows 3.1 dialog buttons
   were bold). No gradient, no glow, no lift; :active inverts the bevel and
   shifts the label a pixel, as the real control did. Disabled = engraved grey
   text, not a faded button. The four variants keep the same chrome and differ
   only by their text colour; danger is maroon because there the colour means
   "destructive action", not the accent, as in the other nine themes. */
:root[data-theme="win311"] .qci-btn{
  background: var(--w31-grey);
  border: 1px solid;
  border-color: var(--w31-edge-raised);
  border-radius: 0;
  box-shadow: var(--w31-raised);
  color: var(--w31-black);
  font-family: var(--font);
  font-weight: 700;
  font-size: 13px;
  letter-spacing: .02em;
  text-transform: none;
  transition: none;
}
:root[data-theme="win311"] .qci-btn:hover{
  background: var(--w31-light);
  border-color: var(--w31-edge-raised);
  box-shadow: var(--w31-raised);
  transform: none;
}
:root[data-theme="win311"] .qci-btn:active{
  background: var(--w31-grey);
  border-color: var(--w31-edge-pressed);
  box-shadow: var(--w31-pressed);
  transform: translate(1px, 1px);
}
:root[data-theme="win311"] .qci-btn:disabled,
:root[data-theme="win311"] .qci-btn:disabled:hover{
  opacity: 1;
  background: var(--w31-grey);
  color: var(--w31-dark);
  text-shadow: 1px 1px 0 var(--w31-white);
  transform: none;
}
:root[data-theme="win311"] .qci-btn-sm{ font-size: 12px; border-radius: 0; }
:root[data-theme="win311"] .qci-btn-ghost{ color: var(--muted); }
:root[data-theme="win311"] .qci-btn-ghost:hover{ color: var(--w31-black); }
:root[data-theme="win311"] .qci-btn-blue{ color: var(--w31-navy); }
:root[data-theme="win311"] .qci-btn-blue:hover{ color: var(--w31-navy); }
:root[data-theme="win311"] .qci-btn-green{ color: var(--w31-green); }
:root[data-theme="win311"] .qci-btn-green:hover{ color: var(--w31-green); }
:root[data-theme="win311"] .qci-btn-danger{ color: var(--w31-maroon); }
:root[data-theme="win311"] .qci-btn-danger:hover{ color: var(--w31-maroon); }

/* ── Tags: status-bar panels ────────────────────────────────────────────────
   Square, thinly sunken, black text. The coloured variants keep their meaning
   through the state solids, which this theme darkened for the grey. */
:root[data-theme="win311"] .qci-tag{
  background: var(--w31-grey);
  border: 1px solid;
  border-color: var(--w31-edge-sunken);
  border-radius: 0;
  box-shadow: none;
  color: var(--tag-text);
}
:root[data-theme="win311"] .qci-tag-red{    color: var(--w31-maroon); }
:root[data-theme="win311"] .qci-tag-green{  color: var(--ok-solid); }
:root[data-theme="win311"] .qci-tag-yellow{ color: var(--warn-solid); }
:root[data-theme="win311"] .qci-tag-blue{   color: var(--info-b-solid); }
:root[data-theme="win311"] .qci-theme-pick > button.qci-tag:hover{
  border-color: var(--w31-edge-sunken);
  color: var(--tag-text);
}

/* ── Fields: white, sunken ──────────────────────────────────────────────────
   The 4px halo becomes a 1px navy ring outside the sunken edge. */
:root[data-theme="win311"] .qci-input,
:root[data-theme="win311"] .qci-textarea,
:root[data-theme="win311"] select.qci-input,
:root[data-theme="win311"] .qci-inline-select{
  background: var(--w31-white);
  border: 1px solid;
  border-color: var(--w31-edge-sunken);
  border-radius: 0;
  box-shadow: var(--w31-sunken);
  color: var(--text);
}
:root[data-theme="win311"] .qci-input:focus,
:root[data-theme="win311"] .qci-textarea:focus,
:root[data-theme="win311"] select.qci-input:focus,
:root[data-theme="win311"] .qci-inline-select:focus{
  border-color: var(--w31-edge-sunken);
  box-shadow: var(--w31-sunken), var(--w31-focus);
}
:root[data-theme="win311"] .qci-terminal{
  background: var(--w31-white);
  border: 1px solid;
  border-color: var(--w31-edge-sunken);
  border-radius: 0;
  box-shadow: var(--w31-sunken);
  color: var(--term-text);
}

/* ── Message boxes ──────────────────────────────────────────────────────────
   Errors and successes are small dialogs: grey, framed, square. They also sit
   outside the cards on some pages (the flash), where a navy tint on teal would
   be unreadable. */
:root[data-theme="win311"] .qci-error,
:root[data-theme="win311"] .qci-success{
  background: var(--w31-grey);
  border: 1px solid var(--w31-black);
  border-radius: 0;
  box-shadow: var(--w31-frame);
}

/* ── Tabs ───────────────────────────────────────────────────────────────────
   Raised grey tabs on a dark rule; the current one is the selection: navy
   with white text. */
:root[data-theme="win311"] .qci-tabs{ border-bottom: 1px solid var(--w31-dark); }
:root[data-theme="win311"] .qci-tab{
  background: var(--w31-grey);
  border: 1px solid;
  border-color: var(--w31-edge-raised);
  border-bottom: none;
  border-radius: 0;
  box-shadow: var(--w31-raised);
  color: var(--text);
  font-family: var(--font);
  font-weight: 700;
  font-size: 13px;
  letter-spacing: .02em;
  text-transform: none;
  transition: none;
}
:root[data-theme="win311"] .qci-tab:hover{
  background: var(--w31-light);
  color: var(--text);
}
:root[data-theme="win311"] .qci-tab.is-current{
  background: var(--w31-navy);
  border-color: var(--w31-black);
  box-shadow: none;
  color: var(--w31-on-navy);
}

/* ── Tables ─────────────────────────────────────────────────────────────────
   A list box: grey header on a dark rule, light rules between rows. The hover
   is a light grey and NOT the navy selection on purpose: rows carry inline
   style="color:…" P&L colours that would sit on navy at 1.5:1. Navy is kept
   for the states that really are "selected" (tabs, menu item, calendar/hive
   tabs). */
:root[data-theme="win311"] .qci-table th{
  background: var(--w31-grey);
  color: var(--text);
  border-bottom: 1px solid var(--w31-dark);
}
:root[data-theme="win311"] .qci-table td{
  border-bottom: 1px solid var(--w31-light);
}
:root[data-theme="win311"] .qci-table tr:hover td{
  background: var(--w31-light);
}
:root[data-theme="win311"] .qci-table-totals td,
:root[data-theme="win311"] .qci-table tr.qci-table-totals:hover td{
  background: var(--w31-light);
  border-top: 1px solid var(--w31-dark);
  color: var(--text);
}

/* ── Stat tiles: group boxes ────────────────────────────────────────────────
   The etched frame of a Windows group box: dark line, white line offset. */
:root[data-theme="win311"] .qci-stat{
  background: var(--w31-grey);
  border: 1px solid var(--w31-dark);
  border-radius: 0;
  box-shadow: var(--w31-etched);
}

/* ── Menus ──────────────────────────────────────────────────────────────────
   White, black 1px border, hard 2px black shadow, UI font instead of mono.
   Hover and the current theme are the Windows selection: navy, white text.
   The ✓ on the current theme is inherited from the base rule. The menu keeps
   its overflow:hidden (the :has() release for flyouts still applies); with
   the radius at 0 it clips nothing visible. */
:root[data-theme="win311"] .qci-dropdown-menu,
:root[data-theme="win311"] .qci-dropdown-submenu-flyout{
  background: var(--w31-white);
  border: 1px solid var(--w31-black);
  border-radius: 0;
  box-shadow: var(--w31-menu-shadow);
  padding-top: 2px;
}
:root[data-theme="win311"] .qci-dropdown-menu a,
:root[data-theme="win311"] .qci-dropdown-menu button,
:root[data-theme="win311"] .qci-dropdown-menu .qci-dropdown-placeholder,
:root[data-theme="win311"] .qci-dropdown-submenu-label,
:root[data-theme="win311"] .qci-dropdown-submenu-flyout a{
  font-family: var(--font);
  font-size: 13px;
  letter-spacing: 0;
  padding: 6px 24px 6px 16px;
  color: var(--text);
  border-bottom: none;
  transition: none;
}
:root[data-theme="win311"] .qci-dropdown-menu a:hover,
:root[data-theme="win311"] .qci-dropdown-menu button:hover,
:root[data-theme="win311"] .qci-dropdown-menu button.is-current,
:root[data-theme="win311"] .qci-dropdown-submenu:hover .qci-dropdown-submenu-label,
:root[data-theme="win311"] .qci-dropdown-submenu:focus-within .qci-dropdown-submenu-label,
:root[data-theme="win311"] .qci-dropdown-submenu-flyout a:hover{
  background: var(--w31-navy);
  color: var(--w31-on-navy);
}
/* A placeholder is a disabled menu item: engraved grey. */
:root[data-theme="win311"] .qci-dropdown-menu .qci-dropdown-placeholder,
:root[data-theme="win311"] .qci-dropdown-menu .qci-dropdown-placeholder:hover{
  background: none;
  color: var(--w31-dark);
  text-shadow: 1px 1px 0 var(--w31-white);
}

/* ── Help button, modal, tooltip ────────────────────────────────────────────
   Square bevelled "?" and "×"; the modal is a dialog (grey, framed, hard
   shadow); the tooltip likewise. */
:root[data-theme="win311"] .qci-help-btn,
:root[data-theme="win311"] .qci-modal-close{
  border-radius: 0;
  background: var(--w31-grey);
  border: 1px solid;
  border-color: var(--w31-edge-raised);
  box-shadow: var(--w31-raised);
  color: var(--w31-black);
  font-family: var(--font);
}
:root[data-theme="win311"] .qci-help-btn:hover,
:root[data-theme="win311"] .qci-modal-close:hover{
  background: var(--w31-light);
  border-color: var(--w31-edge-raised);
  color: var(--w31-black);
}
:root[data-theme="win311"] .qci-modal-box{
  background: var(--panel-solid);
  border: 1px solid var(--w31-black);
  box-shadow: var(--w31-frame), var(--w31-menu-shadow);
}
:root[data-theme="win311"] .qci-modal-title{ font-family: var(--font); }
:root[data-theme="win311"] .qci-tip{
  border: 1px solid var(--w31-black);
  box-shadow: var(--w31-menu-shadow);
}

/* ── Engine stopped ─────────────────────────────────────────────────────────
   The liveness dot stays (it is a signal, not decoration) but becomes a
   square LED that 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="win311"] .qci-pulse{
  animation: none;
  box-shadow: none;
  border-radius: 0;
}

/* ── One-off page corrections ───────────────────────────────────────────────
   Same precedent as the light themes' .view-tab.active rule: page-local
   classes that set a radius or an accent-tinted "selected" state. */
:root[data-theme="win311"] .view-tab{
  border-radius: 0;
  background: var(--w31-grey);
  border: 1px solid;
  border-color: var(--w31-edge-raised);
  color: var(--text);
}
:root[data-theme="win311"] .view-tab.active,
:root[data-theme="win311"] .hive-tab.active{
  background: var(--w31-navy);
  border-color: var(--w31-black);
  color: var(--w31-on-navy);
}
/* dashboard.php's telemetry tiles sit directly on the desktop (not in a card)
   with a near-transparent --sink-06: on the teal their text would be 2-4:1.
   They become Program Manager group windows. */
:root[data-theme="win311"] .dash-stat{
  background: var(--w31-grey);
  border: 1px solid var(--w31-black);
  border-radius: 0;
  box-shadow: var(--w31-frame);
}
/* The dashboard's centrepiece is the reactor scaled 7x with an animated HUD of
   rings and corner brackets around it. A 364px bevelled tile is not a Program
   Manager icon, so the scale drops to 3 (the page's own breakpoints only
   lower it further, and lose to this rule's specificity) and the HUD — the one
   thing on the page that still moved — is hidden. */
:root[data-theme="win311"] .dash-reactor{ --dash-reactor-scale: 3; }
:root[data-theme="win311"] .dash-hud,
:root[data-theme="win311"] .dash-corner{ display: none; }
/* crypto_dashboard.php / crypto_dashboard_global.php: the P&L tiles above the
   cards sit on the desktop with a near-transparent --ov-03 gradient — grey
   text on teal. Same treatment as .dash-stat; the coloured accent stripe on
   top (their ::before) stays. */
:root[data-theme="win311"] .stat-tile{
  background: var(--w31-grey);
  border: 1px solid var(--w31-black);
  border-radius: 0;
  box-shadow: var(--w31-frame);
}
/* The phone layer's burger (qci-responsive.css, loaded after this file but at
   class specificity) is an accent-tinted rounded pill; here it is a button. */
:root[data-theme="win311"] .qci-nav-burger{
  background: var(--w31-grey);
  border: 1px solid;
  border-color: var(--w31-edge-raised);
  border-radius: 0;
  box-shadow: var(--w31-raised);
  color: var(--w31-black);
  font-family: var(--font);
  font-weight: 700;
  letter-spacing: .02em;
  text-transform: none;
}
/* The open state is an id selector in qci-responsive.css and beats the rule
   above, so it is restated at id specificity: a pressed button. */
:root[data-theme="win311"] #qci-nav-toggle:checked ~ .qci-nav-burger{
  background: var(--w31-light);
  border-color: var(--w31-edge-pressed);
  box-shadow: var(--w31-pressed);
}

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

   Same architecture as Windows 3.11: the theme takes the light themes' shared
   TOKENS (it is in that selector) but not their grouped structural rules, so
   the base dark chrome — glows, HUD corners, gradients, spinning reactor —
   still applies until a rule below replaces it. This section therefore covers
   every shared class the :root chrome styles, one by one, in the same order
   as the Windows 3.11 section.

   Reference: Luna Blue, 2001 — the Bliss desktop, beige dialogs with a blue
   frame and rounded top corners, a blue gradient title bar with white bold
   text, white-to-beige push buttons with an orange hover ring, white fields
   with a blue-grey border, white menus with a hard shadow and a blue
   selection. Nothing glows, nothing moves. Every colour is an --xp-* token
   from the theme's token block; no literal is written here.
   ═══════════════════════════════════════════════════════════════════════════ */

/* ── Desktop: Bliss ─────────────────────────────────────────────────────────
   The photograph itself, served from this site (/assets/bliss.jpg — the CSP
   is default-src 'self', so it has to live here; the ?v= is for Cloudflare's
   cache, bump it when the file changes). body paints the sky's top flat (the
   canvas); body::before paints the picture on a fixed, viewport-sized layer
   with the CSS sky gradient underneath as the fallback while it loads or if
   it ever 404s. cover + center bottom keeps the hill in frame at any ratio.
   z-index:-1 puts it under every in-flow element — the base pseudo is
   z-index:auto, which is fine for a 7% grid and would hide the topnav under
   an opaque desktop. position:fixed gives it its own compositor layer, so
   scrolling does not repaint it. The scanline layer and the card sweep go
   entirely.

   The file is the owner's 3840x2160 JPEG of the photograph, ~1 MB (the
   original is Microsoft's); to change it, drop the new file over the same
   path and bump ?v= — nothing else changes. */
:root[data-theme="winxp"] body{
  background: var(--xp-sky-1);
}
:root[data-theme="winxp"] body::before{
  content: "";
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  opacity: 1;
  transform: none;
  animation: none;
  filter: none;
  background:
    url('/assets/bliss.jpg?v=3') center bottom / cover no-repeat,
    linear-gradient(180deg, var(--xp-sky-1) 0%, var(--xp-sky-2) 45%, var(--xp-sky-3) 78%, var(--xp-sky-3) 100%);
}
:root[data-theme="winxp"] body::after{ display: none; }
:root[data-theme="winxp"] .qci-sweep{ display: none; }

/* Text that sits directly on the desktop (a caption outside any card) is an
   XP desktop-icon label: white with a dark drop shadow. White is 4.9:1 on
   the sky's top and less further down; the shadow is what makes it read
   over a photograph, as it did in 2001. */
:root[data-theme="winxp"] .qci-wrap > .qci-muted{
  color: var(--xp-white);
  text-shadow: var(--xp-label-shadow);
}

/* ── Windows ────────────────────────────────────────────────────────────────
   A card is a dialog panel: beige, a 1px edge, 3px corners, a short soft
   shadow, no blur. The HUD corners have no equivalent in XP and go. The
   header card (the one holding the reactor) is the WINDOW: a blue frame — the
   1px edge plus a 3px inset ring — with 8px top corners and square bottom
   ones. The ring runs under the title band at the top and shows on the other
   three sides. No overflow:hidden anywhere here, and nothing may add it. */
:root[data-theme="winxp"] .qci-card{
  border: 1px solid var(--xp-line-2);
  border-radius: 3px;
  background: var(--panel);
  box-shadow: var(--shadow2);
  backdrop-filter: none;
}
:root[data-theme="winxp"] .qci-card::before,
:root[data-theme="winxp"] .qci-card::after{ display: none; }
:root[data-theme="winxp"] .qci-card:has(.qci-reactor){
  border-color: var(--xp-frame-edge);
  border-radius: 8px 8px 0 0;
  box-shadow: var(--xp-window-frame), var(--shadow2);
}

/* The glow bar becomes XP's etched separator: a grey line over a white one. */
:root[data-theme="winxp"] .qci-glowbar{
  height: 2px;
  margin: 10px 0 14px;
  background: none;
  opacity: 1;
  border-top: 1px solid var(--xp-line);
  border-bottom: 1px solid var(--xp-white);
}

/* ── Title bar ──────────────────────────────────────────────────────────────
   Same trick as Windows 3.11: .qci-reactor appears exactly once per page and
   on all 28 pages the row holding it is .qci-pagehead, whose inline style
   only sets the flex layout. The row is pulled out to the card's border
   (24px padding on every header card) and painted with the Luna gradient;
   its corners are the card's 8px minus the 1px border. The title, the icon
   tile, the pills and the Theme dropdown are its children. The dropdown menu
   is position:absolute inside it and is not clipped. The phone layer changes
   the card padding to 14px and 12px, so the margin is restated at both tiers. */
:root[data-theme="winxp"] .qci-card:has(.qci-reactor) .qci-pagehead{
  margin: -24px -24px 0;
  padding: 6px 8px;
  background: var(--xp-title-grad);
  color: var(--xp-on-title);
  border-radius: 7px 7px 0 0;
  /* Page-local captions on the band (crypto_dashboard.php's refresh badge, and
     anything else that paints with a muted token) go white with it: the
     tokens are re-scoped here rather than chasing the classes. The Theme menu
     inside the band does not use them. */
  --muted:   var(--xp-on-title);
  --muted-2: var(--xp-on-title);
  --muted-3: var(--xp-on-title);
  --muted-4: var(--xp-on-title);
  --label:   var(--xp-on-title);
}
@media (max-width: 820px){
  :root[data-theme="winxp"] .qci-card:has(.qci-reactor) .qci-pagehead{ margin: -14px -14px 0; }
}
@media (max-width: 480px){
  :root[data-theme="winxp"] .qci-card:has(.qci-reactor) .qci-pagehead{ margin: -12px -12px 0; }
}
:root[data-theme="winxp"] .qci-card:has(.qci-reactor) .qci-pagehead .qci-title{
  color: var(--xp-on-title);
  text-shadow: 1px 1px 0 var(--xp-title-shadow);
}
:root[data-theme="winxp"] .qci-card:has(.qci-reactor) .qci-pagehead .qci-muted{
  color: var(--xp-on-title);
}
/* USER / QCIADMINS / Theme pills become Luna caption buttons: blue gradient,
   white inner border, dark outer ring, white text — including the red admin
   tag, which would vanish on the blue. */
:root[data-theme="winxp"] .qci-card:has(.qci-reactor) .qci-pagehead .qci-tag,
:root[data-theme="winxp"] .qci-card:has(.qci-reactor) .qci-pagehead .qci-btn-ghost{
  background: var(--xp-cap-grad);
  border: 1px solid var(--xp-white);
  border-radius: 3px;
  box-shadow: 0 0 0 1px var(--xp-cap-edge);
  color: var(--xp-on-title);
  text-shadow: none;
}
:root[data-theme="winxp"] .qci-card:has(.qci-reactor) .qci-pagehead .qci-tag:hover,
:root[data-theme="winxp"] .qci-card:has(.qci-reactor) .qci-pagehead .qci-btn-ghost:hover{
  background: var(--xp-cap-grad-hover);
  border-color: var(--xp-white);
  box-shadow: 0 0 0 1px var(--xp-cap-edge);
  color: var(--xp-on-title);
}
/* The close button. .qci-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 natural place for it. With three items space-between
   would centre the tools cluster, so the cluster takes margin-left:auto
   (auto margins win over justify-content) and sits flush against the button
   with the row's 12px gap. Decoration only: no content text (screen readers
   get nothing), pointer-events:none, and the × is two diagonal gradients.
   Below 820px the row stacks vertically and the button would be a stray
   square under the pills, so it is hidden there and the auto margin is not
   applied. */
@media (min-width: 821px){
  :root[data-theme="winxp"] .qci-card:has(.qci-reactor) .qci-pagehead .qci-pagehead-tools{
    margin-left: auto;
  }
  :root[data-theme="winxp"] .qci-card:has(.qci-reactor) .qci-pagehead::after{
    content: "";
    flex: 0 0 21px;
    width: 21px;
    height: 21px;
    margin-top: 2px;
    border: 1px solid var(--xp-white);
    border-radius: 3px;
    box-shadow: 0 0 0 1px var(--xp-close-edge);
    background:
      linear-gradient(45deg, transparent calc(50% - 1px), var(--xp-white) calc(50% - 1px), var(--xp-white) calc(50% + 1px), transparent calc(50% + 1px)) center / 11px 11px no-repeat,
      linear-gradient(-45deg, transparent calc(50% - 1px), var(--xp-white) calc(50% - 1px), var(--xp-white) calc(50% + 1px), transparent calc(50% + 1px)) center / 11px 11px no-repeat,
      var(--xp-close-grad);
    pointer-events: none;
  }
}

/* ── Title: Trebuchet MS, kept to the title ─────────────────────────────────
   XP's title bars were bold Trebuchet in mixed case. 700 rather than the base
   950 (which the browser would fake), no tracking, no glow. Colour outside
   the band is the text colour; inside it the band rule above wins. */
:root[data-theme="winxp"] .qci-title{
  font-family: 'Trebuchet MS', Tahoma, var(--font);
  font-weight: 700;
  font-size: 20px;
  letter-spacing: 0;
  text-transform: none;
  text-shadow: none;
  color: var(--text);
}
/* qci-responsive.css sets 19px at 820 and 16px at 480 with a lower
   specificity than the rule above, so both phone sizes are restated here. */
@media (max-width: 820px){
  :root[data-theme="winxp"] .qci-title{ font-size: 18px; }
}
@media (max-width: 480px){
  :root[data-theme="winxp"] .qci-title{ font-size: 16px; }
}
/* No chromatic aberration in XP. */
:root[data-theme="winxp"] .qci-glitch{ text-shadow: none; }
:root[data-theme="winxp"] .qci-glitch::before,
:root[data-theme="winxp"] .qci-glitch::after{ display: none; }

/* ── Icon tile ──────────────────────────────────────────────────────────────
   The reactor stops: no rings, no spin, no glow. The 52px box becomes a
   glossy rounded Luna tile (gradient, dark edge, a white highlight along the
   top) and the core becomes a static window glyph — white title stripe over
   a beige body, white outline. Not the Windows flag: a generic icon. */
:root[data-theme="winxp"] .qci-reactor{
  box-sizing: border-box;
  background: var(--xp-icon-grad);
  border: 1px solid var(--xp-icon-edge);
  border-radius: 6px;
  box-shadow: inset 0 1px 0 var(--xp-gloss), inset 0 0 0 1px var(--xp-gloss-2);
}
:root[data-theme="winxp"] .qci-reactor-ring{ display: none; }
:root[data-theme="winxp"] .qci-reactor-core{
  inset: 14px;
  border-radius: 2px;
  border: 1px solid var(--xp-white);
  background: linear-gradient(180deg, var(--xp-white) 0 6px, var(--xp-face) 6px);
  box-shadow: var(--xp-icon-shadow);
  animation: none;
}

/* ── Buttons ────────────────────────────────────────────────────────────────
   The XP push button: white-to-beige face, #003c74 border, 3px corners,
   black Tahoma in mixed case, not bold. Hover is the orange inner ring —
   nothing lifts, nothing glows; :active is the darker pressed face;
   :focus-visible a blue inner ring. Disabled = engraved grey text. XP had no
   coloured buttons, so the variants keep the same face and differ by text
   colour; danger also takes a red border because there the colour means
   "destructive action", not the accent, as in the other ten themes. */
:root[data-theme="winxp"] .qci-btn{
  background: var(--xp-btn-grad);
  border: 1px solid var(--xp-btn-border);
  border-radius: 3px;
  box-shadow: none;
  color: var(--xp-black);
  font-family: var(--font);
  font-weight: 400;
  font-size: 12px;
  letter-spacing: 0;
  text-transform: none;
  transition: none;
}
:root[data-theme="winxp"] .qci-btn:hover{
  background: var(--xp-btn-grad);
  border-color: var(--xp-btn-border);
  box-shadow: var(--xp-hover-ring);
  transform: none;
}
:root[data-theme="winxp"] .qci-btn:active{
  background: var(--xp-btn-pressed);
  box-shadow: var(--xp-pressed-ring);
  transform: none;
}
:root[data-theme="winxp"] .qci-btn:focus-visible{
  outline: none;
  box-shadow: var(--xp-focus-ring);
}
:root[data-theme="winxp"] .qci-btn:disabled,
:root[data-theme="winxp"] .qci-btn:disabled:hover{
  opacity: 1;
  background: var(--xp-face);
  border-color: var(--xp-btn-disabled-border);
  box-shadow: none;
  color: var(--xp-disabled);
  text-shadow: 1px 1px 0 var(--xp-white);
  transform: none;
}
:root[data-theme="winxp"] .qci-btn-sm{ font-size: 11px; border-radius: 3px; }
:root[data-theme="winxp"] .qci-btn-ghost{ color: var(--muted); }
:root[data-theme="winxp"] .qci-btn-ghost:hover{ color: var(--xp-black); }
:root[data-theme="winxp"] .qci-btn-blue{ color: var(--xp-navy); }
:root[data-theme="winxp"] .qci-btn-blue:hover{ color: var(--xp-navy); }
:root[data-theme="winxp"] .qci-btn-green{ color: var(--xp-green); }
:root[data-theme="winxp"] .qci-btn-green:hover{ color: var(--xp-green); }
:root[data-theme="winxp"] .qci-btn-danger{ color: var(--xp-danger); border-color: var(--xp-danger); }
:root[data-theme="winxp"] .qci-btn-danger:hover{ color: var(--xp-danger); border-color: var(--xp-danger); }

/* ── Tags ───────────────────────────────────────────────────────────────────
   XP had no pills: light beige boxes with a grey border and 3px corners,
   black text. The coloured variants keep their meaning through the state
   solids this theme darkened for the beige; the red one is the admin marker
   and takes the danger tint rather than the (blue) accent tint. */
:root[data-theme="winxp"] .qci-tag{
  background: var(--xp-face-2);
  border: 1px solid var(--xp-line);
  border-radius: 3px;
  box-shadow: none;
  color: var(--tag-text);
}
:root[data-theme="winxp"] .qci-tag-red{
  border-color: var(--danger-30);
  background: var(--danger-09);
  color: var(--danger);
}
:root[data-theme="winxp"] .qci-tag-green{  color: var(--ok-solid); }
:root[data-theme="winxp"] .qci-tag-yellow{ color: var(--warn-solid); }
:root[data-theme="winxp"] .qci-tag-blue{   color: var(--info-b-solid); }
:root[data-theme="winxp"] .qci-theme-pick > button.qci-tag:hover{
  border-color: var(--xp-btn-border);
  color: var(--tag-text);
}

/* ── Fields: white, the XP blue-grey border, square ─────────────────────────
   The 4px halo goes; focus is the border turning Luna blue, nothing else. */
:root[data-theme="winxp"] .qci-input,
:root[data-theme="winxp"] .qci-textarea,
:root[data-theme="winxp"] select.qci-input,
:root[data-theme="winxp"] .qci-inline-select{
  background: var(--xp-white);
  border: 1px solid var(--xp-field-edge);
  border-radius: 0;
  box-shadow: none;
  color: var(--text);
}
:root[data-theme="winxp"] .qci-input:focus,
:root[data-theme="winxp"] .qci-textarea:focus,
:root[data-theme="winxp"] select.qci-input:focus,
:root[data-theme="winxp"] .qci-inline-select:focus{
  border-color: var(--xp-focus);
  box-shadow: none;
}
:root[data-theme="winxp"] .qci-terminal{
  background: var(--xp-white);
  border: 1px solid var(--xp-field-edge);
  border-radius: 0;
  box-shadow: none;
  color: var(--term-text);
}

/* ── Message boxes ──────────────────────────────────────────────────────────
   Small dialogs: beige face, 3px corners, a 1px border in the state colour.
   They also sit outside the cards on some pages (the flash), where an
   accent-blue tint on the Bliss sky would be unreadable. */
:root[data-theme="winxp"] .qci-error{
  background: var(--xp-face);
  border: 1px solid var(--danger);
  border-radius: 3px;
  box-shadow: var(--shadow);
}
:root[data-theme="winxp"] .qci-success{
  background: var(--xp-face);
  border: 1px solid var(--ok-solid);
  border-radius: 3px;
  box-shadow: var(--shadow);
}

/* ── Tabs: the XP tab control ───────────────────────────────────────────────
   Beige tabs with a grey border and 3px top corners on a grey rule; the
   selected one is white with the orange line along its top edge, hover shows
   the same line in the hover orange. */
:root[data-theme="winxp"] .qci-tabs{ border-bottom: 1px solid var(--xp-line-2); }
:root[data-theme="winxp"] .qci-tab{
  background: var(--xp-face);
  border: 1px solid var(--xp-line-2);
  border-bottom: none;
  border-radius: 3px 3px 0 0;
  box-shadow: none;
  color: var(--text);
  font-family: var(--font);
  font-weight: 400;
  font-size: 12px;
  letter-spacing: 0;
  text-transform: none;
  transition: none;
}
:root[data-theme="winxp"] .qci-tab:hover{
  background: var(--xp-face-3);
  color: var(--text);
  box-shadow: inset 0 2px 0 var(--xp-hover-1);
}
:root[data-theme="winxp"] .qci-tab.is-current{
  background: var(--xp-white);
  border-color: var(--xp-line-2);
  box-shadow: inset 0 2px 0 var(--xp-tab-hot);
  color: var(--text);
}

/* ── Tables: a list view ────────────────────────────────────────────────────
   Light beige header on a grey rule, faint rules between rows, a light blue
   row hover. The hover is NOT the selection blue on purpose: rows carry
   inline style="color:…" P&L colours that would sit on #316ac5 at ~1.5:1.
   The selection blue is kept for the states that really are "selected". */
:root[data-theme="winxp"] .qci-table th{
  background: var(--xp-face-2);
  color: var(--muted);
  border-bottom: 1px solid var(--xp-line);
}
:root[data-theme="winxp"] .qci-table td{
  border-bottom: 1px solid var(--xp-line-3);
}
:root[data-theme="winxp"] .qci-table tr:hover td{
  background: var(--xp-row-hover);
}
:root[data-theme="winxp"] .qci-table-totals td,
:root[data-theme="winxp"] .qci-table tr.qci-table-totals:hover td{
  background: var(--xp-face-2);
  border-top: 1px solid var(--xp-line);
  color: var(--text);
}

/* ── Stat tiles: the task pane ──────────────────────────────────────────────
   Explorer's "common tasks" pane: light blue with a blue border. Black is
   15.8:1 and the muted grey 6.3:1 on it. */
:root[data-theme="winxp"] .qci-stat{
  background: var(--xp-pane);
  border: 1px solid var(--xp-pane-edge);
  border-radius: 3px;
}

/* ── Menus ──────────────────────────────────────────────────────────────────
   White, grey 1px border, square, hard 2px shadow, UI font instead of mono.
   Hover and the current theme are the XP selection: blue, white text. The ✓
   on the current theme is inherited from the base rule. The menu keeps its
   overflow:hidden (the :has() release for flyouts still applies); with the
   radius at 0 it clips nothing visible. */
:root[data-theme="winxp"] .qci-dropdown-menu,
:root[data-theme="winxp"] .qci-dropdown-submenu-flyout{
  background: var(--xp-white);
  border: 1px solid var(--xp-line);
  border-radius: 0;
  box-shadow: var(--xp-menu-shadow);
  padding-top: 2px;
}
:root[data-theme="winxp"] .qci-dropdown-menu a,
:root[data-theme="winxp"] .qci-dropdown-menu button,
:root[data-theme="winxp"] .qci-dropdown-menu .qci-dropdown-placeholder,
:root[data-theme="winxp"] .qci-dropdown-submenu-label,
:root[data-theme="winxp"] .qci-dropdown-submenu-flyout a{
  font-family: var(--font);
  font-size: 12px;
  letter-spacing: 0;
  padding: 5px 24px 5px 16px;
  color: var(--text);
  border-bottom: none;
  transition: none;
}
:root[data-theme="winxp"] .qci-dropdown-menu a:hover,
:root[data-theme="winxp"] .qci-dropdown-menu button:hover,
:root[data-theme="winxp"] .qci-dropdown-menu button.is-current,
:root[data-theme="winxp"] .qci-dropdown-submenu:hover .qci-dropdown-submenu-label,
:root[data-theme="winxp"] .qci-dropdown-submenu:focus-within .qci-dropdown-submenu-label,
:root[data-theme="winxp"] .qci-dropdown-submenu-flyout a:hover{
  background: var(--xp-sel);
  color: var(--xp-on-sel);
}
/* A placeholder is a disabled menu item: engraved grey. */
:root[data-theme="winxp"] .qci-dropdown-menu .qci-dropdown-placeholder,
:root[data-theme="winxp"] .qci-dropdown-menu .qci-dropdown-placeholder:hover{
  background: none;
  color: var(--xp-disabled);
  text-shadow: 1px 1px 0 var(--xp-white);
}

/* ── Help button, modal, tooltip ────────────────────────────────────────────
   The "?" is a push button. The modal is a dialog window: blue frame, 8px
   top corners, the Luna band on its title (pulled out to the box's 24px
   padding like the page header's band) and the red close button on it — the
   close button precedes the title in the markup and is absolutely
   positioned, so it lands on the band. The tooltip is the XP balloon face. */
:root[data-theme="winxp"] .qci-help-btn{
  border-radius: 3px;
  background: var(--xp-btn-grad);
  border: 1px solid var(--xp-btn-border);
  box-shadow: none;
  color: var(--xp-black);
  font-family: var(--font);
  transition: none;
}
:root[data-theme="winxp"] .qci-help-btn:hover{
  color: var(--xp-black);
  border-color: var(--xp-btn-border);
  background: var(--xp-btn-grad);
  box-shadow: var(--xp-hover-ring);
}
:root[data-theme="winxp"] .qci-modal-box{
  background: var(--panel-solid);
  border: 1px solid var(--xp-frame-edge);
  border-radius: 8px 8px 0 0;
  box-shadow: var(--xp-window-frame), var(--shadow2);
}
:root[data-theme="winxp"] .qci-modal-title{
  margin: -24px -24px 14px;
  padding: 10px 44px 10px 12px;
  min-height: 24px;
  line-height: 24px;
  background: var(--xp-title-grad);
  border-radius: 7px 7px 0 0;
  color: var(--xp-on-title);
  text-shadow: 1px 1px 0 var(--xp-title-shadow);
  font-family: var(--font);
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0;
}
:root[data-theme="winxp"] .qci-modal-close{
  top: 11px;
  right: 11px;
  width: 21px;
  height: 21px;
  border-radius: 3px;
  border: 1px solid var(--xp-white);
  box-shadow: 0 0 0 1px var(--xp-close-edge);
  background: var(--xp-close-grad);
  color: var(--xp-on-title);
  font-family: var(--font);
  font-size: 15px;
  font-weight: 700;
  line-height: 1;
}
:root[data-theme="winxp"] .qci-modal-close:hover{
  color: var(--xp-on-title);
  border-color: var(--xp-white);
  background: var(--xp-close-grad-hover);
}
:root[data-theme="winxp"] .qci-tip{
  background: var(--xp-tip);
  border: 1px solid var(--xp-black);
  border-radius: 0;
  box-shadow: var(--xp-menu-shadow);
  color: var(--xp-black);
}

/* ── Engine stopped ─────────────────────────────────────────────────────────
   The liveness dot stays (it is a signal, not decoration) but 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="winxp"] .qci-pulse{
  animation: none;
  box-shadow: none;
}

/* ── One-off page corrections ───────────────────────────────────────────────
   Same precedent as Windows 3.11: page-local classes that set a radius or an
   accent-tinted "selected" state. */
:root[data-theme="winxp"] .view-tab{
  border-radius: 3px;
  background: var(--xp-btn-grad);
  border: 1px solid var(--xp-btn-border);
  color: var(--text);
}
:root[data-theme="winxp"] .view-tab.active,
:root[data-theme="winxp"] .hive-tab.active{
  background: var(--xp-sel);
  border-color: var(--xp-sel);
  color: var(--xp-on-sel);
}
/* dashboard.php's telemetry tiles sit directly on the desktop (not in a card)
   with a near-transparent --sink-06: on Bliss their text would be unreadable.
   They become beige panels. */
:root[data-theme="winxp"] .dash-stat{
  background: var(--xp-face);
  border: 1px solid var(--xp-line-2);
  border-radius: 3px;
  box-shadow: var(--shadow2);
}
/* The dashboard's centrepiece is the reactor scaled 7x with an animated HUD
   around it. A 364px glossy tile is 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="winxp"] .dash-reactor{ --dash-reactor-scale: 3; }
:root[data-theme="winxp"] .dash-hud,
:root[data-theme="winxp"] .dash-corner{ display: none; }
/* crypto_dashboard.php / crypto_dashboard_global.php: the P&L tiles above the
   cards sit on the desktop with a near-transparent --ov-03 gradient. Same
   treatment as .dash-stat; the coloured accent stripe on top (their ::before)
   stays. */
:root[data-theme="winxp"] .stat-tile{
  background: var(--xp-face);
  border: 1px solid var(--xp-line-2);
  border-radius: 3px;
  box-shadow: var(--shadow2);
}
/* The phone layer's burger (qci-responsive.css, loaded after this file but at
   class specificity) is an accent-tinted rounded pill; here it is a push
   button. */
:root[data-theme="winxp"] .qci-nav-burger{
  background: var(--xp-btn-grad);
  border: 1px solid var(--xp-btn-border);
  border-radius: 3px;
  box-shadow: none;
  color: var(--xp-black);
  font-family: var(--font);
  font-weight: 400;
  font-size: 12px;
  letter-spacing: 0;
  text-transform: none;
}
/* The open state is an id selector in qci-responsive.css and beats the rule
   above, so it is restated at id specificity: a pressed button. */
:root[data-theme="winxp"] #qci-nav-toggle:checked ~ .qci-nav-burger{
  background: var(--xp-btn-pressed);
  border-color: var(--xp-btn-border);
  box-shadow: var(--xp-pressed-ring);
}

/* ═══════════════════════════════════════════════════════════════════════════
   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"] .qci-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"] .qci-wrap > .qci-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"] .qci-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"] .qci-card::before,
:root[data-theme="vista"] .qci-card::after{ display: none; }

/* 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 the page-local captions too (the "COMMAND PANEL"
   label, crypto_dashboard.php's refresh badge) without naming their classes. */
:root[data-theme="vista"] .qci-card:has(.qci-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"] .qci-card:has(.qci-reactor) .qci-dropdown-menu,
:root[data-theme="vista"] .qci-card:has(.qci-reactor) .qci-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"] .qci-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"] .qci-card:has(.qci-reactor) .qci-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: .qci-reactor appears once
   per page and the row holding it is .qci-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"] .qci-card:has(.qci-reactor) .qci-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"] .qci-card:has(.qci-reactor) .qci-pagehead{ margin: -14px -14px 0; }
}
@media (max-width: 480px){
  :root[data-theme="vista"] .qci-card:has(.qci-reactor) .qci-pagehead{ margin: -12px -12px 0; }
}
:root[data-theme="vista"] .qci-card:has(.qci-reactor) .qci-pagehead .qci-title{
  color: var(--vi-on-glass);
  text-shadow: var(--vi-title-glow);
}
:root[data-theme="vista"] .qci-card:has(.qci-reactor) .qci-pagehead .qci-muted{
  color: var(--vi-on-glass-dim);
  text-shadow: var(--vi-label-glow);
}
/* The close button. .qci-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"] .qci-card:has(.qci-reactor) .qci-pagehead .qci-pagehead-tools{
    margin-left: auto;
  }
  :root[data-theme="vista"] .qci-card:has(.qci-reactor) .qci-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"] .qci-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"] .qci-title{ font-size: 19px; }
}
@media (max-width: 480px){
  :root[data-theme="vista"] .qci-title{ font-size: 17px; }
}
:root[data-theme="vista"] .qci-glitch{ text-shadow: none; }
:root[data-theme="vista"] .qci-glitch::before,
:root[data-theme="vista"] .qci-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"] .qci-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"] .qci-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"] .qci-reactor-ring:nth-child(2){
  inset: 3px;
  border: none;
  border-radius: 50%;
  background: var(--vi-orb-gloss);
  animation: none;
}
:root[data-theme="vista"] .qci-reactor-ring:nth-child(3){ display: none; }
:root[data-theme="vista"] .qci-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"] .qci-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"] .qci-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"] .qci-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"] .qci-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"] .qci-btn:disabled,
:root[data-theme="vista"] .qci-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"] .qci-btn-sm{ font-size: 11.5px; border-radius: 3px; }
:root[data-theme="vista"] .qci-btn-ghost{ color: var(--vi-ink-muted); }
:root[data-theme="vista"] .qci-btn-ghost:hover{ color: var(--vi-ink); }
:root[data-theme="vista"] .qci-btn-blue{ color: var(--red2); }
:root[data-theme="vista"] .qci-btn-blue:hover{ color: var(--red2); }
:root[data-theme="vista"] .qci-btn-green{ color: var(--ok-solid); }
:root[data-theme="vista"] .qci-btn-green:hover{ color: var(--ok-solid); }
:root[data-theme="vista"] .qci-btn-danger{ color: var(--danger); border-color: var(--danger-30); }
:root[data-theme="vista"] .qci-btn-danger:hover{ color: var(--danger); border-color: var(--danger); }

/* 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"] .qci-card:has(.qci-reactor) .qci-btn,
:root[data-theme="vista"] .qci-card:has(.qci-reactor) .qci-tag,
:root[data-theme="vista"] .qci-card:has(.qci-reactor) .qci-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"] .qci-card:has(.qci-reactor) .qci-btn:hover,
:root[data-theme="vista"] .qci-card:has(.qci-reactor) .qci-tag:hover,
:root[data-theme="vista"] .qci-card:has(.qci-reactor) .qci-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);
}
:root[data-theme="vista"] .qci-card:has(.qci-reactor) .qci-btn:active{
  background: var(--vi-glass-btn);
  box-shadow: var(--vi-btn-down-ring);
}
:root[data-theme="vista"] .qci-card:has(.qci-reactor) .qci-btn:disabled,
:root[data-theme="vista"] .qci-card:has(.qci-reactor) .qci-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"] .qci-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"] .qci-tag-red{
  border-color: var(--danger-30);
  background: var(--danger-09);
  color: var(--danger);
}
:root[data-theme="vista"] .qci-tag-green{  color: var(--ok-solid); }
:root[data-theme="vista"] .qci-tag-yellow{ color: var(--warn-solid); }
:root[data-theme="vista"] .qci-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"] .qci-input,
:root[data-theme="vista"] .qci-textarea,
:root[data-theme="vista"] select.qci-input,
:root[data-theme="vista"] .qci-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"] .qci-input:focus,
:root[data-theme="vista"] .qci-textarea:focus,
:root[data-theme="vista"] select.qci-input:focus,
:root[data-theme="vista"] .qci-inline-select:focus{
  border-color: var(--vi-btn-border-hot);
  box-shadow: var(--vi-field-ring), var(--vi-focus-ring);
}
:root[data-theme="vista"] .qci-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"] .qci-error{
  background: var(--vi-panel);
  border: 1px solid var(--danger);
  border-radius: 4px;
  box-shadow: var(--shadow2);
}
:root[data-theme="vista"] .qci-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"] .qci-tabs{ border-bottom: 1px solid var(--vi-head-edge); }
:root[data-theme="vista"] .qci-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"] .qci-tab:hover{
  background: var(--vi-btn-grad-hot);
  border-color: var(--vi-btn-border-hot);
  color: var(--vi-ink);
}
:root[data-theme="vista"] .qci-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"] .qci-table th{
  background: var(--vi-head);
  color: var(--muted);
  border-bottom: 1px solid var(--vi-head-edge);
}
:root[data-theme="vista"] .qci-table td{
  border-bottom: 1px solid var(--vi-rule);
}
:root[data-theme="vista"] .qci-table tr:hover td{
  background: var(--vi-row-hover);
}
:root[data-theme="vista"] .qci-table-totals td,
:root[data-theme="vista"] .qci-table tr.qci-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"] .qci-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"] .qci-dropdown-menu,
:root[data-theme="vista"] .qci-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"] .qci-dropdown-menu a,
:root[data-theme="vista"] .qci-dropdown-menu button,
:root[data-theme="vista"] .qci-dropdown-menu .qci-dropdown-placeholder,
:root[data-theme="vista"] .qci-dropdown-submenu-label,
:root[data-theme="vista"] .qci-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"] .qci-dropdown-menu a:hover,
:root[data-theme="vista"] .qci-dropdown-menu button:hover,
:root[data-theme="vista"] .qci-dropdown-menu button.is-current,
:root[data-theme="vista"] .qci-dropdown-submenu:hover .qci-dropdown-submenu-label,
:root[data-theme="vista"] .qci-dropdown-submenu:focus-within .qci-dropdown-submenu-label,
:root[data-theme="vista"] .qci-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"] .qci-dropdown-menu .qci-dropdown-placeholder,
:root[data-theme="vista"] .qci-dropdown-menu .qci-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"] .qci-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"] .qci-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"] .qci-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"] .qci-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"] .qci-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"] .qci-modal-close:hover{
  color: var(--vi-on-glass);
  border-color: var(--vi-close-edge);
  background: var(--vi-close-grad-hot);
}
:root[data-theme="vista"] .qci-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"] .qci-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 qci-responsive
   .css sets at id specificity. */
:root[data-theme="vista"] #qci-nav-toggle:checked ~ .qci-nav-burger{
  background: var(--vi-glass-btn-hot);
  border-color: var(--vi-glass-btn-edge-hot);
  box-shadow: var(--vi-btn-down-ring);
}

/* ═══════════════════════════════════════════════════════════════════════════
   MACOS 27 — structural section, shared by MacOS 27 (Light) and (Dark)
   Everything here is scoped to :root[data-theme^="macos27"] — both slugs start
   with that and no other theme does. The prefix selector has the specificity of
   one attribute, exactly like [data-theme="…"], so it beats the pages' <style>
   blocks the same way. No rule may escape it, or it dirties the other twelve.

   Same architecture as the three Windows themes: the base chrome applies until
   a rule below replaces it, so this section covers every shared class the
   :root chrome styles, in the same order as theirs. It contains NO colour of
   its own — day and night differ only through the --mac-* tokens each half
   defines, which is what lets one section serve two themes.

   Reference: macOS with Liquid Glass — windows of frosted glass that pick up
   the wallpaper's colour, a bright rim where the glass catches the light,
   capsule controls, accent-filled default buttons, segmented controls, menus
   whose highlight is the accent. Nothing moves.
   ═══════════════════════════════════════════════════════════════════════════ */

/* ── Desktop ────────────────────────────────────────────────────────────────
   The wallpaper sits on body::before — fixed, viewport-sized, z-index:-1 — and
   not on body's own background, so that the cards' backdrop-filter has
   something painted behind them to blur (the same reason as Vista's). It is a
   JPEG served from this site; bump ?v= in --mac-wall when the file changes. The
   scanline layer and the card sweep go. */
:root[data-theme^="macos27"] body{
  background: var(--bg0);
}
:root[data-theme^="macos27"] body::before{
  content: "";
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  opacity: 1;
  transform: none;
  animation: none;
  filter: none;
  background: var(--mac-wall) center center / cover no-repeat, var(--bg0);
}
:root[data-theme^="macos27"] body::after{ display: none; }
:root[data-theme^="macos27"] .qci-sweep{ display: none; }

/* Text directly on the desktop is a desktop-icon label: white with a soft
   shadow, because the wallpaper under it runs from cream to deep slate. */
:root[data-theme^="macos27"] .qci-wrap > .qci-muted{
  color: var(--mac-desk-ink);
  text-shadow: var(--mac-desk-shadow);
}

/* ── Windows ────────────────────────────────────────────────────────────────
   A card is a window of glass: the translucent body, the blur-and-saturate
   that makes it glass rather than a tint, a bright rim (stronger along the
   top, where light would catch it), a dark hairline and a wide soft drop. The
   HUD corners have no equivalent and go. */
:root[data-theme^="macos27"] .qci-card{
  border: 1px solid var(--mac-edge);
  border-radius: var(--radius);
  background: var(--panel);
  box-shadow:
    inset 0 1px 0 var(--mac-edge-top),
    var(--shadow2);
  backdrop-filter: var(--mac-blur);
  -webkit-backdrop-filter: var(--mac-blur);
}
:root[data-theme^="macos27"] .qci-card::before,
:root[data-theme^="macos27"] .qci-card::after{ display: none; }

/* The header card is the toolbar window: the same glass, more see-through.
   Unlike Vista's it keeps the theme's own ink — light glass by day, dark by
   night — so no token is re-scoped here and the menus need nothing put back. */
:root[data-theme^="macos27"] .qci-card:has(.qci-reactor){
  background: var(--mac-bar);
}

/* The glow bar becomes a separator hairline. */
:root[data-theme^="macos27"] .qci-glowbar{
  height: 1px;
  margin: 12px 0 14px;
  background: var(--mac-rule);
  opacity: 1;
}

/* ── Traffic lights ─────────────────────────────────────────────────────────
   .qci-pagehead is a flex row with justify-content:space-between from its
   inline style, so a ::before is a first flex item at the far left; the id
   cluster takes margin-right:auto so it stays next to it (auto margins win
   over justify-content). Decoration only — three radial gradients, no content
   text, pointer-events:none. 20px of top margin centres the 12px lights on the
   52px icon beside them. Hidden below 821px, where the row stacks. */
@media (min-width: 821px){
  :root[data-theme^="macos27"] .qci-card:has(.qci-reactor) .qci-pagehead::before{
    content: "";
    flex: 0 0 52px;
    width: 52px;
    height: 12px;
    margin-top: 20px;
    pointer-events: none;
    background:
      radial-gradient(circle at 6px 6px,  var(--mac-tl-close) 0 5px, var(--mac-tl-close-edge) 5px 6px, transparent 6.5px),
      radial-gradient(circle at 26px 6px, var(--mac-tl-min) 0 5px,   var(--mac-tl-min-edge) 5px 6px,   transparent 6.5px),
      radial-gradient(circle at 46px 6px, var(--mac-tl-zoom) 0 5px,  var(--mac-tl-zoom-edge) 5px 6px,  transparent 6.5px);
  }
  :root[data-theme^="macos27"] .qci-card:has(.qci-reactor) .qci-pagehead .qci-pagehead-id{
    margin-right: auto;
  }
}

/* ── Title ──────────────────────────────────────────────────────────────────
   The UI face, bold, mixed case, tight tracking — a window title, not a HUD
   banner. */
:root[data-theme^="macos27"] .qci-title{
  font-family: var(--font);
  font-weight: 700;
  font-size: 21px;
  letter-spacing: -.01em;
  text-transform: none;
  text-shadow: none;
  color: var(--text);
}
@media (max-width: 820px){
  :root[data-theme^="macos27"] .qci-title{ font-size: 18px; }
}
@media (max-width: 480px){
  :root[data-theme^="macos27"] .qci-title{ font-size: 16.5px; }
}
:root[data-theme^="macos27"] .qci-glitch{ text-shadow: none; }
:root[data-theme^="macos27"] .qci-glitch::before,
:root[data-theme^="macos27"] .qci-glitch::after{ display: none; }

/* ── The app icon ───────────────────────────────────────────────────────────
   The reactor becomes what sits in a Dock: a rounded-square icon (--mac-icon,
   a data: URI — three folded sheets with a lit edge, echoing the wallpaper,
   by day or by night).
   The rings and the core have no part in it and go. 23% is the corner ratio of
   a macOS icon. */
:root[data-theme^="macos27"] .qci-reactor{
  border-radius: 23%;
  background: var(--mac-icon) center / cover no-repeat;
  box-shadow:
    inset 0 0 0 .5px var(--mac-edge),
    0 1px 2px rgba(0,0,0,.25),
    0 4px 10px rgba(0,0,0,.22);
}
:root[data-theme^="macos27"] .qci-reactor-ring,
:root[data-theme^="macos27"] .qci-reactor-core{
  display: none;
  animation: none;
}

/* ── Buttons ────────────────────────────────────────────────────────────────
   A capsule of glass with the UI face in mixed case. Hover brightens it,
   pressed sinks it, focus draws the accent ring macOS draws. The variants
   keep the face and differ by ink — and danger is red ink, because there the
   colour means "destructive action" and not the accent, as in every theme. */
:root[data-theme^="macos27"] .qci-btn{
  background: var(--mac-ctl);
  border: 1px solid var(--mac-ctl-edge);
  border-radius: 999px;
  box-shadow: var(--mac-ctl-shadow);
  padding: 7px 14px;
  color: var(--text);
  font-family: var(--font);
  font-weight: 500;
  font-size: 13px;
  letter-spacing: 0;
  text-transform: none;
  transition: background .15s ease, box-shadow .15s ease;
}
:root[data-theme^="macos27"] .qci-btn:hover{
  background: var(--mac-ctl-hot);
  border-color: var(--mac-ctl-edge);
  box-shadow: var(--mac-ctl-shadow);
  transform: none;
}
:root[data-theme^="macos27"] .qci-btn:active{
  background: var(--mac-ctl-down);
  box-shadow: none;
  transform: none;
}
:root[data-theme^="macos27"] .qci-btn:focus-visible{
  outline: none;
  box-shadow: var(--mac-ctl-shadow), var(--mac-focus);
}
:root[data-theme^="macos27"] .qci-btn:disabled,
:root[data-theme^="macos27"] .qci-btn:disabled:hover{
  opacity: 1;
  background: var(--mac-ctl-down);
  box-shadow: none;
  color: var(--mac-disabled);
  transform: none;
}
:root[data-theme^="macos27"] .qci-btn-sm{ padding: 4px 11px; font-size: 12px; border-radius: 999px; }
:root[data-theme^="macos27"] .qci-btn-ghost{ background: transparent; box-shadow: none; color: var(--muted); }
:root[data-theme^="macos27"] .qci-btn-ghost:hover{ background: var(--mac-ctl-down); box-shadow: none; color: var(--text); }
:root[data-theme^="macos27"] .qci-btn-blue,
:root[data-theme^="macos27"] .qci-btn-blue:hover{ color: var(--info-b-solid); }
:root[data-theme^="macos27"] .qci-btn-green,
:root[data-theme^="macos27"] .qci-btn-green:hover{ color: var(--ok-c-solid); }
:root[data-theme^="macos27"] .qci-btn-danger,
:root[data-theme^="macos27"] .qci-btn-danger:hover{ color: var(--danger); border-color: var(--danger-30); }

/* The default button of a form is filled with the accent — the one place the
   orange is a surface. Only a plain submit takes it: a ghost, a coloured
   variant or a danger button already says what it is. */
:root[data-theme^="macos27"] button.qci-btn[type="submit"]:not(.qci-btn-ghost):not(.qci-btn-blue):not(.qci-btn-green):not(.qci-btn-danger):not(:disabled){
  background: var(--mac-fill);
  border-color: transparent;
  color: var(--mac-on-fill);
}
:root[data-theme^="macos27"] button.qci-btn[type="submit"]:not(.qci-btn-ghost):not(.qci-btn-blue):not(.qci-btn-green):not(.qci-btn-danger):not(:disabled):hover{
  background: var(--mac-fill-hot);
}
:root[data-theme^="macos27"] button.qci-btn[type="submit"]:not(.qci-btn-ghost):not(.qci-btn-blue):not(.qci-btn-green):not(.qci-btn-danger):not(:disabled):active{
  background: var(--mac-fill-down);
}

/* ── Tags ───────────────────────────────────────────────────────────────────
   Already capsules. The plain one is a glass chip; the coloured ones are
   restated with the STATE tokens — the base rule paints "red" with the accent,
   and here the accent is orange, which must never stand in for a state. */
:root[data-theme^="macos27"] .qci-tag{
  background: var(--mac-ctl);
  border: 1px solid var(--mac-ctl-edge);
  color: var(--tag-text);
  letter-spacing: .06em;
}
:root[data-theme^="macos27"] .qci-tag-red{
  border-color: var(--danger-30);
  background: var(--danger-09);
  color: var(--danger);
}
:root[data-theme^="macos27"] .qci-tag-green{
  border-color: var(--ok-30);
  background: var(--ok-08);
  color: var(--ok-solid);
}
:root[data-theme^="macos27"] .qci-tag-yellow{
  border-color: var(--warn-b-30);
  background: var(--warn-b-08);
  color: var(--warn-b-solid);
}
:root[data-theme^="macos27"] .qci-tag-blue{
  border-color: var(--info-b-30);
  background: var(--info-b-08);
  color: var(--info-b-solid);
}
/* The theme picker's trigger is a tag that behaves like a button. */
:root[data-theme^="macos27"] .qci-theme-pick > button.qci-tag:hover{
  background: var(--mac-ctl-hot);
  border-color: var(--mac-ctl-edge);
  color: var(--text);
}

/* ── Fields ─────────────────────────────────────────────────────────────────
   A rounded rectangle (fields are not capsules on macOS), a hairline, and on
   focus the wide soft accent ring. */
:root[data-theme^="macos27"] .qci-input,
:root[data-theme^="macos27"] .qci-textarea,
:root[data-theme^="macos27"] select.qci-input,
:root[data-theme^="macos27"] .qci-inline-select{
  background: var(--mac-field);
  border: 1px solid var(--mac-field-edge);
  border-radius: 8px;
  box-shadow: none;
  color: var(--text);
}
:root[data-theme^="macos27"] .qci-inline-select{ border-radius: 7px; }
:root[data-theme^="macos27"] .qci-input:focus,
:root[data-theme^="macos27"] .qci-textarea:focus,
:root[data-theme^="macos27"] select.qci-input:focus,
:root[data-theme^="macos27"] .qci-inline-select:focus{
  border-color: var(--red-60);
  box-shadow: var(--mac-focus);
}
:root[data-theme^="macos27"] .qci-terminal{
  background: var(--mac-well);
  border: 1px solid var(--mac-rule);
  border-radius: 10px;
  color: var(--term-text);
}

/* ── Message boxes ──────────────────────────────────────────────────────────
   They also sit outside the cards on some pages (the flash), straight on the
   wallpaper, where a tint would be unreadable — so they are glass of their
   own, with the border in the state colour. */
:root[data-theme^="macos27"] .qci-error,
:root[data-theme^="macos27"] .qci-success{
  background: var(--mac-sheet);
  border-radius: 12px;
  box-shadow: var(--shadow2);
  backdrop-filter: var(--mac-blur);
  -webkit-backdrop-filter: var(--mac-blur);
  color: var(--text);
}
:root[data-theme^="macos27"] .qci-error{   border: 1px solid var(--danger); }
:root[data-theme^="macos27"] .qci-success{ border: 1px solid var(--ok-solid); }

/* ── Tabs ───────────────────────────────────────────────────────────────────
   A segmented control: a recessed track, and the current segment a raised
   chip. fit-content keeps the track as wide as its segments instead of the
   card; it still wraps on a phone. */
:root[data-theme^="macos27"] .qci-tabs{
  width: fit-content;
  max-width: 100%;
  gap: 2px;
  padding: 3px;
  border-bottom: none;
  border-radius: 10px;
  background: var(--mac-seg);
  box-shadow: inset 0 0 0 .5px var(--mac-seg-edge);
}
:root[data-theme^="macos27"] .qci-tab{
  padding: 6px 14px;
  border: none;
  border-radius: 8px;
  color: var(--muted);
  font-family: var(--font);
  font-weight: 500;
  font-size: 13px;
  letter-spacing: 0;
  text-transform: none;
}
:root[data-theme^="macos27"] .qci-tab:hover{
  background: var(--mac-ctl-down);
  color: var(--text);
}
:root[data-theme^="macos27"] .qci-tab.is-current{
  background: var(--mac-ctl-on);
  border: none;
  box-shadow: var(--mac-ctl-shadow);
  color: var(--text);
}

/* ── Tables ─────────────────────────────────────────────────────────────────
   A list view: a quiet header, hairlines between rows, a faint row hover. The
   hover is not the accent on purpose — rows carry inline P&L colours. */
:root[data-theme^="macos27"] .qci-table th{
  background: var(--mac-head);
  color: var(--muted);
  letter-spacing: .06em;
  border-bottom: 1px solid var(--mac-rule);
}
:root[data-theme^="macos27"] .qci-table td{
  border-bottom: 1px solid var(--mac-rule);
}
:root[data-theme^="macos27"] .qci-table tr:hover td{
  background: var(--mac-row-hover);
}
:root[data-theme^="macos27"] .qci-table-totals td,
:root[data-theme^="macos27"] .qci-table tr.qci-table-totals:hover td{
  background: var(--mac-head);
  border-top: 1px solid var(--mac-rule-strong);
  color: var(--text);
}

/* ── Stat tiles ─────────────────────────────────────────────────────────────
   A pane of lighter glass set into the window. */
:root[data-theme^="macos27"] .qci-stat{
  background: var(--mac-tile);
  border: 1px solid var(--mac-rule);
  border-radius: 14px;
}

/* ── Menus ──────────────────────────────────────────────────────────────────
   A rounded panel with padding around the list; each item is a rounded row in
   the UI face, and the highlight is the accent with white text — the macOS
   menu, and the other place the orange is a surface. The check mark on the
   current theme is inherited from the base rule. The 6px bridge above the
   menu (::before) is kept: it is what stops :hover being lost on the way in. */
:root[data-theme^="macos27"] .qci-dropdown-menu,
:root[data-theme^="macos27"] .qci-dropdown-submenu-flyout{
  background: var(--mac-menu);
  border: 1px solid var(--mac-menu-edge);
  border-radius: 12px;
  box-shadow: var(--mac-menu-shadow);
  padding: 5px;
}
:root[data-theme^="macos27"] .qci-dropdown-menu a,
:root[data-theme^="macos27"] .qci-dropdown-menu button,
:root[data-theme^="macos27"] .qci-dropdown-menu .qci-dropdown-placeholder,
:root[data-theme^="macos27"] .qci-dropdown-submenu-label,
:root[data-theme^="macos27"] .qci-dropdown-submenu-flyout a{
  font-family: var(--font);
  font-size: 13px;
  letter-spacing: 0;
  padding: 6px 10px;
  border-radius: 7px;
  border-bottom: none;
  color: var(--text);
  transition: none;
}
:root[data-theme^="macos27"] .qci-dropdown-menu a:hover,
:root[data-theme^="macos27"] .qci-dropdown-menu button:hover,
:root[data-theme^="macos27"] .qci-dropdown-menu button.is-current:hover,
:root[data-theme^="macos27"] .qci-dropdown-submenu:hover > .qci-dropdown-submenu-label,
:root[data-theme^="macos27"] .qci-dropdown-submenu:focus-within > .qci-dropdown-submenu-label,
:root[data-theme^="macos27"] .qci-dropdown-submenu-flyout a:hover{
  background: var(--mac-fill);
  color: var(--mac-on-fill);
}
:root[data-theme^="macos27"] .qci-dropdown-menu button.is-current{ color: var(--text); font-weight: 600; }
:root[data-theme^="macos27"] .qci-dropdown-menu .qci-dropdown-placeholder,
:root[data-theme^="macos27"] .qci-dropdown-menu .qci-dropdown-placeholder:hover{
  background: none;
  color: var(--mac-disabled);
}

/* ── Help button, modal, tooltip ────────────────────────────────────────────
   The "?" is macOS's round help button. The modal is a sheet of glass — it is
   fixed over the page with nothing of its own behind it, so its blur does see
   the page — and its close button is the small round one sheets use. */
:root[data-theme^="macos27"] .qci-help-btn{
  background: var(--mac-ctl);
  border: 1px solid var(--mac-ctl-edge);
  box-shadow: var(--mac-ctl-shadow);
  color: var(--muted);
  font-family: var(--font);
}
:root[data-theme^="macos27"] .qci-help-btn:hover{
  background: var(--mac-ctl-hot);
  border-color: var(--mac-ctl-edge);
  color: var(--text);
}
:root[data-theme^="macos27"] .qci-modal-box{
  background: var(--mac-sheet);
  border: 1px solid var(--mac-edge);
  border-radius: var(--radius);
  box-shadow:
    inset 0 1px 0 var(--mac-edge-top),
    var(--shadow2);
  backdrop-filter: var(--mac-blur);
  -webkit-backdrop-filter: var(--mac-blur);
}
:root[data-theme^="macos27"] .qci-modal-title{
  font-family: var(--font);
  font-size: 15px;
  font-weight: 700;
  letter-spacing: -.005em;
}
:root[data-theme^="macos27"] .qci-modal-close{
  width: 24px;
  height: 24px;
  background: var(--mac-ctl-down);
  border: none;
  color: var(--muted);
  font-family: var(--font);
  font-size: 15px;
}
:root[data-theme^="macos27"] .qci-modal-close:hover{
  background: var(--mac-ctl-edge);
  color: var(--text);
}
:root[data-theme^="macos27"] .qci-tip{
  background: var(--mac-menu);
  border: 1px solid var(--mac-menu-edge);
  border-radius: 8px;
  box-shadow: var(--mac-menu-shadow);
  color: var(--text);
}

/* ── 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^="macos27"] .qci-pulse{
  animation: none;
}

/* ── One-off page corrections ───────────────────────────────────────────────
   The same list Vista needed, for the same reason — a translucent window over
   a picture: page-local "selected" states, the two families of tile that sit
   straight on the wallpaper (they become small windows), the dashboard's
   7x reactor (an icon carries being large, but 364px is a poster: scale 3,
   and the animated HUD around it goes), and the sticky calendar column that
   relied on an opaque --panel to cover what scrolls beneath it. */
:root[data-theme^="macos27"] .view-tab{
  border-radius: 8px;
  background: var(--mac-ctl);
  border: 1px solid var(--mac-ctl-edge);
  color: var(--text);
}
:root[data-theme^="macos27"] .view-tab.active,
:root[data-theme^="macos27"] .hive-tab.active{
  background: var(--mac-fill);
  border-color: transparent;
  color: var(--mac-on-fill);
}
:root[data-theme^="macos27"] .dash-stat,
:root[data-theme^="macos27"] .stat-tile{
  background: var(--panel);
  border: 1px solid var(--mac-edge);
  border-radius: 16px;
  box-shadow:
    inset 0 1px 0 var(--mac-edge-top),
    var(--shadow2);
  backdrop-filter: var(--mac-blur);
  -webkit-backdrop-filter: var(--mac-blur);
}
:root[data-theme^="macos27"] .dash-reactor{ --dash-reactor-scale: 3; }
:root[data-theme^="macos27"] .dash-hud,
:root[data-theme^="macos27"] .dash-corner{ display: none; }
:root[data-theme^="macos27"] .tg-time-col{
  background: var(--panel-solid);
}
/* The phone layer's burger: a glass control like the rest; qci-responsive.css
   sets its open state at id specificity, so that one is restated too. */
:root[data-theme^="macos27"] .qci-nav-burger{
  background: var(--mac-ctl);
  border: 1px solid var(--mac-ctl-edge);
  font-family: var(--font);
}
:root[data-theme^="macos27"] #qci-nav-toggle:checked ~ .qci-nav-burger{
  background: var(--mac-ctl-down);
  border-color: var(--mac-ctl-edge);
}

/* ---------- Tooltip (cabeçalhos da tabela do BTF V2) ---------- */
/* O `title` do browser não se estiliza: o tamanho da letra vem do sistema
   operativo. Este substitui-o para o texto poder ser maior e legível.
   Um só elemento, posicionado por JS e pendurado no <body> — dentro da tabela
   ficava cortado pelo `overflow-x:auto` do contentor que a envolve. */
.qci-tip{
  position: fixed;
  z-index: 1200;
  display: none;
  max-width: 420px;
  background: var(--panel-solid);
  border: 1px solid var(--ov-15);
  border-radius: var(--radius);
  box-shadow: var(--shadow2);
  color: var(--text);
  padding: 10px 12px;
  font-size: 17px;
  line-height: 1.45;
  font-weight: 400;
  text-align: left;
  text-transform: none;
  letter-spacing: normal;
  pointer-events: none;   /* nunca rouba o rato ao que está por baixo */
}
.qci-tip.open{ display: block; }

/* ---------- Pills dos grupos de colunas (tabela do BTF V2) ---------- */
/* Ligam e desligam blocos de colunas. Ficam por cima da tabela e não dentro do
   cabeçalho: dentro, cada grupo tinha de caber na largura das suas colunas e a
   tabela rola na horizontal — metade das pills ficava fora do ecrã. */
.qci-colpills{
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  align-items: center;
  margin-top: 12px;
}
.qci-colpill{
  cursor: pointer;
  font-family: inherit;
  border-color: var(--ov-15);
}
.qci-colpill:hover{ border-color: var(--red-25); color: var(--text); }
/* Desligada: continua legível, para se saber o que se pode voltar a ligar. */
.qci-colpill.is-off{
  opacity: .42;
  text-decoration: line-through;
}

/* ═══════════════════════════════════════════════════════════════════════════
   PAPER SITE — tokens and structural section
   Everything here is scoped to :root[data-theme="paper_site"]. No rule may
   escape that, or it dirties the other themes.

   A desk of cream sheets: every card is a page of a ruled notebook (faint blue
   lines, a red margin, a strip of tape holding it down), the title is written
   with a pen, buttons and fields are drawn by hand, the current tab and the
   menu selection are a swipe of yellow highlighter. Prose is handwritten
   (Kalam); figures are TYPED (Courier Prime in --mono), which is also what
   keeps a table of numbers readable. Nothing glows and nothing moves.

   Like Windows 3.11 it takes the light themes' shared TOKENS (it is in that
   selector) but not their grouped structural rules, so this section replaces
   every piece of base dark chrome one by one. The same checklist: body and its
   two pseudos, card and its corners, glowbar, sweep, title/glitch, reactor,
   buttons, tags, fields, terminal, messages, tabs, tables, stat, menus, help,
   modal, tooltip, page one-offs, the phone burger.
   ═══════════════════════════════════════════════════════════════════════════ */

:root[data-theme="paper_site"]{
  --accent-glow: rgba(35,64,142,.05);
  --red: #23408e;
  --red2: #1d3576;
  --rc-a-15: rgba(35,64,142,.22);
  --rc-a-60: rgba(35,64,142,.6);
  --rc-a-85: rgba(35,64,142,.85);
  --rc-b-35: rgba(26,46,106,.52);
  --rc-b-50: rgba(26,46,106,.5);
  --rc-c-18: rgba(35,64,142,.27);
  --rc-c-95: rgba(35,64,142,.95);
  --rc-cold: #152650;
  --rc-d-12: rgba(35,64,142,.18);
  --rc-d-70: rgba(35,64,142,.7);
  --rc-e-90: rgba(35,64,142,.9);
  --rc-f-50: rgba(35,64,142,.5);
  --rc-g-100: rgba(35,64,142,1);
  --rc-h-80: rgba(26,46,106,.8);
  --rc-hot: #8ea3dd;
  --rc-mid: #23408e;
  --red-03: rgba(35,64,142,.04);
  --red-04: rgba(35,64,142,.06);
  --red-05: rgba(35,64,142,.08);
  --red-06: rgba(35,64,142,.09);
  --red-07: rgba(35,64,142,.11);
  --red-08: rgba(35,64,142,.12);
  --red-10: rgba(35,64,142,.15);
  --red-12: rgba(35,64,142,.18);
  --red-14: rgba(35,64,142,.21);
  --red-16: rgba(35,64,142,.24);
  --red-18: rgba(35,64,142,.27);
  --red-20: rgba(35,64,142,.3);
  --red-22: rgba(35,64,142,.33);
  --red-28: rgba(35,64,142,.42);
  --red-30: rgba(35,64,142,.45);
  --red-35: rgba(35,64,142,.52);
  --red-40: rgba(35,64,142,.6);
  --red-45: rgba(35,64,142,.68);
  --red-55: rgba(35,64,142,.55);
  --red-60: rgba(35,64,142,.6);
  --red-70: rgba(35,64,142,.7);
  --red-95: rgba(35,64,142,.95);
  --red-b-10: rgba(35,64,142,.15);
  --red-b-25: rgba(35,64,142,.38);
  --red-b-50: rgba(35,64,142,.5);
  --red-d-15: rgba(35,64,142,.22);
  --red-dark-18: rgba(26,46,106,.27);
  --red-dark-60: rgba(26,46,106,.6);
  --red-dark2-35: rgba(26,46,106,.52);
  --red-e-85: rgba(35,64,142,.85);
  --red-15: rgba(35,64,142,.22);
  --red-25: rgba(35,64,142,.38);
  --red-b-85: rgba(35,64,142,.85);
  --red-e-90: rgba(35,64,142,.9);
  --red-e-95: rgba(35,64,142,.95);
  --red-b-70: rgba(35,64,142,.7);
}
:root[data-theme="paper_site"]{
  /* Handwriting for words, a typewriter for figures, Caveat for the title only
     (see .qci-title below — the rule Blueprint and ZX Spectrum follow). Kalam
     has real 300/400/700 weights and a normal x-height, so bold is never faked
     and 12-13px captions still resolve. */
  --font: 'Kalam', 'Segoe Print', 'Bradley Hand', 'Comic Sans MS', cursive;
  --mono: 'Courier Prime', 'Courier New', Courier, ui-monospace, monospace;

  /* The desk, and the sheets on it. --panel is opaque, so family_calendar.php's
     sticky column needs nothing. */
  --bg0: #e9e0c9;
  --bg1: #e2d8bf;
  --panel: #fffdf6;
  --panel-solid: #fffdf6;
  --line: rgba(38,36,43,.18);
  --radius: 3px;
  --shadow: 0 1px 2px rgba(70,52,20,.14);
  --shadow2: 0 1px 1px rgba(70,52,20,.10), 0 12px 24px -10px rgba(70,52,20,.32);

  /* Text: graphite and ink. Measured on the paper #fffdf6 and on the
     highlighter #fff1a6 (the worst background a line of text sits on here):
     --text 15.1 / 13.4, --muted 6.9 / 6.2, --muted-2..4 5.8 / 5.1, --label 9.4. */
  --text: #26242b;
  --text-b: #26242b;
  --text-c: #3b3834;
  --text-d: #3b3834;
  --muted:   #5e584d;
  --muted-2: #6b6457;
  --muted-3: #6b6457;
  --muted-4: #6b6457;
  --label:   #4a4538;
  --grey-a:  #5e584d;
  --grey-b:  #5e584d;
  --grey-c:  #6b6457;
  --tag-text: #3b3834;
  --term-text: #26242b;

  /* State colours as ink on cream, same hues as the light block, darkened to
     hold AA on the highlighter too: ok 6.5 / 5.8, warn 6.7 / 6.0, info 7.1 /
     6.3, danger 6.4 / 5.7 (paper / highlighter). */
  --ok-solid:   #1b6b34;
  --ok-b-solid: #1b6b34;
  --ok-c-solid: #1b6b34;
  --ok-d-solid: #1b6b34;
  --ok-e-solid: #1b6b34;
  --warn-solid:    #8a4b00;
  --warn-b-solid:  #8a4b00;
  --amber-solid:   #8a4b00;
  --amber-f-solid: #8a4b00;
  --info-solid:   #0b5f73;
  --info-b-solid: #0b5f73;
  --info-c-solid: #0b5f73;
  --info-d-solid: #0b5f73;
  --danger:      #b3261e;
  --red-f-solid: #b3261e;
  --purple-solid:   #6b21a8;
  --purple-c-solid: #6b21a8;
  --purple-d-solid: #6b21a8;
  --error-text:   #8f1d17;
  --success-text: #14532d;

  /* The stationery, for this theme's chrome only. --pp-ink is the accent. */
  --pp-desk:        #e9e0c9;
  --pp-paper:       #fffdf6;
  --pp-ink:         #23408e;
  --pp-graphite:    #26242b;
  --pp-pencil:      #6b6457;
  --pp-edge:        rgba(90,70,30,.16);
  --pp-rule:        rgba(58,110,190,.13);
  --pp-margin:      rgba(214,64,64,.34);
  --pp-tape:        rgba(236,222,168,.78);
  --pp-tape-edge:   rgba(120,100,50,.16);
  --pp-grain:       rgba(90,70,30,.16);
  --pp-hilite:      #fff1a6;
  --pp-hilite-soft: rgba(255,236,120,.38);
  --pp-note:        #fff5bf;
  --pp-note-pink:   #ffe4df;
  --pp-note-green:  #e4f4dc;
  --pp-lift:        2px 3px 0 -1px rgba(38,36,43,.30);
  /* Hand-drawn corners: four different radii on each axis is what makes a box
     read as drawn rather than printed. -sm is the same idea for small pills. */
  --pp-wobble:    255px 18px 225px 18px / 18px 225px 18px 255px;
  --pp-wobble-sm: 12px 4px 10px 5px / 5px 10px 4px 12px;
}

/* ── The desk ───────────────────────────────────────────────────────────────
   Kraft-coloured, with a paper grain from an SVG noise used as a MASK over a
   token colour (a mask carries no colour of its own). z-index:-1 keeps it
   behind every card — the base pseudo is z-index:auto and would sit on top of
   non-positioned text. The scanlines go. */
:root[data-theme="paper_site"] body{
  background: var(--pp-desk);
}
:root[data-theme="paper_site"] body::before{
  inset: 0;
  z-index: -1;
  background: var(--pp-grain);
  background-size: auto;
  opacity: 1;
  transform: none;
  animation: none;
  -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='240' height='240'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.8' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1.4 -.35'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
          mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='240' height='240'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.8' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1.4 -.35'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
}
:root[data-theme="paper_site"] body::after{ display: none; }
:root[data-theme="paper_site"] .qci-sweep{ display: none; }
/* A caption lying on the desk rather than on a sheet: --muted is 5.4:1 there,
   the lighter greys are not. */
:root[data-theme="paper_site"] .qci-wrap > .qci-muted{ color: var(--muted); }

/* ── The sheets ─────────────────────────────────────────────────────────────
   Ruled every 28px with a red margin 13px in (inside the 24px padding, so no
   text crosses it), lifted off the desk by a soft shadow. The HUD corners
   become a strip of tape at the top; the other corner goes. */
:root[data-theme="paper_site"] .qci-card{
  border: 1px solid var(--pp-edge);
  border-radius: var(--radius);
  background:
    linear-gradient(90deg, transparent 0 13px, var(--pp-margin) 13px 14px, transparent 14px),
    repeating-linear-gradient(to bottom, transparent 0 27px, var(--pp-rule) 27px 28px),
    var(--pp-paper);
  box-shadow: var(--shadow2);
  backdrop-filter: none;
}
/* The phone layer pads a card at 14px and 12px, so the margin line would run
   through the first letter of every line: below 820px the sheet keeps only
   its rules. */
@media (max-width: 820px){
  :root[data-theme="paper_site"] .qci-card{
    background:
      repeating-linear-gradient(to bottom, transparent 0 27px, var(--pp-rule) 27px 28px),
      var(--pp-paper);
  }
}
:root[data-theme="paper_site"] .qci-card::before{
  left: 50%; top: -11px;
  width: 104px; height: 24px;
  border: none;
  border-radius: 0;
  background: var(--pp-tape);
  box-shadow: 0 1px 1px var(--pp-tape-edge);
  opacity: 1;
  transform: translateX(-50%) rotate(-2.5deg);
  /* torn ends */
  clip-path: polygon(0 8%, 4% 0, 8% 10%, 12% 0, 88% 0, 92% 12%, 96% 0, 100% 10%, 100% 90%, 96% 100%, 92% 88%, 88% 100%, 12% 100%, 8% 90%, 4% 100%, 0 92%);
}
:root[data-theme="paper_site"] .qci-card::after{ display: none; }

/* The glow bar becomes a line drawn in ink: a wave from an SVG mask, painted
   with the accent token. */
:root[data-theme="paper_site"] .qci-glowbar{
  height: 8px;
  margin: 8px 0 12px;
  opacity: .8;
  background: var(--pp-ink);
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='64' height='8'%3E%3Cpath d='M0 4 Q8 1 16 4 T32 4 T48 4 T64 4' fill='none' stroke='black' stroke-width='1.6' stroke-linecap='round'/%3E%3C/svg%3E") repeat-x left center / 64px 8px;
          mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='64' height='8'%3E%3Cpath d='M0 4 Q8 1 16 4 T32 4 T48 4 T64 4' fill='none' stroke='black' stroke-width='1.6' stroke-linecap='round'/%3E%3C/svg%3E") repeat-x left center / 64px 8px;
}

/* ── Title: written with a pen ──────────────────────────────────────────────
   Caveat 700 in ink, mixed case, tilted a degree. Caveat runs small for its
   size, hence 42px. */
:root[data-theme="paper_site"] .qci-title{
  font-family: 'Caveat', var(--font);
  font-weight: 700;
  font-size: 42px;
  line-height: 1;
  letter-spacing: .01em;
  text-transform: none;
  text-shadow: none;
  color: var(--pp-ink);
  transform: rotate(-1deg);
  transform-origin: left center;
}
@media (max-width: 820px){
  :root[data-theme="paper_site"] .qci-title{ font-size: 32px; }
}
:root[data-theme="paper_site"] .qci-glitch{ text-shadow: none; }
:root[data-theme="paper_site"] .qci-glitch::before,
:root[data-theme="paper_site"] .qci-glitch::after{ display: none; }

/* Captions: the base is uppercase with wide tracking, which in a hand is
   shouting. Written normally instead. */
:root[data-theme="paper_site"] .qci-muted{
  text-transform: none;
  letter-spacing: .02em;
  font-size: 13px;
}

/* ── The reactor becomes a doodle ───────────────────────────────────────────
   Two loops of a pen that do not quite close (different radii, turned apart)
   around an ink dot. Nothing spins. */
:root[data-theme="paper_site"] .qci-reactor-ring{
  animation: none;
  box-shadow: none;
  border: 2px solid var(--pp-ink);
  border-radius: 48% 52% 45% 55% / 55% 45% 52% 48%;
  opacity: .85;
}
:root[data-theme="paper_site"] .qci-reactor-ring:nth-child(1){ inset: 2px; transform: rotate(8deg); }
:root[data-theme="paper_site"] .qci-reactor-ring:nth-child(2){ inset: 5px; transform: rotate(-22deg); border-color: var(--pp-pencil); opacity: .7; }
:root[data-theme="paper_site"] .qci-reactor-ring:nth-child(3){ display: none; }
:root[data-theme="paper_site"] .qci-reactor-core{
  inset: 20px;
  border-radius: 45% 55% 50% 50% / 55% 45% 55% 45%;
  background: var(--pp-ink);
  box-shadow: none;
  animation: none;
}

/* ── Buttons: drawn by hand ─────────────────────────────────────────────────
   A pencil outline with wobbly corners and a hard offset shadow, handwritten
   label. Hover tilts the paper a degree and runs the highlighter over it;
   pressing flattens the shadow. The variants change the ink, never the shape;
   danger stays red because there the colour means "destructive". */
:root[data-theme="paper_site"] .qci-btn{
  background: var(--pp-paper);
  border: 2px solid var(--pp-graphite);
  border-radius: var(--pp-wobble);
  box-shadow: var(--pp-lift);
  color: var(--text);
  font-family: var(--font);
  font-weight: 700;
  font-size: 15px;
  line-height: 1.2;
  letter-spacing: .01em;
  text-transform: none;
  transition: transform .12s ease, background .12s ease;
}
:root[data-theme="paper_site"] .qci-btn:hover{
  background: var(--pp-hilite-soft);
  border-color: var(--pp-graphite);
  box-shadow: var(--pp-lift);
  transform: rotate(-1deg) translateY(-1px);
}
:root[data-theme="paper_site"] .qci-btn:active{
  box-shadow: none;
  transform: translate(1px, 2px);
}
:root[data-theme="paper_site"] .qci-btn:disabled,
:root[data-theme="paper_site"] .qci-btn:disabled:hover{
  opacity: .5;
  background: var(--pp-paper);
  transform: none;
}
:root[data-theme="paper_site"] .qci-btn-sm{ font-size: 14px; }
:root[data-theme="paper_site"] .qci-btn-ghost{
  border-style: dashed;
  border-color: var(--pp-pencil);
  box-shadow: none;
  color: var(--muted);
}
:root[data-theme="paper_site"] .qci-btn-ghost:hover{ border-color: var(--pp-pencil); box-shadow: none; color: var(--text); }
:root[data-theme="paper_site"] .qci-btn-blue,
:root[data-theme="paper_site"] .qci-btn-blue:hover{ border-color: var(--pp-ink); color: var(--pp-ink); }
:root[data-theme="paper_site"] .qci-btn-green,
:root[data-theme="paper_site"] .qci-btn-green:hover{ border-color: var(--ok-solid); color: var(--ok-solid); }
:root[data-theme="paper_site"] .qci-btn-danger,
:root[data-theme="paper_site"] .qci-btn-danger:hover{ border-color: var(--danger); color: var(--danger); }

/* ── Tags: pencilled labels ─────────────────────────────────────────────── */
:root[data-theme="paper_site"] .qci-tag{
  background: transparent;
  border: 1.5px solid var(--pp-pencil);
  border-radius: var(--pp-wobble-sm);
  box-shadow: none;
  color: var(--tag-text);
  font-family: var(--font);
  font-size: 13px;
  letter-spacing: .02em;
  text-transform: none;
}
:root[data-theme="paper_site"] .qci-tag-red{    border-color: var(--danger);     color: var(--danger); }
:root[data-theme="paper_site"] .qci-tag-green{  border-color: var(--ok-solid);   color: var(--ok-solid); }
:root[data-theme="paper_site"] .qci-tag-yellow{ border-color: var(--warn-solid); color: var(--warn-solid); }
:root[data-theme="paper_site"] .qci-tag-blue{   border-color: var(--info-solid); color: var(--info-solid); }
:root[data-theme="paper_site"] .qci-theme-pick > button.qci-tag:hover{
  border-color: var(--pp-graphite);
  background: var(--pp-hilite-soft);
  color: var(--text);
}

/* ── Fields: boxes drawn on the page ────────────────────────────────────────
   Focus is an ink outline and a faint blue wash, not a glow. */
:root[data-theme="paper_site"] .qci-input,
:root[data-theme="paper_site"] .qci-textarea,
:root[data-theme="paper_site"] select.qci-input,
:root[data-theme="paper_site"] .qci-inline-select{
  background: var(--pp-paper);
  border: 1.5px solid var(--pp-pencil);
  border-radius: var(--pp-wobble-sm);
  box-shadow: none;
  color: var(--text);
  font-family: var(--font);
  /* Kalam's ascent and descent are tall; at the inherited line-height a
     select grew to ~50px. */
  line-height: 1.2;
}
:root[data-theme="paper_site"] .qci-input:focus,
:root[data-theme="paper_site"] .qci-textarea:focus,
:root[data-theme="paper_site"] select.qci-input:focus,
:root[data-theme="paper_site"] .qci-inline-select:focus{
  border-color: var(--pp-ink);
  box-shadow: 0 0 0 3px var(--red-10);
}
/* The terminal is a typed sheet. */
:root[data-theme="paper_site"] .qci-terminal{
  background: var(--pp-paper);
  border: 1px dashed var(--pp-pencil);
  border-radius: var(--radius);
  box-shadow: none;
  color: var(--term-text);
  font-family: var(--mono);
}

/* ── Messages: sticky notes ─────────────────────────────────────────────────
   Pink for an error, green for a success, a hair off square. The base paints
   them with the accent family, which here would be blue. Text: 7.1:1 / 8.6:1. */
:root[data-theme="paper_site"] .qci-error,
:root[data-theme="paper_site"] .qci-success{
  border: none;
  border-radius: 2px;
  box-shadow: var(--shadow), 0 6px 12px -8px var(--pp-tape-edge);
  transform: rotate(-.4deg);
}
:root[data-theme="paper_site"] .qci-error{   background: var(--pp-note-pink);  color: var(--error-text); }
:root[data-theme="paper_site"] .qci-success{ background: var(--pp-note-green); color: var(--success-text); }

/* ── Tabs: the highlighter ──────────────────────────────────────────────────
   Plain handwritten words on the page; the current one is swiped with yellow
   highlighter (the lower two thirds of the line, as a real swipe lands). */
:root[data-theme="paper_site"] .qci-tabs{ border-bottom: 1.5px solid var(--line); }
:root[data-theme="paper_site"] .qci-tab{
  background: none;
  border: none;
  border-radius: 0;
  box-shadow: none;
  color: var(--muted);
  font-family: var(--font);
  font-size: 15px;
  letter-spacing: .01em;
  text-transform: none;
}
:root[data-theme="paper_site"] .qci-tab:hover{
  color: var(--text);
  background: linear-gradient(transparent 62%, var(--pp-hilite-soft) 62% 90%, transparent 90%);
}
:root[data-theme="paper_site"] .qci-tab.is-current{
  color: var(--text);
  font-weight: 700;
  background: linear-gradient(transparent 36%, var(--pp-hilite) 36% 90%, transparent 90%);
  border: none;
  box-shadow: none;
}

/* ── Tables: a ruled ledger ─────────────────────────────────────────────────
   Handwritten headings over a double rule, a faint rule under each line, the
   hover is a pale highlighter (inline P&L colours hold AA on it). */
:root[data-theme="paper_site"] .qci-table th{
  background: none;
  color: var(--text);
  font-family: var(--font);
  font-weight: 700;
  font-size: 13px;
  letter-spacing: .02em;
  text-transform: none;
  border-bottom: 3px double var(--pp-pencil);
}
:root[data-theme="paper_site"] .qci-table td{ border-bottom: 1px solid var(--pp-rule); }
:root[data-theme="paper_site"] .qci-table tr:hover td{ background: var(--pp-hilite-soft); }
:root[data-theme="paper_site"] .qci-table-totals td,
:root[data-theme="paper_site"] .qci-table tr.qci-table-totals:hover td{
  background: none;
  border-top: 2px solid var(--pp-graphite);
  color: var(--text);
  font-weight: 700;
}

/* ── Stat tiles: index cards ────────────────────────────────────────────── */
:root[data-theme="paper_site"] .qci-stat{
  background: var(--pp-paper);
  border: 1.5px solid var(--line);
  border-radius: var(--pp-wobble-sm);
  box-shadow: var(--shadow);
}

/* ── Menus: a slip of paper; the selection is highlighted ─────────────────── */
:root[data-theme="paper_site"] .qci-dropdown-menu,
:root[data-theme="paper_site"] .qci-dropdown-submenu-flyout{
  background: var(--pp-paper);
  border: 1px solid var(--pp-edge);
  border-radius: var(--radius);
  box-shadow: var(--shadow2);
}
:root[data-theme="paper_site"] .qci-dropdown-menu a,
:root[data-theme="paper_site"] .qci-dropdown-menu button,
:root[data-theme="paper_site"] .qci-dropdown-menu .qci-dropdown-placeholder,
:root[data-theme="paper_site"] .qci-dropdown-submenu-label,
:root[data-theme="paper_site"] .qci-dropdown-submenu-flyout a{
  font-family: var(--font);
  font-size: 15px;
  letter-spacing: 0;
  text-transform: none;
  color: var(--text);
  border-bottom: 1px solid var(--pp-rule);
}
:root[data-theme="paper_site"] .qci-dropdown-menu a:hover,
:root[data-theme="paper_site"] .qci-dropdown-menu button:hover,
:root[data-theme="paper_site"] .qci-dropdown-menu button.is-current,
:root[data-theme="paper_site"] .qci-dropdown-submenu:hover .qci-dropdown-submenu-label,
:root[data-theme="paper_site"] .qci-dropdown-submenu:focus-within .qci-dropdown-submenu-label,
:root[data-theme="paper_site"] .qci-dropdown-submenu-flyout a:hover{
  background: var(--pp-hilite);
  color: var(--text);
}
:root[data-theme="paper_site"] .qci-dropdown-menu .qci-dropdown-placeholder,
:root[data-theme="paper_site"] .qci-dropdown-menu .qci-dropdown-placeholder:hover{
  background: none;
  color: var(--muted-2);
}

/* ── Help button, modal, tooltip ────────────────────────────────────────────
   "?" and "×" in pencilled circles; the modal is another sheet (ruled, taped
   by nothing — it floats); the tooltip is a sticky note. */
:root[data-theme="paper_site"] .qci-help-btn,
:root[data-theme="paper_site"] .qci-modal-close{
  background: var(--pp-paper);
  border: 1.5px solid var(--pp-graphite);
  border-radius: 48% 52% 45% 55% / 55% 45% 52% 48%;
  box-shadow: none;
  color: var(--text);
  font-family: var(--font);
}
:root[data-theme="paper_site"] .qci-help-btn:hover,
:root[data-theme="paper_site"] .qci-modal-close:hover{
  background: var(--pp-hilite-soft);
  border-color: var(--pp-graphite);
  color: var(--text);
}
:root[data-theme="paper_site"] .qci-modal-box{
  background:
    linear-gradient(90deg, transparent 0 13px, var(--pp-margin) 13px 14px, transparent 14px),
    repeating-linear-gradient(to bottom, transparent 0 27px, var(--pp-rule) 27px 28px),
    var(--pp-paper);
  border: 1px solid var(--pp-edge);
  border-radius: var(--radius);
  box-shadow: var(--shadow2);
}
:root[data-theme="paper_site"] .qci-modal-title{
  font-family: 'Caveat', var(--font);
  font-weight: 700;
  font-size: 30px;
  letter-spacing: .01em;
  text-transform: none;
  color: var(--pp-ink);
}
:root[data-theme="paper_site"] .qci-tip{
  background: var(--pp-note);
  border: none;
  border-radius: 2px;
  box-shadow: var(--shadow2);
  color: var(--text);
  font-family: var(--font);
}

/* ── One-off page corrections ───────────────────────────────────────────── */
:root[data-theme="paper_site"] .view-tab{ border-radius: var(--pp-wobble-sm); font-family: var(--font); }
:root[data-theme="paper_site"] .view-tab.active,
:root[data-theme="paper_site"] .hive-tab.active{
  background: var(--pp-hilite);
  border-color: var(--pp-graphite);
  color: var(--text);
}
/* dashboard.php's tiles and the crypto dashboards' P&L tiles sit on the desk,
   not on a sheet: they become index cards. */
:root[data-theme="paper_site"] .dash-stat,
:root[data-theme="paper_site"] .stat-tile{
  background: var(--pp-paper);
  border: 1px solid var(--pp-edge);
  border-radius: var(--radius);
  box-shadow: var(--shadow2);
}
/* The dashboard's centrepiece is the reactor scaled 7x inside an animated HUD.
   A doodle that size is a scribble; scale 3 and no HUD, like Windows 3.11. */
:root[data-theme="paper_site"] .dash-reactor{ --dash-reactor-scale: 3; }
:root[data-theme="paper_site"] .dash-hud,
:root[data-theme="paper_site"] .dash-corner{ display: none; }
/* The phone burger (qci-responsive.css, class specificity) and its open state
   (id specificity there, so restated at id specificity here). */
:root[data-theme="paper_site"] .qci-nav-burger{
  background: var(--pp-paper);
  border: 2px solid var(--pp-graphite);
  border-radius: var(--pp-wobble);
  box-shadow: var(--pp-lift);
  color: var(--text);
  font-family: var(--font);
  font-weight: 700;
  letter-spacing: .02em;
  text-transform: none;
}
:root[data-theme="paper_site"] #qci-nav-toggle:checked ~ .qci-nav-burger{
  background: var(--pp-hilite-soft);
  box-shadow: none;
}

@media (prefers-reduced-motion: reduce){
  :root[data-theme="paper_site"] .qci-btn,
  :root[data-theme="paper_site"] .qci-btn:hover{ transition: none; transform: none; }
}


/* ── Silver button (the MystiQ topnav link, 2026-10-19) ───────────────────────
   Brushed metal: a steel gradient with a light sheen on the upper half, a silver
   edge and a cool glow. Unlike .qci-btn-blue it is meant to look the same on every
   theme, so it outranks each theme's own `.qci-btn` (`:root[data-theme] .qci-btn`
   rules, specificity 0,3,0) and sits at the end of the file. Light themes get a
   bright silver with dark text instead, which reads as metal on a white page. */
.qci-btn.qci-btn-silver,
:root[data-theme] .qci-btn.qci-btn-silver{
  color: #f2f4f7;
  border-color: #c3c9d2;
  background:
    linear-gradient(180deg, rgba(255,255,255,.30) 0%, rgba(255,255,255,0) 46%, rgba(0,0,0,.20) 54%, rgba(255,255,255,.08) 100%),
    linear-gradient(180deg, #8d949e, #5a606a);
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,.45),
    0 0 10px rgba(200,207,216,.30),
    0 0 26px rgba(200,207,216,.14);
  text-shadow: 0 1px 1px rgba(0,0,0,.45);
}
.qci-btn.qci-btn-silver:hover,
:root[data-theme] .qci-btn.qci-btn-silver:hover{
  color: #ffffff;
  border-color: #eef1f5;
  background:
    linear-gradient(180deg, rgba(255,255,255,.38) 0%, rgba(255,255,255,0) 46%, rgba(0,0,0,.16) 54%, rgba(255,255,255,.10) 100%),
    linear-gradient(180deg, #a2a9b3, #69707a);
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,.55),
    0 0 14px rgba(220,226,234,.40),
    0 0 40px rgba(220,226,234,.20);
}
:root[data-theme="red_quito"] .qci-btn.qci-btn-silver,
:root[data-theme="blue_quito"] .qci-btn.qci-btn-silver,
:root[data-theme="zx_spectrum"] .qci-btn.qci-btn-silver,
:root[data-theme="paper_site"] .qci-btn.qci-btn-silver,
:root[data-theme="macos27_light"] .qci-btn.qci-btn-silver,
:root[data-theme="win311"] .qci-btn.qci-btn-silver,
:root[data-theme="winxp"] .qci-btn.qci-btn-silver{
  color: #1f2329;
  border-color: #8e959f;
  background: linear-gradient(180deg, #fbfcfd 0%, #e2e6ea 45%, #c3c8cf 55%, #e7eaee 100%);
  box-shadow: inset 0 1px 0 #ffffff, 0 1px 2px rgba(0,0,0,.18);
  text-shadow: 0 1px 0 rgba(255,255,255,.75);
}
:root[data-theme="red_quito"] .qci-btn.qci-btn-silver:hover,
:root[data-theme="blue_quito"] .qci-btn.qci-btn-silver:hover,
:root[data-theme="zx_spectrum"] .qci-btn.qci-btn-silver:hover,
:root[data-theme="paper_site"] .qci-btn.qci-btn-silver:hover,
:root[data-theme="macos27_light"] .qci-btn.qci-btn-silver:hover,
:root[data-theme="win311"] .qci-btn.qci-btn-silver:hover,
:root[data-theme="winxp"] .qci-btn.qci-btn-silver:hover{
  color: #0b0d10;
  border-color: #6f7680;
  background: linear-gradient(180deg, #ffffff 0%, #eceff2 45%, #cfd4da 55%, #f1f3f5 100%);
  box-shadow: inset 0 1px 0 #ffffff, 0 0 8px rgba(140,148,160,.45);
}
/* Windows Vista is dark glass, and its header-card buttons carry a stronger rule
   (`.qci-card:has(.qci-reactor) .qci-btn`, 0,5,0) than the generic one above. */
:root[data-theme="vista"] .qci-card:has(.qci-reactor) .qci-btn.qci-btn-silver{
  color: #f2f4f7;
  border-color: #c3c9d2;
  background:
    linear-gradient(180deg, rgba(255,255,255,.30) 0%, rgba(255,255,255,0) 46%, rgba(0,0,0,.20) 54%, rgba(255,255,255,.08) 100%),
    linear-gradient(180deg, #8d949e, #5a606a);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.45), 0 0 8px rgba(200,207,216,.30);
  text-shadow: 0 1px 1px rgba(0,0,0,.45);
}
:root[data-theme="vista"] .qci-card:has(.qci-reactor) .qci-btn.qci-btn-silver:hover{
  color: #ffffff;
  border-color: #eef1f5;
  background:
    linear-gradient(180deg, rgba(255,255,255,.38) 0%, rgba(255,255,255,0) 46%, rgba(0,0,0,.16) 54%, rgba(255,255,255,.10) 100%),
    linear-gradient(180deg, #a2a9b3, #69707a);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.55), 0 0 12px rgba(220,226,234,.40);
}
